mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-06 16:56:55 +08:00
R=fbarchard@google.com BUG=libyuv:634 Performance Gain (vs C vectorized) ScaleARGBRowDown2_MSA - ~2.6x ScaleARGBRowDown2Linear_MSA - ~7.9x ScaleARGBRowDown2Box_MSA - ~3.7x ScaleARGBRowDownEven_MSA - ~1.2x ScaleARGBRowDownEvenBox_MSA - ~3.5x ScaleARGBRowDown2_Any_MSA - ~2.6x ScaleARGBRowDown2Linear_Any_MSA - ~7.9x ScaleARGBRowDown2Box_Any_MSA - ~3.6x ScaleARGBRowDownEven_Any_MSA - ~1.2x ScaleARGBRowDownEvenBox_Any_MSA - ~3.5x Performance Gain (vs C non-vectorized) ScaleARGBRowDown2_MSA - 2.6x ScaleARGBRowDown2Linear_MSA - 13.5x ScaleARGBRowDown2Box_MSA - 5.8x ScaleARGBRowDownEven_MSA - 1.2x ScaleARGBRowDownEvenBox_MSA - 3.7x ScaleARGBRowDown2_Any_MSA - 2.6x ScaleARGBRowDown2Linear_Any_MSA - 13.5x ScaleARGBRowDown2Box_Any_MSA - 5.3x ScaleARGBRowDownEven_Any_MSA - 1.2x ScaleARGBRowDownEvenBox_Any_MSA - 3.7x Review URL: https://codereview.chromium.org/2527983002 .
178 lines
6.0 KiB
C++
178 lines
6.0 KiB
C++
/*
|
|
* Copyright 2016 The LibYuv Project Authors. All rights reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "libyuv/scale_row.h"
|
|
|
|
// This module is for GCC MSA
|
|
#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)
|
|
#include "libyuv/macros_msa.h"
|
|
|
|
#ifdef __cplusplus
|
|
namespace libyuv {
|
|
extern "C" {
|
|
#endif
|
|
|
|
void ScaleARGBRowDown2_MSA(const uint8_t* src_argb,
|
|
ptrdiff_t src_stride,
|
|
uint8_t* dst_argb,
|
|
int dst_width) {
|
|
int x;
|
|
v16u8 src0, src1, dst0;
|
|
|
|
for (x = 0; x < dst_width; x += 4) {
|
|
src0 = (v16u8)__msa_ld_b((v16i8*)src_argb, 0);
|
|
src1 = (v16u8)__msa_ld_b((v16i8*)src_argb, 16);
|
|
dst0 = (v16u8)__msa_pckod_w((v4i32)src1, (v4i32)src0);
|
|
ST_UB(dst0, dst_argb);
|
|
src_argb += 32;
|
|
dst_argb += 16;
|
|
}
|
|
}
|
|
|
|
void ScaleARGBRowDown2Linear_MSA(const uint8_t* src_argb,
|
|
ptrdiff_t src_stride,
|
|
uint8_t* dst_argb,
|
|
int dst_width) {
|
|
int x;
|
|
v16u8 src0, src1, vec0, vec1, dst0;
|
|
|
|
for (x = 0; x < dst_width; x += 4) {
|
|
src0 = (v16u8)__msa_ld_b((v16i8*)src_argb, 0);
|
|
src1 = (v16u8)__msa_ld_b((v16i8*)src_argb, 16);
|
|
vec0 = (v16u8)__msa_pckev_w((v4i32)src1, (v4i32)src0);
|
|
vec1 = (v16u8)__msa_pckod_w((v4i32)src1, (v4i32)src0);
|
|
dst0 = (v16u8)__msa_aver_u_b((v16u8)vec0, (v16u8)vec1);
|
|
ST_UB(dst0, dst_argb);
|
|
src_argb += 32;
|
|
dst_argb += 16;
|
|
}
|
|
}
|
|
|
|
void ScaleARGBRowDown2Box_MSA(const uint8_t* src_argb,
|
|
ptrdiff_t src_stride,
|
|
uint8_t* dst_argb,
|
|
int dst_width) {
|
|
int x;
|
|
const uint8_t* s = src_argb;
|
|
const uint8_t* t = src_argb + src_stride;
|
|
v16u8 src0, src1, src2, src3, vec0, vec1, vec2, vec3, dst0;
|
|
v8u16 reg0, reg1, reg2, reg3;
|
|
v16i8 shuffler = {0, 4, 1, 5, 2, 6, 3, 7, 8, 12, 9, 13, 10, 14, 11, 15};
|
|
|
|
for (x = 0; x < dst_width; x += 4) {
|
|
src0 = (v16u8)__msa_ld_b((v16i8*)s, 0);
|
|
src1 = (v16u8)__msa_ld_b((v16i8*)s, 16);
|
|
src2 = (v16u8)__msa_ld_b((v16i8*)t, 0);
|
|
src3 = (v16u8)__msa_ld_b((v16i8*)t, 16);
|
|
vec0 = (v16u8)__msa_vshf_b(shuffler, (v16i8)src0, (v16i8)src0);
|
|
vec1 = (v16u8)__msa_vshf_b(shuffler, (v16i8)src1, (v16i8)src1);
|
|
vec2 = (v16u8)__msa_vshf_b(shuffler, (v16i8)src2, (v16i8)src2);
|
|
vec3 = (v16u8)__msa_vshf_b(shuffler, (v16i8)src3, (v16i8)src3);
|
|
reg0 = __msa_hadd_u_h(vec0, vec0);
|
|
reg1 = __msa_hadd_u_h(vec1, vec1);
|
|
reg2 = __msa_hadd_u_h(vec2, vec2);
|
|
reg3 = __msa_hadd_u_h(vec3, vec3);
|
|
reg0 += reg2;
|
|
reg1 += reg3;
|
|
reg0 = (v8u16)__msa_srari_h((v8i16)reg0, 2);
|
|
reg1 = (v8u16)__msa_srari_h((v8i16)reg1, 2);
|
|
dst0 = (v16u8)__msa_pckev_b((v16i8)reg1, (v16i8)reg0);
|
|
ST_UB(dst0, dst_argb);
|
|
s += 32;
|
|
t += 32;
|
|
dst_argb += 16;
|
|
}
|
|
}
|
|
|
|
void ScaleARGBRowDownEven_MSA(const uint8_t* src_argb,
|
|
ptrdiff_t src_stride,
|
|
int32_t src_stepx,
|
|
uint8_t* dst_argb,
|
|
int dst_width) {
|
|
int x;
|
|
int32_t stepx = src_stepx * 4;
|
|
int32_t data0, data1, data2, data3;
|
|
|
|
for (x = 0; x < dst_width; x += 4) {
|
|
data0 = LW(src_argb);
|
|
data1 = LW(src_argb + stepx);
|
|
data2 = LW(src_argb + stepx * 2);
|
|
data3 = LW(src_argb + stepx * 3);
|
|
SW(data0, dst_argb);
|
|
SW(data1, dst_argb + 4);
|
|
SW(data2, dst_argb + 8);
|
|
SW(data3, dst_argb + 12);
|
|
src_argb += stepx * 4;
|
|
dst_argb += 16;
|
|
}
|
|
}
|
|
|
|
void ScaleARGBRowDownEvenBox_MSA(const uint8* src_argb,
|
|
ptrdiff_t src_stride,
|
|
int src_stepx,
|
|
uint8* dst_argb,
|
|
int dst_width) {
|
|
int x;
|
|
const uint8* nxt_argb = src_argb + src_stride;
|
|
int32_t stepx = src_stepx * 4;
|
|
int64_t data0, data1, data2, data3;
|
|
v16u8 src0 = {0}, src1 = {0}, src2 = {0}, src3 = {0};
|
|
v16u8 vec0, vec1, vec2, vec3;
|
|
v8u16 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7;
|
|
v16u8 dst0;
|
|
|
|
for (x = 0; x < dst_width; x += 4) {
|
|
data0 = LD(src_argb);
|
|
data1 = LD(src_argb + stepx);
|
|
data2 = LD(src_argb + stepx * 2);
|
|
data3 = LD(src_argb + stepx * 3);
|
|
src0 = (v16u8)__msa_insert_d((v2i64)src0, 0, data0);
|
|
src0 = (v16u8)__msa_insert_d((v2i64)src0, 1, data1);
|
|
src1 = (v16u8)__msa_insert_d((v2i64)src1, 0, data2);
|
|
src1 = (v16u8)__msa_insert_d((v2i64)src1, 1, data3);
|
|
data0 = LD(nxt_argb);
|
|
data1 = LD(nxt_argb + stepx);
|
|
data2 = LD(nxt_argb + stepx * 2);
|
|
data3 = LD(nxt_argb + stepx * 3);
|
|
src2 = (v16u8)__msa_insert_d((v2i64)src2, 0, data0);
|
|
src2 = (v16u8)__msa_insert_d((v2i64)src2, 1, data1);
|
|
src3 = (v16u8)__msa_insert_d((v2i64)src3, 0, data2);
|
|
src3 = (v16u8)__msa_insert_d((v2i64)src3, 1, data3);
|
|
vec0 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src0);
|
|
vec1 = (v16u8)__msa_ilvr_b((v16i8)src3, (v16i8)src1);
|
|
vec2 = (v16u8)__msa_ilvl_b((v16i8)src2, (v16i8)src0);
|
|
vec3 = (v16u8)__msa_ilvl_b((v16i8)src3, (v16i8)src1);
|
|
reg0 = __msa_hadd_u_h(vec0, vec0);
|
|
reg1 = __msa_hadd_u_h(vec1, vec1);
|
|
reg2 = __msa_hadd_u_h(vec2, vec2);
|
|
reg3 = __msa_hadd_u_h(vec3, vec3);
|
|
reg4 = (v8u16)__msa_pckev_d((v2i64)reg2, (v2i64)reg0);
|
|
reg5 = (v8u16)__msa_pckev_d((v2i64)reg3, (v2i64)reg1);
|
|
reg6 = (v8u16)__msa_pckod_d((v2i64)reg2, (v2i64)reg0);
|
|
reg7 = (v8u16)__msa_pckod_d((v2i64)reg3, (v2i64)reg1);
|
|
reg4 += reg6;
|
|
reg5 += reg7;
|
|
reg4 = (v8u16)__msa_srari_h((v8i16)reg4, 2);
|
|
reg5 = (v8u16)__msa_srari_h((v8i16)reg5, 2);
|
|
dst0 = (v16u8)__msa_pckev_b((v16i8)reg5, (v16i8)reg4);
|
|
ST_UB(dst0, dst_argb);
|
|
src_argb += stepx * 4;
|
|
nxt_argb += stepx * 4;
|
|
dst_argb += 16;
|
|
}
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
} // extern "C"
|
|
} // namespace libyuv
|
|
#endif
|
|
|
|
#endif // !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)
|