• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2022 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_rtcd.h"
12 #include "vpx_util/loongson_intrinsics.h"
13 
avg_width4_lsx(const uint8_t * src,int32_t src_stride,uint8_t * dst,int32_t dst_stride,int32_t height)14 static void avg_width4_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
15                            int32_t dst_stride, int32_t height) {
16   int32_t cnt;
17   __m128i src0, src1;
18   __m128i dst0, dst1;
19 
20   int32_t src_stride2 = src_stride << 1;
21 
22   if ((height % 2) == 0) {
23     for (cnt = (height / 2); cnt--;) {
24       src0 = __lsx_vld(src, 0);
25       src1 = __lsx_vldx(src, src_stride);
26       src += src_stride2;
27 
28       dst0 = __lsx_vld(dst, 0);
29       dst1 = __lsx_vldx(dst, dst_stride);
30       DUP2_ARG2(__lsx_vavgr_bu, src0, dst0, src1, dst1, dst0, dst1);
31 
32       __lsx_vstelm_w(dst0, dst, 0, 0);
33       dst += dst_stride;
34       __lsx_vstelm_w(dst1, dst, 0, 0);
35       dst += dst_stride;
36     }
37   }
38 }
39 
avg_width8_lsx(const uint8_t * src,int32_t src_stride,uint8_t * dst,int32_t dst_stride,int32_t height)40 static void avg_width8_lsx(const uint8_t *src, int32_t src_stride, uint8_t *dst,
41                            int32_t dst_stride, int32_t height) {
42   int32_t cnt = (height / 4);
43   __m128i src0, src1, src2, src3;
44   __m128i dst0, dst1, dst2, dst3;
45 
46   int32_t src_stride2 = src_stride << 1;
47   int32_t src_stride3 = src_stride2 + src_stride;
48   int32_t src_stride4 = src_stride2 << 1;
49 
50   int32_t dst_stride2 = dst_stride << 1;
51   int32_t dst_stride3 = dst_stride2 + dst_stride;
52 
53   for (; cnt--;) {
54     src0 = __lsx_vld(src, 0);
55     DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
56     src3 = __lsx_vldx(src, src_stride3);
57     src += src_stride4;
58 
59     dst0 = __lsx_vld(dst, 0);
60     DUP2_ARG2(__lsx_vldx, dst, dst_stride, dst, dst_stride2, dst1, dst2);
61     dst3 = __lsx_vldx(dst, dst_stride3);
62 
63     DUP4_ARG2(__lsx_vavgr_bu, src0, dst0, src1, dst1, src2, dst2, src3, dst3,
64               dst0, dst1, dst2, dst3);
65 
66     __lsx_vstelm_d(dst0, dst, 0, 0);
67     dst += dst_stride;
68     __lsx_vstelm_d(dst1, dst, 0, 0);
69     dst += dst_stride;
70     __lsx_vstelm_d(dst2, dst, 0, 0);
71     dst += dst_stride;
72     __lsx_vstelm_d(dst3, dst, 0, 0);
73     dst += dst_stride;
74   }
75 }
76 
avg_width16_lsx(const uint8_t * src,int32_t src_stride,uint8_t * dst,int32_t dst_stride,int32_t height)77 static void avg_width16_lsx(const uint8_t *src, int32_t src_stride,
78                             uint8_t *dst, int32_t dst_stride, int32_t height) {
79   int32_t cnt = (height / 8);
80   __m128i src0, src1, src2, src3, src4, src5, src6, src7;
81   __m128i dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
82 
83   int32_t src_stride2 = src_stride << 1;
84   int32_t src_stride3 = src_stride2 + src_stride;
85   int32_t src_stride4 = src_stride2 << 1;
86 
87   int32_t dst_stride2 = dst_stride << 1;
88   int32_t dst_stride3 = dst_stride2 + dst_stride;
89   int32_t dst_stride4 = dst_stride2 << 1;
90 
91   for (; cnt--;) {
92     src0 = __lsx_vld(src, 0);
93     DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
94     src3 = __lsx_vldx(src, src_stride3);
95     src += src_stride4;
96     src4 = __lsx_vld(src, 0);
97     DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src5, src6);
98     src7 = __lsx_vldx(src, src_stride3);
99     src += src_stride4;
100 
101     dst0 = __lsx_vld(dst, 0);
102     DUP2_ARG2(__lsx_vldx, dst, dst_stride, dst, dst_stride2, dst1, dst2);
103     dst3 = __lsx_vldx(dst, dst_stride3);
104     dst += dst_stride4;
105     dst4 = __lsx_vld(dst, 0);
106     DUP2_ARG2(__lsx_vldx, dst, dst_stride, dst, dst_stride2, dst5, dst6);
107     dst7 = __lsx_vldx(dst, dst_stride3);
108     dst -= dst_stride4;
109 
110     DUP4_ARG2(__lsx_vavgr_bu, src0, dst0, src1, dst1, src2, dst2, src3, dst3,
111               dst0, dst1, dst2, dst3);
112     DUP4_ARG2(__lsx_vavgr_bu, src4, dst4, src5, dst5, src6, dst6, src7, dst7,
113               dst4, dst5, dst6, dst7);
114 
115     __lsx_vst(dst0, dst, 0);
116     __lsx_vstx(dst1, dst, dst_stride);
117     __lsx_vstx(dst2, dst, dst_stride2);
118     __lsx_vstx(dst3, dst, dst_stride3);
119     dst += dst_stride4;
120     __lsx_vst(dst4, dst, 0);
121     __lsx_vstx(dst5, dst, dst_stride);
122     __lsx_vstx(dst6, dst, dst_stride2);
123     __lsx_vstx(dst7, dst, dst_stride3);
124     dst += dst_stride4;
125   }
126 }
127 
avg_width32_lsx(const uint8_t * src,int32_t src_stride,uint8_t * dst,int32_t dst_stride,int32_t height)128 static void avg_width32_lsx(const uint8_t *src, int32_t src_stride,
129                             uint8_t *dst, int32_t dst_stride, int32_t height) {
130   int32_t cnt = (height / 8);
131   __m128i src0, src1, src2, src3, src4, src5, src6, src7;
132   __m128i src8, src9, src10, src11, src12, src13, src14, src15;
133   __m128i dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
134   __m128i dst8, dst9, dst10, dst11, dst12, dst13, dst14, dst15;
135 
136   int32_t src_stride2 = src_stride << 1;
137   int32_t src_stride3 = src_stride2 + src_stride;
138   int32_t src_stride4 = src_stride2 << 1;
139 
140   int32_t dst_stride2 = dst_stride << 1;
141   int32_t dst_stride3 = dst_stride2 + dst_stride;
142   int32_t dst_stride4 = dst_stride2 << 1;
143 
144   for (; cnt--;) {
145     uint8_t *dst_tmp = dst;
146     uint8_t *dst_tmp1 = dst_tmp + 16;
147     uint8_t *src_tmp = src + 16;
148 
149     src0 = __lsx_vld(src, 0);
150     DUP2_ARG2(__lsx_vld, src, 0, src_tmp, 0, src0, src1);
151     DUP4_ARG2(__lsx_vldx, src, src_stride, src_tmp, src_stride, src,
152               src_stride2, src_tmp, src_stride2, src2, src3, src4, src5);
153     DUP2_ARG2(__lsx_vldx, src, src_stride3, src_tmp, src_stride3, src6, src7);
154     src += src_stride4;
155 
156     DUP2_ARG2(__lsx_vld, dst_tmp, 0, dst_tmp1, 0, dst0, dst1);
157     DUP4_ARG2(__lsx_vldx, dst_tmp, dst_stride, dst_tmp1, dst_stride, dst_tmp,
158               dst_stride2, dst_tmp1, dst_stride2, dst2, dst3, dst4, dst5);
159     DUP2_ARG2(__lsx_vldx, dst_tmp, dst_stride3, dst_tmp1, dst_stride3, dst6,
160               dst7);
161     dst_tmp += dst_stride4;
162     dst_tmp1 += dst_stride4;
163 
164     src_tmp = src + 16;
165     DUP2_ARG2(__lsx_vld, src, 0, src_tmp, 0, src8, src9);
166     DUP4_ARG2(__lsx_vldx, src, src_stride, src_tmp, src_stride, src,
167               src_stride2, src_tmp, src_stride2, src10, src11, src12, src13);
168     DUP2_ARG2(__lsx_vldx, src, src_stride3, src_tmp, src_stride3, src14, src15);
169     src += src_stride4;
170 
171     DUP2_ARG2(__lsx_vld, dst_tmp, 0, dst_tmp1, 0, dst8, dst9);
172     DUP4_ARG2(__lsx_vldx, dst_tmp, dst_stride, dst_tmp1, dst_stride, dst_tmp,
173               dst_stride2, dst_tmp1, dst_stride2, dst10, dst11, dst12, dst13);
174     DUP2_ARG2(__lsx_vldx, dst_tmp, dst_stride3, dst_tmp1, dst_stride3, dst14,
175               dst15);
176     DUP4_ARG2(__lsx_vavgr_bu, src0, dst0, src1, dst1, src2, dst2, src3, dst3,
177               dst0, dst1, dst2, dst3);
178     DUP4_ARG2(__lsx_vavgr_bu, src4, dst4, src5, dst5, src6, dst6, src7, dst7,
179               dst4, dst5, dst6, dst7);
180     DUP4_ARG2(__lsx_vavgr_bu, src8, dst8, src9, dst9, src10, dst10, src11,
181               dst11, dst8, dst9, dst10, dst11);
182     DUP4_ARG2(__lsx_vavgr_bu, src12, dst12, src13, dst13, src14, dst14, src15,
183               dst15, dst12, dst13, dst14, dst15);
184 
185     dst_tmp = dst + 16;
186     __lsx_vst(dst0, dst, 0);
187     __lsx_vstx(dst2, dst, dst_stride);
188     __lsx_vstx(dst4, dst, dst_stride2);
189     __lsx_vstx(dst6, dst, dst_stride3);
190     __lsx_vst(dst1, dst_tmp, 0);
191     __lsx_vstx(dst3, dst_tmp, dst_stride);
192     __lsx_vstx(dst5, dst_tmp, dst_stride2);
193     __lsx_vstx(dst7, dst_tmp, dst_stride3);
194     dst += dst_stride4;
195 
196     __lsx_vst(dst8, dst, 0);
197     __lsx_vstx(dst10, dst, dst_stride);
198     __lsx_vstx(dst12, dst, dst_stride2);
199     __lsx_vstx(dst14, dst, dst_stride3);
200     __lsx_vst(dst9, dst_tmp1, 0);
201     __lsx_vstx(dst11, dst_tmp1, dst_stride);
202     __lsx_vstx(dst13, dst_tmp1, dst_stride2);
203     __lsx_vstx(dst15, dst_tmp1, dst_stride3);
204     dst += dst_stride4;
205   }
206 }
207 
avg_width64_lsx(const uint8_t * src,int32_t src_stride,uint8_t * dst,int32_t dst_stride,int32_t height)208 static void avg_width64_lsx(const uint8_t *src, int32_t src_stride,
209                             uint8_t *dst, int32_t dst_stride, int32_t height) {
210   int32_t cnt = (height / 4);
211   uint8_t *dst_tmp = dst;
212 
213   __m128i src0, src1, src2, src3, src4, src5, src6, src7;
214   __m128i src8, src9, src10, src11, src12, src13, src14, src15;
215   __m128i dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
216   __m128i dst8, dst9, dst10, dst11, dst12, dst13, dst14, dst15;
217 
218   for (; cnt--;) {
219     DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src0, src1, src2,
220               src3);
221     src += src_stride;
222     DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src4, src5, src6,
223               src7);
224     src += src_stride;
225     DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src8, src9, src10,
226               src11);
227     src += src_stride;
228     DUP4_ARG2(__lsx_vld, src, 0, src, 16, src, 32, src, 48, src12, src13, src14,
229               src15);
230     src += src_stride;
231 
232     DUP4_ARG2(__lsx_vld, dst_tmp, 0, dst_tmp, 16, dst_tmp, 32, dst_tmp, 48,
233               dst0, dst1, dst2, dst3);
234     dst_tmp += dst_stride;
235     DUP4_ARG2(__lsx_vld, dst_tmp, 0, dst_tmp, 16, dst_tmp, 32, dst_tmp, 48,
236               dst4, dst5, dst6, dst7);
237     dst_tmp += dst_stride;
238     DUP4_ARG2(__lsx_vld, dst_tmp, 0, dst_tmp, 16, dst_tmp, 32, dst_tmp, 48,
239               dst8, dst9, dst10, dst11);
240     dst_tmp += dst_stride;
241     DUP4_ARG2(__lsx_vld, dst_tmp, 0, dst_tmp, 16, dst_tmp, 32, dst_tmp, 48,
242               dst12, dst13, dst14, dst15);
243     dst_tmp += dst_stride;
244 
245     DUP4_ARG2(__lsx_vavgr_bu, src0, dst0, src1, dst1, src2, dst2, src3, dst3,
246               dst0, dst1, dst2, dst3);
247     DUP4_ARG2(__lsx_vavgr_bu, src4, dst4, src5, dst5, src6, dst6, src7, dst7,
248               dst4, dst5, dst6, dst7);
249     DUP4_ARG2(__lsx_vavgr_bu, src8, dst8, src9, dst9, src10, dst10, src11,
250               dst11, dst8, dst9, dst10, dst11);
251     DUP4_ARG2(__lsx_vavgr_bu, src12, dst12, src13, dst13, src14, dst14, src15,
252               dst15, dst12, dst13, dst14, dst15);
253 
254     __lsx_vst(dst0, dst, 0);
255     __lsx_vst(dst1, dst, 16);
256     __lsx_vst(dst2, dst, 32);
257     __lsx_vst(dst3, dst, 48);
258     dst += dst_stride;
259     __lsx_vst(dst4, dst, 0);
260     __lsx_vst(dst5, dst, 16);
261     __lsx_vst(dst6, dst, 32);
262     __lsx_vst(dst7, dst, 48);
263     dst += dst_stride;
264     __lsx_vst(dst8, dst, 0);
265     __lsx_vst(dst9, dst, 16);
266     __lsx_vst(dst10, dst, 32);
267     __lsx_vst(dst11, dst, 48);
268     dst += dst_stride;
269     __lsx_vst(dst12, dst, 0);
270     __lsx_vst(dst13, dst, 16);
271     __lsx_vst(dst14, dst, 32);
272     __lsx_vst(dst15, dst, 48);
273     dst += dst_stride;
274   }
275 }
276 
vpx_convolve_avg_lsx(const uint8_t * src,ptrdiff_t src_stride,uint8_t * dst,ptrdiff_t dst_stride,const InterpKernel * filter,int x0_q4,int32_t x_step_q4,int y0_q4,int32_t y_step_q4,int32_t w,int32_t h)277 void vpx_convolve_avg_lsx(const uint8_t *src, ptrdiff_t src_stride,
278                           uint8_t *dst, ptrdiff_t dst_stride,
279                           const InterpKernel *filter, int x0_q4,
280                           int32_t x_step_q4, int y0_q4, int32_t y_step_q4,
281                           int32_t w, int32_t h) {
282   (void)filter;
283   (void)x0_q4;
284   (void)x_step_q4;
285   (void)y0_q4;
286   (void)y_step_q4;
287   switch (w) {
288     case 4: {
289       avg_width4_lsx(src, src_stride, dst, dst_stride, h);
290       break;
291     }
292 
293     case 8: {
294       avg_width8_lsx(src, src_stride, dst, dst_stride, h);
295       break;
296     }
297     case 16: {
298       avg_width16_lsx(src, src_stride, dst, dst_stride, h);
299       break;
300     }
301     case 32: {
302       avg_width32_lsx(src, src_stride, dst, dst_stride, h);
303       break;
304     }
305     case 64: {
306       avg_width64_lsx(src, src_stride, dst, dst_stride, h);
307       break;
308     }
309     default: {
310       int32_t lp, cnt;
311       for (cnt = h; cnt--;) {
312         for (lp = 0; lp < w; ++lp) {
313           dst[lp] = (((dst[lp] + src[lp]) + 1) >> 1);
314         }
315         src += src_stride;
316         dst += dst_stride;
317       }
318       break;
319     }
320   }
321 }
322