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