diff --git a/media/libyuv/libyuv.gypi b/media/libyuv/libyuv.gypi index 48936aa7b0..25641ea4b4 100644 --- a/media/libyuv/libyuv.gypi +++ b/media/libyuv/libyuv.gypi @@ -57,6 +57,7 @@ 'source/rotate_argb.cc', 'source/rotate_common.cc', 'source/rotate_gcc.cc', + 'source/rotate_lsx.cc', 'source/rotate_msa.cc', 'source/rotate_neon.cc', 'source/rotate_neon64.cc', @@ -64,6 +65,8 @@ 'source/row_any.cc', 'source/row_common.cc', 'source/row_gcc.cc', + 'source/row_lasx.cc', + 'source/row_lsx.cc', 'source/row_msa.cc', 'source/row_neon.cc', 'source/row_neon64.cc', @@ -73,6 +76,7 @@ 'source/scale_argb.cc', 'source/scale_common.cc', 'source/scale_gcc.cc', + 'source/scale_lsx.cc', 'source/scale_msa.cc', 'source/scale_neon.cc', 'source/scale_neon64.cc', diff --git a/media/libyuv/moz.build b/media/libyuv/moz.build index 8aa6408319..5565eb8763 100644 --- a/media/libyuv/moz.build +++ b/media/libyuv/moz.build @@ -35,6 +35,13 @@ if CONFIG['CPU_ARCH'] == 'aarch64': 'source/row_neon64.cc', 'source/scale_neon64.cc', ] +if CONFIG['CPU_ARCH'] == 'loongarch64': + libyuv_non_unified_sources += [ + 'source/rotate_lsx.cc', + 'source/row_lasx.cc', + 'source/row_lsx.cc', + 'source/scale_lsx.cc', + ] GYP_DIRS['.'].input = 'libyuv.gyp' GYP_DIRS['.'].variables = gyp_vars diff --git a/media/libyuv/source/row_lasx.cc b/media/libyuv/source/row_lasx.cc index 29ac9254d9..52b7d5822c 100644 --- a/media/libyuv/source/row_lasx.cc +++ b/media/libyuv/source/row_lasx.cc @@ -193,18 +193,30 @@ extern "C" { #define RGBTOUV(_tmpb, _tmpg, _tmpr, _nexb, _nexg, _nexr, _reg0, _reg1) \ { \ - __m256i _tmp0, _tmp1, _tmp2, _tmp3; \ + __m256i _tmp0, _tmp1, _tmp2, _tmp3, _tmp4, _tmp5; \ _tmp0 = __lasx_xvaddwev_h_bu(_tmpb, _nexb); \ _tmp1 = __lasx_xvaddwod_h_bu(_tmpb, _nexb); \ _tmp2 = __lasx_xvaddwev_h_bu(_tmpg, _nexg); \ _tmp3 = __lasx_xvaddwod_h_bu(_tmpg, _nexg); \ _reg0 = __lasx_xvaddwev_h_bu(_tmpr, _nexr); \ _reg1 = __lasx_xvaddwod_h_bu(_tmpr, _nexr); \ - _tmpb = __lasx_xvavgr_hu(_tmp0, _tmp1); \ - _tmpg = __lasx_xvavgr_hu(_tmp2, _tmp3); \ - _tmpr = __lasx_xvavgr_hu(_reg0, _reg1); \ - _reg0 = __lasx_xvmadd_h(const_8080, const_112, _tmpb); \ - _reg1 = __lasx_xvmadd_h(const_8080, const_112, _tmpr); \ + _tmp4 = __lasx_xvaddwev_w_hu(_tmp0, _tmp1); \ + _tmp5 = __lasx_xvaddwod_w_hu(_tmp0, _tmp1); \ + _tmp0 = __lasx_xvilvl_w(_tmp5, _tmp4); \ + _tmp1 = __lasx_xvilvh_w(_tmp5, _tmp4); \ + _tmpb = __lasx_xvssrarni_hu_w(_tmp1, _tmp0, 2); \ + _tmp4 = __lasx_xvaddwev_w_hu(_tmp2, _tmp3); \ + _tmp5 = __lasx_xvaddwod_w_hu(_tmp2, _tmp3); \ + _tmp2 = __lasx_xvilvl_w(_tmp5, _tmp4); \ + _tmp3 = __lasx_xvilvh_w(_tmp5, _tmp4); \ + _tmpg = __lasx_xvssrarni_hu_w(_tmp3, _tmp2, 2); \ + _tmp4 = __lasx_xvaddwev_w_hu(_reg0, _reg1); \ + _tmp5 = __lasx_xvaddwod_w_hu(_reg0, _reg1); \ + _tmp0 = __lasx_xvilvl_w(_tmp5, _tmp4); \ + _tmp1 = __lasx_xvilvh_w(_tmp5, _tmp4); \ + _tmpr = __lasx_xvssrarni_hu_w(_tmp1, _tmp0, 2); \ + _reg0 = __lasx_xvmadd_h(const_8000, const_112, _tmpb); \ + _reg1 = __lasx_xvmadd_h(const_8000, const_112, _tmpr); \ _reg0 = __lasx_xvmsub_h(_reg0, const_74, _tmpg); \ _reg1 = __lasx_xvmsub_h(_reg1, const_94, _tmpg); \ _reg0 = __lasx_xvmsub_h(_reg0, const_38, _tmpr); \ @@ -543,8 +555,8 @@ void I422ToARGB4444Row_LASX(const uint8_t* src_y, __m256i vec_yb, vec_yg, vec_ub, vec_vr, vec_ug, vec_vg; __m256i vec_ubvr, vec_ugvg; __m256i const_0x80 = __lasx_xvldi(0x80); - __m256i alpha = {0xF000F000F000F000, 0xF000F000F000F000, 0xF000F000F000F000, - 0xF000F000F000F000}; + __m256i alpha = (__m256i)v4u64{0xF000F000F000F000, 0xF000F000F000F000, + 0xF000F000F000F000, 0xF000F000F000F000}; __m256i mask = {0x00F000F000F000F0, 0x00F000F000F000F0, 0x00F000F000F000F0, 0x00F000F000F000F0}; @@ -595,8 +607,8 @@ void I422ToARGB1555Row_LASX(const uint8_t* src_y, __m256i vec_yb, vec_yg, vec_ub, vec_vr, vec_ug, vec_vg; __m256i vec_ubvr, vec_ugvg; __m256i const_0x80 = __lasx_xvldi(0x80); - __m256i alpha = {0x8000800080008000, 0x8000800080008000, 0x8000800080008000, - 0x8000800080008000}; + __m256i alpha = (__m256i)v4u64{0x8000800080008000, 0x8000800080008000, + 0x8000800080008000, 0x8000800080008000}; YUVTORGB_SETUP(yuvconstants, vec_ub, vec_vr, vec_ug, vec_vg, vec_yg, vec_yb); vec_ubvr = __lasx_xvilvl_h(vec_ub, vec_vr); @@ -787,20 +799,16 @@ void ARGBToUVRow_LASX(const uint8_t* src_argb0, __m256i src0, src1, src2, src3, src4, src5, src6, src7; __m256i vec0, vec1, vec2, vec3; __m256i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, dst0, dst1; - __m256i const_0x70 = {0x0038003800380038, 0x0038003800380038, - 0x0038003800380038, 0x0038003800380038}; - __m256i const_0x4A = {0x0025002500250025, 0x0025002500250025, - 0x0025002500250025, 0x0025002500250025}; - __m256i const_0x26 = {0x0013001300130013, 0x0013001300130013, - 0x0013001300130013, 0x0013001300130013}; - __m256i const_0x5E = {0x002f002f002f002f, 0x002f002f002f002f, - 0x002f002f002f002f, 0x002f002f002f002f}; - __m256i const_0x12 = {0x0009000900090009, 0x0009000900090009, - 0x0009000900090009, 0x0009000900090009}; + __m256i const_0x70 = __lasx_xvldi(0x470); + __m256i const_0x4A = __lasx_xvldi(0x44A); + __m256i const_0x26 = __lasx_xvldi(0x426); + __m256i const_0x5E = __lasx_xvldi(0x45E); + __m256i const_0x12 = __lasx_xvldi(0x412); + __m256i control = {0x0000000400000000, 0x0000000500000001, 0x0000000600000002, 0x0000000700000003}; - __m256i const_0x8080 = {0x8080808080808080, 0x8080808080808080, - 0x8080808080808080, 0x8080808080808080}; + __m256i const_0x8000 = (__m256i)v4u64{0x8000800080008000, 0x8000800080008000, + 0x8000800080008000, 0x8000800080008000}; for (x = 0; x < len; x++) { DUP4_ARG2(__lasx_xvld, src_argb0, 0, src_argb0, 32, src_argb0, 64, @@ -823,17 +831,20 @@ void ARGBToUVRow_LASX(const uint8_t* src_argb0, tmp5 = __lasx_xvpickev_h(vec3, vec2); vec0 = __lasx_xvpickev_h(tmp1, tmp0); vec1 = __lasx_xvpickod_h(tmp1, tmp0); - src0 = __lasx_xvavgr_h(vec0, vec1); + src0 = __lasx_xvadd_h(vec0, vec1); + src0 = __lasx_xvsrari_h(src0, 2); vec0 = __lasx_xvpickev_h(tmp3, tmp2); vec1 = __lasx_xvpickod_h(tmp3, tmp2); - src1 = __lasx_xvavgr_h(vec0, vec1); + src1 = __lasx_xvadd_h(vec0, vec1); + src1 = __lasx_xvsrari_h(src1, 2); vec0 = __lasx_xvpickev_h(tmp5, tmp4); vec1 = __lasx_xvpickod_h(tmp5, tmp4); - src2 = __lasx_xvavgr_h(vec0, vec1); - dst0 = __lasx_xvmadd_h(const_0x8080, src0, const_0x70); + src2 = __lasx_xvadd_h(vec0, vec1); + src2 = __lasx_xvsrari_h(src2, 2); + dst0 = __lasx_xvmadd_h(const_0x8000, src0, const_0x70); dst0 = __lasx_xvmsub_h(dst0, src2, const_0x4A); dst0 = __lasx_xvmsub_h(dst0, src1, const_0x26); - dst1 = __lasx_xvmadd_h(const_0x8080, src1, const_0x70); + dst1 = __lasx_xvmadd_h(const_0x8000, src1, const_0x70); dst1 = __lasx_xvmsub_h(dst1, src2, const_0x5E); dst1 = __lasx_xvmsub_h(dst1, src0, const_0x12); dst0 = __lasx_xvperm_w(dst0, control); @@ -1037,8 +1048,8 @@ void ARGBToUV444Row_LASX(const uint8_t* src_argb, __m256i const_38 = __lasx_xvldi(38); __m256i const_94 = __lasx_xvldi(94); __m256i const_18 = __lasx_xvldi(18); - __m256i const_0x8080 = {0x8080808080808080, 0x8080808080808080, - 0x8080808080808080, 0x8080808080808080}; + __m256i const_0x8000 = (__m256i)v4u64{0x8000800080008000, 0x8000800080008000, + 0x8000800080008000, 0x8000800080008000}; __m256i control = {0x0000000400000000, 0x0000000500000001, 0x0000000600000002, 0x0000000700000003}; for (x = 0; x < len; x++) { @@ -1048,8 +1059,8 @@ void ARGBToUV444Row_LASX(const uint8_t* src_argb, tmp1 = __lasx_xvpickod_h(src1, src0); tmp2 = __lasx_xvpickev_h(src3, src2); tmp3 = __lasx_xvpickod_h(src3, src2); - reg0 = __lasx_xvmaddwev_h_bu(const_0x8080, tmp0, const_112); - reg1 = __lasx_xvmaddwev_h_bu(const_0x8080, tmp2, const_112); + reg0 = __lasx_xvmaddwev_h_bu(const_0x8000, tmp0, const_112); + reg1 = __lasx_xvmaddwev_h_bu(const_0x8000, tmp2, const_112); reg2 = __lasx_xvmulwod_h_bu(tmp0, const_74); reg3 = __lasx_xvmulwod_h_bu(tmp2, const_74); reg2 = __lasx_xvmaddwev_h_bu(reg2, tmp1, const_38); @@ -1058,8 +1069,8 @@ void ARGBToUV444Row_LASX(const uint8_t* src_argb, reg1 = __lasx_xvsub_h(reg1, reg3); dst0 = __lasx_xvssrani_b_h(reg1, reg0, 8); dst0 = __lasx_xvperm_w(dst0, control); - reg0 = __lasx_xvmaddwev_h_bu(const_0x8080, tmp1, const_112); - reg1 = __lasx_xvmaddwev_h_bu(const_0x8080, tmp3, const_112); + reg0 = __lasx_xvmaddwev_h_bu(const_0x8000, tmp1, const_112); + reg1 = __lasx_xvmaddwev_h_bu(const_0x8000, tmp3, const_112); reg2 = __lasx_xvmulwev_h_bu(tmp0, const_18); reg3 = __lasx_xvmulwev_h_bu(tmp2, const_18); reg2 = __lasx_xvmaddwod_h_bu(reg2, tmp0, const_94); @@ -1148,24 +1159,26 @@ void ARGBAttenuateRow_LASX(const uint8_t* src_argb, __m256i b, g, r, a, dst0, dst1; __m256i control = {0x0005000100040000, 0x0007000300060002, 0x0005000100040000, 0x0007000300060002}; + __m256i zero = __lasx_xvldi(0); + __m256i const_add = __lasx_xvldi(0x8ff); for (x = 0; x < len; x++) { DUP2_ARG2(__lasx_xvld, src_argb, 0, src_argb, 32, src0, src1); tmp0 = __lasx_xvpickev_b(src1, src0); tmp1 = __lasx_xvpickod_b(src1, src0); - b = __lasx_xvpackev_b(tmp0, tmp0); - r = __lasx_xvpackod_b(tmp0, tmp0); - g = __lasx_xvpackev_b(tmp1, tmp1); - a = __lasx_xvpackod_b(tmp1, tmp1); - reg0 = __lasx_xvmulwev_w_hu(b, a); - reg1 = __lasx_xvmulwod_w_hu(b, a); - reg2 = __lasx_xvmulwev_w_hu(r, a); - reg3 = __lasx_xvmulwod_w_hu(r, a); - reg4 = __lasx_xvmulwev_w_hu(g, a); - reg5 = __lasx_xvmulwod_w_hu(g, a); - reg0 = __lasx_xvssrani_h_w(reg1, reg0, 24); - reg2 = __lasx_xvssrani_h_w(reg3, reg2, 24); - reg4 = __lasx_xvssrani_h_w(reg5, reg4, 24); + b = __lasx_xvpackev_b(zero, tmp0); + r = __lasx_xvpackod_b(zero, tmp0); + g = __lasx_xvpackev_b(zero, tmp1); + a = __lasx_xvpackod_b(zero, tmp1); + reg0 = __lasx_xvmaddwev_w_hu(const_add, b, a); + reg1 = __lasx_xvmaddwod_w_hu(const_add, b, a); + reg2 = __lasx_xvmaddwev_w_hu(const_add, r, a); + reg3 = __lasx_xvmaddwod_w_hu(const_add, r, a); + reg4 = __lasx_xvmaddwev_w_hu(const_add, g, a); + reg5 = __lasx_xvmaddwod_w_hu(const_add, g, a); + reg0 = __lasx_xvssrani_h_w(reg1, reg0, 8); + reg2 = __lasx_xvssrani_h_w(reg3, reg2, 8); + reg4 = __lasx_xvssrani_h_w(reg5, reg4, 8); reg0 = __lasx_xvshuf_h(control, reg0, reg0); reg2 = __lasx_xvshuf_h(control, reg2, reg2); reg4 = __lasx_xvshuf_h(control, reg4, reg4); @@ -1182,7 +1195,7 @@ void ARGBAttenuateRow_LASX(const uint8_t* src_argb, void ARGBToRGB565DitherRow_LASX(const uint8_t* src_argb, uint8_t* dst_rgb, - const uint32_t dither4, + uint32_t dither4, int width) { int x; int len = width / 16; @@ -1604,13 +1617,13 @@ void ARGB1555ToUVRow_LASX(const uint8_t* src_argb1555, __m256i tmp0, tmp1, tmp2, tmp3; __m256i tmpb, tmpg, tmpr, nexb, nexg, nexr; __m256i reg0, reg1, reg2, reg3, dst0; - __m256i const_112 = __lasx_xvldi(0x438); - __m256i const_74 = __lasx_xvldi(0x425); - __m256i const_38 = __lasx_xvldi(0x413); - __m256i const_94 = __lasx_xvldi(0x42F); - __m256i const_18 = __lasx_xvldi(0x409); - __m256i const_8080 = {0x8080808080808080, 0x8080808080808080, - 0x8080808080808080, 0x8080808080808080}; + __m256i const_112 = __lasx_xvldi(0x470); + __m256i const_74 = __lasx_xvldi(0x44A); + __m256i const_38 = __lasx_xvldi(0x426); + __m256i const_94 = __lasx_xvldi(0x45E); + __m256i const_18 = __lasx_xvldi(0x412); + __m256i const_8000 = (__m256i)v4u64{0x8000800080008000, 0x8000800080008000, + 0x8000800080008000, 0x8000800080008000}; for (x = 0; x < len; x++) { DUP4_ARG2(__lasx_xvld, src_argb1555, 0, src_argb1555, 32, next_argb1555, 0, @@ -1721,13 +1734,13 @@ void RGB565ToUVRow_LASX(const uint8_t* src_rgb565, __m256i tmp0, tmp1, tmp2, tmp3; __m256i tmpb, tmpg, tmpr, nexb, nexg, nexr; __m256i reg0, reg1, reg2, reg3, dst0; - __m256i const_112 = __lasx_xvldi(0x438); - __m256i const_74 = __lasx_xvldi(0x425); - __m256i const_38 = __lasx_xvldi(0x413); - __m256i const_94 = __lasx_xvldi(0x42F); - __m256i const_18 = __lasx_xvldi(0x409); - __m256i const_8080 = {0x8080808080808080, 0x8080808080808080, - 0x8080808080808080, 0x8080808080808080}; + __m256i const_112 = __lasx_xvldi(0x470); + __m256i const_74 = __lasx_xvldi(0x44A); + __m256i const_38 = __lasx_xvldi(0x426); + __m256i const_94 = __lasx_xvldi(0x45E); + __m256i const_18 = __lasx_xvldi(0x412); + __m256i const_8000 = (__m256i)v4u64{0x8000800080008000, 0x8000800080008000, + 0x8000800080008000, 0x8000800080008000}; for (x = 0; x < len; x++) { DUP4_ARG2(__lasx_xvld, src_rgb565, 0, src_rgb565, 32, next_rgb565, 0, @@ -1788,13 +1801,13 @@ void RGB24ToUVRow_LASX(const uint8_t* src_rgb24, __m256i src0, src1, src2, reg0, reg1, reg2; __m256i nex0, nex1, nex2, dst0, tmp0, tmp1, tmp2; __m256i tmpb, tmpg, tmpr, nexb, nexg, nexr; - __m256i const_112 = __lasx_xvldi(0x438); - __m256i const_74 = __lasx_xvldi(0x425); - __m256i const_38 = __lasx_xvldi(0x413); - __m256i const_94 = __lasx_xvldi(0x42F); - __m256i const_18 = __lasx_xvldi(0x409); - __m256i const_8080 = {0x8080808080808080, 0x8080808080808080, - 0x8080808080808080, 0x8080808080808080}; + __m256i const_112 = __lasx_xvldi(0x470); + __m256i const_74 = __lasx_xvldi(0x44A); + __m256i const_38 = __lasx_xvldi(0x426); + __m256i const_94 = __lasx_xvldi(0x45E); + __m256i const_18 = __lasx_xvldi(0x412); + __m256i const_8000 = (__m256i)v4u64{0x8000800080008000, 0x8000800080008000, + 0x8000800080008000, 0x8000800080008000}; __m256i shuff0_b = {0x15120F0C09060300, 0x00000000001E1B18, 0x15120F0C09060300, 0x00000000001E1B18}; __m256i shuff1_b = {0x0706050403020100, 0x1D1A1714110A0908, @@ -1851,13 +1864,13 @@ void RAWToUVRow_LASX(const uint8_t* src_raw, __m256i src0, src1, src2, reg0, reg1, reg2; __m256i nex0, nex1, nex2, dst0, tmp0, tmp1, tmp2; __m256i tmpb, tmpg, tmpr, nexb, nexg, nexr; - __m256i const_112 = __lasx_xvldi(0x438); - __m256i const_74 = __lasx_xvldi(0x425); - __m256i const_38 = __lasx_xvldi(0x413); - __m256i const_94 = __lasx_xvldi(0x42F); - __m256i const_18 = __lasx_xvldi(0x409); - __m256i const_8080 = {0x8080808080808080, 0x8080808080808080, - 0x8080808080808080, 0x8080808080808080}; + __m256i const_112 = __lasx_xvldi(0x470); + __m256i const_74 = __lasx_xvldi(0x44A); + __m256i const_38 = __lasx_xvldi(0x426); + __m256i const_94 = __lasx_xvldi(0x45E); + __m256i const_18 = __lasx_xvldi(0x412); + __m256i const_8000 = (__m256i)v4u64{0x8000800080008000, 0x8000800080008000, + 0x8000800080008000, 0x8000800080008000}; __m256i shuff0_r = {0x15120F0C09060300, 0x00000000001E1B18, 0x15120F0C09060300, 0x00000000001E1B18}; __m256i shuff1_r = {0x0706050403020100, 0x1D1A1714110A0908, @@ -2000,11 +2013,13 @@ void NV21ToARGBRow_LASX(const uint8_t* src_y, } } +#ifndef RgbConstants struct RgbConstants { uint8_t kRGBToY[4]; uint16_t kAddY; uint16_t pad; }; +#define RgbConstants RgbConstants // RGB to JPeg coefficients // B * 0.1140 coefficient = 29 @@ -2030,6 +2045,7 @@ static const struct RgbConstants kRgb24I601Constants = {{25, 129, 66, 0}, static const struct RgbConstants kRawI601Constants = {{66, 129, 25, 0}, 0x1080, 0}; +#endif // RgbConstants // ARGB expects first 3 values to contain RGB and 4th value is ignored. static void ARGBToYMatrixRow_LASX(const uint8_t* src_argb, @@ -2234,16 +2250,16 @@ void ARGBToUVJRow_LASX(const uint8_t* src_argb, int len = width / 32; __m256i src0, src1, src2, src3; __m256i nex0, nex1, nex2, nex3; - __m256i tmp0, tmp1, tmp2, tmp3; + __m256i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; __m256i reg0, reg1, dst0; __m256i tmpb, tmpg, tmpr, nexb, nexg, nexr; - __m256i const_63 = __lasx_xvldi(0x43F); - __m256i const_42 = __lasx_xvldi(0x42A); + __m256i const_128 = __lasx_xvldi(0x480); + __m256i const_85 = __lasx_xvldi(0x455); + __m256i const_43 = __lasx_xvldi(0x42B); + __m256i const_107 = __lasx_xvldi(0x46B); __m256i const_21 = __lasx_xvldi(0x415); - __m256i const_53 = __lasx_xvldi(0x435); - __m256i const_10 = __lasx_xvldi(0x40A); - __m256i const_8080 = {0x8080808080808080, 0x8080808080808080, - 0x8080808080808080, 0x8080808080808080}; + __m256i const_8000 = (__m256i)v4u64{0x8000800080008000, 0x8000800080008000, + 0x8000800080008000, 0x8000800080008000}; __m256i shuff = {0x1614060412100200, 0x1E1C0E0C1A180A08, 0x1715070513110301, 0x1F1D0F0D1B190B09}; @@ -2272,15 +2288,27 @@ void ARGBToUVJRow_LASX(const uint8_t* src_argb, tmp3 = __lasx_xvaddwod_h_bu(tmpg, nexg); reg0 = __lasx_xvaddwev_h_bu(tmpr, nexr); reg1 = __lasx_xvaddwod_h_bu(tmpr, nexr); - tmpb = __lasx_xvavgr_hu(tmp0, tmp1); - tmpg = __lasx_xvavgr_hu(tmp2, tmp3); - tmpr = __lasx_xvavgr_hu(reg0, reg1); - reg0 = __lasx_xvmadd_h(const_8080, const_63, tmpb); - reg1 = __lasx_xvmadd_h(const_8080, const_63, tmpr); - reg0 = __lasx_xvmsub_h(reg0, const_42, tmpg); - reg1 = __lasx_xvmsub_h(reg1, const_53, tmpg); - reg0 = __lasx_xvmsub_h(reg0, const_21, tmpr); - reg1 = __lasx_xvmsub_h(reg1, const_10, tmpb); + tmp4 = __lasx_xvaddwev_w_hu(tmp0, tmp1); + tmp5 = __lasx_xvaddwod_w_hu(tmp0, tmp1); + tmp0 = __lasx_xvilvl_w(tmp5, tmp4); + tmp1 = __lasx_xvilvh_w(tmp5, tmp4); + tmpb = __lasx_xvssrarni_hu_w(tmp1, tmp0, 2); + tmp4 = __lasx_xvaddwev_w_hu(tmp2, tmp3); + tmp5 = __lasx_xvaddwod_w_hu(tmp2, tmp3); + tmp2 = __lasx_xvilvl_w(tmp5, tmp4); + tmp3 = __lasx_xvilvh_w(tmp5, tmp4); + tmpg = __lasx_xvssrarni_hu_w(tmp3, tmp2, 2); + tmp4 = __lasx_xvaddwev_w_hu(reg0, reg1); + tmp5 = __lasx_xvaddwod_w_hu(reg0, reg1); + tmp0 = __lasx_xvilvl_w(tmp5, tmp4); + tmp1 = __lasx_xvilvh_w(tmp5, tmp4); + tmpr = __lasx_xvssrarni_hu_w(tmp1, tmp0, 2); + reg0 = __lasx_xvmadd_h(const_8000, const_128, tmpb); + reg1 = __lasx_xvmadd_h(const_8000, const_128, tmpr); + reg0 = __lasx_xvmsub_h(reg0, const_85, tmpg); + reg1 = __lasx_xvmsub_h(reg1, const_107, tmpg); + reg0 = __lasx_xvmsub_h(reg0, const_43, tmpr); + reg1 = __lasx_xvmsub_h(reg1, const_21, tmpb); dst0 = __lasx_xvpackod_b(reg1, reg0); tmp0 = __lasx_xvpermi_d(dst0, 0x44); tmp1 = __lasx_xvpermi_d(dst0, 0xEE); @@ -2296,9 +2324,21 @@ void ARGBToUVJRow_LASX(const uint8_t* src_argb, } } +// undef for unified sources build +#undef ALPHA_VAL +#undef YUVTORGB_SETUP +#undef READYUV422_D +#undef READYUV422 +#undef YUVTORGB_D +#undef YUVTORGB +#undef STOREARGB_D +#undef STOREARGB +#undef RGBTOUV + #ifdef __cplusplus } // extern "C" } // namespace libyuv #endif #endif // !defined(LIBYUV_DISABLE_LASX) && defined(__loongarch_asx) + diff --git a/media/libyuv/source/row_lsx.cc b/media/libyuv/source/row_lsx.cc index 9c1e16f22e..a4246151ba 100644 --- a/media/libyuv/source/row_lsx.cc +++ b/media/libyuv/source/row_lsx.cc @@ -31,6 +31,91 @@ extern "C" { yb = __lsx_vreplgr2vr_w(yuvconst->kYBiasToRgb[0]); \ } +// Load 32 YUV422 pixel data +#define READYUV422_D(psrc_y, psrc_u, psrc_v, out_y, uv_l, uv_h) \ + { \ + __m128i temp0, temp1; \ + \ + DUP2_ARG2(__lsx_vld, psrc_y, 0, psrc_u, 0, out_y, temp0); \ + temp1 = __lsx_vld(psrc_v, 0); \ + temp0 = __lsx_vsub_b(temp0, const_80); \ + temp1 = __lsx_vsub_b(temp1, const_80); \ + temp0 = __lsx_vsllwil_h_b(temp0, 0); \ + temp1 = __lsx_vsllwil_h_b(temp1, 0); \ + uv_l = __lsx_vilvl_h(temp0, temp1); \ + uv_h = __lsx_vilvh_h(temp0, temp1); \ + } + +// Load 16 YUV422 pixel data +#define READYUV422(psrc_y, psrc_u, psrc_v, out_y, uv) \ + { \ + __m128i temp0, temp1; \ + \ + out_y = __lsx_vld(psrc_y, 0); \ + temp0 = __lsx_vldrepl_d(psrc_u, 0); \ + temp1 = __lsx_vldrepl_d(psrc_v, 0); \ + uv = __lsx_vilvl_b(temp0, temp1); \ + uv = __lsx_vsub_b(uv, const_80); \ + uv = __lsx_vsllwil_h_b(uv, 0); \ + } + +// Convert 16 pixels of YUV420 to RGB. +#define YUVTORGB_D(in_y, in_uvl, in_uvh, ubvr, ugvg, yg, yb, b_l, b_h, g_l, \ + g_h, r_l, r_h) \ + { \ + __m128i u_l, u_h, v_l, v_h; \ + __m128i yl_ev, yl_od, yh_ev, yh_od; \ + __m128i temp0, temp1, temp2, temp3; \ + \ + temp0 = __lsx_vilvl_b(in_y, in_y); \ + temp1 = __lsx_vilvh_b(in_y, in_y); \ + yl_ev = __lsx_vmulwev_w_hu_h(temp0, yg); \ + yl_od = __lsx_vmulwod_w_hu_h(temp0, yg); \ + yh_ev = __lsx_vmulwev_w_hu_h(temp1, yg); \ + yh_od = __lsx_vmulwod_w_hu_h(temp1, yg); \ + DUP4_ARG2(__lsx_vsrai_w, yl_ev, 16, yl_od, 16, yh_ev, 16, yh_od, 16, \ + yl_ev, yl_od, yh_ev, yh_od); \ + yl_ev = __lsx_vadd_w(yl_ev, yb); \ + yl_od = __lsx_vadd_w(yl_od, yb); \ + yh_ev = __lsx_vadd_w(yh_ev, yb); \ + yh_od = __lsx_vadd_w(yh_od, yb); \ + v_l = __lsx_vmulwev_w_h(in_uvl, ubvr); \ + u_l = __lsx_vmulwod_w_h(in_uvl, ubvr); \ + v_h = __lsx_vmulwev_w_h(in_uvh, ubvr); \ + u_h = __lsx_vmulwod_w_h(in_uvh, ubvr); \ + temp0 = __lsx_vadd_w(yl_ev, u_l); \ + temp1 = __lsx_vadd_w(yl_od, u_l); \ + temp2 = __lsx_vadd_w(yh_ev, u_h); \ + temp3 = __lsx_vadd_w(yh_od, u_h); \ + DUP4_ARG2(__lsx_vsrai_w, temp0, 6, temp1, 6, temp2, 6, temp3, 6, temp0, \ + temp1, temp2, temp3); \ + DUP4_ARG1(__lsx_vclip255_w, temp0, temp1, temp2, temp3, temp0, temp1, \ + temp2, temp3); \ + b_l = __lsx_vpackev_h(temp1, temp0); \ + b_h = __lsx_vpackev_h(temp3, temp2); \ + temp0 = __lsx_vadd_w(yl_ev, v_l); \ + temp1 = __lsx_vadd_w(yl_od, v_l); \ + temp2 = __lsx_vadd_w(yh_ev, v_h); \ + temp3 = __lsx_vadd_w(yh_od, v_h); \ + DUP4_ARG2(__lsx_vsrai_w, temp0, 6, temp1, 6, temp2, 6, temp3, 6, temp0, \ + temp1, temp2, temp3); \ + DUP4_ARG1(__lsx_vclip255_w, temp0, temp1, temp2, temp3, temp0, temp1, \ + temp2, temp3); \ + r_l = __lsx_vpackev_h(temp1, temp0); \ + r_h = __lsx_vpackev_h(temp3, temp2); \ + DUP2_ARG2(__lsx_vdp2_w_h, in_uvl, ugvg, in_uvh, ugvg, u_l, u_h); \ + temp0 = __lsx_vsub_w(yl_ev, u_l); \ + temp1 = __lsx_vsub_w(yl_od, u_l); \ + temp2 = __lsx_vsub_w(yh_ev, u_h); \ + temp3 = __lsx_vsub_w(yh_od, u_h); \ + DUP4_ARG2(__lsx_vsrai_w, temp0, 6, temp1, 6, temp2, 6, temp3, 6, temp0, \ + temp1, temp2, temp3); \ + DUP4_ARG1(__lsx_vclip255_w, temp0, temp1, temp2, temp3, temp0, temp1, \ + temp2, temp3); \ + g_l = __lsx_vpackev_h(temp1, temp0); \ + g_h = __lsx_vpackev_h(temp3, temp2); \ + } + // Convert 8 pixels of YUV420 to RGB. #define YUVTORGB(in_y, in_vu, vrub, vgug, yg, yb, out_b, out_g, out_r) \ { \ @@ -118,6 +203,25 @@ extern "C" { out_g = __lsx_vpackev_h(tmp1, tmp0); \ } +// Pack and Store 16 ARGB values. +#define STOREARGB_D(a_l, a_h, r_l, r_h, g_l, g_h, b_l, b_h, pdst_argb) \ + { \ + __m128i temp0, temp1, temp2, temp3; \ + temp0 = __lsx_vpackev_b(g_l, b_l); \ + temp1 = __lsx_vpackev_b(a_l, r_l); \ + temp2 = __lsx_vpackev_b(g_h, b_h); \ + temp3 = __lsx_vpackev_b(a_h, r_h); \ + r_l = __lsx_vilvl_h(temp1, temp0); \ + r_h = __lsx_vilvh_h(temp1, temp0); \ + g_l = __lsx_vilvl_h(temp3, temp2); \ + g_h = __lsx_vilvh_h(temp3, temp2); \ + __lsx_vst(r_l, pdst_argb, 0); \ + __lsx_vst(r_h, pdst_argb, 16); \ + __lsx_vst(g_l, pdst_argb, 32); \ + __lsx_vst(g_h, pdst_argb, 48); \ + pdst_argb += 64; \ + } + // Pack and Store 8 ARGB values. #define STOREARGB(in_a, in_r, in_g, in_b, pdst_argb) \ { \ @@ -135,7 +239,7 @@ extern "C" { #define RGBTOUV(_tmpb, _tmpg, _tmpr, _nexb, _nexg, _nexr, _dst0) \ { \ - __m128i _tmp0, _tmp1, _tmp2, _tmp3; \ + __m128i _tmp0, _tmp1, _tmp2, _tmp3, _tmp4, _tmp5; \ __m128i _reg0, _reg1; \ _tmp0 = __lsx_vaddwev_h_bu(_tmpb, _nexb); \ _tmp1 = __lsx_vaddwod_h_bu(_tmpb, _nexb); \ @@ -143,11 +247,23 @@ extern "C" { _tmp3 = __lsx_vaddwod_h_bu(_tmpg, _nexg); \ _reg0 = __lsx_vaddwev_h_bu(_tmpr, _nexr); \ _reg1 = __lsx_vaddwod_h_bu(_tmpr, _nexr); \ - _tmpb = __lsx_vavgr_hu(_tmp0, _tmp1); \ - _tmpg = __lsx_vavgr_hu(_tmp2, _tmp3); \ - _tmpr = __lsx_vavgr_hu(_reg0, _reg1); \ - _reg0 = __lsx_vmadd_h(const_8080, const_112, _tmpb); \ - _reg1 = __lsx_vmadd_h(const_8080, const_112, _tmpr); \ + _tmp4 = __lsx_vaddwev_w_hu(_tmp0, _tmp1); \ + _tmp5 = __lsx_vaddwod_w_hu(_tmp0, _tmp1); \ + _tmp0 = __lsx_vilvl_w(_tmp5, _tmp4); \ + _tmp1 = __lsx_vilvh_w(_tmp5, _tmp4); \ + _tmpb = __lsx_vssrarni_hu_w(_tmp1, _tmp0, 2); \ + _tmp4 = __lsx_vaddwev_w_hu(_tmp2, _tmp3); \ + _tmp5 = __lsx_vaddwod_w_hu(_tmp2, _tmp3); \ + _tmp2 = __lsx_vilvl_w(_tmp5, _tmp4); \ + _tmp3 = __lsx_vilvh_w(_tmp5, _tmp4); \ + _tmpg = __lsx_vssrarni_hu_w(_tmp3, _tmp2, 2); \ + _tmp4 = __lsx_vaddwev_w_hu(_reg0, _reg1); \ + _tmp5 = __lsx_vaddwod_w_hu(_reg0, _reg1); \ + _tmp0 = __lsx_vilvl_w(_tmp5, _tmp4); \ + _tmp1 = __lsx_vilvh_w(_tmp5, _tmp4); \ + _tmpr = __lsx_vssrarni_hu_w(_tmp1, _tmp0, 2); \ + _reg0 = __lsx_vmadd_h(const_8000, const_112, _tmpb); \ + _reg1 = __lsx_vmadd_h(const_8000, const_112, _tmpr); \ _reg0 = __lsx_vmsub_h(_reg0, const_74, _tmpg); \ _reg1 = __lsx_vmsub_h(_reg1, const_94, _tmpg); \ _reg0 = __lsx_vmsub_h(_reg0, const_38, _tmpr); \ @@ -155,6 +271,1033 @@ extern "C" { _dst0 = __lsx_vpickod_b(_reg1, _reg0); \ } +void MirrorRow_LSX(const uint8_t* src, uint8_t* dst, int width) { + int x; + int len = width / 32; + __m128i src0, src1; + __m128i shuffler = {0x08090A0B0C0D0E0F, 0x0001020304050607}; + src += width - 32; + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src1); + DUP2_ARG3(__lsx_vshuf_b, src0, src0, shuffler, src1, src1, shuffler, src0, + src1); + __lsx_vst(src1, dst, 0); + __lsx_vst(src0, dst, 16); + dst += 32; + src -= 32; + } +} + +void MirrorUVRow_LSX(const uint8_t* src_uv, uint8_t* dst_uv, int width) { + int x; + int len = width / 8; + __m128i src, dst; + __m128i shuffler = {0x0004000500060007, 0x0000000100020003}; + + src_uv += (width - 8) << 1; + for (x = 0; x < len; x++) { + src = __lsx_vld(src_uv, 0); + dst = __lsx_vshuf_h(shuffler, src, src); + __lsx_vst(dst, dst_uv, 0); + src_uv -= 16; + dst_uv += 16; + } +} + +void ARGBMirrorRow_LSX(const uint8_t* src, uint8_t* dst, int width) { + int x; + int len = width / 8; + __m128i src0, src1; + __m128i shuffler = {0x0B0A09080F0E0D0C, 0x0302010007060504}; + + src += (width * 4) - 32; + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src1); + DUP2_ARG3(__lsx_vshuf_b, src0, src0, shuffler, src1, src1, shuffler, src0, + src1); + __lsx_vst(src1, dst, 0); + __lsx_vst(src0, dst, 16); + dst += 32; + src -= 32; + } +} + +void I422ToYUY2Row_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_yuy2, + int width) { + int x; + int len = width / 16; + __m128i src_u0, src_v0, src_y0, vec_uv0; + __m128i vec_yuy2_0, vec_yuy2_1; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_u, 0, src_v, 0, src_u0, src_v0); + src_y0 = __lsx_vld(src_y, 0); + vec_uv0 = __lsx_vilvl_b(src_v0, src_u0); + vec_yuy2_0 = __lsx_vilvl_b(vec_uv0, src_y0); + vec_yuy2_1 = __lsx_vilvh_b(vec_uv0, src_y0); + __lsx_vst(vec_yuy2_0, dst_yuy2, 0); + __lsx_vst(vec_yuy2_1, dst_yuy2, 16); + src_u += 8; + src_v += 8; + src_y += 16; + dst_yuy2 += 32; + } +} + +void I422ToUYVYRow_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_uyvy, + int width) { + int x; + int len = width / 16; + __m128i src_u0, src_v0, src_y0, vec_uv0; + __m128i vec_uyvy0, vec_uyvy1; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_u, 0, src_v, 0, src_u0, src_v0); + src_y0 = __lsx_vld(src_y, 0); + vec_uv0 = __lsx_vilvl_b(src_v0, src_u0); + vec_uyvy0 = __lsx_vilvl_b(src_y0, vec_uv0); + vec_uyvy1 = __lsx_vilvh_b(src_y0, vec_uv0); + __lsx_vst(vec_uyvy0, dst_uyvy, 0); + __lsx_vst(vec_uyvy1, dst_uyvy, 16); + src_u += 8; + src_v += 8; + src_y += 16; + dst_uyvy += 32; + } +} + +void I422ToARGBRow_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width) { + int x; + int len = width / 16; + __m128i vec_yb, vec_yg, vec_ub, vec_ug, vec_vr, vec_vg; + __m128i vec_ubvr, vec_ugvg; + __m128i alpha = __lsx_vldi(0xFF); + __m128i const_80 = __lsx_vldi(0x80); + + YUVTORGB_SETUP(yuvconstants, vec_vr, vec_ub, vec_vg, vec_ug, vec_yg, vec_yb); + vec_ubvr = __lsx_vilvl_h(vec_ub, vec_vr); + vec_ugvg = __lsx_vilvl_h(vec_ug, vec_vg); + + for (x = 0; x < len; x++) { + __m128i y, uv_l, uv_h, b_l, b_h, g_l, g_h, r_l, r_h; + + READYUV422_D(src_y, src_u, src_v, y, uv_l, uv_h); + YUVTORGB_D(y, uv_l, uv_h, vec_ubvr, vec_ugvg, vec_yg, vec_yb, b_l, b_h, g_l, + g_h, r_l, r_h); + STOREARGB_D(alpha, alpha, r_l, r_h, g_l, g_h, b_l, b_h, dst_argb); + src_y += 16; + src_u += 8; + src_v += 8; + } +} + +void I422ToRGBARow_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width) { + int x; + int len = width / 16; + __m128i vec_yb, vec_yg, vec_ub, vec_vr, vec_ug, vec_vg; + __m128i vec_ubvr, vec_ugvg; + __m128i alpha = __lsx_vldi(0xFF); + __m128i const_80 = __lsx_vldi(0x80); + + YUVTORGB_SETUP(yuvconstants, vec_vr, vec_ub, vec_vg, vec_ug, vec_yg, vec_yb); + vec_ubvr = __lsx_vilvl_h(vec_ub, vec_vr); + vec_ugvg = __lsx_vilvl_h(vec_ug, vec_vg); + + for (x = 0; x < len; x++) { + __m128i y, uv_l, uv_h, b_l, b_h, g_l, g_h, r_l, r_h; + + READYUV422_D(src_y, src_u, src_v, y, uv_l, uv_h); + YUVTORGB_D(y, uv_l, uv_h, vec_ubvr, vec_ugvg, vec_yg, vec_yb, b_l, b_h, g_l, + g_h, r_l, r_h); + STOREARGB_D(r_l, r_h, g_l, g_h, b_l, b_h, alpha, alpha, dst_argb); + src_y += 16; + src_u += 8; + src_v += 8; + } +} + +void I422AlphaToARGBRow_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + const uint8_t* src_a, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width) { + int x; + int len = width / 16; + int res = width & 15; + __m128i vec_yb, vec_yg, vec_ub, vec_vr, vec_ug, vec_vg; + __m128i vec_ubvr, vec_ugvg; + __m128i zero = __lsx_vldi(0); + __m128i const_80 = __lsx_vldi(0x80); + + YUVTORGB_SETUP(yuvconstants, vec_vr, vec_ub, vec_vg, vec_ug, vec_yg, vec_yb); + vec_ubvr = __lsx_vilvl_h(vec_ub, vec_vr); + vec_ugvg = __lsx_vilvl_h(vec_ug, vec_vg); + + for (x = 0; x < len; x++) { + __m128i y, uv_l, uv_h, b_l, b_h, g_l, g_h, r_l, r_h, a_l, a_h; + + y = __lsx_vld(src_a, 0); + a_l = __lsx_vilvl_b(zero, y); + a_h = __lsx_vilvh_b(zero, y); + READYUV422_D(src_y, src_u, src_v, y, uv_l, uv_h); + YUVTORGB_D(y, uv_l, uv_h, vec_ubvr, vec_ugvg, vec_yg, vec_yb, b_l, b_h, g_l, + g_h, r_l, r_h); + STOREARGB_D(a_l, a_h, r_l, r_h, g_l, g_h, b_l, b_h, dst_argb); + src_y += 16; + src_u += 8; + src_v += 8; + src_a += 16; + } + if (res) { + __m128i y, uv, r, g, b, a; + a = __lsx_vld(src_a, 0); + a = __lsx_vsllwil_hu_bu(a, 0); + READYUV422(src_y, src_u, src_v, y, uv); + YUVTORGB(y, uv, vec_ubvr, vec_ugvg, vec_yg, vec_yb, b, g, r); + STOREARGB(a, r, g, b, dst_argb); + } +} + +void I422ToRGB24Row_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int32_t width) { + int x; + int len = width / 16; + __m128i vec_yb, vec_yg, vec_ub, vec_vr, vec_ug, vec_vg; + __m128i vec_ubvr, vec_ugvg; + __m128i const_80 = __lsx_vldi(0x80); + __m128i shuffler0 = {0x0504120302100100, 0x0A18090816070614}; + __m128i shuffler1 = {0x1E0F0E1C0D0C1A0B, 0x1E0F0E1C0D0C1A0B}; + + YUVTORGB_SETUP(yuvconstants, vec_vr, vec_ub, vec_vg, vec_ug, vec_yg, vec_yb); + vec_ubvr = __lsx_vilvl_h(vec_ub, vec_vr); + vec_ugvg = __lsx_vilvl_h(vec_ug, vec_vg); + + for (x = 0; x < len; x++) { + __m128i y, uv_l, uv_h, b_l, b_h, g_l, g_h, r_l, r_h; + __m128i temp0, temp1, temp2, temp3; + + READYUV422_D(src_y, src_u, src_v, y, uv_l, uv_h); + YUVTORGB_D(y, uv_l, uv_h, vec_ubvr, vec_ugvg, vec_yg, vec_yb, b_l, b_h, g_l, + g_h, r_l, r_h); + temp0 = __lsx_vpackev_b(g_l, b_l); + temp1 = __lsx_vpackev_b(g_h, b_h); + DUP4_ARG3(__lsx_vshuf_b, r_l, temp0, shuffler1, r_h, temp1, shuffler1, r_l, + temp0, shuffler0, r_h, temp1, shuffler0, temp2, temp3, temp0, + temp1); + + b_l = __lsx_vilvl_d(temp1, temp2); + b_h = __lsx_vilvh_d(temp3, temp1); + __lsx_vst(temp0, dst_argb, 0); + __lsx_vst(b_l, dst_argb, 16); + __lsx_vst(b_h, dst_argb, 32); + dst_argb += 48; + src_y += 16; + src_u += 8; + src_v += 8; + } +} + +// TODO(fbarchard): Consider AND instead of shift to isolate 5 upper bits of R. +void I422ToRGB565Row_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_rgb565, + const struct YuvConstants* yuvconstants, + int width) { + int x; + int len = width / 16; + __m128i vec_yb, vec_yg, vec_ub, vec_vr, vec_ug, vec_vg; + __m128i vec_ubvr, vec_ugvg; + __m128i const_80 = __lsx_vldi(0x80); + + YUVTORGB_SETUP(yuvconstants, vec_vr, vec_ub, vec_vg, vec_ug, vec_yg, vec_yb); + vec_ubvr = __lsx_vilvl_h(vec_ub, vec_vr); + vec_ugvg = __lsx_vilvl_h(vec_ug, vec_vg); + + for (x = 0; x < len; x++) { + __m128i y, uv_l, uv_h, b_l, b_h, g_l, g_h, r_l, r_h; + + READYUV422_D(src_y, src_u, src_v, y, uv_l, uv_h); + YUVTORGB_D(y, uv_l, uv_h, vec_ubvr, vec_ugvg, vec_yg, vec_yb, b_l, b_h, g_l, + g_h, r_l, r_h); + b_l = __lsx_vsrli_h(b_l, 3); + b_h = __lsx_vsrli_h(b_h, 3); + g_l = __lsx_vsrli_h(g_l, 2); + g_h = __lsx_vsrli_h(g_h, 2); + r_l = __lsx_vsrli_h(r_l, 3); + r_h = __lsx_vsrli_h(r_h, 3); + r_l = __lsx_vslli_h(r_l, 11); + r_h = __lsx_vslli_h(r_h, 11); + g_l = __lsx_vslli_h(g_l, 5); + g_h = __lsx_vslli_h(g_h, 5); + r_l = __lsx_vor_v(r_l, g_l); + r_l = __lsx_vor_v(r_l, b_l); + r_h = __lsx_vor_v(r_h, g_h); + r_h = __lsx_vor_v(r_h, b_h); + __lsx_vst(r_l, dst_rgb565, 0); + __lsx_vst(r_h, dst_rgb565, 16); + dst_rgb565 += 32; + src_y += 16; + src_u += 8; + src_v += 8; + } +} + +// TODO(fbarchard): Consider AND instead of shift to isolate 4 upper bits of G. +void I422ToARGB4444Row_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb4444, + const struct YuvConstants* yuvconstants, + int width) { + int x; + int len = width / 16; + __m128i vec_yb, vec_yg, vec_ub, vec_vr, vec_ug, vec_vg; + __m128i vec_ubvr, vec_ugvg; + __m128i const_80 = __lsx_vldi(0x80); + __m128i alpha = (__m128i)v2u64{0xF000F000F000F000, 0xF000F000F000F000}; + __m128i mask = {0x00F000F000F000F0, 0x00F000F000F000F0}; + + YUVTORGB_SETUP(yuvconstants, vec_vr, vec_ub, vec_vg, vec_ug, vec_yg, vec_yb); + vec_ubvr = __lsx_vilvl_h(vec_ub, vec_vr); + vec_ugvg = __lsx_vilvl_h(vec_ug, vec_vg); + + for (x = 0; x < len; x++) { + __m128i y, uv_l, uv_h, b_l, b_h, g_l, g_h, r_l, r_h; + + READYUV422_D(src_y, src_u, src_v, y, uv_l, uv_h); + YUVTORGB_D(y, uv_l, uv_h, vec_ubvr, vec_ugvg, vec_yg, vec_yb, b_l, b_h, g_l, + g_h, r_l, r_h); + b_l = __lsx_vsrli_h(b_l, 4); + b_h = __lsx_vsrli_h(b_h, 4); + r_l = __lsx_vsrli_h(r_l, 4); + r_h = __lsx_vsrli_h(r_h, 4); + g_l = __lsx_vand_v(g_l, mask); + g_h = __lsx_vand_v(g_h, mask); + r_l = __lsx_vslli_h(r_l, 8); + r_h = __lsx_vslli_h(r_h, 8); + r_l = __lsx_vor_v(r_l, alpha); + r_h = __lsx_vor_v(r_h, alpha); + r_l = __lsx_vor_v(r_l, g_l); + r_h = __lsx_vor_v(r_h, g_h); + r_l = __lsx_vor_v(r_l, b_l); + r_h = __lsx_vor_v(r_h, b_h); + __lsx_vst(r_l, dst_argb4444, 0); + __lsx_vst(r_h, dst_argb4444, 16); + dst_argb4444 += 32; + src_y += 16; + src_u += 8; + src_v += 8; + } +} + +void I422ToARGB1555Row_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb1555, + const struct YuvConstants* yuvconstants, + int width) { + int x; + int len = width / 16; + __m128i vec_yb, vec_yg, vec_ub, vec_vr, vec_ug, vec_vg; + __m128i vec_ubvr, vec_ugvg; + __m128i const_80 = __lsx_vldi(0x80); + __m128i alpha = (__m128i)v2u64{0x8000800080008000, 0x8000800080008000}; + + YUVTORGB_SETUP(yuvconstants, vec_vr, vec_ub, vec_vg, vec_ug, vec_yg, vec_yb); + vec_ubvr = __lsx_vilvl_h(vec_ub, vec_vr); + vec_ugvg = __lsx_vilvl_h(vec_ug, vec_vg); + + for (x = 0; x < len; x++) { + __m128i y, uv_l, uv_h, b_l, b_h, g_l, g_h, r_l, r_h; + + READYUV422_D(src_y, src_u, src_v, y, uv_l, uv_h); + YUVTORGB_D(y, uv_l, uv_h, vec_ubvr, vec_ugvg, vec_yg, vec_yb, b_l, b_h, g_l, + g_h, r_l, r_h); + b_l = __lsx_vsrli_h(b_l, 3); + b_h = __lsx_vsrli_h(b_h, 3); + g_l = __lsx_vsrli_h(g_l, 3); + + g_h = __lsx_vsrli_h(g_h, 3); + g_l = __lsx_vslli_h(g_l, 5); + g_h = __lsx_vslli_h(g_h, 5); + r_l = __lsx_vsrli_h(r_l, 3); + r_h = __lsx_vsrli_h(r_h, 3); + r_l = __lsx_vslli_h(r_l, 10); + r_h = __lsx_vslli_h(r_h, 10); + r_l = __lsx_vor_v(r_l, alpha); + r_h = __lsx_vor_v(r_h, alpha); + r_l = __lsx_vor_v(r_l, g_l); + r_h = __lsx_vor_v(r_h, g_h); + r_l = __lsx_vor_v(r_l, b_l); + r_h = __lsx_vor_v(r_h, b_h); + __lsx_vst(r_l, dst_argb1555, 0); + __lsx_vst(r_h, dst_argb1555, 16); + dst_argb1555 += 32; + src_y += 16; + src_u += 8; + src_v += 8; + } +} + +void YUY2ToYRow_LSX(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { + int x; + int len = width / 16; + __m128i src0, src1, dst0; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_yuy2, 0, src_yuy2, 16, src0, src1); + dst0 = __lsx_vpickev_b(src1, src0); + __lsx_vst(dst0, dst_y, 0); + src_yuy2 += 32; + dst_y += 16; + } +} + +void YUY2ToUVRow_LSX(const uint8_t* src_yuy2, + int src_stride_yuy2, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { + const uint8_t* src_yuy2_next = src_yuy2 + src_stride_yuy2; + int x; + int len = width / 16; + __m128i src0, src1, src2, src3; + __m128i tmp0, dst0, dst1; + + for (x = 0; x < len; x++) { + DUP4_ARG2(__lsx_vld, src_yuy2, 0, src_yuy2, 16, src_yuy2_next, 0, + src_yuy2_next, 16, src0, src1, src2, src3); + src0 = __lsx_vpickod_b(src1, src0); + src1 = __lsx_vpickod_b(src3, src2); + tmp0 = __lsx_vavgr_bu(src1, src0); + dst0 = __lsx_vpickev_b(tmp0, tmp0); + dst1 = __lsx_vpickod_b(tmp0, tmp0); + __lsx_vstelm_d(dst0, dst_u, 0, 0); + __lsx_vstelm_d(dst1, dst_v, 0, 0); + src_yuy2 += 32; + src_yuy2_next += 32; + dst_u += 8; + dst_v += 8; + } +} + +void YUY2ToUV422Row_LSX(const uint8_t* src_yuy2, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { + int x; + int len = width / 16; + __m128i src0, src1, tmp0, dst0, dst1; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_yuy2, 0, src_yuy2, 16, src0, src1); + tmp0 = __lsx_vpickod_b(src1, src0); + dst0 = __lsx_vpickev_b(tmp0, tmp0); + dst1 = __lsx_vpickod_b(tmp0, tmp0); + __lsx_vstelm_d(dst0, dst_u, 0, 0); + __lsx_vstelm_d(dst1, dst_v, 0, 0); + src_yuy2 += 32; + dst_u += 8; + dst_v += 8; + } +} + +void UYVYToYRow_LSX(const uint8_t* src_uyvy, uint8_t* dst_y, int width) { + int x; + int len = width / 16; + __m128i src0, src1, dst0; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_uyvy, 0, src_uyvy, 16, src0, src1); + dst0 = __lsx_vpickod_b(src1, src0); + __lsx_vst(dst0, dst_y, 0); + src_uyvy += 32; + dst_y += 16; + } +} + +void UYVYToUVRow_LSX(const uint8_t* src_uyvy, + int src_stride_uyvy, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { + const uint8_t* src_uyvy_next = src_uyvy + src_stride_uyvy; + int x; + int len = width / 16; + __m128i src0, src1, src2, src3, tmp0, dst0, dst1; + + for (x = 0; x < len; x++) { + DUP4_ARG2(__lsx_vld, src_uyvy, 0, src_uyvy, 16, src_uyvy_next, 0, + src_uyvy_next, 16, src0, src1, src2, src3); + src0 = __lsx_vpickev_b(src1, src0); + src1 = __lsx_vpickev_b(src3, src2); + tmp0 = __lsx_vavgr_bu(src1, src0); + dst0 = __lsx_vpickev_b(tmp0, tmp0); + dst1 = __lsx_vpickod_b(tmp0, tmp0); + __lsx_vstelm_d(dst0, dst_u, 0, 0); + __lsx_vstelm_d(dst1, dst_v, 0, 0); + src_uyvy += 32; + src_uyvy_next += 32; + dst_u += 8; + dst_v += 8; + } +} + +void UYVYToUV422Row_LSX(const uint8_t* src_uyvy, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { + int x; + int len = width / 16; + __m128i src0, src1, tmp0, dst0, dst1; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_uyvy, 0, src_uyvy, 16, src0, src1); + tmp0 = __lsx_vpickev_b(src1, src0); + dst0 = __lsx_vpickev_b(tmp0, tmp0); + dst1 = __lsx_vpickod_b(tmp0, tmp0); + __lsx_vstelm_d(dst0, dst_u, 0, 0); + __lsx_vstelm_d(dst1, dst_v, 0, 0); + src_uyvy += 32; + dst_u += 8; + dst_v += 8; + } +} + +void ARGBToUVRow_LSX(const uint8_t* src_argb0, + int src_stride_argb, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { + int x; + int len = width / 16; + const uint8_t* src_argb1 = src_argb0 + src_stride_argb; + + __m128i src0, src1, src2, src3, src4, src5, src6, src7; + __m128i vec0, vec1, vec2, vec3; + __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, dst0, dst1; + __m128i const_0x70 = __lsx_vldi(0x470); + __m128i const_0x4A = __lsx_vldi(0x44A); + __m128i const_0x26 = __lsx_vldi(0x426); + __m128i const_0x5E = __lsx_vldi(0x45E); + __m128i const_0x12 = __lsx_vldi(0x412); + __m128i const_0x8000 = (__m128i)v2u64{0x8000800080008000, 0x8000800080008000}; + for (x = 0; x < len; x++) { + DUP4_ARG2(__lsx_vld, src_argb0, 0, src_argb0, 16, src_argb0, 32, src_argb0, + 48, src0, src1, src2, src3); + DUP4_ARG2(__lsx_vld, src_argb1, 0, src_argb1, 16, src_argb1, 32, src_argb1, + 48, src4, src5, src6, src7); + vec0 = __lsx_vaddwev_h_bu(src0, src4); + vec1 = __lsx_vaddwev_h_bu(src1, src5); + vec2 = __lsx_vaddwev_h_bu(src2, src6); + vec3 = __lsx_vaddwev_h_bu(src3, src7); + tmp0 = __lsx_vpickev_h(vec1, vec0); + tmp1 = __lsx_vpickev_h(vec3, vec2); + tmp2 = __lsx_vpickod_h(vec1, vec0); + tmp3 = __lsx_vpickod_h(vec3, vec2); + vec0 = __lsx_vaddwod_h_bu(src0, src4); + vec1 = __lsx_vaddwod_h_bu(src1, src5); + vec2 = __lsx_vaddwod_h_bu(src2, src6); + vec3 = __lsx_vaddwod_h_bu(src3, src7); + tmp4 = __lsx_vpickev_h(vec1, vec0); + tmp5 = __lsx_vpickev_h(vec3, vec2); + vec0 = __lsx_vpickev_h(tmp1, tmp0); + vec1 = __lsx_vpickod_h(tmp1, tmp0); + src0 = __lsx_vadd_h(vec0, vec1); + src0 = __lsx_vsrari_h(src0, 2); + vec0 = __lsx_vpickev_h(tmp3, tmp2); + vec1 = __lsx_vpickod_h(tmp3, tmp2); + src1 = __lsx_vadd_h(vec0, vec1); + src1 = __lsx_vsrari_h(src1, 2); + vec0 = __lsx_vpickev_h(tmp5, tmp4); + vec1 = __lsx_vpickod_h(tmp5, tmp4); + src2 = __lsx_vadd_h(vec0, vec1); + src2 = __lsx_vsrari_h(src2, 2); + dst0 = __lsx_vmadd_h(const_0x8000, src0, const_0x70); + dst0 = __lsx_vmsub_h(dst0, src2, const_0x4A); + dst0 = __lsx_vmsub_h(dst0, src1, const_0x26); + dst1 = __lsx_vmadd_h(const_0x8000, src1, const_0x70); + dst1 = __lsx_vmsub_h(dst1, src2, const_0x5E); + dst1 = __lsx_vmsub_h(dst1, src0, const_0x12); + dst0 = __lsx_vsrai_h(dst0, 8); + dst1 = __lsx_vsrai_h(dst1, 8); + dst0 = __lsx_vpickev_b(dst1, dst0); + __lsx_vstelm_d(dst0, dst_u, 0, 0); + __lsx_vstelm_d(dst0, dst_v, 0, 1); + src_argb0 += 64; + src_argb1 += 64; + dst_u += 8; + dst_v += 8; + } +} + +void ARGBToRGB24Row_LSX(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { + int x; + int len = (width / 16) - 1; + __m128i src0, src1, src2, src3; + __m128i tmp0, tmp1, tmp2, tmp3; + __m128i shuf = {0x0908060504020100, 0x000000000E0D0C0A}; + for (x = 0; x < len; x++) { + DUP4_ARG2(__lsx_vld, src_argb, 0, src_argb, 16, src_argb, 32, src_argb, 48, + src0, src1, src2, src3); + tmp0 = __lsx_vshuf_b(src0, src0, shuf); + tmp1 = __lsx_vshuf_b(src1, src1, shuf); + tmp2 = __lsx_vshuf_b(src2, src2, shuf); + tmp3 = __lsx_vshuf_b(src3, src3, shuf); + __lsx_vst(tmp0, dst_rgb, 0); + __lsx_vst(tmp1, dst_rgb, 12); + __lsx_vst(tmp2, dst_rgb, 24); + __lsx_vst(tmp3, dst_rgb, 36); + dst_rgb += 48; + src_argb += 64; + } + DUP4_ARG2(__lsx_vld, src_argb, 0, src_argb, 16, src_argb, 32, src_argb, 48, + src0, src1, src2, src3); + tmp0 = __lsx_vshuf_b(src0, src0, shuf); + tmp1 = __lsx_vshuf_b(src1, src1, shuf); + tmp2 = __lsx_vshuf_b(src2, src2, shuf); + tmp3 = __lsx_vshuf_b(src3, src3, shuf); + __lsx_vst(tmp0, dst_rgb, 0); + __lsx_vst(tmp1, dst_rgb, 12); + __lsx_vst(tmp2, dst_rgb, 24); + dst_rgb += 36; + __lsx_vst(tmp3, dst_rgb, 0); +} + +void ARGBToRAWRow_LSX(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { + int x; + int len = (width / 16) - 1; + __m128i src0, src1, src2, src3; + __m128i tmp0, tmp1, tmp2, tmp3; + __m128i shuf = {0x090A040506000102, 0x000000000C0D0E08}; + for (x = 0; x < len; x++) { + DUP4_ARG2(__lsx_vld, src_argb, 0, src_argb, 16, src_argb, 32, src_argb, 48, + src0, src1, src2, src3); + tmp0 = __lsx_vshuf_b(src0, src0, shuf); + tmp1 = __lsx_vshuf_b(src1, src1, shuf); + tmp2 = __lsx_vshuf_b(src2, src2, shuf); + tmp3 = __lsx_vshuf_b(src3, src3, shuf); + __lsx_vst(tmp0, dst_rgb, 0); + __lsx_vst(tmp1, dst_rgb, 12); + __lsx_vst(tmp2, dst_rgb, 24); + __lsx_vst(tmp3, dst_rgb, 36); + dst_rgb += 48; + src_argb += 64; + } + DUP4_ARG2(__lsx_vld, src_argb, 0, src_argb, 16, src_argb, 32, src_argb, 48, + src0, src1, src2, src3); + tmp0 = __lsx_vshuf_b(src0, src0, shuf); + tmp1 = __lsx_vshuf_b(src1, src1, shuf); + tmp2 = __lsx_vshuf_b(src2, src2, shuf); + tmp3 = __lsx_vshuf_b(src3, src3, shuf); + __lsx_vst(tmp0, dst_rgb, 0); + __lsx_vst(tmp1, dst_rgb, 12); + __lsx_vst(tmp2, dst_rgb, 24); + dst_rgb += 36; + __lsx_vst(tmp3, dst_rgb, 0); +} + +void ARGBToRGB565Row_LSX(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { + int x; + int len = width / 8; + __m128i zero = __lsx_vldi(0); + __m128i src0, src1, tmp0, tmp1, dst0; + __m128i shift = {0x0300030003000300, 0x0300030003000300}; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_argb, 0, src_argb, 16, src0, src1); + tmp0 = __lsx_vpickev_b(src1, src0); + tmp1 = __lsx_vpickod_b(src1, src0); + tmp0 = __lsx_vsrli_b(tmp0, 3); + tmp1 = __lsx_vpackev_b(zero, tmp1); + tmp1 = __lsx_vsrli_h(tmp1, 2); + tmp0 = __lsx_vsll_b(tmp0, shift); + tmp1 = __lsx_vslli_h(tmp1, 5); + dst0 = __lsx_vor_v(tmp0, tmp1); + __lsx_vst(dst0, dst_rgb, 0); + dst_rgb += 16; + src_argb += 32; + } +} + +void ARGBToARGB1555Row_LSX(const uint8_t* src_argb, + uint8_t* dst_rgb, + int width) { + int x; + int len = width / 8; + __m128i zero = __lsx_vldi(0); + __m128i src0, src1, tmp0, tmp1, tmp2, tmp3, dst0; + __m128i shift1 = {0x0703070307030703, 0x0703070307030703}; + __m128i shift2 = {0x0200020002000200, 0x0200020002000200}; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_argb, 0, src_argb, 16, src0, src1); + tmp0 = __lsx_vpickev_b(src1, src0); + tmp1 = __lsx_vpickod_b(src1, src0); + tmp0 = __lsx_vsrli_b(tmp0, 3); + tmp1 = __lsx_vsrl_b(tmp1, shift1); + tmp0 = __lsx_vsll_b(tmp0, shift2); + tmp2 = __lsx_vpackev_b(zero, tmp1); + tmp3 = __lsx_vpackod_b(zero, tmp1); + tmp2 = __lsx_vslli_h(tmp2, 5); + tmp3 = __lsx_vslli_h(tmp3, 15); + dst0 = __lsx_vor_v(tmp0, tmp2); + dst0 = __lsx_vor_v(dst0, tmp3); + __lsx_vst(dst0, dst_rgb, 0); + dst_rgb += 16; + src_argb += 32; + } +} + +void ARGBToARGB4444Row_LSX(const uint8_t* src_argb, + uint8_t* dst_rgb, + int width) { + int x; + int len = width / 8; + __m128i src0, src1, tmp0, tmp1, dst0; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_argb, 0, src_argb, 16, src0, src1); + tmp0 = __lsx_vpickev_b(src1, src0); + tmp1 = __lsx_vpickod_b(src1, src0); + tmp1 = __lsx_vandi_b(tmp1, 0xF0); + tmp0 = __lsx_vsrli_b(tmp0, 4); + dst0 = __lsx_vor_v(tmp1, tmp0); + __lsx_vst(dst0, dst_rgb, 0); + dst_rgb += 16; + src_argb += 32; + } +} + +void ARGBToUV444Row_LSX(const uint8_t* src_argb, + uint8_t* dst_u, + uint8_t* dst_v, + int32_t width) { + int x; + int len = width / 16; + __m128i src0, src1, src2, src3; + __m128i tmp0, tmp1, tmp2, tmp3; + __m128i reg0, reg1, reg2, reg3, dst0, dst1; + __m128i const_112 = __lsx_vldi(112); + __m128i const_74 = __lsx_vldi(74); + __m128i const_38 = __lsx_vldi(38); + __m128i const_94 = __lsx_vldi(94); + __m128i const_18 = __lsx_vldi(18); + __m128i const_0x8000 = (__m128i)v2u64{0x8000800080008000, 0x8000800080008000}; + for (x = 0; x < len; x++) { + DUP4_ARG2(__lsx_vld, src_argb, 0, src_argb, 16, src_argb, 32, src_argb, 48, + src0, src1, src2, src3); + tmp0 = __lsx_vpickev_h(src1, src0); + tmp1 = __lsx_vpickod_h(src1, src0); + tmp2 = __lsx_vpickev_h(src3, src2); + tmp3 = __lsx_vpickod_h(src3, src2); + reg0 = __lsx_vmaddwev_h_bu(const_0x8000, tmp0, const_112); + reg1 = __lsx_vmaddwev_h_bu(const_0x8000, tmp2, const_112); + reg2 = __lsx_vmulwod_h_bu(tmp0, const_74); + reg3 = __lsx_vmulwod_h_bu(tmp2, const_74); + reg2 = __lsx_vmaddwev_h_bu(reg2, tmp1, const_38); + reg3 = __lsx_vmaddwev_h_bu(reg3, tmp3, const_38); + reg0 = __lsx_vsub_h(reg0, reg2); + reg1 = __lsx_vsub_h(reg1, reg3); + reg0 = __lsx_vsrai_h(reg0, 8); + reg1 = __lsx_vsrai_h(reg1, 8); + dst0 = __lsx_vpickev_b(reg1, reg0); + + reg0 = __lsx_vmaddwev_h_bu(const_0x8000, tmp1, const_112); + reg1 = __lsx_vmaddwev_h_bu(const_0x8000, tmp3, const_112); + reg2 = __lsx_vmulwev_h_bu(tmp0, const_18); + reg3 = __lsx_vmulwev_h_bu(tmp2, const_18); + reg2 = __lsx_vmaddwod_h_bu(reg2, tmp0, const_94); + reg3 = __lsx_vmaddwod_h_bu(reg3, tmp2, const_94); + reg0 = __lsx_vsub_h(reg0, reg2); + reg1 = __lsx_vsub_h(reg1, reg3); + reg0 = __lsx_vsrai_h(reg0, 8); + reg1 = __lsx_vsrai_h(reg1, 8); + dst1 = __lsx_vpickev_b(reg1, reg0); + + __lsx_vst(dst0, dst_u, 0); + __lsx_vst(dst1, dst_v, 0); + dst_u += 16; + dst_v += 16; + src_argb += 64; + } +} + +void ARGBMultiplyRow_LSX(const uint8_t* src_argb0, + const uint8_t* src_argb1, + uint8_t* dst_argb, + int width) { + int x; + int len = width / 4; + __m128i zero = __lsx_vldi(0); + __m128i src0, src1, dst0, dst1; + __m128i tmp0, tmp1, tmp2, tmp3; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_argb0, 0, src_argb1, 0, src0, src1); + tmp0 = __lsx_vilvl_b(src0, src0); + tmp1 = __lsx_vilvh_b(src0, src0); + tmp2 = __lsx_vilvl_b(zero, src1); + tmp3 = __lsx_vilvh_b(zero, src1); + dst0 = __lsx_vmuh_hu(tmp0, tmp2); + dst1 = __lsx_vmuh_hu(tmp1, tmp3); + dst0 = __lsx_vpickev_b(dst1, dst0); + __lsx_vst(dst0, dst_argb, 0); + src_argb0 += 16; + src_argb1 += 16; + dst_argb += 16; + } +} + +void ARGBAddRow_LSX(const uint8_t* src_argb0, + const uint8_t* src_argb1, + uint8_t* dst_argb, + int width) { + int x; + int len = width / 4; + __m128i src0, src1, dst0; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_argb0, 0, src_argb1, 0, src0, src1); + dst0 = __lsx_vsadd_bu(src0, src1); + __lsx_vst(dst0, dst_argb, 0); + src_argb0 += 16; + src_argb1 += 16; + dst_argb += 16; + } +} + +void ARGBSubtractRow_LSX(const uint8_t* src_argb0, + const uint8_t* src_argb1, + uint8_t* dst_argb, + int width) { + int x; + int len = width / 4; + __m128i src0, src1, dst0; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_argb0, 0, src_argb1, 0, src0, src1); + dst0 = __lsx_vssub_bu(src0, src1); + __lsx_vst(dst0, dst_argb, 0); + src_argb0 += 16; + src_argb1 += 16; + dst_argb += 16; + } +} + +void ARGBAttenuateRow_LSX(const uint8_t* src_argb, + uint8_t* dst_argb, + int width) { + int x; + int len = width / 8; + __m128i src0, src1, tmp0, tmp1; + __m128i reg0, reg1, reg2, reg3, reg4, reg5; + __m128i b, g, r, a, dst0, dst1; + __m128i control = {0x0005000100040000, 0x0007000300060002}; + __m128i zero = __lsx_vldi(0); + __m128i const_add = __lsx_vldi(0x8ff); + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_argb, 0, src_argb, 16, src0, src1); + tmp0 = __lsx_vpickev_b(src1, src0); + tmp1 = __lsx_vpickod_b(src1, src0); + b = __lsx_vpackev_b(zero, tmp0); + r = __lsx_vpackod_b(zero, tmp0); + g = __lsx_vpackev_b(zero, tmp1); + a = __lsx_vpackod_b(zero, tmp1); + reg0 = __lsx_vmaddwev_w_hu(const_add, b, a); + reg1 = __lsx_vmaddwod_w_hu(const_add, b, a); + reg2 = __lsx_vmaddwev_w_hu(const_add, r, a); + reg3 = __lsx_vmaddwod_w_hu(const_add, r, a); + reg4 = __lsx_vmaddwev_w_hu(const_add, g, a); + reg5 = __lsx_vmaddwod_w_hu(const_add, g, a); + reg0 = __lsx_vssrani_h_w(reg1, reg0, 8); + reg2 = __lsx_vssrani_h_w(reg3, reg2, 8); + reg4 = __lsx_vssrani_h_w(reg5, reg4, 8); + reg0 = __lsx_vshuf_h(control, reg0, reg0); + reg2 = __lsx_vshuf_h(control, reg2, reg2); + reg4 = __lsx_vshuf_h(control, reg4, reg4); + tmp0 = __lsx_vpackev_b(reg4, reg0); + tmp1 = __lsx_vpackev_b(a, reg2); + dst0 = __lsx_vilvl_h(tmp1, tmp0); + dst1 = __lsx_vilvh_h(tmp1, tmp0); + __lsx_vst(dst0, dst_argb, 0); + __lsx_vst(dst1, dst_argb, 16); + dst_argb += 32; + src_argb += 32; + } +} + +void ARGBToRGB565DitherRow_LSX(const uint8_t* src_argb, + uint8_t* dst_rgb, + uint32_t dither4, + int width) { + int x; + int len = width / 8; + __m128i src0, src1, tmp0, tmp1, dst0; + __m128i b, g, r; + __m128i zero = __lsx_vldi(0); + __m128i vec_dither = __lsx_vldrepl_w(&dither4, 0); + + vec_dither = __lsx_vilvl_b(zero, vec_dither); + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_argb, 0, src_argb, 16, src0, src1); + tmp0 = __lsx_vpickev_b(src1, src0); + tmp1 = __lsx_vpickod_b(src1, src0); + b = __lsx_vpackev_b(zero, tmp0); + r = __lsx_vpackod_b(zero, tmp0); + g = __lsx_vpackev_b(zero, tmp1); + b = __lsx_vadd_h(b, vec_dither); + g = __lsx_vadd_h(g, vec_dither); + r = __lsx_vadd_h(r, vec_dither); + DUP2_ARG1(__lsx_vclip255_h, b, g, b, g); + r = __lsx_vclip255_h(r); + b = __lsx_vsrai_h(b, 3); + g = __lsx_vsrai_h(g, 2); + r = __lsx_vsrai_h(r, 3); + g = __lsx_vslli_h(g, 5); + r = __lsx_vslli_h(r, 11); + dst0 = __lsx_vor_v(b, g); + dst0 = __lsx_vor_v(dst0, r); + __lsx_vst(dst0, dst_rgb, 0); + src_argb += 32; + dst_rgb += 16; + } +} + +void ARGBShuffleRow_LSX(const uint8_t* src_argb, + uint8_t* dst_argb, + const uint8_t* shuffler, + int width) { + int x; + int len = width / 8; + __m128i src0, src1, dst0, dst1; + __m128i shuf = {0x0404040400000000, 0x0C0C0C0C08080808}; + __m128i temp = __lsx_vldrepl_w(shuffler, 0); + + shuf = __lsx_vadd_b(shuf, temp); + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_argb, 0, src_argb, 16, src0, src1); + dst0 = __lsx_vshuf_b(src0, src0, shuf); + dst1 = __lsx_vshuf_b(src1, src1, shuf); + __lsx_vst(dst0, dst_argb, 0); + __lsx_vst(dst1, dst_argb, 16); + src_argb += 32; + dst_argb += 32; + } +} + +void ARGBShadeRow_LSX(const uint8_t* src_argb, + uint8_t* dst_argb, + int width, + uint32_t value) { + int x; + int len = width / 4; + __m128i src0, dst0, tmp0, tmp1; + __m128i vec_value = __lsx_vreplgr2vr_w(value); + + vec_value = __lsx_vilvl_b(vec_value, vec_value); + for (x = 0; x < len; x++) { + src0 = __lsx_vld(src_argb, 0); + tmp0 = __lsx_vilvl_b(src0, src0); + tmp1 = __lsx_vilvh_b(src0, src0); + tmp0 = __lsx_vmuh_hu(tmp0, vec_value); + tmp1 = __lsx_vmuh_hu(tmp1, vec_value); + dst0 = __lsx_vpickod_b(tmp1, tmp0); + __lsx_vst(dst0, dst_argb, 0); + src_argb += 16; + dst_argb += 16; + } +} + +void ARGBGrayRow_LSX(const uint8_t* src_argb, uint8_t* dst_argb, int width) { + int x; + int len = width / 8; + __m128i src0, src1, tmp0, tmp1; + __m128i reg0, reg1, reg2, dst0, dst1; + __m128i const_128 = __lsx_vldi(0x480); + __m128i const_150 = __lsx_vldi(0x96); + __m128i const_br = {0x4D1D4D1D4D1D4D1D, 0x4D1D4D1D4D1D4D1D}; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_argb, 0, src_argb, 16, src0, src1); + tmp0 = __lsx_vpickev_b(src1, src0); + tmp1 = __lsx_vpickod_b(src1, src0); + reg0 = __lsx_vdp2_h_bu(tmp0, const_br); + reg1 = __lsx_vmaddwev_h_bu(const_128, tmp1, const_150); + reg2 = __lsx_vadd_h(reg0, reg1); + tmp0 = __lsx_vpackod_b(reg2, reg2); + tmp1 = __lsx_vpackod_b(tmp1, reg2); + dst0 = __lsx_vilvl_h(tmp1, tmp0); + dst1 = __lsx_vilvh_h(tmp1, tmp0); + __lsx_vst(dst0, dst_argb, 0); + __lsx_vst(dst1, dst_argb, 16); + src_argb += 32; + dst_argb += 32; + } +} + +void ARGBSepiaRow_LSX(uint8_t* dst_argb, int width) { + int x; + int len = width / 8; + __m128i src0, src1, tmp0, tmp1; + __m128i reg0, reg1, spb, spg, spr; + __m128i dst0, dst1; + __m128i spb_g = __lsx_vldi(68); + __m128i spg_g = __lsx_vldi(88); + __m128i spr_g = __lsx_vldi(98); + __m128i spb_br = {0x2311231123112311, 0x2311231123112311}; + __m128i spg_br = {0x2D162D162D162D16, 0x2D162D162D162D16}; + __m128i spr_br = {0x3218321832183218, 0x3218321832183218}; + __m128i shuff = {0x1706150413021100, 0x1F0E1D0C1B0A1908}; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, dst_argb, 0, dst_argb, 16, src0, src1); + tmp0 = __lsx_vpickev_b(src1, src0); + tmp1 = __lsx_vpickod_b(src1, src0); + DUP2_ARG2(__lsx_vdp2_h_bu, tmp0, spb_br, tmp0, spg_br, spb, spg); + spr = __lsx_vdp2_h_bu(tmp0, spr_br); + spb = __lsx_vmaddwev_h_bu(spb, tmp1, spb_g); + spg = __lsx_vmaddwev_h_bu(spg, tmp1, spg_g); + spr = __lsx_vmaddwev_h_bu(spr, tmp1, spr_g); + spb = __lsx_vsrli_h(spb, 7); + spg = __lsx_vsrli_h(spg, 7); + spr = __lsx_vsrli_h(spr, 7); + spg = __lsx_vsat_hu(spg, 7); + spr = __lsx_vsat_hu(spr, 7); + reg0 = __lsx_vpackev_b(spg, spb); + reg1 = __lsx_vshuf_b(tmp1, spr, shuff); + dst0 = __lsx_vilvl_h(reg1, reg0); + dst1 = __lsx_vilvh_h(reg1, reg0); + __lsx_vst(dst0, dst_argb, 0); + __lsx_vst(dst1, dst_argb, 16); + dst_argb += 32; + } +} + void ARGB4444ToARGBRow_LSX(const uint8_t* src_argb4444, uint8_t* dst_argb, int width) { @@ -402,12 +1545,12 @@ void ARGB1555ToUVRow_LSX(const uint8_t* src_argb1555, __m128i tmp0, tmp1, tmp2, tmp3; __m128i tmpb, tmpg, tmpr, nexb, nexg, nexr; __m128i reg0, reg1, reg2, reg3, dst0; - __m128i const_112 = __lsx_vldi(0x438); - __m128i const_74 = __lsx_vldi(0x425); - __m128i const_38 = __lsx_vldi(0x413); - __m128i const_94 = __lsx_vldi(0x42F); - __m128i const_18 = __lsx_vldi(0x409); - __m128i const_8080 = {0x8080808080808080, 0x8080808080808080}; + __m128i const_112 = __lsx_vldi(0x470); + __m128i const_74 = __lsx_vldi(0x44A); + __m128i const_38 = __lsx_vldi(0x426); + __m128i const_94 = __lsx_vldi(0x45E); + __m128i const_18 = __lsx_vldi(0x412); + __m128i const_8000 = (__m128i)v2u64{0x8000800080008000, 0x8000800080008000}; for (x = 0; x < len; x++) { DUP4_ARG2(__lsx_vld, src_argb1555, 0, src_argb1555, 16, next_argb1555, 0, @@ -511,12 +1654,12 @@ void RGB565ToUVRow_LSX(const uint8_t* src_rgb565, __m128i tmp0, tmp1, tmp2, tmp3; __m128i tmpb, tmpg, tmpr, nexb, nexg, nexr; __m128i reg0, reg1, reg2, reg3, dst0; - __m128i const_112 = __lsx_vldi(0x438); - __m128i const_74 = __lsx_vldi(0x425); - __m128i const_38 = __lsx_vldi(0x413); - __m128i const_94 = __lsx_vldi(0x42F); - __m128i const_18 = __lsx_vldi(0x409); - __m128i const_8080 = {0x8080808080808080, 0x8080808080808080}; + __m128i const_112 = __lsx_vldi(0x470); + __m128i const_74 = __lsx_vldi(0x44A); + __m128i const_38 = __lsx_vldi(0x426); + __m128i const_94 = __lsx_vldi(0x45E); + __m128i const_18 = __lsx_vldi(0x412); + __m128i const_8000 = (__m128i)v2u64{0x8000800080008000, 0x8000800080008000}; for (x = 0; x < len; x++) { DUP4_ARG2(__lsx_vld, src_rgb565, 0, src_rgb565, 16, next_rgb565, 0, @@ -572,12 +1715,12 @@ void RGB24ToUVRow_LSX(const uint8_t* src_rgb24, __m128i src0, src1, src2; __m128i nex0, nex1, nex2, dst0; __m128i tmpb, tmpg, tmpr, nexb, nexg, nexr; - __m128i const_112 = __lsx_vldi(0x438); - __m128i const_74 = __lsx_vldi(0x425); - __m128i const_38 = __lsx_vldi(0x413); - __m128i const_94 = __lsx_vldi(0x42F); - __m128i const_18 = __lsx_vldi(0x409); - __m128i const_8080 = {0x8080808080808080, 0x8080808080808080}; + __m128i const_112 = __lsx_vldi(0x470); + __m128i const_74 = __lsx_vldi(0x44A); + __m128i const_38 = __lsx_vldi(0x426); + __m128i const_94 = __lsx_vldi(0x45E); + __m128i const_18 = __lsx_vldi(0x412); + __m128i const_8000 = (__m128i)v2u64{0x8000800080008000, 0x8000800080008000}; __m128i shuff0_b = {0x15120F0C09060300, 0x00000000001E1B18}; __m128i shuff1_b = {0x0706050403020100, 0x1D1A1714110A0908}; __m128i shuff0_g = {0x1613100D0A070401, 0x00000000001F1C19}; @@ -625,12 +1768,12 @@ void RAWToUVRow_LSX(const uint8_t* src_raw, __m128i src0, src1, src2; __m128i nex0, nex1, nex2, dst0; __m128i tmpb, tmpg, tmpr, nexb, nexg, nexr; - __m128i const_112 = __lsx_vldi(0x438); - __m128i const_74 = __lsx_vldi(0x425); - __m128i const_38 = __lsx_vldi(0x413); - __m128i const_94 = __lsx_vldi(0x42F); - __m128i const_18 = __lsx_vldi(0x409); - __m128i const_8080 = {0x8080808080808080, 0x8080808080808080}; + __m128i const_112 = __lsx_vldi(0x470); + __m128i const_74 = __lsx_vldi(0x44A); + __m128i const_38 = __lsx_vldi(0x426); + __m128i const_94 = __lsx_vldi(0x45E); + __m128i const_18 = __lsx_vldi(0x412); + __m128i const_8000 = (__m128i)v2u64{0x8000800080008000, 0x8000800080008000}; __m128i shuff0_r = {0x15120F0C09060300, 0x00000000001E1B18}; __m128i shuff1_r = {0x0706050403020100, 0x1D1A1714110A0908}; __m128i shuff0_g = {0x1613100D0A070401, 0x00000000001F1C19}; @@ -860,12 +2003,12 @@ void BGRAToUVRow_LSX(const uint8_t* src_bgra, __m128i nex0, nex1, nex2, nex3; __m128i tmp0, tmp1, tmp2, tmp3, dst0; __m128i tmpb, tmpg, tmpr, nexb, nexg, nexr; - __m128i const_112 = __lsx_vldi(0x438); - __m128i const_74 = __lsx_vldi(0x425); - __m128i const_38 = __lsx_vldi(0x413); - __m128i const_94 = __lsx_vldi(0x42F); - __m128i const_18 = __lsx_vldi(0x409); - __m128i const_8080 = {0x8080808080808080, 0x8080808080808080}; + __m128i const_112 = __lsx_vldi(0x470); + __m128i const_74 = __lsx_vldi(0x44A); + __m128i const_38 = __lsx_vldi(0x426); + __m128i const_94 = __lsx_vldi(0x45E); + __m128i const_18 = __lsx_vldi(0x412); + __m128i const_8000 = (__m128i)v2u64{0x8000800080008000, 0x8000800080008000}; for (x = 0; x < len; x++) { DUP4_ARG2(__lsx_vld, src_bgra, 0, src_bgra, 16, src_bgra, 32, src_bgra, 48, @@ -908,12 +2051,12 @@ void ABGRToUVRow_LSX(const uint8_t* src_abgr, __m128i nex0, nex1, nex2, nex3; __m128i tmp0, tmp1, tmp2, tmp3, dst0; __m128i tmpb, tmpg, tmpr, nexb, nexg, nexr; - __m128i const_112 = __lsx_vldi(0x438); - __m128i const_74 = __lsx_vldi(0x425); - __m128i const_38 = __lsx_vldi(0x413); - __m128i const_94 = __lsx_vldi(0x42F); - __m128i const_18 = __lsx_vldi(0x409); - __m128i const_8080 = {0x8080808080808080, 0x8080808080808080}; + __m128i const_112 = __lsx_vldi(0x470); + __m128i const_74 = __lsx_vldi(0x44A); + __m128i const_38 = __lsx_vldi(0x426); + __m128i const_94 = __lsx_vldi(0x45E); + __m128i const_18 = __lsx_vldi(0x412); + __m128i const_8000 = (__m128i)v2u64{0x8000800080008000, 0x8000800080008000}; for (x = 0; x < len; x++) { DUP4_ARG2(__lsx_vld, src_abgr, 0, src_abgr, 16, src_abgr, 32, src_abgr, 48, @@ -956,12 +2099,12 @@ void RGBAToUVRow_LSX(const uint8_t* src_rgba, __m128i nex0, nex1, nex2, nex3; __m128i tmp0, tmp1, tmp2, tmp3, dst0; __m128i tmpb, tmpg, tmpr, nexb, nexg, nexr; - __m128i const_112 = __lsx_vldi(0x438); - __m128i const_74 = __lsx_vldi(0x425); - __m128i const_38 = __lsx_vldi(0x413); - __m128i const_94 = __lsx_vldi(0x42F); - __m128i const_18 = __lsx_vldi(0x409); - __m128i const_8080 = {0x8080808080808080, 0x8080808080808080}; + __m128i const_112 = __lsx_vldi(0x470); + __m128i const_74 = __lsx_vldi(0x44A); + __m128i const_38 = __lsx_vldi(0x426); + __m128i const_94 = __lsx_vldi(0x45E); + __m128i const_18 = __lsx_vldi(0x412); + __m128i const_8000 = (__m128i)v2u64{0x8000800080008000, 0x8000800080008000}; for (x = 0; x < len; x++) { DUP4_ARG2(__lsx_vld, src_rgba, 0, src_rgba, 16, src_rgba, 32, src_rgba, 48, @@ -1002,15 +2145,15 @@ void ARGBToUVJRow_LSX(const uint8_t* src_argb, int len = width / 16; __m128i src0, src1, src2, src3; __m128i nex0, nex1, nex2, nex3; - __m128i tmp0, tmp1, tmp2, tmp3; + __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; __m128i reg0, reg1, dst0; __m128i tmpb, tmpg, tmpr, nexb, nexg, nexr; - __m128i const_63 = __lsx_vldi(0x43F); - __m128i const_42 = __lsx_vldi(0x42A); + __m128i const_128 = __lsx_vldi(0x480); + __m128i const_85 = __lsx_vldi(0x455); + __m128i const_43 = __lsx_vldi(0x42B); + __m128i const_107 = __lsx_vldi(0x46B); __m128i const_21 = __lsx_vldi(0x415); - __m128i const_53 = __lsx_vldi(0x435); - __m128i const_10 = __lsx_vldi(0x40A); - __m128i const_8080 = {0x8080808080808080, 0x8080808080808080}; + __m128i const_8000 = (__m128i)v2u64{0x8000800080008000, 0x8000800080008000}; for (x = 0; x < len; x++) { DUP4_ARG2(__lsx_vld, src_argb, 0, src_argb, 16, src_argb, 32, src_argb, 48, @@ -1037,15 +2180,27 @@ void ARGBToUVJRow_LSX(const uint8_t* src_argb, tmp3 = __lsx_vaddwod_h_bu(tmpg, nexg); reg0 = __lsx_vaddwev_h_bu(tmpr, nexr); reg1 = __lsx_vaddwod_h_bu(tmpr, nexr); - tmpb = __lsx_vavgr_hu(tmp0, tmp1); - tmpg = __lsx_vavgr_hu(tmp2, tmp3); - tmpr = __lsx_vavgr_hu(reg0, reg1); - reg0 = __lsx_vmadd_h(const_8080, const_63, tmpb); - reg1 = __lsx_vmadd_h(const_8080, const_63, tmpr); - reg0 = __lsx_vmsub_h(reg0, const_42, tmpg); - reg1 = __lsx_vmsub_h(reg1, const_53, tmpg); - reg0 = __lsx_vmsub_h(reg0, const_21, tmpr); - reg1 = __lsx_vmsub_h(reg1, const_10, tmpb); + tmp4 = __lsx_vaddwev_w_hu(tmp0, tmp1); + tmp5 = __lsx_vaddwod_w_hu(tmp0, tmp1); + tmp0 = __lsx_vilvl_w(tmp5, tmp4); + tmp1 = __lsx_vilvh_w(tmp5, tmp4); + tmpb = __lsx_vssrarni_hu_w(tmp1, tmp0, 2); + tmp4 = __lsx_vaddwev_w_hu(tmp2, tmp3); + tmp5 = __lsx_vaddwod_w_hu(tmp2, tmp3); + tmp2 = __lsx_vilvl_w(tmp5, tmp4); + tmp3 = __lsx_vilvh_w(tmp5, tmp4); + tmpg = __lsx_vssrarni_hu_w(tmp3, tmp2, 2); + tmp4 = __lsx_vaddwev_w_hu(reg0, reg1); + tmp5 = __lsx_vaddwod_w_hu(reg0, reg1); + tmp0 = __lsx_vilvl_w(tmp5, tmp4); + tmp1 = __lsx_vilvh_w(tmp5, tmp4); + tmpr = __lsx_vssrarni_hu_w(tmp1, tmp0, 2); + reg0 = __lsx_vmadd_h(const_8000, const_128, tmpb); + reg1 = __lsx_vmadd_h(const_8000, const_128, tmpr); + reg0 = __lsx_vmsub_h(reg0, const_85, tmpg); + reg1 = __lsx_vmsub_h(reg1, const_107, tmpg); + reg0 = __lsx_vmsub_h(reg0, const_43, tmpr); + reg1 = __lsx_vmsub_h(reg1, const_21, tmpb); dst0 = __lsx_vpickod_b(reg1, reg0); __lsx_vstelm_d(dst0, dst_u, 0, 0); __lsx_vstelm_d(dst0, dst_v, 0, 1); @@ -1388,7 +2543,7 @@ void ARGBBlendRow_LSX(const uint8_t* src_argb, __m128i const_256 = __lsx_vldi(0x500); __m128i zero = __lsx_vldi(0); __m128i alpha = __lsx_vldi(0xFF); - __m128i control = {0xFF000000FF000000, 0xFF000000FF000000}; + __m128i control = (__m128i)v2u64{0xFF000000FF000000, 0xFF000000FF000000}; for (x = 0; x < len; x++) { DUP4_ARG2(__lsx_vld, src_argb, 0, src_argb, 16, src_argb1, 0, src_argb1, 16, @@ -1434,7 +2589,7 @@ void ARGBQuantizeRow_LSX(uint8_t* dst_argb, __m128i vec_offset = __lsx_vreplgr2vr_b(interval_offset); __m128i vec_scale = __lsx_vreplgr2vr_w(scale); __m128i zero = __lsx_vldi(0); - __m128i control = {0xFF000000FF000000, 0xFF000000FF000000}; + __m128i control = (__m128i)v2u64{0xFF000000FF000000, 0xFF000000FF000000}; for (x = 0; x < len; x++) { DUP4_ARG2(__lsx_vld, dst_argb, 0, dst_argb, 16, dst_argb, 32, dst_argb, 48, @@ -1643,11 +2798,13 @@ void HalfFloatRow_LSX(const uint16_t* src, } } +#ifndef RgbConstants struct RgbConstants { uint8_t kRGBToY[4]; uint16_t kAddY; uint16_t pad; }; +#define RgbConstants RgbConstants // RGB to JPeg coefficients // B * 0.1140 coefficient = 29 @@ -1673,6 +2830,7 @@ static const struct RgbConstants kRgb24I601Constants = {{25, 129, 66, 0}, static const struct RgbConstants kRawI601Constants = {{66, 129, 25, 0}, 0x1080, 0}; +#endif // RgbConstants // ARGB expects first 3 values to contain RGB and 4th value is ignored. static void ARGBToYMatrixRow_LSX(const uint8_t* src_argb, @@ -1853,9 +3011,21 @@ void RAWToYRow_LSX(const uint8_t* src_raw, uint8_t* dst_y, int width) { RGBToYMatrixRow_LSX(src_raw, dst_y, width, &kRawI601Constants); } +// undef for unified sources build +#undef YUVTORGB_SETUP +#undef READYUV422_D +#undef READYUV422 +#undef YUVTORGB_D +#undef YUVTORGB +#undef I444TORGB +#undef STOREARGB_D +#undef STOREARGB +#undef RGBTOUV + #ifdef __cplusplus } // extern "C" } // namespace libyuv #endif #endif // !defined(LIBYUV_DISABLE_LSX) && defined(__loongarch_sx) +