Coverage Report

Created: 2026-07-14 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/aom/av1/common/x86/convolve_avx2.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2017, Alliance for Open Media. All rights reserved.
3
 *
4
 * This source code is subject to the terms of the BSD 2 Clause License and
5
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6
 * was not distributed with this source code in the LICENSE file, you can
7
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8
 * Media Patent License 1.0 was not distributed with this source code in the
9
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10
 */
11
12
#include <immintrin.h>
13
14
#include "config/av1_rtcd.h"
15
16
#include "aom_dsp/aom_dsp_common.h"
17
#include "aom_dsp/x86/convolve_avx2.h"
18
#include "aom_dsp/x86/convolve_common_intrin.h"
19
#include "aom_dsp/x86/synonyms.h"
20
21
void av1_convolve_y_sr_avx2(const uint8_t *src, int32_t src_stride,
22
                            uint8_t *dst, int32_t dst_stride, int32_t w,
23
                            int32_t h,
24
                            const InterpFilterParams *filter_params_y,
25
554k
                            const int32_t subpel_y_qn) {
26
554k
  __m128i coeffs_128[4];
27
554k
  __m256i coeffs[6];
28
554k
  int x = 0, y = h;
29
30
554k
  int i, vert_tap = get_filter_tap(filter_params_y, subpel_y_qn);
31
554k
  assert(vert_tap == 2 || vert_tap == 4 || vert_tap == 6 || vert_tap == 8 ||
32
554k
         vert_tap == 12);
33
554k
  assert(!(w % 2));
34
554k
  assert(!(h % 2));
35
36
554k
  const int fo_vert = vert_tap / 2 - 1;
37
554k
  const uint8_t *const src_ptr = src - fo_vert * src_stride;
38
554k
  const uint8_t *data = src_ptr;
39
554k
  uint8_t *dst_ptr = dst;
40
41
554k
  if (vert_tap == 2) {
42
29.0k
    if (subpel_y_qn != 8) {
43
13.9k
      if (w <= 4) {
44
6.76k
        prepare_coeffs_2t_ssse3(filter_params_y, subpel_y_qn, coeffs_128);
45
6.76k
        __m128i d[2], res;
46
6.76k
        if (w == 2) {
47
1.72k
          d[0] = _mm_cvtsi32_si128(loadu_int16(data));
48
49
3.55k
          do {
50
3.55k
            convolve_y_2tap_2x2_ssse3(data, src_stride, coeffs_128, d, &res);
51
3.55k
            res = round_sr_y_ssse3(res);
52
3.55k
            pack_store_u8_2x2_sse2(res, dst_ptr, dst_stride);
53
54
3.55k
            dst_ptr += 2 * dst_stride;
55
3.55k
            data += 2 * src_stride;
56
3.55k
            y -= 2;
57
3.55k
          } while (y > 0);
58
5.04k
        } else {
59
5.04k
          assert(w == 4);
60
5.04k
          d[0] = _mm_cvtsi32_si128(loadu_int32(data));
61
62
14.8k
          do {
63
14.8k
            convolve_y_2tap_4x2_ssse3(data, src_stride, coeffs_128, d, &res);
64
14.8k
            res = round_sr_y_ssse3(res);
65
14.8k
            pack_store_u8_4x2_sse2(res, dst_ptr, dst_stride);
66
67
14.8k
            dst_ptr += 2 * dst_stride;
68
14.8k
            data += 2 * src_stride;
69
14.8k
            y -= 2;
70
14.8k
          } while (y > 0);
71
5.04k
        }
72
7.19k
      } else {
73
7.19k
        prepare_coeffs_2t_lowbd(filter_params_y, subpel_y_qn, coeffs);
74
75
7.19k
        if (w == 8) {
76
4.04k
          __m128i d[2];
77
4.04k
          d[0] = _mm_loadl_epi64((__m128i *)data);
78
79
13.1k
          do {
80
13.1k
            __m256i res;
81
13.1k
            convolve_y_2tap_8x2_avx2(data, src_stride, coeffs, d, &res);
82
13.1k
            round_pack_store_y_8x2_avx2(res, dst_ptr, dst_stride);
83
84
13.1k
            dst_ptr += 2 * dst_stride;
85
13.1k
            data += 2 * src_stride;
86
13.1k
            y -= 2;
87
88
13.1k
          } while (y > 0);
89
90
4.04k
        } else if (w == 16) {
91
1.95k
          __m128i d[2];
92
1.95k
          d[0] = _mm_loadu_si128((__m128i *)data);
93
94
13.0k
          do {
95
13.0k
            __m256i res[2];
96
13.0k
            convolve_y_2tap_16x2_avx2(data, src_stride, coeffs, d, res);
97
13.0k
            round_pack_store_y_16x2_avx2(res, dst_ptr, dst_stride);
98
99
13.0k
            dst_ptr += 2 * dst_stride;
100
13.0k
            data += 2 * src_stride;
101
13.0k
            y -= 2;
102
13.0k
          } while (y > 0);
103
104
1.95k
        } else {
105
1.20k
          assert(!(w % 32));
106
107
1.20k
          __m256i d[2];
108
1.74k
          do {
109
1.74k
            data = src_ptr + x;
110
1.74k
            dst_ptr = dst + x;
111
1.74k
            y = h;
112
113
1.74k
            d[0] = _mm256_loadu_si256((__m256i *)data);
114
115
39.6k
            do {
116
39.6k
              __m256i res[4];
117
39.6k
              convolve_y_2tap_32x2_avx2(data, src_stride, coeffs, d, res);
118
39.6k
              round_pack_store_y_32x2_avx2(res, dst_ptr, dst_stride);
119
120
39.6k
              dst_ptr += 2 * dst_stride;
121
39.6k
              data += 2 * src_stride;
122
39.6k
              y -= 2;
123
39.6k
            } while (y > 0);
124
125
1.74k
            x += 32;
126
1.74k
          } while (x < w);
127
1.20k
        }
128
7.19k
      }
129
15.0k
    } else {
130
15.0k
      if (w <= 16) {
131
14.2k
        __m128i s[2], res;
132
133
14.2k
        if (w == 2) {
134
3.42k
          s[0] = _mm_cvtsi32_si128(loadu_int16(data));
135
136
6.45k
          do {
137
6.45k
            s[1] = _mm_cvtsi32_si128(loadu_int16(data + src_stride));
138
6.45k
            res = _mm_avg_epu8(s[0], s[1]);
139
6.45k
            xx_storel_16(dst_ptr, res);
140
6.45k
            s[0] = _mm_cvtsi32_si128(loadu_int16(data + 2 * src_stride));
141
6.45k
            res = _mm_avg_epu8(s[1], s[0]);
142
6.45k
            xx_storel_16(dst_ptr + dst_stride, res);
143
144
6.45k
            data += 2 * src_stride;
145
6.45k
            dst_ptr += 2 * dst_stride;
146
6.45k
            y -= 2;
147
6.45k
          } while (y > 0);
148
10.7k
        } else if (w == 4) {
149
5.65k
          s[0] = _mm_cvtsi32_si128(loadu_int32(data));
150
151
15.4k
          do {
152
15.4k
            s[1] = _mm_cvtsi32_si128(loadu_int32(data + src_stride));
153
15.4k
            res = _mm_avg_epu8(s[0], s[1]);
154
15.4k
            xx_storel_32(dst_ptr, res);
155
15.4k
            s[0] = _mm_cvtsi32_si128(loadu_int32(data + 2 * src_stride));
156
15.4k
            res = _mm_avg_epu8(s[1], s[0]);
157
15.4k
            xx_storel_32(dst_ptr + dst_stride, res);
158
159
15.4k
            data += 2 * src_stride;
160
15.4k
            dst_ptr += 2 * dst_stride;
161
15.4k
            y -= 2;
162
15.4k
          } while (y > 0);
163
5.65k
        } else if (w == 8) {
164
3.77k
          s[0] = _mm_loadl_epi64((__m128i *)data);
165
166
12.1k
          do {
167
12.1k
            s[1] = _mm_loadl_epi64((__m128i *)(data + src_stride));
168
12.1k
            res = _mm_avg_epu8(s[0], s[1]);
169
12.1k
            _mm_storel_epi64((__m128i *)dst_ptr, res);
170
12.1k
            s[0] = _mm_loadl_epi64((__m128i *)(data + 2 * src_stride));
171
12.1k
            res = _mm_avg_epu8(s[1], s[0]);
172
12.1k
            _mm_storel_epi64((__m128i *)(dst_ptr + dst_stride), res);
173
174
12.1k
            data += 2 * src_stride;
175
12.1k
            dst_ptr += 2 * dst_stride;
176
12.1k
            y -= 2;
177
12.1k
          } while (y > 0);
178
3.77k
        } else {
179
1.35k
          assert(w == 16);
180
181
1.35k
          s[0] = _mm_loadu_si128((__m128i *)data);
182
183
7.63k
          do {
184
7.63k
            s[1] = _mm_loadu_si128((__m128i *)(data + src_stride));
185
7.63k
            res = _mm_avg_epu8(s[0], s[1]);
186
7.63k
            _mm_storeu_si128((__m128i *)dst_ptr, res);
187
7.63k
            s[0] = _mm_loadu_si128((__m128i *)(data + 2 * src_stride));
188
7.63k
            res = _mm_avg_epu8(s[1], s[0]);
189
7.63k
            _mm_storeu_si128((__m128i *)(dst_ptr + dst_stride), res);
190
191
7.63k
            data += 2 * src_stride;
192
7.63k
            dst_ptr += 2 * dst_stride;
193
7.63k
            y -= 2;
194
7.63k
          } while (y > 0);
195
1.35k
        }
196
14.2k
      } else {
197
855
        assert(!(w % 32));
198
199
855
        __m256i s[2], res;
200
1.28k
        do {
201
1.28k
          data = src_ptr + x;
202
1.28k
          dst_ptr = dst + x;
203
1.28k
          y = h;
204
205
1.28k
          s[0] = _mm256_loadu_si256((__m256i *)data);
206
207
33.9k
          do {
208
33.9k
            s[1] = _mm256_loadu_si256((__m256i *)(data + src_stride));
209
33.9k
            res = _mm256_avg_epu8(s[0], s[1]);
210
33.9k
            _mm256_storeu_si256((__m256i *)dst_ptr, res);
211
33.9k
            s[0] = _mm256_loadu_si256((__m256i *)(data + 2 * src_stride));
212
33.9k
            res = _mm256_avg_epu8(s[1], s[0]);
213
33.9k
            _mm256_storeu_si256((__m256i *)(dst_ptr + dst_stride), res);
214
215
33.9k
            data += 2 * src_stride;
216
33.9k
            dst_ptr += 2 * dst_stride;
217
33.9k
            y -= 2;
218
33.9k
          } while (y > 0);
219
220
1.28k
          x += 32;
221
1.28k
        } while (x < w);
222
855
      }
223
15.0k
    }
224
525k
  } else if (vert_tap == 4) {
225
277k
    if (w <= 4) {
226
128k
      prepare_coeffs_4t_ssse3(filter_params_y, subpel_y_qn, coeffs_128);
227
128k
      __m128i d[4], s[2];
228
229
128k
      if (w == 2) {
230
23.4k
        d[0] = _mm_cvtsi32_si128(loadu_int16(data + 0 * src_stride));
231
23.4k
        d[1] = _mm_cvtsi32_si128(loadu_int16(data + 1 * src_stride));
232
23.4k
        d[2] = _mm_cvtsi32_si128(loadu_int16(data + 2 * src_stride));
233
234
23.4k
        const __m128i src_01a = _mm_unpacklo_epi16(d[0], d[1]);
235
23.4k
        const __m128i src_12a = _mm_unpacklo_epi16(d[1], d[2]);
236
237
23.4k
        s[0] = _mm_unpacklo_epi8(src_01a, src_12a);
238
40.3k
        do {
239
40.3k
          __m128i res;
240
40.3k
          convolve_y_4tap_2x2_ssse3(data, src_stride, coeffs_128, d, s, &res);
241
40.3k
          res = round_sr_y_ssse3(res);
242
40.3k
          pack_store_u8_2x2_sse2(res, dst_ptr, dst_stride);
243
244
40.3k
          dst_ptr += 2 * dst_stride;
245
40.3k
          data += 2 * src_stride;
246
40.3k
          y -= 2;
247
248
40.3k
          s[0] = s[1];
249
40.3k
        } while (y > 0);
250
251
105k
      } else {
252
105k
        assert(w == 4);
253
254
105k
        d[0] = _mm_cvtsi32_si128(loadu_int32(data + 0 * src_stride));
255
105k
        d[1] = _mm_cvtsi32_si128(loadu_int32(data + 1 * src_stride));
256
105k
        d[2] = _mm_cvtsi32_si128(loadu_int32(data + 2 * src_stride));
257
258
105k
        const __m128i src_01a = _mm_unpacklo_epi32(d[0], d[1]);
259
105k
        const __m128i src_12a = _mm_unpacklo_epi32(d[1], d[2]);
260
261
105k
        s[0] = _mm_unpacklo_epi8(src_01a, src_12a);
262
207k
        do {
263
207k
          __m128i res;
264
207k
          convolve_y_4tap_4x2_ssse3(data, src_stride, coeffs_128, d, s, &res);
265
207k
          res = round_sr_y_ssse3(res);
266
207k
          pack_store_u8_4x2_sse2(res, dst_ptr, dst_stride);
267
268
207k
          dst_ptr += 2 * dst_stride;
269
207k
          data += 2 * src_stride;
270
207k
          y -= 2;
271
272
207k
          s[0] = s[1];
273
207k
        } while (y > 0);
274
105k
      }
275
148k
    } else {
276
148k
      prepare_coeffs_4t_lowbd(filter_params_y, subpel_y_qn, coeffs);
277
278
148k
      if (w == 8) {
279
96.8k
        __m128i d[4];
280
96.8k
        __m256i s[2];
281
282
96.8k
        d[0] = _mm_loadl_epi64((__m128i *)(data + 0 * src_stride));
283
96.8k
        d[1] = _mm_loadl_epi64((__m128i *)(data + 1 * src_stride));
284
96.8k
        d[2] = _mm_loadl_epi64((__m128i *)(data + 2 * src_stride));
285
286
96.8k
        const __m256i src_01a = _mm256_setr_m128i(d[0], d[1]);
287
96.8k
        const __m256i src_12a = _mm256_setr_m128i(d[1], d[2]);
288
289
96.8k
        s[0] = _mm256_unpacklo_epi8(src_01a, src_12a);
290
181k
        do {
291
181k
          __m256i res;
292
181k
          convolve_y_4tap_8x2_avx2(data, src_stride, coeffs, d, s, &res);
293
181k
          round_pack_store_y_8x2_avx2(res, dst_ptr, dst_stride);
294
295
181k
          dst_ptr += 2 * dst_stride;
296
181k
          data += 2 * src_stride;
297
181k
          y -= 2;
298
299
181k
          s[0] = s[1];
300
181k
        } while (y > 0);
301
96.8k
      } else if (w == 16) {
302
48.1k
        __m128i d[4];
303
48.1k
        __m256i s[4];
304
305
48.1k
        d[0] = _mm_loadu_si128((__m128i *)(data + 0 * src_stride));
306
48.1k
        d[1] = _mm_loadu_si128((__m128i *)(data + 1 * src_stride));
307
48.1k
        d[2] = _mm_loadu_si128((__m128i *)(data + 2 * src_stride));
308
309
48.1k
        const __m256i src_01a = _mm256_setr_m128i(d[0], d[1]);
310
48.1k
        const __m256i src_12a = _mm256_setr_m128i(d[1], d[2]);
311
312
48.1k
        s[0] = _mm256_unpacklo_epi8(src_01a, src_12a);
313
48.1k
        s[2] = _mm256_unpackhi_epi8(src_01a, src_12a);
314
315
112k
        do {
316
112k
          __m256i res[2];
317
112k
          convolve_y_4tap_16x2_avx2(data, src_stride, coeffs, d, s, res);
318
112k
          round_pack_store_y_16x2_avx2(res, dst_ptr, dst_stride);
319
320
112k
          dst_ptr += 2 * dst_stride;
321
112k
          data += 2 * src_stride;
322
112k
          y -= 2;
323
324
112k
          s[0] = s[1];
325
112k
          s[2] = s[3];
326
112k
        } while (y > 0);
327
48.1k
      } else {
328
3.76k
        assert(!(w % 32));
329
330
3.76k
        __m256i d[4], s1[4], s2[4];
331
5.42k
        do {
332
5.42k
          data = src_ptr + x;
333
5.42k
          dst_ptr = dst + x;
334
5.42k
          y = h;
335
336
5.42k
          d[0] = _mm256_loadu_si256((__m256i *)(data + 0 * src_stride));
337
5.42k
          d[1] = _mm256_loadu_si256((__m256i *)(data + 1 * src_stride));
338
5.42k
          d[2] = _mm256_loadu_si256((__m256i *)(data + 2 * src_stride));
339
340
5.42k
          s1[0] = _mm256_unpacklo_epi8(d[0], d[1]);
341
5.42k
          s1[2] = _mm256_unpackhi_epi8(d[0], d[1]);
342
343
5.42k
          s2[0] = _mm256_unpacklo_epi8(d[1], d[2]);
344
5.42k
          s2[2] = _mm256_unpackhi_epi8(d[1], d[2]);
345
346
141k
          do {
347
141k
            __m256i res[4];
348
141k
            convolve_y_4tap_32x2_avx2(data, src_stride, coeffs, d, s1, s2, res);
349
141k
            round_pack_store_y_32x2_avx2(res, dst_ptr, dst_stride);
350
351
141k
            dst_ptr += 2 * dst_stride;
352
141k
            data += 2 * src_stride;
353
141k
            y -= 2;
354
355
141k
            s1[0] = s1[1];
356
141k
            s1[2] = s1[3];
357
358
141k
            s2[0] = s2[1];
359
141k
            s2[2] = s2[3];
360
141k
          } while (y > 0);
361
362
5.42k
          x += 32;
363
5.42k
        } while (x < w);
364
3.76k
      }
365
148k
    }
366
277k
  } else if (vert_tap == 6) {
367
233k
    if (w <= 4) {
368
72.9k
      prepare_coeffs_6t_ssse3(filter_params_y, subpel_y_qn, coeffs_128);
369
370
72.9k
      __m128i d[6], s[3];
371
72.9k
      if (w == 2) {
372
13.5k
        d[0] = _mm_cvtsi32_si128(loadu_int16(data + 0 * src_stride));
373
13.5k
        d[1] = _mm_cvtsi32_si128(loadu_int16(data + 1 * src_stride));
374
13.5k
        d[2] = _mm_cvtsi32_si128(loadu_int16(data + 2 * src_stride));
375
13.5k
        d[3] = _mm_cvtsi32_si128(loadu_int16(data + 3 * src_stride));
376
13.5k
        d[4] = _mm_cvtsi32_si128(loadu_int16(data + 4 * src_stride));
377
378
13.5k
        const __m128i src_01a = _mm_unpacklo_epi16(d[0], d[1]);
379
13.5k
        const __m128i src_12a = _mm_unpacklo_epi16(d[1], d[2]);
380
13.5k
        const __m128i src_23a = _mm_unpacklo_epi16(d[2], d[3]);
381
13.5k
        const __m128i src_34a = _mm_unpacklo_epi16(d[3], d[4]);
382
383
13.5k
        s[0] = _mm_unpacklo_epi8(src_01a, src_12a);
384
13.5k
        s[1] = _mm_unpacklo_epi8(src_23a, src_34a);
385
386
54.0k
        do {
387
54.0k
          __m128i res;
388
54.0k
          convolve_y_6tap_2x2_ssse3(data, src_stride, coeffs_128, d, s, &res);
389
54.0k
          res = round_sr_y_ssse3(res);
390
54.0k
          pack_store_u8_2x2_sse2(res, dst_ptr, dst_stride);
391
392
54.0k
          dst_ptr += 2 * dst_stride;
393
54.0k
          data += 2 * src_stride;
394
54.0k
          y -= 2;
395
396
54.0k
          s[0] = s[1];
397
54.0k
          s[1] = s[2];
398
54.0k
        } while (y > 0);
399
400
59.4k
      } else {
401
59.4k
        assert(w == 4);
402
59.4k
        d[0] = _mm_cvtsi32_si128(loadu_int32(data + 0 * src_stride));
403
59.4k
        d[1] = _mm_cvtsi32_si128(loadu_int32(data + 1 * src_stride));
404
59.4k
        d[2] = _mm_cvtsi32_si128(loadu_int32(data + 2 * src_stride));
405
59.4k
        d[3] = _mm_cvtsi32_si128(loadu_int32(data + 3 * src_stride));
406
59.4k
        d[4] = _mm_cvtsi32_si128(loadu_int32(data + 4 * src_stride));
407
408
59.4k
        const __m128i src_01a = _mm_unpacklo_epi32(d[0], d[1]);
409
59.4k
        const __m128i src_12a = _mm_unpacklo_epi32(d[1], d[2]);
410
59.4k
        const __m128i src_23a = _mm_unpacklo_epi32(d[2], d[3]);
411
59.4k
        const __m128i src_34a = _mm_unpacklo_epi32(d[3], d[4]);
412
413
59.4k
        s[0] = _mm_unpacklo_epi8(src_01a, src_12a);
414
59.4k
        s[1] = _mm_unpacklo_epi8(src_23a, src_34a);
415
416
321k
        do {
417
321k
          __m128i res;
418
321k
          convolve_y_6tap_4x2_ssse3(data, src_stride, coeffs_128, d, s, &res);
419
321k
          res = round_sr_y_ssse3(res);
420
321k
          pack_store_u8_4x2_sse2(res, dst_ptr, dst_stride);
421
422
321k
          dst_ptr += 2 * dst_stride;
423
321k
          data += 2 * src_stride;
424
321k
          y -= 2;
425
426
321k
          s[0] = s[1];
427
321k
          s[1] = s[2];
428
321k
        } while (y > 0);
429
59.4k
      }
430
160k
    } else {
431
160k
      prepare_coeffs_6t_lowbd(filter_params_y, subpel_y_qn, coeffs);
432
433
160k
      if (w == 8) {
434
74.6k
        __m128i d[6];
435
74.6k
        __m256i s[3];
436
437
74.6k
        d[0] = _mm_loadl_epi64((__m128i *)(data + 0 * src_stride));
438
74.6k
        d[1] = _mm_loadl_epi64((__m128i *)(data + 1 * src_stride));
439
74.6k
        d[2] = _mm_loadl_epi64((__m128i *)(data + 2 * src_stride));
440
74.6k
        d[3] = _mm_loadl_epi64((__m128i *)(data + 3 * src_stride));
441
74.6k
        d[4] = _mm_loadl_epi64((__m128i *)(data + 4 * src_stride));
442
443
74.6k
        const __m256i src_01a = _mm256_setr_m128i(d[0], d[1]);
444
74.6k
        const __m256i src_12a = _mm256_setr_m128i(d[1], d[2]);
445
74.6k
        const __m256i src_23a = _mm256_setr_m128i(d[2], d[3]);
446
74.6k
        const __m256i src_34a = _mm256_setr_m128i(d[3], d[4]);
447
448
74.6k
        s[0] = _mm256_unpacklo_epi8(src_01a, src_12a);
449
74.6k
        s[1] = _mm256_unpacklo_epi8(src_23a, src_34a);
450
451
419k
        do {
452
419k
          __m256i res;
453
419k
          convolve_y_6tap_8x2_avx2(data, src_stride, coeffs, d, s, &res);
454
419k
          round_pack_store_y_8x2_avx2(res, dst_ptr, dst_stride);
455
456
419k
          dst_ptr += 2 * dst_stride;
457
419k
          data += 2 * src_stride;
458
419k
          y -= 2;
459
460
419k
          s[0] = s[1];
461
419k
          s[1] = s[2];
462
419k
        } while (y > 0);
463
464
86.1k
      } else {
465
86.1k
        assert(!(w % 16));
466
467
86.1k
        __m128i d[6];
468
86.1k
        __m256i s[6];
469
126k
        do {
470
126k
          data = src_ptr + x;
471
126k
          dst_ptr = dst + x;
472
126k
          y = h;
473
474
126k
          d[0] = _mm_loadu_si128((__m128i *)(data + 0 * src_stride));
475
126k
          d[1] = _mm_loadu_si128((__m128i *)(data + 1 * src_stride));
476
126k
          d[2] = _mm_loadu_si128((__m128i *)(data + 2 * src_stride));
477
126k
          d[3] = _mm_loadu_si128((__m128i *)(data + 3 * src_stride));
478
126k
          d[4] = _mm_loadu_si128((__m128i *)(data + 4 * src_stride));
479
480
126k
          const __m256i src_01a = _mm256_setr_m128i(d[0], d[1]);
481
126k
          const __m256i src_12a = _mm256_setr_m128i(d[1], d[2]);
482
126k
          const __m256i src_23a = _mm256_setr_m128i(d[2], d[3]);
483
126k
          const __m256i src_34a = _mm256_setr_m128i(d[3], d[4]);
484
485
126k
          s[0] = _mm256_unpacklo_epi8(src_01a, src_12a);
486
126k
          s[1] = _mm256_unpacklo_epi8(src_23a, src_34a);
487
488
126k
          s[3] = _mm256_unpackhi_epi8(src_01a, src_12a);
489
126k
          s[4] = _mm256_unpackhi_epi8(src_23a, src_34a);
490
491
1.63M
          do {
492
1.63M
            __m256i res[2];
493
1.63M
            convolve_y_6tap_16x2_avx2(data, src_stride, coeffs, d, s, res);
494
1.63M
            round_pack_store_y_16x2_avx2(res, dst_ptr, dst_stride);
495
496
1.63M
            dst_ptr += 2 * dst_stride;
497
1.63M
            data += 2 * src_stride;
498
1.63M
            y -= 2;
499
500
1.63M
            s[0] = s[1];
501
1.63M
            s[1] = s[2];
502
503
1.63M
            s[3] = s[4];
504
1.63M
            s[4] = s[5];
505
1.63M
          } while (y > 0);
506
507
126k
          x += 16;
508
126k
        } while (x < w);
509
86.1k
      }
510
160k
    }
511
233k
  } else if (vert_tap == 12) {  // vert_tap == 12
512
0
    __m128i d[12];
513
0
    __m256i s[12];
514
0
    prepare_coeffs_12taps(filter_params_y, subpel_y_qn, coeffs);
515
0
    const __m256i v_zero = _mm256_setzero_si256();
516
0
    __m128i right_shift = _mm_cvtsi32_si128(FILTER_BITS);
517
0
    __m256i right_shift_const = _mm256_set1_epi32((1 << FILTER_BITS) >> 1);
518
519
0
    for (int j = 0; j < w; j += 8) {
520
0
      data = &src_ptr[j];
521
0
      __m256i src10;
522
523
0
      d[0] = _mm_loadl_epi64((__m128i *)(data + 0 * src_stride));
524
0
      d[1] = _mm_loadl_epi64((__m128i *)(data + 1 * src_stride));
525
0
      d[2] = _mm_loadl_epi64((__m128i *)(data + 2 * src_stride));
526
0
      d[3] = _mm_loadl_epi64((__m128i *)(data + 3 * src_stride));
527
0
      d[4] = _mm_loadl_epi64((__m128i *)(data + 4 * src_stride));
528
0
      d[5] = _mm_loadl_epi64((__m128i *)(data + 5 * src_stride));
529
0
      d[6] = _mm_loadl_epi64((__m128i *)(data + 6 * src_stride));
530
0
      d[7] = _mm_loadl_epi64((__m128i *)(data + 7 * src_stride));
531
0
      d[8] = _mm_loadl_epi64((__m128i *)(data + 8 * src_stride));
532
0
      d[9] = _mm_loadl_epi64((__m128i *)(data + 9 * src_stride));
533
      // Load lines a and b. Line a to lower 128, line b to upper 128
534
0
      const __m256i src_01a = _mm256_permute2x128_si256(
535
0
          _mm256_castsi128_si256(d[0]), _mm256_castsi128_si256(d[1]), 0x20);
536
537
0
      const __m256i src_12a = _mm256_permute2x128_si256(
538
0
          _mm256_castsi128_si256(d[1]), _mm256_castsi128_si256(d[2]), 0x20);
539
540
0
      const __m256i src_23a = _mm256_permute2x128_si256(
541
0
          _mm256_castsi128_si256(d[2]), _mm256_castsi128_si256(d[3]), 0x20);
542
543
0
      const __m256i src_34a = _mm256_permute2x128_si256(
544
0
          _mm256_castsi128_si256(d[3]), _mm256_castsi128_si256(d[4]), 0x20);
545
546
0
      const __m256i src_45a = _mm256_permute2x128_si256(
547
0
          _mm256_castsi128_si256(d[4]), _mm256_castsi128_si256(d[5]), 0x20);
548
549
0
      const __m256i src_56a = _mm256_permute2x128_si256(
550
0
          _mm256_castsi128_si256(d[5]), _mm256_castsi128_si256(d[6]), 0x20);
551
552
0
      const __m256i src_67a = _mm256_permute2x128_si256(
553
0
          _mm256_castsi128_si256(d[6]), _mm256_castsi128_si256(d[7]), 0x20);
554
555
0
      const __m256i src_78a = _mm256_permute2x128_si256(
556
0
          _mm256_castsi128_si256(d[7]), _mm256_castsi128_si256(d[8]), 0x20);
557
558
0
      const __m256i src_89a = _mm256_permute2x128_si256(
559
0
          _mm256_castsi128_si256(d[8]), _mm256_castsi128_si256(d[9]), 0x20);
560
561
0
      src10 = _mm256_castsi128_si256(
562
0
          _mm_loadl_epi64((__m128i *)(data + 10 * src_stride)));
563
0
      const __m256i src_910a =
564
0
          _mm256_permute2x128_si256(_mm256_castsi128_si256(d[9]), src10, 0x20);
565
566
0
      const __m256i src_01 = _mm256_unpacklo_epi8(src_01a, v_zero);
567
0
      const __m256i src_12 = _mm256_unpacklo_epi8(src_12a, v_zero);
568
0
      const __m256i src_23 = _mm256_unpacklo_epi8(src_23a, v_zero);
569
0
      const __m256i src_34 = _mm256_unpacklo_epi8(src_34a, v_zero);
570
0
      const __m256i src_45 = _mm256_unpacklo_epi8(src_45a, v_zero);
571
0
      const __m256i src_56 = _mm256_unpacklo_epi8(src_56a, v_zero);
572
0
      const __m256i src_67 = _mm256_unpacklo_epi8(src_67a, v_zero);
573
0
      const __m256i src_78 = _mm256_unpacklo_epi8(src_78a, v_zero);
574
0
      const __m256i src_89 = _mm256_unpacklo_epi8(src_89a, v_zero);
575
0
      const __m256i src_910 = _mm256_unpacklo_epi8(src_910a, v_zero);
576
577
0
      s[0] = _mm256_unpacklo_epi16(src_01, src_12);
578
0
      s[1] = _mm256_unpacklo_epi16(src_23, src_34);
579
0
      s[2] = _mm256_unpacklo_epi16(src_45, src_56);
580
0
      s[3] = _mm256_unpacklo_epi16(src_67, src_78);
581
0
      s[4] = _mm256_unpacklo_epi16(src_89, src_910);
582
583
0
      s[6] = _mm256_unpackhi_epi16(src_01, src_12);
584
0
      s[7] = _mm256_unpackhi_epi16(src_23, src_34);
585
0
      s[8] = _mm256_unpackhi_epi16(src_45, src_56);
586
0
      s[9] = _mm256_unpackhi_epi16(src_67, src_78);
587
0
      s[10] = _mm256_unpackhi_epi16(src_89, src_910);
588
589
0
      for (i = 0; i < h; i += 2) {
590
0
        data = &src_ptr[i * src_stride + j];
591
0
        const __m256i src_1011a = _mm256_permute2x128_si256(
592
0
            src10,
593
0
            _mm256_castsi128_si256(
594
0
                _mm_loadl_epi64((__m128i *)(data + 11 * src_stride))),
595
0
            0x20);
596
597
0
        src10 = _mm256_castsi128_si256(
598
0
            _mm_loadl_epi64((__m128i *)(data + 12 * src_stride)));
599
600
0
        const __m256i src_1112a = _mm256_permute2x128_si256(
601
0
            _mm256_castsi128_si256(
602
0
                _mm_loadl_epi64((__m128i *)(data + 11 * src_stride))),
603
0
            src10, 0x20);
604
605
0
        const __m256i src_1011 = _mm256_unpacklo_epi8(src_1011a, v_zero);
606
0
        const __m256i src_1112 = _mm256_unpacklo_epi8(src_1112a, v_zero);
607
608
0
        s[5] = _mm256_unpacklo_epi16(src_1011, src_1112);
609
0
        s[11] = _mm256_unpackhi_epi16(src_1011, src_1112);
610
611
0
        const __m256i res_lo = convolve_12taps(s, coeffs);
612
613
0
        const __m256i res_32b_lo = _mm256_sra_epi32(
614
0
            _mm256_add_epi32(res_lo, right_shift_const), right_shift);
615
        // 8 bit conversion and saturation to uint8
616
0
        __m256i res_16b_lo = _mm256_packs_epi32(res_32b_lo, res_32b_lo);
617
0
        __m256i res_8b_lo = _mm256_packus_epi16(res_16b_lo, res_16b_lo);
618
619
0
        if (w - j > 4) {
620
0
          const __m256i res_hi = convolve_12taps(s + 6, coeffs);
621
622
0
          const __m256i res_32b_hi = _mm256_sra_epi32(
623
0
              _mm256_add_epi32(res_hi, right_shift_const), right_shift);
624
0
          __m256i res_16b_hi = _mm256_packs_epi32(res_32b_hi, res_32b_hi);
625
          // 8 bit conversion and saturation to uint8
626
0
          __m256i res_8b_hi = _mm256_packus_epi16(res_16b_hi, res_16b_hi);
627
628
0
          __m256i res_a = _mm256_unpacklo_epi32(res_8b_lo, res_8b_hi);
629
630
0
          const __m128i res_0 = _mm256_extracti128_si256(res_a, 0);
631
0
          const __m128i res_1 = _mm256_extracti128_si256(res_a, 1);
632
633
0
          _mm_storel_epi64((__m128i *)&dst[i * dst_stride + j], res_0);
634
0
          _mm_storel_epi64((__m128i *)&dst[i * dst_stride + j + dst_stride],
635
0
                           res_1);
636
0
        } else {
637
0
          const __m128i res_0 = _mm256_extracti128_si256(res_8b_lo, 0);
638
0
          const __m128i res_1 = _mm256_extracti128_si256(res_8b_lo, 1);
639
0
          if (w - j > 2) {
640
0
            xx_storel_32(&dst[i * dst_stride + j], res_0);
641
0
            xx_storel_32(&dst[i * dst_stride + j + dst_stride], res_1);
642
0
          } else {
643
0
            xx_storel_16(&dst[i * dst_stride + j], res_0);
644
0
            xx_storel_16(&dst[i * dst_stride + j + dst_stride], res_1);
645
0
          }
646
0
        }
647
0
        s[0] = s[1];
648
0
        s[1] = s[2];
649
0
        s[2] = s[3];
650
0
        s[3] = s[4];
651
0
        s[4] = s[5];
652
653
0
        s[6] = s[7];
654
0
        s[7] = s[8];
655
0
        s[8] = s[9];
656
0
        s[9] = s[10];
657
0
        s[10] = s[11];
658
0
      }
659
0
    }
660
14.0k
  } else {
661
14.0k
    assert(vert_tap == 8);
662
663
14.0k
    if (w <= 4) {
664
6.14k
      prepare_coeffs_ssse3(filter_params_y, subpel_y_qn, coeffs_128);
665
666
6.14k
      __m128i d[8], s[4], res;
667
6.14k
      if (w == 2) {
668
1.31k
        d[0] = _mm_cvtsi32_si128(loadu_int16(data + 0 * src_stride));
669
1.31k
        d[1] = _mm_cvtsi32_si128(loadu_int16(data + 1 * src_stride));
670
1.31k
        d[2] = _mm_cvtsi32_si128(loadu_int16(data + 2 * src_stride));
671
1.31k
        d[3] = _mm_cvtsi32_si128(loadu_int16(data + 3 * src_stride));
672
1.31k
        d[4] = _mm_cvtsi32_si128(loadu_int16(data + 4 * src_stride));
673
1.31k
        d[5] = _mm_cvtsi32_si128(loadu_int16(data + 5 * src_stride));
674
1.31k
        d[6] = _mm_cvtsi32_si128(loadu_int16(data + 6 * src_stride));
675
676
1.31k
        const __m128i src_01a = _mm_unpacklo_epi16(d[0], d[1]);
677
1.31k
        const __m128i src_12a = _mm_unpacklo_epi16(d[1], d[2]);
678
1.31k
        const __m128i src_23a = _mm_unpacklo_epi16(d[2], d[3]);
679
1.31k
        const __m128i src_34a = _mm_unpacklo_epi16(d[3], d[4]);
680
1.31k
        const __m128i src_45a = _mm_unpacklo_epi16(d[4], d[5]);
681
1.31k
        const __m128i src_56a = _mm_unpacklo_epi16(d[5], d[6]);
682
683
1.31k
        s[0] = _mm_unpacklo_epi8(src_01a, src_12a);
684
1.31k
        s[1] = _mm_unpacklo_epi8(src_23a, src_34a);
685
1.31k
        s[2] = _mm_unpacklo_epi8(src_45a, src_56a);
686
687
5.26k
        do {
688
5.26k
          convolve_y_8tap_2x2_ssse3(data, src_stride, coeffs_128, d, s, &res);
689
5.26k
          res = round_sr_y_ssse3(res);
690
5.26k
          pack_store_u8_2x2_sse2(res, dst_ptr, dst_stride);
691
692
5.26k
          dst_ptr += 2 * dst_stride;
693
5.26k
          data += 2 * src_stride;
694
5.26k
          y -= 2;
695
696
5.26k
          s[0] = s[1];
697
5.26k
          s[1] = s[2];
698
5.26k
          s[2] = s[3];
699
5.26k
        } while (y > 0);
700
701
4.82k
      } else {
702
4.82k
        assert(w == 4);
703
704
4.82k
        d[0] = _mm_cvtsi32_si128(loadu_int32(data + 0 * src_stride));
705
4.82k
        d[1] = _mm_cvtsi32_si128(loadu_int32(data + 1 * src_stride));
706
4.82k
        d[2] = _mm_cvtsi32_si128(loadu_int32(data + 2 * src_stride));
707
4.82k
        d[3] = _mm_cvtsi32_si128(loadu_int32(data + 3 * src_stride));
708
4.82k
        d[4] = _mm_cvtsi32_si128(loadu_int32(data + 4 * src_stride));
709
4.82k
        d[5] = _mm_cvtsi32_si128(loadu_int32(data + 5 * src_stride));
710
4.82k
        d[6] = _mm_cvtsi32_si128(loadu_int32(data + 6 * src_stride));
711
712
4.82k
        const __m128i src_01a = _mm_unpacklo_epi32(d[0], d[1]);
713
4.82k
        const __m128i src_12a = _mm_unpacklo_epi32(d[1], d[2]);
714
4.82k
        const __m128i src_23a = _mm_unpacklo_epi32(d[2], d[3]);
715
4.82k
        const __m128i src_34a = _mm_unpacklo_epi32(d[3], d[4]);
716
4.82k
        const __m128i src_45a = _mm_unpacklo_epi32(d[4], d[5]);
717
4.82k
        const __m128i src_56a = _mm_unpacklo_epi32(d[5], d[6]);
718
719
4.82k
        s[0] = _mm_unpacklo_epi8(src_01a, src_12a);
720
4.82k
        s[1] = _mm_unpacklo_epi8(src_23a, src_34a);
721
4.82k
        s[2] = _mm_unpacklo_epi8(src_45a, src_56a);
722
723
26.5k
        do {
724
26.5k
          convolve_y_8tap_4x2_ssse3(data, src_stride, coeffs_128, d, s, &res);
725
26.5k
          res = round_sr_y_ssse3(res);
726
26.5k
          pack_store_u8_4x2_sse2(res, dst_ptr, dst_stride);
727
728
26.5k
          dst_ptr += 2 * dst_stride;
729
26.5k
          data += 2 * src_stride;
730
26.5k
          y -= 2;
731
732
26.5k
          s[0] = s[1];
733
26.5k
          s[1] = s[2];
734
26.5k
          s[2] = s[3];
735
26.5k
        } while (y > 0);
736
4.82k
      }
737
7.91k
    } else {
738
7.91k
      prepare_coeffs_lowbd(filter_params_y, subpel_y_qn, coeffs);
739
740
7.91k
      if (w == 8) {
741
4.03k
        __m128i d[8];
742
4.03k
        __m256i s[4];
743
744
4.03k
        d[0] = _mm_loadl_epi64((__m128i *)(data + 0 * src_stride));
745
4.03k
        d[1] = _mm_loadl_epi64((__m128i *)(data + 1 * src_stride));
746
4.03k
        d[2] = _mm_loadl_epi64((__m128i *)(data + 2 * src_stride));
747
4.03k
        d[3] = _mm_loadl_epi64((__m128i *)(data + 3 * src_stride));
748
4.03k
        d[4] = _mm_loadl_epi64((__m128i *)(data + 4 * src_stride));
749
4.03k
        d[5] = _mm_loadl_epi64((__m128i *)(data + 5 * src_stride));
750
4.03k
        d[6] = _mm_loadl_epi64((__m128i *)(data + 6 * src_stride));
751
752
4.03k
        const __m256i src_01a = _mm256_setr_m128i(d[0], d[1]);
753
4.03k
        const __m256i src_12a = _mm256_setr_m128i(d[1], d[2]);
754
4.03k
        const __m256i src_23a = _mm256_setr_m128i(d[2], d[3]);
755
4.03k
        const __m256i src_34a = _mm256_setr_m128i(d[3], d[4]);
756
4.03k
        const __m256i src_45a = _mm256_setr_m128i(d[4], d[5]);
757
4.03k
        const __m256i src_56a = _mm256_setr_m128i(d[5], d[6]);
758
759
4.03k
        s[0] = _mm256_unpacklo_epi8(src_01a, src_12a);
760
4.03k
        s[1] = _mm256_unpacklo_epi8(src_23a, src_34a);
761
4.03k
        s[2] = _mm256_unpacklo_epi8(src_45a, src_56a);
762
763
25.9k
        do {
764
25.9k
          __m256i res;
765
25.9k
          convolve_y_8tap_8x2_avx2(data, src_stride, coeffs, d, s, &res);
766
25.9k
          round_pack_store_y_8x2_avx2(res, dst_ptr, dst_stride);
767
768
25.9k
          dst_ptr += 2 * dst_stride;
769
25.9k
          data += 2 * src_stride;
770
25.9k
          y -= 2;
771
772
25.9k
          s[0] = s[1];
773
25.9k
          s[1] = s[2];
774
25.9k
          s[2] = s[3];
775
25.9k
        } while (y > 0);
776
777
4.03k
      } else {
778
3.88k
        assert(!(w % 16));
779
780
3.88k
        __m128i d[8];
781
3.88k
        __m256i s[8];
782
5.95k
        do {
783
5.95k
          data = src_ptr + x;
784
5.95k
          dst_ptr = dst + x;
785
5.95k
          y = h;
786
787
5.95k
          d[0] = _mm_loadu_si128((__m128i *)(data + 0 * src_stride));
788
5.95k
          d[1] = _mm_loadu_si128((__m128i *)(data + 1 * src_stride));
789
5.95k
          d[2] = _mm_loadu_si128((__m128i *)(data + 2 * src_stride));
790
5.95k
          d[3] = _mm_loadu_si128((__m128i *)(data + 3 * src_stride));
791
5.95k
          d[4] = _mm_loadu_si128((__m128i *)(data + 4 * src_stride));
792
5.95k
          d[5] = _mm_loadu_si128((__m128i *)(data + 5 * src_stride));
793
5.95k
          d[6] = _mm_loadu_si128((__m128i *)(data + 6 * src_stride));
794
795
5.95k
          const __m256i src_01a = _mm256_setr_m128i(d[0], d[1]);
796
5.95k
          const __m256i src_12a = _mm256_setr_m128i(d[1], d[2]);
797
5.95k
          const __m256i src_23a = _mm256_setr_m128i(d[2], d[3]);
798
5.95k
          const __m256i src_34a = _mm256_setr_m128i(d[3], d[4]);
799
5.95k
          const __m256i src_45a = _mm256_setr_m128i(d[4], d[5]);
800
5.95k
          const __m256i src_56a = _mm256_setr_m128i(d[5], d[6]);
801
802
5.95k
          s[0] = _mm256_unpacklo_epi8(src_01a, src_12a);
803
5.95k
          s[1] = _mm256_unpacklo_epi8(src_23a, src_34a);
804
5.95k
          s[2] = _mm256_unpacklo_epi8(src_45a, src_56a);
805
806
5.95k
          s[4] = _mm256_unpackhi_epi8(src_01a, src_12a);
807
5.95k
          s[5] = _mm256_unpackhi_epi8(src_23a, src_34a);
808
5.95k
          s[6] = _mm256_unpackhi_epi8(src_45a, src_56a);
809
810
78.2k
          do {
811
78.2k
            __m256i res[2];
812
78.2k
            convolve_y_8tap_16x2_avx2(data, src_stride, coeffs, d, s, res);
813
78.2k
            round_pack_store_y_16x2_avx2(res, dst_ptr, dst_stride);
814
815
78.2k
            dst_ptr += 2 * dst_stride;
816
78.2k
            data += 2 * src_stride;
817
78.2k
            y -= 2;
818
819
78.2k
            s[0] = s[1];
820
78.2k
            s[1] = s[2];
821
78.2k
            s[2] = s[3];
822
823
78.2k
            s[4] = s[5];
824
78.2k
            s[5] = s[6];
825
78.2k
            s[6] = s[7];
826
78.2k
          } while (y > 0);
827
828
5.95k
          x += 16;
829
5.95k
        } while (x < w);
830
3.88k
      }
831
7.91k
    }
832
14.0k
  }
833
554k
}
834
835
void av1_convolve_x_sr_avx2(const uint8_t *src, int32_t src_stride,
836
                            uint8_t *dst, int32_t dst_stride, int32_t w,
837
                            int32_t h,
838
                            const InterpFilterParams *filter_params_x,
839
                            const int32_t subpel_x_qn,
840
492k
                            ConvolveParams *conv_params) {
841
492k
  const int bits = FILTER_BITS - conv_params->round_0;
842
492k
  int i, j, horiz_tap = get_filter_tap(filter_params_x, subpel_x_qn);
843
844
492k
  assert(bits >= 0);
845
492k
  assert((FILTER_BITS - conv_params->round_1) >= 0 ||
846
492k
         ((conv_params->round_0 + conv_params->round_1) == 2 * FILTER_BITS));
847
492k
  assert(conv_params->round_0 > 0);
848
849
492k
  assert(horiz_tap == 2 || horiz_tap == 4 || horiz_tap == 6 || horiz_tap == 8 ||
850
492k
         horiz_tap == 12);
851
492k
  assert((!(w % 2)) || (w <= 128));
852
492k
  assert((h % 2) == 0);
853
854
492k
  __m256i coeffs[6] = { 0 }, filt[4] = { 0 };
855
492k
  __m128i coeffs_128[4] = { 0 };
856
857
492k
  i = 0;
858
  // horz_filt as 4 tap
859
492k
  if (horiz_tap == 4) {
860
    // since fo_horiz = 1
861
185k
    const uint8_t *src_ptr = src - 1;
862
185k
    if (w == 2) {
863
31.3k
      prepare_coeffs_4t_ssse3(filter_params_x, subpel_x_qn, coeffs_128);
864
82.0k
      do {
865
82.0k
        const __m128i res =
866
82.0k
            convolve_x_4tap_2x2_ssse3(src_ptr, src_stride, coeffs_128);
867
82.0k
        const __m128i reg = round_sr_x_ssse3(res);
868
82.0k
        pack_store_u8_2x2_sse2(reg, dst, dst_stride);
869
82.0k
        src_ptr += 2 * src_stride;
870
82.0k
        dst += 2 * dst_stride;
871
82.0k
        h -= 2;
872
82.0k
      } while (h);
873
154k
    } else if (w == 4) {
874
140k
      prepare_coeffs_4t_ssse3(filter_params_x, subpel_x_qn, coeffs_128);
875
462k
      do {
876
462k
        const __m128i reg =
877
462k
            convolve_x_4tap_4x2_ssse3(src_ptr, src_stride, coeffs_128);
878
462k
        const __m128i res = round_sr_x_ssse3(reg);
879
462k
        pack_store_u8_4x2_sse2(res, dst, dst_stride);
880
462k
        src_ptr += 2 * src_stride;
881
462k
        dst += 2 * dst_stride;
882
462k
        h -= 2;
883
462k
      } while (h);
884
140k
    } else if (w == 8) {
885
7.34k
      prepare_coeffs_lowbd(filter_params_x, subpel_x_qn, coeffs);
886
7.34k
      filt[0] = _mm256_load_si256((__m256i const *)(filt_global_avx2));
887
7.34k
      filt[1] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32));
888
26.9k
      do {
889
26.9k
        const __m256i data = _mm256_setr_m128i(
890
26.9k
            _mm_loadu_si128((__m128i *)(&src_ptr[i * src_stride])),
891
26.9k
            _mm_loadu_si128(
892
26.9k
                (__m128i *)(&src_ptr[i * src_stride + src_stride])));
893
894
26.9k
        __m256i res_16b = convolve_lowbd_x_4tap(data, coeffs + 1, filt);
895
896
26.9k
        res_16b = round_sr_x_avx2(res_16b);
897
898
        /* rounding code */
899
        // 8 bit conversion and saturation to uint8
900
26.9k
        __m256i res_8b = _mm256_packus_epi16(res_16b, res_16b);
901
902
26.9k
        const __m128i res_0 = _mm256_castsi256_si128(res_8b);
903
26.9k
        const __m128i res_1 = _mm256_extracti128_si256(res_8b, 1);
904
905
26.9k
        _mm_storel_epi64((__m128i *)&dst[i * dst_stride], res_0);
906
26.9k
        _mm_storel_epi64((__m128i *)&dst[i * dst_stride + dst_stride], res_1);
907
26.9k
        i += 2;
908
26.9k
      } while (i < h);
909
7.34k
    } else {
910
6.76k
      assert(!(w % 16));
911
6.76k
      prepare_coeffs_lowbd(filter_params_x, subpel_x_qn, coeffs);
912
6.76k
      filt[0] = _mm256_load_si256((__m256i const *)(filt_global_avx2));
913
6.76k
      filt[1] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32));
914
177k
      do {
915
177k
        j = 0;
916
660k
        do {
917
          // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 8 9 10 11 12 13 14 15 16 17
918
          // 18 19 20 21 22 23
919
660k
          const __m256i data = _mm256_inserti128_si256(
920
660k
              _mm256_loadu_si256((__m256i *)&src_ptr[(i * src_stride) + j]),
921
660k
              _mm_loadu_si128((__m128i *)&src_ptr[(i * src_stride) + (j + 8)]),
922
660k
              1);
923
924
660k
          __m256i res_16b = convolve_lowbd_x_4tap(data, coeffs + 1, filt);
925
926
660k
          res_16b = round_sr_x_avx2(res_16b);
927
928
          /* rounding code */
929
          // 8 bit conversion and saturation to uint8
930
660k
          __m256i res_8b = _mm256_packus_epi16(res_16b, res_16b);
931
932
          // Store values into the destination buffer
933
          // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
934
660k
          res_8b = _mm256_permute4x64_epi64(res_8b, 216);
935
660k
          __m128i res = _mm256_castsi256_si128(res_8b);
936
660k
          _mm_storeu_si128((__m128i *)&dst[i * dst_stride + j], res);
937
660k
          j += 16;
938
660k
        } while (j < w);
939
177k
        i++;
940
177k
      } while (i < h);
941
6.76k
    }
942
306k
  } else if (horiz_tap == 6) {
943
    // since (horiz_tap/2 - 1 == 2)
944
257k
    const uint8_t *src_ptr = src - 2;
945
257k
    prepare_coeffs_6t_lowbd(filter_params_x, subpel_x_qn, coeffs);
946
257k
    filt[0] = _mm256_load_si256((__m256i const *)(filt_global_avx2));
947
257k
    filt[1] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32));
948
257k
    filt[2] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 2));
949
257k
    if (w == 8) {
950
495k
      do {
951
495k
        const __m256i data = _mm256_setr_m128i(
952
495k
            _mm_loadu_si128((__m128i *)(&src_ptr[i * src_stride])),
953
495k
            _mm_loadu_si128(
954
495k
                (__m128i *)(&src_ptr[i * src_stride + src_stride])));
955
956
495k
        __m256i res_16b = convolve_lowbd_x_6tap(data, coeffs, filt);
957
958
495k
        res_16b = round_sr_x_avx2(res_16b);
959
960
        /* rounding code */
961
        // 8 bit conversion and saturation to uint8
962
495k
        __m256i res_8b = _mm256_packus_epi16(res_16b, res_16b);
963
964
495k
        const __m128i res_0 = _mm256_castsi256_si128(res_8b);
965
495k
        const __m128i res_1 = _mm256_extracti128_si256(res_8b, 1);
966
495k
        _mm_storel_epi64((__m128i *)&dst[i * dst_stride], res_0);
967
495k
        _mm_storel_epi64((__m128i *)&dst[i * dst_stride + dst_stride], res_1);
968
495k
        i += 2;
969
495k
      } while (i < h);
970
138k
    } else if (w == 16) {
971
444k
      do {
972
444k
        __m256i data[2] = { 0 };
973
974
444k
        load_convolve_6tap_16x2_avx2(src_ptr, src_stride, coeffs, filt, data);
975
444k
        round_pack_store_16x2_avx2(data, dst, dst_stride);
976
444k
        src_ptr += 2 * src_stride;
977
444k
        dst += 2 * dst_stride;
978
444k
        h -= 2;
979
444k
      } while (h);
980
89.5k
    } else if (w == 32) {
981
449k
      do {
982
449k
        convolve_sr_store_6tap_32_avx2(src_ptr, coeffs, filt, dst);
983
449k
        src_ptr += src_stride;
984
449k
        dst += dst_stride;
985
449k
      } while ((--h) > 0);
986
23.1k
    } else if (w == 64) {
987
240k
      do {
988
240k
        convolve_sr_store_6tap_32_avx2(src_ptr, coeffs, filt, dst);
989
240k
        convolve_sr_store_6tap_32_avx2(src_ptr + 32, coeffs, filt, dst + 32);
990
240k
        src_ptr += src_stride;
991
240k
        dst += dst_stride;
992
240k
      } while ((--h) > 0);
993
4.83k
    } else {
994
1.18k
      assert(w == 128);
995
996
140k
      do {
997
140k
        convolve_sr_store_6tap_32_avx2(src_ptr, coeffs, filt, dst);
998
140k
        convolve_sr_store_6tap_32_avx2(src_ptr + SECOND_32_BLK, coeffs, filt,
999
140k
                                       dst + SECOND_32_BLK);
1000
140k
        convolve_sr_store_6tap_32_avx2(src_ptr + THIRD_32_BLK, coeffs, filt,
1001
140k
                                       dst + THIRD_32_BLK);
1002
140k
        convolve_sr_store_6tap_32_avx2(src_ptr + FOURTH_32_BLK, coeffs, filt,
1003
140k
                                       dst + FOURTH_32_BLK);
1004
140k
        src_ptr += src_stride;
1005
140k
        dst += dst_stride;
1006
140k
      } while ((--h) > 0);
1007
1.23k
    }
1008
257k
  } else if (horiz_tap == 8) {
1009
    // since (horiz_tap / 2 - 1) == 3
1010
13.8k
    const uint8_t *src_ptr = src - 3;
1011
13.8k
    prepare_coeffs_lowbd(filter_params_x, subpel_x_qn, coeffs);
1012
13.8k
    filt[0] = _mm256_load_si256((__m256i const *)(filt_global_avx2));
1013
13.8k
    filt[1] =
1014
13.8k
        _mm256_load_si256((__m256i const *)(filt_global_avx2 + SECOND_32_BLK));
1015
13.8k
    filt[2] =
1016
13.8k
        _mm256_load_si256((__m256i const *)(filt_global_avx2 + THIRD_32_BLK));
1017
13.8k
    filt[3] =
1018
13.8k
        _mm256_load_si256((__m256i const *)(filt_global_avx2 + FOURTH_32_BLK));
1019
1020
13.8k
    if (w == 8) {
1021
26.0k
      do {
1022
26.0k
        const __m256i data = _mm256_setr_m128i(
1023
26.0k
            _mm_loadu_si128((__m128i *)(&src_ptr[i * src_stride])),
1024
26.0k
            _mm_loadu_si128(
1025
26.0k
                (__m128i *)(&src_ptr[i * src_stride + src_stride])));
1026
1027
26.0k
        __m256i res_16b = convolve_lowbd_x(data, coeffs, filt);
1028
1029
26.0k
        res_16b = round_sr_x_avx2(res_16b);
1030
1031
        /* rounding code */
1032
        // 8 bit conversion and saturation to uint8
1033
26.0k
        __m256i res_8b = _mm256_packus_epi16(res_16b, res_16b);
1034
1035
26.0k
        const __m128i res_0 = _mm256_castsi256_si128(res_8b);
1036
26.0k
        const __m128i res_1 = _mm256_extracti128_si256(res_8b, 1);
1037
26.0k
        _mm_storel_epi64((__m128i *)&dst[i * dst_stride], res_0);
1038
26.0k
        _mm_storel_epi64((__m128i *)&dst[i * dst_stride + dst_stride], res_1);
1039
26.0k
        i += 2;
1040
26.0k
      } while (i < h);
1041
7.14k
    } else if (w == 16) {
1042
24.8k
      do {
1043
24.8k
        __m256i data[2] = { 0 };
1044
1045
24.8k
        load_convolve_8tap_16x2_avx2(src_ptr, src_stride, coeffs, filt, data);
1046
24.8k
        round_pack_store_16x2_avx2(data, dst, dst_stride);
1047
24.8k
        src_ptr += 2 * src_stride;
1048
24.8k
        dst += 2 * dst_stride;
1049
24.8k
        h -= 2;
1050
24.8k
      } while (h);
1051
4.48k
    } else if (w == 32) {
1052
35.5k
      do {
1053
35.5k
        load_convolve_round_8tap_32_avx2(src_ptr, coeffs, filt, dst);
1054
35.5k
        src_ptr += src_stride;
1055
35.5k
        dst += dst_stride;
1056
35.5k
      } while ((--h) > 0);
1057
1.48k
    } else if (w == 64) {
1058
27.1k
      do {
1059
27.1k
        load_convolve_round_8tap_32_avx2(src_ptr, coeffs, filt, dst);
1060
27.1k
        load_convolve_round_8tap_32_avx2(src_ptr + 32, coeffs, filt, dst + 32);
1061
27.1k
        src_ptr += src_stride;
1062
27.1k
        dst += dst_stride;
1063
27.1k
      } while ((--h) > 0);
1064
555
    } else {
1065
170
      assert(w == 128);
1066
18.3k
      do {
1067
18.3k
        load_convolve_round_8tap_32_avx2(src_ptr, coeffs, filt, dst);
1068
18.3k
        load_convolve_round_8tap_32_avx2(src_ptr + SECOND_32_BLK, coeffs, filt,
1069
18.3k
                                         dst + SECOND_32_BLK);
1070
18.3k
        load_convolve_round_8tap_32_avx2(src_ptr + THIRD_32_BLK, coeffs, filt,
1071
18.3k
                                         dst + THIRD_32_BLK);
1072
18.3k
        load_convolve_round_8tap_32_avx2(src_ptr + FOURTH_32_BLK, coeffs, filt,
1073
18.3k
                                         dst + FOURTH_32_BLK);
1074
18.3k
        src_ptr += src_stride;
1075
18.3k
        dst += dst_stride;
1076
18.3k
      } while ((--h) > 0);
1077
175
    }
1078
35.7k
  } else if (horiz_tap == 12) {  // horiz_tap == 12
1079
0
    const int fo_horiz = filter_params_x->taps / 2 - 1;
1080
0
    prepare_coeffs_12taps(filter_params_x, subpel_x_qn, coeffs);
1081
0
    const __m128i round_shift = _mm_cvtsi32_si128(bits);
1082
0
    const uint8_t *const src_ptr = src - fo_horiz;
1083
0
    const __m256i v_zero = _mm256_setzero_si256();
1084
0
    __m256i round_0_const =
1085
0
        _mm256_set1_epi32((1 << (conv_params->round_0)) >> 1);
1086
0
    __m256i round_const = _mm256_set1_epi32((1 << bits) >> 1);
1087
0
    __m128i round_0_shift = _mm_cvtsi32_si128(conv_params->round_0);
1088
0
    __m256i s[6] = { 0 };
1089
1090
0
    if (w <= 4) {
1091
0
      do {
1092
0
        const __m256i data = _mm256_permute2x128_si256(
1093
0
            _mm256_castsi128_si256(
1094
0
                _mm_loadu_si128((__m128i *)(&src_ptr[i * src_stride]))),
1095
0
            _mm256_castsi128_si256(_mm_loadu_si128(
1096
0
                (__m128i *)(&src_ptr[i * src_stride + src_stride]))),
1097
0
            0x20);
1098
        // row0 0..7 row1 0..7
1099
0
        const __m256i s_16lo = _mm256_unpacklo_epi8(data, v_zero);
1100
        // row0 8..F row1 8..F
1101
0
        const __m256i s_16hi = _mm256_unpackhi_epi8(data, v_zero);
1102
1103
        // row0 00 00 01 01 .. 03 03 row1 00 00 01 01 .. 03 03
1104
0
        const __m256i s_lolo = _mm256_unpacklo_epi16(s_16lo, s_16lo);
1105
        // row0 04 04 .. 07 07 row1 04 04 .. 07 07
1106
0
        const __m256i s_lohi = _mm256_unpackhi_epi16(s_16lo, s_16lo);
1107
1108
        // row0 08 08 09 09 .. 0B 0B row1 08 08 09 09 .. 0B 0B
1109
0
        const __m256i s_hilo = _mm256_unpacklo_epi16(s_16hi, s_16hi);
1110
        // row0 0C 0C .. 0F 0F row1 0C 0C .. 0F 0F
1111
0
        const __m256i s_hihi = _mm256_unpackhi_epi16(s_16hi, s_16hi);
1112
1113
        // 00 01 01 02 02 03 03 04 10 11 11 12 12 13 13 14
1114
0
        s[0] = _mm256_alignr_epi8(s_lohi, s_lolo, 2);
1115
        // 02 03 03 04 04 05 05 06 12 13 13 14 14 15 15 16
1116
0
        s[1] = _mm256_alignr_epi8(s_lohi, s_lolo, 10);
1117
        // 04 05 05 06 06 07 07 08 14 15 15 16 16 17 17 18
1118
0
        s[2] = _mm256_alignr_epi8(s_hilo, s_lohi, 2);
1119
        // 06 07 07 08 08 09 09 0A 16 17 17 18 18 19 19 1A
1120
0
        s[3] = _mm256_alignr_epi8(s_hilo, s_lohi, 10);
1121
        // 08 09 09 0A 0A 0B 0B 0C 18 19 19 1A 1A 1B 1B 1C
1122
0
        s[4] = _mm256_alignr_epi8(s_hihi, s_hilo, 2);
1123
        // 0A 0B 0B 0C 0C 0D 0D 0E 1A 1B 1B 1C 1C 1D 1D 1E
1124
0
        s[5] = _mm256_alignr_epi8(s_hihi, s_hilo, 10);
1125
1126
0
        const __m256i res_lo = convolve_12taps(s, coeffs);
1127
1128
0
        __m256i res_32b_lo = _mm256_sra_epi32(
1129
0
            _mm256_add_epi32(res_lo, round_0_const), round_0_shift);
1130
1131
        // 00 01 02 03 10 12 13 14
1132
0
        res_32b_lo = _mm256_sra_epi32(_mm256_add_epi32(res_32b_lo, round_const),
1133
0
                                      round_shift);
1134
        // 8 bit conversion and saturation to uint8
1135
        // 00 01 02 03 00 01 02 03 10 11 12 13 10 11 12 13
1136
0
        __m256i res_16b_lo = _mm256_packs_epi32(res_32b_lo, res_32b_lo);
1137
        // 00 01 02 03 00 01 02 03 00 01 02 03 00 01 02 03
1138
        // 10 11 12 13 10 11 12 13 10 11 12 13 10 11 12 13
1139
0
        __m256i res_8b_lo = _mm256_packus_epi16(res_16b_lo, res_16b_lo);
1140
1141
        // 00 01 02 03 00 01 02 03 00 01 02 03 00 01 02 03
1142
0
        const __m128i res_0 = _mm256_extracti128_si256(res_8b_lo, 0);
1143
        // 10 11 12 13 10 11 12 13 10 11 12 13 10 11 12 13
1144
0
        const __m128i res_1 = _mm256_extracti128_si256(res_8b_lo, 1);
1145
0
        if (w > 2) {
1146
          // 00 01 02 03
1147
0
          xx_storel_32(&dst[i * dst_stride], res_0);
1148
          // 10 11 12 13
1149
0
          xx_storel_32(&dst[i * dst_stride + dst_stride], res_1);
1150
0
        } else {
1151
          // 00 01
1152
0
          xx_storel_16(&dst[i * dst_stride], res_0);
1153
          // 10 11
1154
0
          xx_storel_16(&dst[i * dst_stride + dst_stride], res_1);
1155
0
        }
1156
0
        i += 2;
1157
0
      } while (i < h);
1158
0
    } else {
1159
0
      assert(!(w % 8));
1160
0
      do {
1161
0
        j = 0;
1162
0
        do {
1163
0
          const __m256i data = _mm256_permute2x128_si256(
1164
0
              _mm256_castsi128_si256(
1165
0
                  _mm_loadu_si128((__m128i *)(&src_ptr[i * src_stride + j]))),
1166
0
              _mm256_castsi128_si256(_mm_loadu_si128(
1167
0
                  (__m128i *)(&src_ptr[i * src_stride + j + 4]))),
1168
0
              0x20);
1169
          // row0 0..7 4..B
1170
0
          const __m256i s_16lo = _mm256_unpacklo_epi8(data, v_zero);
1171
          // row0 8..F C..13
1172
0
          const __m256i s_16hi = _mm256_unpackhi_epi8(data, v_zero);
1173
1174
          // row0 00 00 01 01 .. 03 03 04 04 05 05 .. 07 07
1175
0
          const __m256i s_lolo = _mm256_unpacklo_epi16(s_16lo, s_16lo);
1176
          // row0 04 04 .. 07 07 08 08 .. 0B 0B
1177
0
          const __m256i s_lohi = _mm256_unpackhi_epi16(s_16lo, s_16lo);
1178
1179
          // row0 08 08 09 09 .. 0B 0B 0C 0C 0D 0D .. 0F 0F
1180
0
          const __m256i s_hilo = _mm256_unpacklo_epi16(s_16hi, s_16hi);
1181
          // row0 0C 0C 0D 0D .. 0F 0F 10 10 11 11 .. 13 13
1182
0
          const __m256i s_hihi = _mm256_unpackhi_epi16(s_16hi, s_16hi);
1183
1184
0
          s[0] = _mm256_alignr_epi8(s_lohi, s_lolo, 2);
1185
0
          s[1] = _mm256_alignr_epi8(s_lohi, s_lolo, 10);
1186
0
          s[2] = _mm256_alignr_epi8(s_hilo, s_lohi, 2);
1187
0
          s[3] = _mm256_alignr_epi8(s_hilo, s_lohi, 10);
1188
0
          s[4] = _mm256_alignr_epi8(s_hihi, s_hilo, 2);
1189
0
          s[5] = _mm256_alignr_epi8(s_hihi, s_hilo, 10);
1190
1191
0
          const __m256i res_lo = convolve_12taps(s, coeffs);
1192
1193
0
          __m256i res_32b_lo = _mm256_sra_epi32(
1194
0
              _mm256_add_epi32(res_lo, round_0_const), round_0_shift);
1195
1196
0
          res_32b_lo = _mm256_sra_epi32(
1197
0
              _mm256_add_epi32(res_32b_lo, round_const), round_shift);
1198
          // 8 bit conversion and saturation to uint8
1199
0
          __m256i res_16b_lo = _mm256_packs_epi32(res_32b_lo, res_32b_lo);
1200
0
          __m256i res_8b_lo = _mm256_packus_epi16(res_16b_lo, res_16b_lo);
1201
0
          const __m128i res_0 = _mm256_extracti128_si256(res_8b_lo, 0);
1202
0
          const __m128i res_1 = _mm256_extracti128_si256(res_8b_lo, 1);
1203
0
          xx_storel_32(&dst[i * dst_stride + j], res_0);
1204
0
          xx_storel_32(&dst[i * dst_stride + j + 4], res_1);
1205
1206
0
          j += 8;
1207
0
        } while (j < w);
1208
0
        i++;
1209
0
      } while (i < h);
1210
0
    }
1211
35.7k
  } else {
1212
35.7k
    assert(horiz_tap == 2);
1213
    // since (filter_params_x->taps / 2 - 1) == 0
1214
35.7k
    const uint8_t *src_ptr = src;
1215
35.7k
    if (subpel_x_qn != 8) {
1216
15.4k
      if (w <= 8) {
1217
11.6k
        prepare_coeffs_2t_ssse3(filter_params_x, subpel_x_qn, coeffs_128);
1218
1219
11.6k
        if (w == 2) {
1220
3.71k
          do {
1221
3.71k
            const __m128i data =
1222
3.71k
                convolve_x_2tap_2x2_ssse3(src_ptr, src_stride, coeffs_128);
1223
3.71k
            const __m128i reg = round_sr_x_ssse3(data);
1224
3.71k
            pack_store_u8_2x2_sse2(reg, dst, dst_stride);
1225
3.71k
            src_ptr += 2 * src_stride;
1226
3.71k
            dst += 2 * dst_stride;
1227
3.71k
            h -= 2;
1228
3.71k
          } while (h);
1229
10.0k
        } else if (w == 4) {
1230
15.6k
          do {
1231
15.6k
            const __m128i data =
1232
15.6k
                convolve_x_2tap_4x2_ssse3(src_ptr, src_stride, coeffs_128);
1233
15.6k
            const __m128i reg = round_sr_x_ssse3(data);
1234
15.6k
            pack_store_u8_4x2_sse2(reg, dst, dst_stride);
1235
15.6k
            src_ptr += 2 * src_stride;
1236
15.6k
            dst += 2 * dst_stride;
1237
15.6k
            h -= 2;
1238
15.6k
          } while (h);
1239
5.31k
        } else {
1240
4.72k
          assert(w == 8);
1241
1242
15.6k
          do {
1243
15.6k
            __m128i data[2] = { 0 };
1244
1245
15.6k
            convolve_x_2tap_8x2_ssse3(src_ptr, src_stride, coeffs_128, data);
1246
15.6k
            data[0] = round_sr_x_ssse3(data[0]);
1247
15.6k
            data[1] = round_sr_x_ssse3(data[1]);
1248
15.6k
            const __m128i reg = _mm_packus_epi16(data[0], data[1]);
1249
15.6k
            _mm_storel_epi64((__m128i *)dst, reg);
1250
15.6k
            _mm_storeh_epi64((__m128i *)(dst + dst_stride), reg);
1251
1252
15.6k
            src_ptr += 2 * src_stride;
1253
15.6k
            dst += 2 * dst_stride;
1254
15.6k
            h -= 2;
1255
15.6k
          } while (h);
1256
4.72k
        }
1257
11.6k
      } else {
1258
3.81k
        prepare_coeffs_2t_lowbd(filter_params_x, subpel_x_qn, coeffs);
1259
1260
3.81k
        if (w == 16) {
1261
11.4k
          do {
1262
11.4k
            __m256i data[2] = { 0 };
1263
1264
11.4k
            convolve_x_2tap_16x2_avx2(src_ptr, src_stride, coeffs, data);
1265
11.4k
            round_pack_store_16x2_avx2(data, dst, dst_stride);
1266
11.4k
            src_ptr += 2 * src_stride;
1267
11.4k
            dst += 2 * dst_stride;
1268
11.4k
            h -= 2;
1269
11.4k
          } while (h);
1270
2.14k
        } else if (w == 32) {
1271
23.4k
          do {
1272
23.4k
            convolve_round_2tap_32_avx2(src_ptr, coeffs, dst);
1273
23.4k
            src_ptr += src_stride;
1274
23.4k
            dst += dst_stride;
1275
23.4k
          } while ((--h) > 0);
1276
879
        } else if (w == 64) {
1277
28.9k
          do {
1278
28.9k
            convolve_round_2tap_32_avx2(src_ptr, coeffs, dst);
1279
28.9k
            convolve_round_2tap_32_avx2(src_ptr + SECOND_32_BLK, coeffs,
1280
28.9k
                                        dst + SECOND_32_BLK);
1281
28.9k
            src_ptr += src_stride;
1282
28.9k
            dst += dst_stride;
1283
28.9k
          } while ((--h) > 0);
1284
626
        } else {
1285
163
          assert(w == 128);
1286
1287
13.6k
          do {
1288
13.6k
            convolve_round_2tap_32_avx2(src_ptr, coeffs, dst);
1289
13.6k
            convolve_round_2tap_32_avx2(src_ptr + (SECOND_32_BLK), coeffs,
1290
13.6k
                                        dst + (SECOND_32_BLK));
1291
13.6k
            convolve_round_2tap_32_avx2(src_ptr + (THIRD_32_BLK), coeffs,
1292
13.6k
                                        dst + (THIRD_32_BLK));
1293
13.6k
            convolve_round_2tap_32_avx2(src_ptr + (FOURTH_32_BLK), coeffs,
1294
13.6k
                                        dst + (FOURTH_32_BLK));
1295
13.6k
            src_ptr += src_stride;
1296
13.6k
            dst += dst_stride;
1297
13.6k
          } while ((--h) > 0);
1298
163
        }
1299
3.81k
      }
1300
20.3k
    } else {
1301
20.3k
      if (w == 2) {
1302
5.76k
        do {
1303
5.76k
          __m128i data = load_x_u8_4x2_sse4(src_ptr, src_stride);
1304
5.76k
          const __m128i reg1 = _mm_srli_si128(data, 1);
1305
5.76k
          const __m128i reg2 = _mm_avg_epu8(data, reg1);
1306
5.76k
          xx_storel_16(dst, reg2);
1307
5.76k
          {
1308
5.76k
            uint16_t val = (uint16_t)_mm_extract_epi16(reg2, 2);
1309
5.76k
            memcpy(dst + dst_stride, &val, sizeof(val));
1310
5.76k
          }
1311
5.76k
          src_ptr += 2 * src_stride;
1312
5.76k
          dst += 2 * dst_stride;
1313
5.76k
          h -= 2;
1314
5.76k
        } while (h);
1315
17.5k
      } else if (w == 4) {
1316
20.3k
        do {
1317
20.3k
          __m128i data = load_8bit_8x2_to_1_reg_sse2(
1318
20.3k
              src_ptr, (int)(sizeof(*src_ptr) * src_stride));
1319
20.3k
          const __m128i reg1 = _mm_srli_si128(data, 1);
1320
20.3k
          const __m128i reg2 = _mm_avg_epu8(data, reg1);
1321
20.3k
          xx_storel_32(dst, reg2);
1322
20.3k
          {
1323
20.3k
            int32_t val = _mm_extract_epi32(reg2, 2);
1324
20.3k
            memcpy(dst + dst_stride, &val, sizeof(val));
1325
20.3k
          }
1326
1327
20.3k
          src_ptr += 2 * src_stride;
1328
20.3k
          dst += 2 * dst_stride;
1329
20.3k
          h -= 2;
1330
20.3k
        } while (h);
1331
10.5k
      } else if (w == 8) {
1332
22.6k
        do {
1333
22.6k
          const __m128i data00 = _mm_loadu_si128((__m128i *)src_ptr);
1334
22.6k
          const __m128i data10 =
1335
22.6k
              _mm_loadu_si128((__m128i *)(src_ptr + src_stride));
1336
22.6k
          const __m128i data01 = _mm_srli_si128(data00, 1);
1337
22.6k
          const __m128i data11 = _mm_srli_si128(data10, 1);
1338
22.6k
          const __m128i reg0 = _mm_avg_epu8(data00, data01);
1339
22.6k
          const __m128i reg1 = _mm_avg_epu8(data10, data11);
1340
22.6k
          _mm_storel_epi64((__m128i *)dst, reg0);
1341
22.6k
          _mm_storel_epi64((__m128i *)(dst + dst_stride), reg1);
1342
1343
22.6k
          src_ptr += 2 * src_stride;
1344
22.6k
          dst += 2 * dst_stride;
1345
22.6k
          h -= 2;
1346
22.6k
        } while (h);
1347
6.01k
      } else if (w == 16) {
1348
17.0k
        do {
1349
17.0k
          const __m128i data00 = _mm_loadu_si128((__m128i *)src_ptr);
1350
17.0k
          const __m128i data01 = _mm_loadu_si128((__m128i *)(src_ptr + 1));
1351
17.0k
          const __m128i data10 =
1352
17.0k
              _mm_loadu_si128((__m128i *)(src_ptr + src_stride));
1353
17.0k
          const __m128i data11 =
1354
17.0k
              _mm_loadu_si128((__m128i *)(src_ptr + src_stride + 1));
1355
17.0k
          const __m128i reg0 = _mm_avg_epu8(data00, data01);
1356
17.0k
          const __m128i reg1 = _mm_avg_epu8(data10, data11);
1357
17.0k
          _mm_storeu_si128((__m128i *)dst, reg0);
1358
17.0k
          _mm_storeu_si128((__m128i *)(dst + dst_stride), reg1);
1359
1360
17.0k
          src_ptr += 2 * src_stride;
1361
17.0k
          dst += 2 * dst_stride;
1362
17.0k
          h -= 2;
1363
17.0k
        } while (h);
1364
3.07k
      } else if (w == 32) {
1365
23.1k
        do {
1366
23.1k
          load_avg_store_2tap_32_avx2(src_ptr, dst);
1367
23.1k
          src_ptr += src_stride;
1368
23.1k
          dst += dst_stride;
1369
23.1k
        } while ((--h) > 0);
1370
965
      } else if (w == 64) {
1371
17.9k
        do {
1372
17.9k
          load_avg_store_2tap_32_avx2(src_ptr, dst);
1373
17.9k
          load_avg_store_2tap_32_avx2(src_ptr + (SECOND_32_BLK),
1374
17.9k
                                      dst + (SECOND_32_BLK));
1375
17.9k
          src_ptr += src_stride;
1376
17.9k
          dst += dst_stride;
1377
17.9k
        } while ((--h) > 0);
1378
363
      } else {
1379
130
        assert(w == 128);
1380
1381
12.2k
        do {
1382
12.2k
          load_avg_store_2tap_32_avx2(src_ptr, dst);
1383
12.2k
          load_avg_store_2tap_32_avx2(src_ptr + (SECOND_32_BLK),
1384
12.2k
                                      dst + (SECOND_32_BLK));
1385
12.2k
          load_avg_store_2tap_32_avx2(src_ptr + (THIRD_32_BLK),
1386
12.2k
                                      dst + (THIRD_32_BLK));
1387
12.2k
          load_avg_store_2tap_32_avx2(src_ptr + (FOURTH_32_BLK),
1388
12.2k
                                      dst + (FOURTH_32_BLK));
1389
12.2k
          src_ptr += src_stride;
1390
12.2k
          dst += dst_stride;
1391
12.2k
        } while ((--h) > 0);
1392
130
      }
1393
20.3k
    }
1394
35.7k
  }
1395
492k
}