xref: /aosp_15_r20/external/libaom/test/lpf_test.cc (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1 /*
2  * Copyright (c) 2016, 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 <cmath>
13 #include <cstdlib>
14 #include <string>
15 #include <tuple>
16 
17 #include "gtest/gtest.h"
18 
19 #include "config/aom_config.h"
20 #include "config/aom_dsp_rtcd.h"
21 
22 #include "test/acm_random.h"
23 #include "test/register_state_check.h"
24 #include "test/util.h"
25 #include "av1/common/av1_loopfilter.h"
26 #include "av1/common/entropy.h"
27 #include "aom/aom_integer.h"
28 
29 using libaom_test::ACMRandom;
30 
31 namespace {
32 // Horizontally and Vertically need 32x32: 8  Coeffs preceeding filtered section
33 //                                         16 Coefs within filtered section
34 //                                         8  Coeffs following filtered section
35 const int kNumCoeffs = 1024;
36 
37 const int number_of_iterations = 10000;
38 
39 const int kSpeedTestNum = 500000;
40 
41 #define LOOP_PARAM \
42   int p, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh
43 #define DUAL_LOOP_PARAM                                                      \
44   int p, const uint8_t *blimit0, const uint8_t *limit0,                      \
45       const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, \
46       const uint8_t *thresh1
47 
48 typedef void (*loop_op_t)(uint8_t *s, LOOP_PARAM);
49 typedef void (*dual_loop_op_t)(uint8_t *s, DUAL_LOOP_PARAM);
50 typedef void (*hbdloop_op_t)(uint16_t *s, LOOP_PARAM, int bd);
51 typedef void (*hbddual_loop_op_t)(uint16_t *s, DUAL_LOOP_PARAM, int bd);
52 
53 typedef std::tuple<hbdloop_op_t, hbdloop_op_t, int> hbdloop_param_t;
54 typedef std::tuple<hbddual_loop_op_t, hbddual_loop_op_t, int>
55     hbddual_loop_param_t;
56 typedef std::tuple<loop_op_t, loop_op_t, int> loop_param_t;
57 typedef std::tuple<dual_loop_op_t, dual_loop_op_t, int> dual_loop_param_t;
58 
59 template <typename Pixel_t, int PIXEL_WIDTH_t>
InitInput(Pixel_t * s,Pixel_t * ref_s,ACMRandom * rnd,const uint8_t limit,const int mask,const int32_t p,const int i)60 void InitInput(Pixel_t *s, Pixel_t *ref_s, ACMRandom *rnd, const uint8_t limit,
61                const int mask, const int32_t p, const int i) {
62   uint16_t tmp_s[kNumCoeffs];
63 
64   for (int j = 0; j < kNumCoeffs;) {
65     const uint8_t val = rnd->Rand8();
66     if (val & 0x80) {  // 50% chance to choose a new value.
67       tmp_s[j] = rnd->Rand16();
68       j++;
69     } else {  // 50% chance to repeat previous value in row X times.
70       int k = 0;
71       while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
72         if (j < 1) {
73           tmp_s[j] = rnd->Rand16();
74         } else if (val & 0x20) {  // Increment by a value within the limit.
75           tmp_s[j] = static_cast<uint16_t>(tmp_s[j - 1] + (limit - 1));
76         } else {  // Decrement by a value within the limit.
77           tmp_s[j] = static_cast<uint16_t>(tmp_s[j - 1] - (limit - 1));
78         }
79         j++;
80       }
81     }
82   }
83 
84   for (int j = 0; j < kNumCoeffs;) {
85     const uint8_t val = rnd->Rand8();
86     if (val & 0x80) {
87       j++;
88     } else {  // 50% chance to repeat previous value in column X times.
89       int k = 0;
90       while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
91         if (j < 1) {
92           tmp_s[j] = rnd->Rand16();
93         } else if (val & 0x20) {  // Increment by a value within the limit.
94           tmp_s[(j % 32) * 32 + j / 32] = static_cast<uint16_t>(
95               tmp_s[((j - 1) % 32) * 32 + (j - 1) / 32] + (limit - 1));
96         } else {  // Decrement by a value within the limit.
97           tmp_s[(j % 32) * 32 + j / 32] = static_cast<uint16_t>(
98               tmp_s[((j - 1) % 32) * 32 + (j - 1) / 32] - (limit - 1));
99         }
100         j++;
101       }
102     }
103   }
104 
105   for (int j = 0; j < kNumCoeffs; j++) {
106     if (i % 2) {
107       s[j] = tmp_s[j] & mask;
108     } else {
109       s[j] = tmp_s[p * (j % p) + j / p] & mask;
110     }
111     ref_s[j] = s[j];
112   }
113 }
114 
GetOuterThresh(ACMRandom * rnd)115 uint8_t GetOuterThresh(ACMRandom *rnd) {
116   return static_cast<uint8_t>(rnd->PseudoUniform(3 * MAX_LOOP_FILTER + 5));
117 }
118 
GetInnerThresh(ACMRandom * rnd)119 uint8_t GetInnerThresh(ACMRandom *rnd) {
120   return static_cast<uint8_t>(rnd->PseudoUniform(MAX_LOOP_FILTER + 1));
121 }
122 
GetHevThresh(ACMRandom * rnd)123 uint8_t GetHevThresh(ACMRandom *rnd) {
124   return static_cast<uint8_t>(rnd->PseudoUniform(MAX_LOOP_FILTER + 1) >> 4);
125 }
126 
127 template <typename func_type_t, typename params_t>
128 class LoopTestParam : public ::testing::TestWithParam<params_t> {
129  public:
130   ~LoopTestParam() override = default;
SetUp()131   void SetUp() override {
132     loopfilter_op_ = std::get<0>(this->GetParam());
133     ref_loopfilter_op_ = std::get<1>(this->GetParam());
134     bit_depth_ = std::get<2>(this->GetParam());
135     mask_ = (1 << bit_depth_) - 1;
136   }
137 
138  protected:
139   int bit_depth_;
140   int mask_;
141   func_type_t loopfilter_op_;
142   func_type_t ref_loopfilter_op_;
143 };
144 
145 #if CONFIG_AV1_HIGHBITDEPTH
call_filter(uint16_t * s,LOOP_PARAM,int bd,hbdloop_op_t op)146 void call_filter(uint16_t *s, LOOP_PARAM, int bd, hbdloop_op_t op) {
147   op(s, p, blimit, limit, thresh, bd);
148 }
call_dualfilter(uint16_t * s,DUAL_LOOP_PARAM,int bd,hbddual_loop_op_t op)149 void call_dualfilter(uint16_t *s, DUAL_LOOP_PARAM, int bd,
150                      hbddual_loop_op_t op) {
151   op(s, p, blimit0, limit0, thresh0, blimit1, limit1, thresh1, bd);
152 }
153 #endif
call_filter(uint8_t * s,LOOP_PARAM,int bd,loop_op_t op)154 void call_filter(uint8_t *s, LOOP_PARAM, int bd, loop_op_t op) {
155   (void)bd;
156   op(s, p, blimit, limit, thresh);
157 }
call_dualfilter(uint8_t * s,DUAL_LOOP_PARAM,int bd,dual_loop_op_t op)158 void call_dualfilter(uint8_t *s, DUAL_LOOP_PARAM, int bd, dual_loop_op_t op) {
159   (void)bd;
160   op(s, p, blimit0, limit0, thresh0, blimit1, limit1, thresh1);
161 }
162 
163 #if CONFIG_AV1_HIGHBITDEPTH
164 typedef LoopTestParam<hbdloop_op_t, hbdloop_param_t> Loop8Test6Param_hbd;
165 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Loop8Test6Param_hbd);
166 typedef LoopTestParam<hbddual_loop_op_t, hbddual_loop_param_t>
167     Loop8Test9Param_hbd;
168 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Loop8Test9Param_hbd);
169 #endif
170 typedef LoopTestParam<loop_op_t, loop_param_t> Loop8Test6Param_lbd;
171 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Loop8Test6Param_lbd);
172 typedef LoopTestParam<dual_loop_op_t, dual_loop_param_t> Loop8Test9Param_lbd;
173 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Loop8Test9Param_lbd);
174 
175 #define OPCHECK(a, b)                                                          \
176   do {                                                                         \
177     ACMRandom rnd(ACMRandom::DeterministicSeed());                             \
178     const int count_test_block = number_of_iterations;                         \
179     const int32_t p = kNumCoeffs / 32;                                         \
180     DECLARE_ALIGNED(b, a, s[kNumCoeffs]);                                      \
181     DECLARE_ALIGNED(b, a, ref_s[kNumCoeffs]);                                  \
182     int err_count_total = 0;                                                   \
183     int first_failure = -1;                                                    \
184     for (int i = 0; i < count_test_block; ++i) {                               \
185       int err_count = 0;                                                       \
186       uint8_t tmp = GetOuterThresh(&rnd);                                      \
187       DECLARE_ALIGNED(16, const uint8_t, blimit[16]) = { tmp, tmp, tmp, tmp,   \
188                                                          tmp, tmp, tmp, tmp,   \
189                                                          tmp, tmp, tmp, tmp,   \
190                                                          tmp, tmp, tmp, tmp }; \
191       tmp = GetInnerThresh(&rnd);                                              \
192       DECLARE_ALIGNED(16, const uint8_t,                                       \
193                       limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,   \
194                                      tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
195       tmp = GetHevThresh(&rnd);                                                \
196       DECLARE_ALIGNED(16, const uint8_t, thresh[16]) = { tmp, tmp, tmp, tmp,   \
197                                                          tmp, tmp, tmp, tmp,   \
198                                                          tmp, tmp, tmp, tmp,   \
199                                                          tmp, tmp, tmp, tmp }; \
200       InitInput<a, b>(s, ref_s, &rnd, *limit, mask_, p, i);                    \
201       call_filter(ref_s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_,     \
202                   ref_loopfilter_op_);                                         \
203       API_REGISTER_STATE_CHECK(call_filter(s + 8 + p * 8, p, blimit, limit,    \
204                                            thresh, bit_depth_,                 \
205                                            loopfilter_op_));                   \
206       for (int j = 0; j < kNumCoeffs; ++j) {                                   \
207         err_count += ref_s[j] != s[j];                                         \
208       }                                                                        \
209       if (err_count && !err_count_total) {                                     \
210         first_failure = i;                                                     \
211       }                                                                        \
212       err_count_total += err_count;                                            \
213     }                                                                          \
214     EXPECT_EQ(0, err_count_total)                                              \
215         << "Error: Loop8Test6Param, C output doesn't match SIMD "              \
216            "loopfilter output. "                                               \
217         << "First failed at test case " << first_failure;                      \
218   } while (false)
219 
220 #if CONFIG_AV1_HIGHBITDEPTH
TEST_P(Loop8Test6Param_hbd,OperationCheck)221 TEST_P(Loop8Test6Param_hbd, OperationCheck) { OPCHECK(uint16_t, 16); }
222 #endif
TEST_P(Loop8Test6Param_lbd,OperationCheck)223 TEST_P(Loop8Test6Param_lbd, OperationCheck) { OPCHECK(uint8_t, 8); }
224 
225 #define VALCHECK(a, b)                                                         \
226   do {                                                                         \
227     ACMRandom rnd(ACMRandom::DeterministicSeed());                             \
228     const int count_test_block = number_of_iterations;                         \
229     DECLARE_ALIGNED(b, a, s[kNumCoeffs]);                                      \
230     DECLARE_ALIGNED(b, a, ref_s[kNumCoeffs]);                                  \
231     int err_count_total = 0;                                                   \
232     int first_failure = -1;                                                    \
233     for (int i = 0; i < count_test_block; ++i) {                               \
234       int err_count = 0;                                                       \
235       uint8_t tmp = GetOuterThresh(&rnd);                                      \
236       DECLARE_ALIGNED(16, const uint8_t, blimit[16]) = { tmp, tmp, tmp, tmp,   \
237                                                          tmp, tmp, tmp, tmp,   \
238                                                          tmp, tmp, tmp, tmp,   \
239                                                          tmp, tmp, tmp, tmp }; \
240       tmp = GetInnerThresh(&rnd);                                              \
241       DECLARE_ALIGNED(16, const uint8_t,                                       \
242                       limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,   \
243                                      tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
244       tmp = GetHevThresh(&rnd);                                                \
245       DECLARE_ALIGNED(16, const uint8_t, thresh[16]) = { tmp, tmp, tmp, tmp,   \
246                                                          tmp, tmp, tmp, tmp,   \
247                                                          tmp, tmp, tmp, tmp,   \
248                                                          tmp, tmp, tmp, tmp }; \
249       int32_t p = kNumCoeffs / 32;                                             \
250       for (int j = 0; j < kNumCoeffs; ++j) {                                   \
251         s[j] = rnd.Rand16() & mask_;                                           \
252         ref_s[j] = s[j];                                                       \
253       }                                                                        \
254       call_filter(ref_s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_,     \
255                   ref_loopfilter_op_);                                         \
256       API_REGISTER_STATE_CHECK(call_filter(s + 8 + p * 8, p, blimit, limit,    \
257                                            thresh, bit_depth_,                 \
258                                            loopfilter_op_));                   \
259       for (int j = 0; j < kNumCoeffs; ++j) {                                   \
260         err_count += ref_s[j] != s[j];                                         \
261       }                                                                        \
262       if (err_count && !err_count_total) {                                     \
263         first_failure = i;                                                     \
264       }                                                                        \
265       err_count_total += err_count;                                            \
266     }                                                                          \
267     EXPECT_EQ(0, err_count_total)                                              \
268         << "Error: Loop8Test6Param, C output doesn't match SIMD "              \
269            "loopfilter output. "                                               \
270         << "First failed at test case " << first_failure;                      \
271   } while (false)
272 
273 #if CONFIG_AV1_HIGHBITDEPTH
TEST_P(Loop8Test6Param_hbd,ValueCheck)274 TEST_P(Loop8Test6Param_hbd, ValueCheck) { VALCHECK(uint16_t, 16); }
275 #endif
TEST_P(Loop8Test6Param_lbd,ValueCheck)276 TEST_P(Loop8Test6Param_lbd, ValueCheck) { VALCHECK(uint8_t, 8); }
277 
278 #define SPEEDCHECK(a, b)                                                      \
279   do {                                                                        \
280     ACMRandom rnd(ACMRandom::DeterministicSeed());                            \
281     const int count_test_block = kSpeedTestNum;                               \
282     const int32_t bd = bit_depth_;                                            \
283     DECLARE_ALIGNED(b, a, s[kNumCoeffs]);                                     \
284     uint8_t tmp = GetOuterThresh(&rnd);                                       \
285     DECLARE_ALIGNED(16, const uint8_t,                                        \
286                     blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,   \
287                                     tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
288     tmp = GetInnerThresh(&rnd);                                               \
289     DECLARE_ALIGNED(16, const uint8_t,                                        \
290                     limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,    \
291                                    tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };  \
292     tmp = GetHevThresh(&rnd);                                                 \
293     DECLARE_ALIGNED(16, const uint8_t,                                        \
294                     thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,   \
295                                     tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
296     int32_t p = kNumCoeffs / 32;                                              \
297     for (int j = 0; j < kNumCoeffs; ++j) {                                    \
298       s[j] = rnd.Rand16() & mask_;                                            \
299     }                                                                         \
300     for (int i = 0; i < count_test_block; ++i) {                              \
301       call_filter(s + 8 + p * 8, p, blimit, limit, thresh, bd,                \
302                   loopfilter_op_);                                            \
303     }                                                                         \
304   } while (false)
305 
306 #if CONFIG_AV1_HIGHBITDEPTH
TEST_P(Loop8Test6Param_hbd,DISABLED_Speed)307 TEST_P(Loop8Test6Param_hbd, DISABLED_Speed) { SPEEDCHECK(uint16_t, 16); }
308 #endif
TEST_P(Loop8Test6Param_lbd,DISABLED_Speed)309 TEST_P(Loop8Test6Param_lbd, DISABLED_Speed) { SPEEDCHECK(uint8_t, 8); }
310 
311 #define OPCHECKd(a, b)                                                         \
312   do {                                                                         \
313     ACMRandom rnd(ACMRandom::DeterministicSeed());                             \
314     const int count_test_block = number_of_iterations;                         \
315     DECLARE_ALIGNED(b, a, s[kNumCoeffs]);                                      \
316     DECLARE_ALIGNED(b, a, ref_s[kNumCoeffs]);                                  \
317     int err_count_total = 0;                                                   \
318     int first_failure = -1;                                                    \
319     for (int i = 0; i < count_test_block; ++i) {                               \
320       int err_count = 0;                                                       \
321       uint8_t tmp = GetOuterThresh(&rnd);                                      \
322       DECLARE_ALIGNED(                                                         \
323           16, const uint8_t, blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp,    \
324                                               tmp, tmp, tmp, tmp, tmp, tmp,    \
325                                               tmp, tmp, tmp, tmp };            \
326       tmp = GetInnerThresh(&rnd);                                              \
327       DECLARE_ALIGNED(16, const uint8_t, limit0[16]) = { tmp, tmp, tmp, tmp,   \
328                                                          tmp, tmp, tmp, tmp,   \
329                                                          tmp, tmp, tmp, tmp,   \
330                                                          tmp, tmp, tmp, tmp }; \
331       tmp = GetHevThresh(&rnd);                                                \
332       DECLARE_ALIGNED(                                                         \
333           16, const uint8_t, thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp,    \
334                                               tmp, tmp, tmp, tmp, tmp, tmp,    \
335                                               tmp, tmp, tmp, tmp };            \
336       tmp = GetOuterThresh(&rnd);                                              \
337       DECLARE_ALIGNED(                                                         \
338           16, const uint8_t, blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp,    \
339                                               tmp, tmp, tmp, tmp, tmp, tmp,    \
340                                               tmp, tmp, tmp, tmp };            \
341       tmp = GetInnerThresh(&rnd);                                              \
342       DECLARE_ALIGNED(16, const uint8_t, limit1[16]) = { tmp, tmp, tmp, tmp,   \
343                                                          tmp, tmp, tmp, tmp,   \
344                                                          tmp, tmp, tmp, tmp,   \
345                                                          tmp, tmp, tmp, tmp }; \
346       tmp = GetHevThresh(&rnd);                                                \
347       DECLARE_ALIGNED(                                                         \
348           16, const uint8_t, thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp,    \
349                                               tmp, tmp, tmp, tmp, tmp, tmp,    \
350                                               tmp, tmp, tmp, tmp };            \
351       int32_t p = kNumCoeffs / 32;                                             \
352       const uint8_t limit = *limit0 < *limit1 ? *limit0 : *limit1;             \
353       InitInput<a, b>(s, ref_s, &rnd, limit, mask_, p, i);                     \
354       call_dualfilter(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1, \
355                       limit1, thresh1, bit_depth_, ref_loopfilter_op_);        \
356       API_REGISTER_STATE_CHECK(                                                \
357           call_dualfilter(s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1, \
358                           limit1, thresh1, bit_depth_, loopfilter_op_));       \
359       for (int j = 0; j < kNumCoeffs; ++j) {                                   \
360         err_count += ref_s[j] != s[j];                                         \
361       }                                                                        \
362       if (err_count && !err_count_total) {                                     \
363         first_failure = i;                                                     \
364       }                                                                        \
365       err_count_total += err_count;                                            \
366     }                                                                          \
367     EXPECT_EQ(0, err_count_total)                                              \
368         << "Error: Loop8Test9Param, C output doesn't match SIMD "              \
369            "loopfilter output. "                                               \
370         << "First failed at test case " << first_failure;                      \
371   } while (false)
372 
373 #if CONFIG_AV1_HIGHBITDEPTH
TEST_P(Loop8Test9Param_hbd,OperationCheck)374 TEST_P(Loop8Test9Param_hbd, OperationCheck) { OPCHECKd(uint16_t, 16); }
375 #endif
TEST_P(Loop8Test9Param_lbd,OperationCheck)376 TEST_P(Loop8Test9Param_lbd, OperationCheck) { OPCHECKd(uint8_t, 8); }
377 
378 #define VALCHECKd(a, b)                                                        \
379   do {                                                                         \
380     ACMRandom rnd(ACMRandom::DeterministicSeed());                             \
381     const int count_test_block = number_of_iterations;                         \
382     DECLARE_ALIGNED(b, a, s[kNumCoeffs]);                                      \
383     DECLARE_ALIGNED(b, a, ref_s[kNumCoeffs]);                                  \
384     int err_count_total = 0;                                                   \
385     int first_failure = -1;                                                    \
386     for (int i = 0; i < count_test_block; ++i) {                               \
387       int err_count = 0;                                                       \
388       uint8_t tmp = GetOuterThresh(&rnd);                                      \
389       DECLARE_ALIGNED(                                                         \
390           16, const uint8_t, blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp,    \
391                                               tmp, tmp, tmp, tmp, tmp, tmp,    \
392                                               tmp, tmp, tmp, tmp };            \
393       tmp = GetInnerThresh(&rnd);                                              \
394       DECLARE_ALIGNED(16, const uint8_t, limit0[16]) = { tmp, tmp, tmp, tmp,   \
395                                                          tmp, tmp, tmp, tmp,   \
396                                                          tmp, tmp, tmp, tmp,   \
397                                                          tmp, tmp, tmp, tmp }; \
398       tmp = GetHevThresh(&rnd);                                                \
399       DECLARE_ALIGNED(                                                         \
400           16, const uint8_t, thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp,    \
401                                               tmp, tmp, tmp, tmp, tmp, tmp,    \
402                                               tmp, tmp, tmp, tmp };            \
403       tmp = GetOuterThresh(&rnd);                                              \
404       DECLARE_ALIGNED(                                                         \
405           16, const uint8_t, blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp,    \
406                                               tmp, tmp, tmp, tmp, tmp, tmp,    \
407                                               tmp, tmp, tmp, tmp };            \
408       tmp = GetInnerThresh(&rnd);                                              \
409       DECLARE_ALIGNED(16, const uint8_t, limit1[16]) = { tmp, tmp, tmp, tmp,   \
410                                                          tmp, tmp, tmp, tmp,   \
411                                                          tmp, tmp, tmp, tmp,   \
412                                                          tmp, tmp, tmp, tmp }; \
413       tmp = GetHevThresh(&rnd);                                                \
414       DECLARE_ALIGNED(                                                         \
415           16, const uint8_t, thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp,    \
416                                               tmp, tmp, tmp, tmp, tmp, tmp,    \
417                                               tmp, tmp, tmp, tmp };            \
418       int32_t p = kNumCoeffs / 32;                                             \
419       for (int j = 0; j < kNumCoeffs; ++j) {                                   \
420         s[j] = rnd.Rand16() & mask_;                                           \
421         ref_s[j] = s[j];                                                       \
422       }                                                                        \
423       call_dualfilter(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1, \
424                       limit1, thresh1, bit_depth_, ref_loopfilter_op_);        \
425       API_REGISTER_STATE_CHECK(                                                \
426           call_dualfilter(s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1, \
427                           limit1, thresh1, bit_depth_, loopfilter_op_));       \
428       for (int j = 0; j < kNumCoeffs; ++j) {                                   \
429         err_count += ref_s[j] != s[j];                                         \
430       }                                                                        \
431       if (err_count && !err_count_total) {                                     \
432         first_failure = i;                                                     \
433       }                                                                        \
434       err_count_total += err_count;                                            \
435     }                                                                          \
436     EXPECT_EQ(0, err_count_total)                                              \
437         << "Error: Loop8Test9Param, C output doesn't match SIMD "              \
438            "loopfilter output. "                                               \
439         << "First failed at test case " << first_failure;                      \
440   } while (false)
441 
442 #if CONFIG_AV1_HIGHBITDEPTH
TEST_P(Loop8Test9Param_hbd,ValueCheck)443 TEST_P(Loop8Test9Param_hbd, ValueCheck) { VALCHECKd(uint16_t, 16); }
444 #endif
TEST_P(Loop8Test9Param_lbd,ValueCheck)445 TEST_P(Loop8Test9Param_lbd, ValueCheck) { VALCHECKd(uint8_t, 8); }
446 
447 #define SPEEDCHECKd(a, b)                                                      \
448   do {                                                                         \
449     ACMRandom rnd(ACMRandom::DeterministicSeed());                             \
450     const int count_test_block = kSpeedTestNum;                                \
451     DECLARE_ALIGNED(b, a, s[kNumCoeffs]);                                      \
452     uint8_t tmp = GetOuterThresh(&rnd);                                        \
453     DECLARE_ALIGNED(16, const uint8_t,                                         \
454                     blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,   \
455                                      tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
456     tmp = GetInnerThresh(&rnd);                                                \
457     DECLARE_ALIGNED(16, const uint8_t,                                         \
458                     limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,    \
459                                     tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };  \
460     tmp = GetHevThresh(&rnd);                                                  \
461     DECLARE_ALIGNED(16, const uint8_t,                                         \
462                     thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,   \
463                                      tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
464     tmp = GetOuterThresh(&rnd);                                                \
465     DECLARE_ALIGNED(16, const uint8_t,                                         \
466                     blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,   \
467                                      tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
468     tmp = GetInnerThresh(&rnd);                                                \
469     DECLARE_ALIGNED(16, const uint8_t,                                         \
470                     limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,    \
471                                     tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };  \
472     tmp = GetHevThresh(&rnd);                                                  \
473     DECLARE_ALIGNED(16, const uint8_t,                                         \
474                     thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,   \
475                                      tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
476     int32_t p = kNumCoeffs / 32;                                               \
477     for (int j = 0; j < kNumCoeffs; ++j) {                                     \
478       s[j] = rnd.Rand16() & mask_;                                             \
479     }                                                                          \
480     for (int i = 0; i < count_test_block; ++i) {                               \
481       call_dualfilter(s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1,     \
482                       limit1, thresh1, bit_depth_, loopfilter_op_);            \
483     }                                                                          \
484   } while (false)
485 
486 #if CONFIG_AV1_HIGHBITDEPTH
TEST_P(Loop8Test9Param_hbd,DISABLED_Speed)487 TEST_P(Loop8Test9Param_hbd, DISABLED_Speed) { SPEEDCHECKd(uint16_t, 16); }
488 #endif
TEST_P(Loop8Test9Param_lbd,DISABLED_Speed)489 TEST_P(Loop8Test9Param_lbd, DISABLED_Speed) { SPEEDCHECKd(uint8_t, 8); }
490 
491 using std::make_tuple;
492 
493 #if HAVE_SSE2
494 #if CONFIG_AV1_HIGHBITDEPTH
495 const hbdloop_param_t kHbdLoop8Test6[] = {
496   make_tuple(&aom_highbd_lpf_horizontal_4_sse2, &aom_highbd_lpf_horizontal_4_c,
497              8),
498   make_tuple(&aom_highbd_lpf_vertical_4_sse2, &aom_highbd_lpf_vertical_4_c, 8),
499   make_tuple(&aom_highbd_lpf_horizontal_6_sse2, &aom_highbd_lpf_horizontal_6_c,
500              8),
501   make_tuple(&aom_highbd_lpf_horizontal_8_sse2, &aom_highbd_lpf_horizontal_8_c,
502              8),
503   make_tuple(&aom_highbd_lpf_horizontal_14_sse2,
504              &aom_highbd_lpf_horizontal_14_c, 8),
505   make_tuple(&aom_highbd_lpf_vertical_6_sse2, &aom_highbd_lpf_vertical_6_c, 8),
506   make_tuple(&aom_highbd_lpf_vertical_8_sse2, &aom_highbd_lpf_vertical_8_c, 8),
507 
508   make_tuple(&aom_highbd_lpf_vertical_14_sse2, &aom_highbd_lpf_vertical_14_c,
509              8),
510   make_tuple(&aom_highbd_lpf_horizontal_4_sse2, &aom_highbd_lpf_horizontal_4_c,
511              10),
512   make_tuple(&aom_highbd_lpf_vertical_4_sse2, &aom_highbd_lpf_vertical_4_c, 10),
513   make_tuple(&aom_highbd_lpf_horizontal_6_sse2, &aom_highbd_lpf_horizontal_6_c,
514              10),
515   make_tuple(&aom_highbd_lpf_horizontal_8_sse2, &aom_highbd_lpf_horizontal_8_c,
516              10),
517   make_tuple(&aom_highbd_lpf_horizontal_14_sse2,
518              &aom_highbd_lpf_horizontal_14_c, 10),
519   make_tuple(&aom_highbd_lpf_vertical_6_sse2, &aom_highbd_lpf_vertical_6_c, 10),
520   make_tuple(&aom_highbd_lpf_vertical_8_sse2, &aom_highbd_lpf_vertical_8_c, 10),
521   make_tuple(&aom_highbd_lpf_vertical_14_sse2, &aom_highbd_lpf_vertical_14_c,
522              10),
523   make_tuple(&aom_highbd_lpf_horizontal_4_sse2, &aom_highbd_lpf_horizontal_4_c,
524              12),
525   make_tuple(&aom_highbd_lpf_vertical_4_sse2, &aom_highbd_lpf_vertical_4_c, 12),
526   make_tuple(&aom_highbd_lpf_horizontal_6_sse2, &aom_highbd_lpf_horizontal_6_c,
527              12),
528   make_tuple(&aom_highbd_lpf_horizontal_8_sse2, &aom_highbd_lpf_horizontal_8_c,
529              12),
530   make_tuple(&aom_highbd_lpf_horizontal_14_sse2,
531              &aom_highbd_lpf_horizontal_14_c, 12),
532   make_tuple(&aom_highbd_lpf_vertical_14_sse2, &aom_highbd_lpf_vertical_14_c,
533              12),
534   make_tuple(&aom_highbd_lpf_vertical_6_sse2, &aom_highbd_lpf_vertical_6_c, 12),
535   make_tuple(&aom_highbd_lpf_vertical_8_sse2, &aom_highbd_lpf_vertical_8_c, 12)
536 };
537 
538 INSTANTIATE_TEST_SUITE_P(SSE2, Loop8Test6Param_hbd,
539                          ::testing::ValuesIn(kHbdLoop8Test6));
540 #endif  // CONFIG_AV1_HIGHBITDEPTH
541 
542 const loop_param_t kLoop8Test6[] = {
543   make_tuple(&aom_lpf_horizontal_4_sse2, &aom_lpf_horizontal_4_c, 8),
544   make_tuple(&aom_lpf_horizontal_8_sse2, &aom_lpf_horizontal_8_c, 8),
545   make_tuple(&aom_lpf_horizontal_6_sse2, &aom_lpf_horizontal_6_c, 8),
546   make_tuple(&aom_lpf_vertical_6_sse2, &aom_lpf_vertical_6_c, 8),
547   make_tuple(&aom_lpf_horizontal_14_sse2, &aom_lpf_horizontal_14_c, 8),
548   make_tuple(&aom_lpf_vertical_4_sse2, &aom_lpf_vertical_4_c, 8),
549   make_tuple(&aom_lpf_vertical_8_sse2, &aom_lpf_vertical_8_c, 8),
550   make_tuple(&aom_lpf_vertical_14_sse2, &aom_lpf_vertical_14_c, 8),
551   make_tuple(&aom_lpf_horizontal_4_quad_sse2, &aom_lpf_horizontal_4_quad_c, 8),
552   make_tuple(&aom_lpf_vertical_4_quad_sse2, &aom_lpf_vertical_4_quad_c, 8),
553   make_tuple(&aom_lpf_horizontal_6_quad_sse2, &aom_lpf_horizontal_6_quad_c, 8),
554   make_tuple(&aom_lpf_vertical_6_quad_sse2, &aom_lpf_vertical_6_quad_c, 8),
555   make_tuple(&aom_lpf_horizontal_8_quad_sse2, &aom_lpf_horizontal_8_quad_c, 8),
556   make_tuple(&aom_lpf_vertical_8_quad_sse2, &aom_lpf_vertical_8_quad_c, 8),
557   make_tuple(&aom_lpf_horizontal_14_quad_sse2, &aom_lpf_horizontal_14_quad_c,
558              8),
559   make_tuple(&aom_lpf_vertical_14_quad_sse2, &aom_lpf_vertical_14_quad_c, 8)
560 };
561 
562 INSTANTIATE_TEST_SUITE_P(SSE2, Loop8Test6Param_lbd,
563                          ::testing::ValuesIn(kLoop8Test6));
564 
565 const dual_loop_param_t kLoop8Test9[] = {
566   make_tuple(&aom_lpf_horizontal_4_dual_sse2, &aom_lpf_horizontal_4_dual_c, 8),
567   make_tuple(&aom_lpf_vertical_4_dual_sse2, &aom_lpf_vertical_4_dual_c, 8),
568   make_tuple(&aom_lpf_horizontal_6_dual_sse2, &aom_lpf_horizontal_6_dual_c, 8),
569   make_tuple(&aom_lpf_vertical_6_dual_sse2, &aom_lpf_vertical_6_dual_c, 8),
570   make_tuple(&aom_lpf_horizontal_8_dual_sse2, &aom_lpf_horizontal_8_dual_c, 8),
571   make_tuple(&aom_lpf_vertical_8_dual_sse2, &aom_lpf_vertical_8_dual_c, 8),
572   make_tuple(&aom_lpf_horizontal_14_dual_sse2, &aom_lpf_horizontal_14_dual_c,
573              8),
574   make_tuple(&aom_lpf_vertical_14_dual_sse2, &aom_lpf_vertical_14_dual_c, 8)
575 };
576 
577 INSTANTIATE_TEST_SUITE_P(SSE2, Loop8Test9Param_lbd,
578                          ::testing::ValuesIn(kLoop8Test9));
579 
580 #endif  // HAVE_SSE2
581 
582 #if HAVE_AVX2
583 const loop_param_t kLoop8Test6Avx2[] = {
584   make_tuple(&aom_lpf_horizontal_6_quad_avx2, &aom_lpf_horizontal_6_quad_c, 8),
585   make_tuple(&aom_lpf_horizontal_8_quad_avx2, &aom_lpf_horizontal_8_quad_c, 8),
586   make_tuple(&aom_lpf_horizontal_14_quad_avx2, &aom_lpf_horizontal_14_quad_c,
587              8),
588   make_tuple(&aom_lpf_vertical_14_quad_avx2, &aom_lpf_vertical_14_quad_c, 8),
589 };
590 
591 INSTANTIATE_TEST_SUITE_P(AVX2, Loop8Test6Param_lbd,
592                          ::testing::ValuesIn(kLoop8Test6Avx2));
593 #endif
594 
595 #if HAVE_SSE2 && CONFIG_AV1_HIGHBITDEPTH
596 const hbddual_loop_param_t kHbdLoop8Test9[] = {
597   make_tuple(&aom_highbd_lpf_horizontal_4_dual_sse2,
598              &aom_highbd_lpf_horizontal_4_dual_c, 8),
599   make_tuple(&aom_highbd_lpf_horizontal_6_dual_sse2,
600              &aom_highbd_lpf_horizontal_6_dual_c, 8),
601   make_tuple(&aom_highbd_lpf_horizontal_8_dual_sse2,
602              &aom_highbd_lpf_horizontal_8_dual_c, 8),
603   make_tuple(&aom_highbd_lpf_horizontal_14_dual_sse2,
604              &aom_highbd_lpf_horizontal_14_dual_c, 8),
605   make_tuple(&aom_highbd_lpf_vertical_4_dual_sse2,
606              &aom_highbd_lpf_vertical_4_dual_c, 8),
607   make_tuple(&aom_highbd_lpf_vertical_6_dual_sse2,
608              &aom_highbd_lpf_vertical_6_dual_c, 8),
609   make_tuple(&aom_highbd_lpf_vertical_8_dual_sse2,
610              &aom_highbd_lpf_vertical_8_dual_c, 8),
611   make_tuple(&aom_highbd_lpf_vertical_14_dual_sse2,
612              &aom_highbd_lpf_vertical_14_dual_c, 8),
613   make_tuple(&aom_highbd_lpf_horizontal_4_dual_sse2,
614              &aom_highbd_lpf_horizontal_4_dual_c, 10),
615   make_tuple(&aom_highbd_lpf_horizontal_6_dual_sse2,
616              &aom_highbd_lpf_horizontal_6_dual_c, 10),
617   make_tuple(&aom_highbd_lpf_horizontal_8_dual_sse2,
618              &aom_highbd_lpf_horizontal_8_dual_c, 10),
619   make_tuple(&aom_highbd_lpf_horizontal_14_dual_sse2,
620              &aom_highbd_lpf_horizontal_14_dual_c, 10),
621   make_tuple(&aom_highbd_lpf_vertical_4_dual_sse2,
622              &aom_highbd_lpf_vertical_4_dual_c, 10),
623   make_tuple(&aom_highbd_lpf_vertical_6_dual_sse2,
624              &aom_highbd_lpf_vertical_6_dual_c, 10),
625   make_tuple(&aom_highbd_lpf_vertical_8_dual_sse2,
626              &aom_highbd_lpf_vertical_8_dual_c, 10),
627   make_tuple(&aom_highbd_lpf_vertical_14_dual_sse2,
628              &aom_highbd_lpf_vertical_14_dual_c, 10),
629   make_tuple(&aom_highbd_lpf_horizontal_4_dual_sse2,
630              &aom_highbd_lpf_horizontal_4_dual_c, 12),
631   make_tuple(&aom_highbd_lpf_horizontal_6_dual_sse2,
632              &aom_highbd_lpf_horizontal_6_dual_c, 12),
633   make_tuple(&aom_highbd_lpf_horizontal_8_dual_sse2,
634              &aom_highbd_lpf_horizontal_8_dual_c, 12),
635   make_tuple(&aom_highbd_lpf_horizontal_14_dual_sse2,
636              &aom_highbd_lpf_horizontal_14_dual_c, 12),
637   make_tuple(&aom_highbd_lpf_vertical_4_dual_sse2,
638              &aom_highbd_lpf_vertical_4_dual_c, 12),
639   make_tuple(&aom_highbd_lpf_vertical_6_dual_sse2,
640              &aom_highbd_lpf_vertical_6_dual_c, 12),
641   make_tuple(&aom_highbd_lpf_vertical_8_dual_sse2,
642              &aom_highbd_lpf_vertical_8_dual_c, 12),
643   make_tuple(&aom_highbd_lpf_vertical_14_dual_sse2,
644              &aom_highbd_lpf_vertical_14_dual_c, 12),
645 };
646 
647 INSTANTIATE_TEST_SUITE_P(SSE2, Loop8Test9Param_hbd,
648                          ::testing::ValuesIn(kHbdLoop8Test9));
649 
650 #endif  // HAVE_SSE2 && CONFIG_AV1_HIGHBITDEPTH
651 
652 #if HAVE_NEON
653 const loop_param_t kLoop8Test6[] = {
654   make_tuple(&aom_lpf_vertical_14_neon, &aom_lpf_vertical_14_c, 8),
655   make_tuple(&aom_lpf_vertical_8_neon, &aom_lpf_vertical_8_c, 8),
656   make_tuple(&aom_lpf_vertical_6_neon, &aom_lpf_vertical_6_c, 8),
657   make_tuple(&aom_lpf_vertical_4_neon, &aom_lpf_vertical_4_c, 8),
658   make_tuple(&aom_lpf_horizontal_14_neon, &aom_lpf_horizontal_14_c, 8),
659   make_tuple(&aom_lpf_horizontal_8_neon, &aom_lpf_horizontal_8_c, 8),
660   make_tuple(&aom_lpf_horizontal_6_neon, &aom_lpf_horizontal_6_c, 8),
661   make_tuple(&aom_lpf_horizontal_4_neon, &aom_lpf_horizontal_4_c, 8),
662   make_tuple(&aom_lpf_horizontal_4_quad_neon, &aom_lpf_horizontal_4_quad_c, 8),
663   make_tuple(&aom_lpf_vertical_4_quad_neon, &aom_lpf_vertical_4_quad_c, 8),
664   make_tuple(&aom_lpf_horizontal_6_quad_neon, &aom_lpf_horizontal_6_quad_c, 8),
665   make_tuple(&aom_lpf_vertical_6_quad_neon, &aom_lpf_vertical_6_quad_c, 8),
666   make_tuple(&aom_lpf_horizontal_8_quad_neon, &aom_lpf_horizontal_8_quad_c, 8),
667   make_tuple(&aom_lpf_vertical_8_quad_neon, &aom_lpf_vertical_8_quad_c, 8),
668   make_tuple(&aom_lpf_horizontal_14_quad_neon, &aom_lpf_horizontal_14_quad_c,
669              8),
670   make_tuple(&aom_lpf_vertical_14_quad_neon, &aom_lpf_vertical_14_quad_c, 8)
671 };
672 
673 INSTANTIATE_TEST_SUITE_P(NEON, Loop8Test6Param_lbd,
674                          ::testing::ValuesIn(kLoop8Test6));
675 
676 const dual_loop_param_t kLoop8Test9[] = {
677   make_tuple(&aom_lpf_horizontal_4_dual_neon, &aom_lpf_horizontal_4_dual_c, 8),
678   make_tuple(&aom_lpf_horizontal_6_dual_neon, &aom_lpf_horizontal_6_dual_c, 8),
679   make_tuple(&aom_lpf_horizontal_8_dual_neon, &aom_lpf_horizontal_8_dual_c, 8),
680   make_tuple(&aom_lpf_horizontal_14_dual_neon, &aom_lpf_horizontal_14_dual_c,
681              8),
682   make_tuple(&aom_lpf_vertical_4_dual_neon, &aom_lpf_vertical_4_dual_c, 8),
683   make_tuple(&aom_lpf_vertical_6_dual_neon, &aom_lpf_vertical_6_dual_c, 8),
684   make_tuple(&aom_lpf_vertical_8_dual_neon, &aom_lpf_vertical_8_dual_c, 8),
685   make_tuple(&aom_lpf_vertical_14_dual_neon, &aom_lpf_vertical_14_dual_c, 8)
686 };
687 
688 INSTANTIATE_TEST_SUITE_P(NEON, Loop8Test9Param_lbd,
689                          ::testing::ValuesIn(kLoop8Test9));
690 #if CONFIG_AV1_HIGHBITDEPTH
691 const hbdloop_param_t kHbdLoop8Test6[] = {
692   make_tuple(&aom_highbd_lpf_horizontal_4_neon, &aom_highbd_lpf_horizontal_4_c,
693              8),
694   make_tuple(&aom_highbd_lpf_horizontal_4_neon, &aom_highbd_lpf_horizontal_4_c,
695              10),
696   make_tuple(&aom_highbd_lpf_horizontal_4_neon, &aom_highbd_lpf_horizontal_4_c,
697              12),
698   make_tuple(&aom_highbd_lpf_horizontal_6_neon, &aom_highbd_lpf_horizontal_6_c,
699              8),
700   make_tuple(&aom_highbd_lpf_horizontal_6_neon, &aom_highbd_lpf_horizontal_6_c,
701              10),
702   make_tuple(&aom_highbd_lpf_horizontal_6_neon, &aom_highbd_lpf_horizontal_6_c,
703              12),
704   make_tuple(&aom_highbd_lpf_horizontal_8_neon, &aom_highbd_lpf_horizontal_8_c,
705              8),
706   make_tuple(&aom_highbd_lpf_horizontal_8_neon, &aom_highbd_lpf_horizontal_8_c,
707              10),
708   make_tuple(&aom_highbd_lpf_horizontal_8_neon, &aom_highbd_lpf_horizontal_8_c,
709              12),
710   make_tuple(&aom_highbd_lpf_horizontal_14_neon,
711              &aom_highbd_lpf_horizontal_14_c, 8),
712   make_tuple(&aom_highbd_lpf_horizontal_14_neon,
713              &aom_highbd_lpf_horizontal_14_c, 10),
714   make_tuple(&aom_highbd_lpf_horizontal_14_neon,
715              &aom_highbd_lpf_horizontal_14_c, 12),
716   make_tuple(&aom_highbd_lpf_vertical_4_neon, &aom_highbd_lpf_vertical_4_c, 8),
717   make_tuple(&aom_highbd_lpf_vertical_4_neon, &aom_highbd_lpf_vertical_4_c, 10),
718   make_tuple(&aom_highbd_lpf_vertical_4_neon, &aom_highbd_lpf_vertical_4_c, 12),
719   make_tuple(&aom_highbd_lpf_vertical_6_neon, &aom_highbd_lpf_vertical_6_c, 8),
720   make_tuple(&aom_highbd_lpf_vertical_6_neon, &aom_highbd_lpf_vertical_6_c, 10),
721   make_tuple(&aom_highbd_lpf_vertical_6_neon, &aom_highbd_lpf_vertical_6_c, 12),
722   make_tuple(&aom_highbd_lpf_vertical_8_neon, &aom_highbd_lpf_vertical_8_c, 8),
723   make_tuple(&aom_highbd_lpf_vertical_8_neon, &aom_highbd_lpf_vertical_8_c, 10),
724   make_tuple(&aom_highbd_lpf_vertical_8_neon, &aom_highbd_lpf_vertical_8_c, 12),
725   make_tuple(&aom_highbd_lpf_vertical_14_neon, &aom_highbd_lpf_vertical_14_c,
726              8),
727   make_tuple(&aom_highbd_lpf_vertical_14_neon, &aom_highbd_lpf_vertical_14_c,
728              10),
729   make_tuple(&aom_highbd_lpf_vertical_14_neon, &aom_highbd_lpf_vertical_14_c,
730              12),
731 };
732 
733 INSTANTIATE_TEST_SUITE_P(NEON, Loop8Test6Param_hbd,
734                          ::testing::ValuesIn(kHbdLoop8Test6));
735 
736 const hbddual_loop_param_t kHbdLoop8Test9[] = {
737   make_tuple(&aom_highbd_lpf_horizontal_4_dual_neon,
738              &aom_highbd_lpf_horizontal_4_dual_c, 8),
739   make_tuple(&aom_highbd_lpf_horizontal_6_dual_neon,
740              &aom_highbd_lpf_horizontal_6_dual_c, 8),
741   make_tuple(&aom_highbd_lpf_horizontal_8_dual_neon,
742              &aom_highbd_lpf_horizontal_8_dual_c, 8),
743   make_tuple(&aom_highbd_lpf_horizontal_14_dual_neon,
744              &aom_highbd_lpf_horizontal_14_dual_c, 8),
745   make_tuple(&aom_highbd_lpf_vertical_4_dual_neon,
746              &aom_highbd_lpf_vertical_4_dual_c, 8),
747   make_tuple(&aom_highbd_lpf_vertical_6_dual_neon,
748              &aom_highbd_lpf_vertical_6_dual_c, 8),
749   make_tuple(&aom_highbd_lpf_vertical_8_dual_neon,
750              &aom_highbd_lpf_vertical_8_dual_c, 8),
751   make_tuple(&aom_highbd_lpf_vertical_14_dual_neon,
752              &aom_highbd_lpf_vertical_14_dual_c, 8),
753   make_tuple(&aom_highbd_lpf_horizontal_4_dual_neon,
754              &aom_highbd_lpf_horizontal_4_dual_c, 10),
755   make_tuple(&aom_highbd_lpf_horizontal_6_dual_neon,
756              &aom_highbd_lpf_horizontal_6_dual_c, 10),
757   make_tuple(&aom_highbd_lpf_horizontal_8_dual_neon,
758              &aom_highbd_lpf_horizontal_8_dual_c, 10),
759   make_tuple(&aom_highbd_lpf_horizontal_14_dual_neon,
760              &aom_highbd_lpf_horizontal_14_dual_c, 10),
761   make_tuple(&aom_highbd_lpf_vertical_4_dual_neon,
762              &aom_highbd_lpf_vertical_4_dual_c, 10),
763   make_tuple(&aom_highbd_lpf_vertical_6_dual_neon,
764              &aom_highbd_lpf_vertical_6_dual_c, 10),
765   make_tuple(&aom_highbd_lpf_vertical_8_dual_neon,
766              &aom_highbd_lpf_vertical_8_dual_c, 10),
767   make_tuple(&aom_highbd_lpf_vertical_14_dual_neon,
768              &aom_highbd_lpf_vertical_14_dual_c, 10),
769   make_tuple(&aom_highbd_lpf_horizontal_4_dual_neon,
770              &aom_highbd_lpf_horizontal_4_dual_c, 12),
771   make_tuple(&aom_highbd_lpf_horizontal_6_dual_neon,
772              &aom_highbd_lpf_horizontal_6_dual_c, 12),
773   make_tuple(&aom_highbd_lpf_horizontal_8_dual_neon,
774              &aom_highbd_lpf_horizontal_8_dual_c, 12),
775   make_tuple(&aom_highbd_lpf_horizontal_14_dual_neon,
776              &aom_highbd_lpf_horizontal_14_dual_c, 12),
777   make_tuple(&aom_highbd_lpf_vertical_4_dual_neon,
778              &aom_highbd_lpf_vertical_4_dual_c, 12),
779   make_tuple(&aom_highbd_lpf_vertical_6_dual_neon,
780              &aom_highbd_lpf_vertical_6_dual_c, 12),
781   make_tuple(&aom_highbd_lpf_vertical_8_dual_neon,
782              &aom_highbd_lpf_vertical_8_dual_c, 12),
783   make_tuple(&aom_highbd_lpf_vertical_14_dual_neon,
784              &aom_highbd_lpf_vertical_14_dual_c, 12),
785 };
786 
787 INSTANTIATE_TEST_SUITE_P(NEON, Loop8Test9Param_hbd,
788                          ::testing::ValuesIn(kHbdLoop8Test9));
789 
790 #endif  // CONFIG_AV1_HIGHBITDEPTH
791 #endif  // HAVE_NEON
792 
793 #if HAVE_AVX2 && CONFIG_AV1_HIGHBITDEPTH
794 const hbddual_loop_param_t kHbdLoop8Test9Avx2[] = {
795   make_tuple(&aom_highbd_lpf_horizontal_4_dual_avx2,
796              &aom_highbd_lpf_horizontal_4_dual_c, 8),
797   make_tuple(&aom_highbd_lpf_horizontal_4_dual_avx2,
798              &aom_highbd_lpf_horizontal_4_dual_c, 10),
799   make_tuple(&aom_highbd_lpf_horizontal_4_dual_avx2,
800              &aom_highbd_lpf_horizontal_4_dual_c, 12),
801   make_tuple(&aom_highbd_lpf_horizontal_8_dual_avx2,
802              &aom_highbd_lpf_horizontal_8_dual_c, 8),
803   make_tuple(&aom_highbd_lpf_horizontal_8_dual_avx2,
804              &aom_highbd_lpf_horizontal_8_dual_c, 10),
805   make_tuple(&aom_highbd_lpf_horizontal_8_dual_avx2,
806              &aom_highbd_lpf_horizontal_8_dual_c, 12),
807   make_tuple(&aom_highbd_lpf_vertical_4_dual_avx2,
808              &aom_highbd_lpf_vertical_4_dual_c, 8),
809   make_tuple(&aom_highbd_lpf_vertical_4_dual_avx2,
810              &aom_highbd_lpf_vertical_4_dual_c, 10),
811   make_tuple(&aom_highbd_lpf_vertical_4_dual_avx2,
812              &aom_highbd_lpf_vertical_4_dual_c, 12),
813   make_tuple(&aom_highbd_lpf_vertical_8_dual_avx2,
814              &aom_highbd_lpf_vertical_8_dual_c, 8),
815   make_tuple(&aom_highbd_lpf_vertical_8_dual_avx2,
816              &aom_highbd_lpf_vertical_8_dual_c, 10),
817   make_tuple(&aom_highbd_lpf_vertical_8_dual_avx2,
818              &aom_highbd_lpf_vertical_8_dual_c, 12),
819 };
820 
821 INSTANTIATE_TEST_SUITE_P(AVX2, Loop8Test9Param_hbd,
822                          ::testing::ValuesIn(kHbdLoop8Test9Avx2));
823 #endif
824 }  // namespace
825