1 /* 2 * Copyright (c) 2015 The WebM project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "vpx_dsp/mips/macros_msa.h" 12 13 static void avg_width4_msa(const uint8_t *src, int32_t src_stride, uint8_t *dst, 14 int32_t dst_stride, int32_t height) { 15 int32_t cnt; 16 uint32_t out0, out1, out2, out3; 17 v16u8 src0, src1, src2, src3; 18 v16u8 dst0, dst1, dst2, dst3; 19 20 if (0 == (height % 4)) { 21 for (cnt = (height / 4); cnt--;) { 22 LD_UB4(src, src_stride, src0, src1, src2, src3); 23 src += (4 * src_stride); 24 25 LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); 26 27 AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1, 28 dst2, dst3); 29 30 out0 = __msa_copy_u_w((v4i32)dst0, 0); 31 out1 = __msa_copy_u_w((v4i32)dst1, 0); 32 out2 = __msa_copy_u_w((v4i32)dst2, 0); 33 out3 = __msa_copy_u_w((v4i32)dst3, 0); 34 SW4(out0, out1, out2, out3, dst, dst_stride); 35 dst += (4 * dst_stride); 36 } 37 } else if (0 == (height % 2)) { 38 for (cnt = (height / 2); cnt--;) { 39 LD_UB2(src, src_stride, src0, src1); 40 src += (2 * src_stride); 41 42 LD_UB2(dst, dst_stride, dst0, dst1); 43 44 AVER_UB2_UB(src0, dst0, src1, dst1, dst0, dst1); 45 46 out0 = __msa_copy_u_w((v4i32)dst0, 0); 47 out1 = __msa_copy_u_w((v4i32)dst1, 0); 48 SW(out0, dst); 49 dst += dst_stride; 50 SW(out1, dst); 51 dst += dst_stride; 52 } 53 } 54 } 55 56 static void avg_width8_msa(const uint8_t *src, int32_t src_stride, uint8_t *dst, 57 int32_t dst_stride, int32_t height) { 58 int32_t cnt; 59 uint64_t out0, out1, out2, out3; 60 v16u8 src0, src1, src2, src3; 61 v16u8 dst0, dst1, dst2, dst3; 62 63 for (cnt = (height / 4); cnt--;) { 64 LD_UB4(src, src_stride, src0, src1, src2, src3); 65 src += (4 * src_stride); 66 LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3); 67 68 AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1, 69 dst2, dst3); 70 71 out0 = __msa_copy_u_d((v2i64)dst0, 0); 72 out1 = __msa_copy_u_d((v2i64)dst1, 0); 73 out2 = __msa_copy_u_d((v2i64)dst2, 0); 74 out3 = __msa_copy_u_d((v2i64)dst3, 0); 75 SD4(out0, out1, out2, out3, dst, dst_stride); 76 dst += (4 * dst_stride); 77 } 78 } 79 80 static void avg_width16_msa(const uint8_t *src, int32_t src_stride, 81 uint8_t *dst, int32_t dst_stride, int32_t height) { 82 int32_t cnt; 83 v16u8 src0, src1, src2, src3, src4, src5, src6, src7; 84 v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; 85 86 for (cnt = (height / 8); cnt--;) { 87 LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7); 88 src += (8 * src_stride); 89 LD_UB8(dst, dst_stride, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7); 90 91 AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1, 92 dst2, dst3); 93 AVER_UB4_UB(src4, dst4, src5, dst5, src6, dst6, src7, dst7, dst4, dst5, 94 dst6, dst7); 95 ST_UB8(dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, dst, dst_stride); 96 dst += (8 * dst_stride); 97 } 98 } 99 100 static void avg_width32_msa(const uint8_t *src, int32_t src_stride, 101 uint8_t *dst, int32_t dst_stride, int32_t height) { 102 int32_t cnt; 103 uint8_t *dst_dup = dst; 104 v16u8 src0, src1, src2, src3, src4, src5, src6, src7; 105 v16u8 src8, src9, src10, src11, src12, src13, src14, src15; 106 v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; 107 v16u8 dst8, dst9, dst10, dst11, dst12, dst13, dst14, dst15; 108 109 for (cnt = (height / 8); cnt--;) { 110 LD_UB4(src, src_stride, src0, src2, src4, src6); 111 LD_UB4(src + 16, src_stride, src1, src3, src5, src7); 112 src += (4 * src_stride); 113 LD_UB4(dst_dup, dst_stride, dst0, dst2, dst4, dst6); 114 LD_UB4(dst_dup + 16, dst_stride, dst1, dst3, dst5, dst7); 115 dst_dup += (4 * dst_stride); 116 LD_UB4(src, src_stride, src8, src10, src12, src14); 117 LD_UB4(src + 16, src_stride, src9, src11, src13, src15); 118 src += (4 * src_stride); 119 LD_UB4(dst_dup, dst_stride, dst8, dst10, dst12, dst14); 120 LD_UB4(dst_dup + 16, dst_stride, dst9, dst11, dst13, dst15); 121 dst_dup += (4 * dst_stride); 122 123 AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1, 124 dst2, dst3); 125 AVER_UB4_UB(src4, dst4, src5, dst5, src6, dst6, src7, dst7, dst4, dst5, 126 dst6, dst7); 127 AVER_UB4_UB(src8, dst8, src9, dst9, src10, dst10, src11, dst11, dst8, dst9, 128 dst10, dst11); 129 AVER_UB4_UB(src12, dst12, src13, dst13, src14, dst14, src15, dst15, dst12, 130 dst13, dst14, dst15); 131 132 ST_UB4(dst0, dst2, dst4, dst6, dst, dst_stride); 133 ST_UB4(dst1, dst3, dst5, dst7, dst + 16, dst_stride); 134 dst += (4 * dst_stride); 135 ST_UB4(dst8, dst10, dst12, dst14, dst, dst_stride); 136 ST_UB4(dst9, dst11, dst13, dst15, dst + 16, dst_stride); 137 dst += (4 * dst_stride); 138 } 139 } 140 141 static void avg_width64_msa(const uint8_t *src, int32_t src_stride, 142 uint8_t *dst, int32_t dst_stride, int32_t height) { 143 int32_t cnt; 144 uint8_t *dst_dup = dst; 145 v16u8 src0, src1, src2, src3, src4, src5, src6, src7; 146 v16u8 src8, src9, src10, src11, src12, src13, src14, src15; 147 v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7; 148 v16u8 dst8, dst9, dst10, dst11, dst12, dst13, dst14, dst15; 149 150 for (cnt = (height / 4); cnt--;) { 151 LD_UB4(src, 16, src0, src1, src2, src3); 152 src += src_stride; 153 LD_UB4(src, 16, src4, src5, src6, src7); 154 src += src_stride; 155 LD_UB4(src, 16, src8, src9, src10, src11); 156 src += src_stride; 157 LD_UB4(src, 16, src12, src13, src14, src15); 158 src += src_stride; 159 160 LD_UB4(dst_dup, 16, dst0, dst1, dst2, dst3); 161 dst_dup += dst_stride; 162 LD_UB4(dst_dup, 16, dst4, dst5, dst6, dst7); 163 dst_dup += dst_stride; 164 LD_UB4(dst_dup, 16, dst8, dst9, dst10, dst11); 165 dst_dup += dst_stride; 166 LD_UB4(dst_dup, 16, dst12, dst13, dst14, dst15); 167 dst_dup += dst_stride; 168 169 AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1, 170 dst2, dst3); 171 AVER_UB4_UB(src4, dst4, src5, dst5, src6, dst6, src7, dst7, dst4, dst5, 172 dst6, dst7); 173 AVER_UB4_UB(src8, dst8, src9, dst9, src10, dst10, src11, dst11, dst8, dst9, 174 dst10, dst11); 175 AVER_UB4_UB(src12, dst12, src13, dst13, src14, dst14, src15, dst15, dst12, 176 dst13, dst14, dst15); 177 178 ST_UB4(dst0, dst1, dst2, dst3, dst, 16); 179 dst += dst_stride; 180 ST_UB4(dst4, dst5, dst6, dst7, dst, 16); 181 dst += dst_stride; 182 ST_UB4(dst8, dst9, dst10, dst11, dst, 16); 183 dst += dst_stride; 184 ST_UB4(dst12, dst13, dst14, dst15, dst, 16); 185 dst += dst_stride; 186 } 187 } 188 189 void vpx_convolve_avg_msa(const uint8_t *src, ptrdiff_t src_stride, 190 uint8_t *dst, ptrdiff_t dst_stride, 191 const int16_t *filter_x, int32_t filter_x_stride, 192 const int16_t *filter_y, int32_t filter_y_stride, 193 int32_t w, int32_t h) { 194 (void)filter_x; 195 (void)filter_y; 196 (void)filter_x_stride; 197 (void)filter_y_stride; 198 199 switch (w) { 200 case 4: { 201 avg_width4_msa(src, src_stride, dst, dst_stride, h); 202 break; 203 } 204 case 8: { 205 avg_width8_msa(src, src_stride, dst, dst_stride, h); 206 break; 207 } 208 case 16: { 209 avg_width16_msa(src, src_stride, dst, dst_stride, h); 210 break; 211 } 212 case 32: { 213 avg_width32_msa(src, src_stride, dst, dst_stride, h); 214 break; 215 } 216 case 64: { 217 avg_width64_msa(src, src_stride, dst, dst_stride, h); 218 break; 219 } 220 default: { 221 int32_t lp, cnt; 222 for (cnt = h; cnt--;) { 223 for (lp = 0; lp < w; ++lp) { 224 dst[lp] = (((dst[lp] + src[lp]) + 1) >> 1); 225 } 226 src += src_stride; 227 dst += dst_stride; 228 } 229 break; 230 } 231 } 232 } 233