]> granicus.if.org Git - libvpx/blob - test/lpf_8_test.cc
Merge "endian_inl.h: fix mips32 android build"
[libvpx] / test / lpf_8_test.cc
1 /*
2  *  Copyright (c) 2014 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11 #include <cmath>
12 #include <cstdlib>
13 #include <string>
14
15 #include "third_party/googletest/src/include/gtest/gtest.h"
16
17 #include "./vpx_config.h"
18 #include "./vpx_dsp_rtcd.h"
19 #include "test/acm_random.h"
20 #include "test/clear_system_state.h"
21 #include "test/register_state_check.h"
22 #include "test/util.h"
23 #include "vp9/common/vp9_entropy.h"
24 #include "vp9/common/vp9_loopfilter.h"
25 #include "vpx/vpx_integer.h"
26
27 using libvpx_test::ACMRandom;
28
29 namespace {
30 // Horizontally and Vertically need 32x32: 8  Coeffs preceeding filtered section
31 //                                         16 Coefs within filtered section
32 //                                         8  Coeffs following filtered section
33 const int kNumCoeffs = 1024;
34
35 const int number_of_iterations = 10000;
36
37 #if CONFIG_VP9_HIGHBITDEPTH
38 typedef void (*loop_op_t)(uint16_t *s, int p, const uint8_t *blimit,
39                           const uint8_t *limit, const uint8_t *thresh,
40                           int count, int bd);
41 typedef void (*dual_loop_op_t)(uint16_t *s, int p, const uint8_t *blimit0,
42                                const uint8_t *limit0, const uint8_t *thresh0,
43                                const uint8_t *blimit1, const uint8_t *limit1,
44                                const uint8_t *thresh1, int bd);
45 #else
46 typedef void (*loop_op_t)(uint8_t *s, int p, const uint8_t *blimit,
47                           const uint8_t *limit, const uint8_t *thresh,
48                           int count);
49 typedef void (*dual_loop_op_t)(uint8_t *s, int p, const uint8_t *blimit0,
50                                const uint8_t *limit0, const uint8_t *thresh0,
51                                const uint8_t *blimit1, const uint8_t *limit1,
52                                const uint8_t *thresh1);
53 #endif  // CONFIG_VP9_HIGHBITDEPTH
54
55 typedef std::tr1::tuple<loop_op_t, loop_op_t, int, int> loop8_param_t;
56 typedef std::tr1::tuple<dual_loop_op_t, dual_loop_op_t, int> dualloop8_param_t;
57
58 #if HAVE_SSE2
59 #if CONFIG_VP9_HIGHBITDEPTH
60 void wrapper_vertical_16_sse2(uint16_t *s, int p, const uint8_t *blimit,
61                               const uint8_t *limit, const uint8_t *thresh,
62                               int count, int bd) {
63   vpx_highbd_lpf_vertical_16_sse2(s, p, blimit, limit, thresh, bd);
64 }
65
66 void wrapper_vertical_16_c(uint16_t *s, int p, const uint8_t *blimit,
67                            const uint8_t *limit, const uint8_t *thresh,
68                            int count, int bd) {
69   vpx_highbd_lpf_vertical_16_c(s, p, blimit, limit, thresh, bd);
70 }
71
72 void wrapper_vertical_16_dual_sse2(uint16_t *s, int p, const uint8_t *blimit,
73                                    const uint8_t *limit, const uint8_t *thresh,
74                                    int count, int bd) {
75   vpx_highbd_lpf_vertical_16_dual_sse2(s, p, blimit, limit, thresh, bd);
76 }
77
78 void wrapper_vertical_16_dual_c(uint16_t *s, int p, const uint8_t *blimit,
79                                 const uint8_t *limit, const uint8_t *thresh,
80                                 int count, int bd) {
81   vpx_highbd_lpf_vertical_16_dual_c(s, p, blimit, limit, thresh, bd);
82 }
83 #else
84 void wrapper_vertical_16_sse2(uint8_t *s, int p, const uint8_t *blimit,
85                               const uint8_t *limit, const uint8_t *thresh,
86                               int count) {
87   vpx_lpf_vertical_16_sse2(s, p, blimit, limit, thresh);
88 }
89
90 void wrapper_vertical_16_c(uint8_t *s, int p, const uint8_t *blimit,
91                            const uint8_t *limit, const uint8_t *thresh,
92                            int count) {
93   vpx_lpf_vertical_16_c(s, p, blimit, limit, thresh);
94 }
95
96 void wrapper_vertical_16_dual_sse2(uint8_t *s, int p, const uint8_t *blimit,
97                                    const uint8_t *limit, const uint8_t *thresh,
98                                    int count) {
99   vpx_lpf_vertical_16_dual_sse2(s, p, blimit, limit, thresh);
100 }
101
102 void wrapper_vertical_16_dual_c(uint8_t *s, int p, const uint8_t *blimit,
103                                 const uint8_t *limit, const uint8_t *thresh,
104                                 int count) {
105   vpx_lpf_vertical_16_dual_c(s, p, blimit, limit, thresh);
106 }
107 #endif  // CONFIG_VP9_HIGHBITDEPTH
108 #endif  // HAVE_SSE2
109
110 #if HAVE_NEON_ASM
111 #if CONFIG_VP9_HIGHBITDEPTH
112 // No neon high bitdepth functions.
113 #else
114 void wrapper_vertical_16_neon(uint8_t *s, int p, const uint8_t *blimit,
115                               const uint8_t *limit, const uint8_t *thresh,
116                               int count) {
117   vpx_lpf_vertical_16_neon(s, p, blimit, limit, thresh);
118 }
119
120 void wrapper_vertical_16_c(uint8_t *s, int p, const uint8_t *blimit,
121                            const uint8_t *limit, const uint8_t *thresh,
122                            int count) {
123   vpx_lpf_vertical_16_c(s, p, blimit, limit, thresh);
124 }
125
126 void wrapper_vertical_16_dual_neon(uint8_t *s, int p, const uint8_t *blimit,
127                                    const uint8_t *limit, const uint8_t *thresh,
128                                    int count) {
129   vpx_lpf_vertical_16_dual_neon(s, p, blimit, limit, thresh);
130 }
131
132 void wrapper_vertical_16_dual_c(uint8_t *s, int p, const uint8_t *blimit,
133                                 const uint8_t *limit, const uint8_t *thresh,
134                                 int count) {
135   vpx_lpf_vertical_16_dual_c(s, p, blimit, limit, thresh);
136 }
137 #endif  // CONFIG_VP9_HIGHBITDEPTH
138 #endif  // HAVE_NEON_ASM
139
140 #if HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
141 void wrapper_vertical_16_msa(uint8_t *s, int p, const uint8_t *blimit,
142                              const uint8_t *limit, const uint8_t *thresh,
143                              int count) {
144   vpx_lpf_vertical_16_msa(s, p, blimit, limit, thresh);
145 }
146
147 void wrapper_vertical_16_c(uint8_t *s, int p, const uint8_t *blimit,
148                            const uint8_t *limit, const uint8_t *thresh,
149                            int count) {
150   vpx_lpf_vertical_16_c(s, p, blimit, limit, thresh);
151 }
152 #endif  // HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
153
154 class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> {
155  public:
156   virtual ~Loop8Test6Param() {}
157   virtual void SetUp() {
158     loopfilter_op_ = GET_PARAM(0);
159     ref_loopfilter_op_ = GET_PARAM(1);
160     bit_depth_ = GET_PARAM(2);
161     count_ = GET_PARAM(3);
162     mask_ = (1 << bit_depth_) - 1;
163   }
164
165   virtual void TearDown() { libvpx_test::ClearSystemState(); }
166
167  protected:
168   int bit_depth_;
169   int count_;
170   int mask_;
171   loop_op_t loopfilter_op_;
172   loop_op_t ref_loopfilter_op_;
173 };
174
175 class Loop8Test9Param : public ::testing::TestWithParam<dualloop8_param_t> {
176  public:
177   virtual ~Loop8Test9Param() {}
178   virtual void SetUp() {
179     loopfilter_op_ = GET_PARAM(0);
180     ref_loopfilter_op_ = GET_PARAM(1);
181     bit_depth_ = GET_PARAM(2);
182     mask_ = (1 << bit_depth_) - 1;
183   }
184
185   virtual void TearDown() { libvpx_test::ClearSystemState(); }
186
187  protected:
188   int bit_depth_;
189   int mask_;
190   dual_loop_op_t loopfilter_op_;
191   dual_loop_op_t ref_loopfilter_op_;
192 };
193
194 TEST_P(Loop8Test6Param, OperationCheck) {
195   ACMRandom rnd(ACMRandom::DeterministicSeed());
196   const int count_test_block = number_of_iterations;
197 #if CONFIG_VP9_HIGHBITDEPTH
198   int32_t bd = bit_depth_;
199   DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
200   DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
201 #else
202   DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
203   DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
204 #endif  // CONFIG_VP9_HIGHBITDEPTH
205   int err_count_total = 0;
206   int first_failure = -1;
207   for (int i = 0; i < count_test_block; ++i) {
208     int err_count = 0;
209     uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
210     DECLARE_ALIGNED(16, const uint8_t, blimit[16]) = {
211         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
212         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
213     };
214     tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
215     DECLARE_ALIGNED(16, const uint8_t, limit[16])  = {
216         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
217         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
218     };
219     tmp = rnd.Rand8();
220     DECLARE_ALIGNED(16, const uint8_t, thresh[16]) = {
221         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
222         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
223     };
224     int32_t p = kNumCoeffs/32;
225
226     uint16_t tmp_s[kNumCoeffs];
227     int j = 0;
228     while (j < kNumCoeffs) {
229       uint8_t val = rnd.Rand8();
230       if (val & 0x80) {  // 50% chance to choose a new value.
231         tmp_s[j] = rnd.Rand16();
232         j++;
233       } else {  // 50% chance to repeat previous value in row X times
234         int k = 0;
235         while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
236           if (j < 1) {
237             tmp_s[j] = rnd.Rand16();
238           } else if (val & 0x20) {  // Increment by an value within the limit
239             tmp_s[j] = (tmp_s[j - 1] + (*limit - 1));
240           } else {  // Decrement by an value within the limit
241             tmp_s[j] = (tmp_s[j - 1] - (*limit - 1));
242           }
243           j++;
244         }
245       }
246     }
247     for (j = 0; j < kNumCoeffs; j++) {
248       if (i % 2) {
249         s[j] = tmp_s[j] & mask_;
250       } else {
251         s[j] = tmp_s[p * (j % p) + j / p] & mask_;
252       }
253       ref_s[j] = s[j];
254     }
255 #if CONFIG_VP9_HIGHBITDEPTH
256     ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, count_, bd);
257     ASM_REGISTER_STATE_CHECK(
258         loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count_, bd));
259 #else
260     ref_loopfilter_op_(ref_s+8+p*8, p, blimit, limit, thresh, count_);
261     ASM_REGISTER_STATE_CHECK(
262         loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count_));
263 #endif  // CONFIG_VP9_HIGHBITDEPTH
264
265     for (int j = 0; j < kNumCoeffs; ++j) {
266       err_count += ref_s[j] != s[j];
267     }
268     if (err_count && !err_count_total) {
269       first_failure = i;
270     }
271     err_count_total += err_count;
272   }
273   EXPECT_EQ(0, err_count_total)
274       << "Error: Loop8Test6Param, C output doesn't match SSE2 "
275          "loopfilter output. "
276       << "First failed at test case " << first_failure;
277 }
278
279 TEST_P(Loop8Test6Param, ValueCheck) {
280   ACMRandom rnd(ACMRandom::DeterministicSeed());
281   const int count_test_block = number_of_iterations;
282 #if CONFIG_VP9_HIGHBITDEPTH
283   const int32_t bd = bit_depth_;
284   DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
285   DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
286 #else
287   DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
288   DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
289 #endif  // CONFIG_VP9_HIGHBITDEPTH
290   int err_count_total = 0;
291   int first_failure = -1;
292
293   // NOTE: The code in vp9_loopfilter.c:update_sharpness computes mblim as a
294   // function of sharpness_lvl and the loopfilter lvl as:
295   // block_inside_limit = lvl >> ((sharpness_lvl > 0) + (sharpness_lvl > 4));
296   // ...
297   // memset(lfi->lfthr[lvl].mblim, (2 * (lvl + 2) + block_inside_limit),
298   //        SIMD_WIDTH);
299   // This means that the largest value for mblim will occur when sharpness_lvl
300   // is equal to 0, and lvl is equal to its greatest value (MAX_LOOP_FILTER).
301   // In this case block_inside_limit will be equal to MAX_LOOP_FILTER and
302   // therefore mblim will be equal to (2 * (lvl + 2) + block_inside_limit) =
303   // 2 * (MAX_LOOP_FILTER + 2) + MAX_LOOP_FILTER = 3 * MAX_LOOP_FILTER + 4
304
305   for (int i = 0; i < count_test_block; ++i) {
306     int err_count = 0;
307     uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
308     DECLARE_ALIGNED(16, const uint8_t, blimit[16]) = {
309         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
310         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
311     };
312     tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
313     DECLARE_ALIGNED(16, const uint8_t, limit[16])  = {
314         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
315         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
316     };
317     tmp = rnd.Rand8();
318     DECLARE_ALIGNED(16, const uint8_t, thresh[16]) = {
319         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
320         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
321     };
322     int32_t p = kNumCoeffs / 32;
323     for (int j = 0; j < kNumCoeffs; ++j) {
324       s[j] = rnd.Rand16() & mask_;
325       ref_s[j] = s[j];
326     }
327 #if CONFIG_VP9_HIGHBITDEPTH
328     ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, count_, bd);
329     ASM_REGISTER_STATE_CHECK(
330         loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count_, bd));
331 #else
332     ref_loopfilter_op_(ref_s+8+p*8, p, blimit, limit, thresh, count_);
333     ASM_REGISTER_STATE_CHECK(
334         loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count_));
335 #endif  // CONFIG_VP9_HIGHBITDEPTH
336     for (int j = 0; j < kNumCoeffs; ++j) {
337       err_count += ref_s[j] != s[j];
338     }
339     if (err_count && !err_count_total) {
340       first_failure = i;
341     }
342     err_count_total += err_count;
343   }
344   EXPECT_EQ(0, err_count_total)
345       << "Error: Loop8Test6Param, C output doesn't match SSE2 "
346          "loopfilter output. "
347       << "First failed at test case " << first_failure;
348 }
349
350 TEST_P(Loop8Test9Param, OperationCheck) {
351   ACMRandom rnd(ACMRandom::DeterministicSeed());
352   const int count_test_block = number_of_iterations;
353 #if CONFIG_VP9_HIGHBITDEPTH
354   const int32_t bd = bit_depth_;
355   DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
356   DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
357 #else
358   DECLARE_ALIGNED(8,  uint8_t,  s[kNumCoeffs]);
359   DECLARE_ALIGNED(8,  uint8_t,  ref_s[kNumCoeffs]);
360 #endif  // CONFIG_VP9_HIGHBITDEPTH
361   int err_count_total = 0;
362   int first_failure = -1;
363   for (int i = 0; i < count_test_block; ++i) {
364     int err_count = 0;
365     uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
366     DECLARE_ALIGNED(16, const uint8_t, blimit0[16]) = {
367         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
368         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
369     };
370     tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
371     DECLARE_ALIGNED(16, const uint8_t, limit0[16])  = {
372         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
373         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
374     };
375     tmp = rnd.Rand8();
376     DECLARE_ALIGNED(16, const uint8_t, thresh0[16]) = {
377         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
378         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
379     };
380     tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
381     DECLARE_ALIGNED(16, const uint8_t, blimit1[16]) = {
382         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
383         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
384     };
385     tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
386     DECLARE_ALIGNED(16, const uint8_t, limit1[16])  = {
387         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
388         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
389     };
390     tmp = rnd.Rand8();
391     DECLARE_ALIGNED(16, const uint8_t, thresh1[16]) = {
392         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
393         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
394     };
395     int32_t p = kNumCoeffs / 32;
396     uint16_t tmp_s[kNumCoeffs];
397     int j = 0;
398     const uint8_t limit = *limit0 < *limit1 ? *limit0 : *limit1;
399     while (j < kNumCoeffs) {
400       uint8_t val = rnd.Rand8();
401       if (val & 0x80) {  // 50% chance to choose a new value.
402         tmp_s[j] = rnd.Rand16();
403         j++;
404       } else {  // 50% chance to repeat previous value in row X times.
405         int k = 0;
406         while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
407           if (j < 1) {
408             tmp_s[j] = rnd.Rand16();
409           } else if (val & 0x20) {  // Increment by a value within the limit.
410             tmp_s[j] = (tmp_s[j - 1] + (limit - 1));
411           } else {  // Decrement by an value within the limit.
412             tmp_s[j] = (tmp_s[j - 1] - (limit - 1));
413           }
414           j++;
415         }
416       }
417     }
418     for (j = 0; j < kNumCoeffs; j++) {
419       if (i % 2) {
420         s[j] = tmp_s[j] & mask_;
421       } else {
422         s[j] = tmp_s[p * (j % p) + j / p] & mask_;
423       }
424       ref_s[j] = s[j];
425     }
426 #if CONFIG_VP9_HIGHBITDEPTH
427     ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0,
428                        blimit1, limit1, thresh1, bd);
429     ASM_REGISTER_STATE_CHECK(
430         loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, thresh0,
431                        blimit1, limit1, thresh1, bd));
432 #else
433     ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0,
434                        blimit1, limit1, thresh1);
435     ASM_REGISTER_STATE_CHECK(
436         loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, thresh0,
437                        blimit1, limit1, thresh1));
438 #endif  // CONFIG_VP9_HIGHBITDEPTH
439     for (int j = 0; j < kNumCoeffs; ++j) {
440       err_count += ref_s[j] != s[j];
441     }
442     if (err_count && !err_count_total) {
443       first_failure = i;
444     }
445     err_count_total += err_count;
446   }
447   EXPECT_EQ(0, err_count_total)
448       << "Error: Loop8Test9Param, C output doesn't match SSE2 "
449          "loopfilter output. "
450       << "First failed at test case " << first_failure;
451 }
452
453 TEST_P(Loop8Test9Param, ValueCheck) {
454   ACMRandom rnd(ACMRandom::DeterministicSeed());
455   const int count_test_block = number_of_iterations;
456 #if CONFIG_VP9_HIGHBITDEPTH
457   DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
458   DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
459 #else
460   DECLARE_ALIGNED(8,  uint8_t, s[kNumCoeffs]);
461   DECLARE_ALIGNED(8,  uint8_t, ref_s[kNumCoeffs]);
462 #endif  // CONFIG_VP9_HIGHBITDEPTH
463   int err_count_total = 0;
464   int first_failure = -1;
465   for (int i = 0; i < count_test_block; ++i) {
466     int err_count = 0;
467     uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
468     DECLARE_ALIGNED(16, const uint8_t, blimit0[16]) = {
469         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
470         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
471     };
472     tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
473     DECLARE_ALIGNED(16, const uint8_t, limit0[16])  = {
474         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
475         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
476     };
477     tmp = rnd.Rand8();
478     DECLARE_ALIGNED(16, const uint8_t, thresh0[16]) = {
479         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
480         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
481     };
482     tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
483     DECLARE_ALIGNED(16, const uint8_t, blimit1[16]) = {
484         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
485         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
486     };
487     tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
488     DECLARE_ALIGNED(16, const uint8_t, limit1[16])  = {
489         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
490         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
491     };
492     tmp = rnd.Rand8();
493     DECLARE_ALIGNED(16, const uint8_t, thresh1[16]) = {
494         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
495         tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
496     };
497     int32_t p = kNumCoeffs / 32;  // TODO(pdlf) can we have non-square here?
498     for (int j = 0; j < kNumCoeffs; ++j) {
499       s[j] = rnd.Rand16() & mask_;
500       ref_s[j] = s[j];
501     }
502 #if CONFIG_VP9_HIGHBITDEPTH
503     const int32_t bd = bit_depth_;
504     ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0,
505                        blimit1, limit1, thresh1, bd);
506     ASM_REGISTER_STATE_CHECK(
507         loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0,
508                        thresh0, blimit1, limit1, thresh1, bd));
509 #else
510     ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0,
511                        blimit1, limit1, thresh1);
512     ASM_REGISTER_STATE_CHECK(
513         loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, thresh0,
514                        blimit1, limit1, thresh1));
515 #endif  // CONFIG_VP9_HIGHBITDEPTH
516     for (int j = 0; j < kNumCoeffs; ++j) {
517       err_count += ref_s[j] != s[j];
518     }
519     if (err_count && !err_count_total) {
520       first_failure = i;
521     }
522     err_count_total += err_count;
523   }
524   EXPECT_EQ(0, err_count_total)
525       << "Error: Loop8Test9Param, C output doesn't match SSE2"
526          "loopfilter output. "
527       << "First failed at test case " << first_failure;
528 }
529
530 using std::tr1::make_tuple;
531
532 #if HAVE_SSE2
533 #if CONFIG_VP9_HIGHBITDEPTH
534 INSTANTIATE_TEST_CASE_P(
535     SSE2, Loop8Test6Param,
536     ::testing::Values(
537         make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
538                    &vpx_highbd_lpf_horizontal_4_c, 8, 1),
539         make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
540                    &vpx_highbd_lpf_vertical_4_c, 8, 1),
541         make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
542                    &vpx_highbd_lpf_horizontal_8_c, 8, 1),
543         make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
544                    &vpx_highbd_lpf_horizontal_16_c, 8, 1),
545         make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
546                    &vpx_highbd_lpf_horizontal_16_c, 8, 2),
547         make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
548                    &vpx_highbd_lpf_vertical_8_c, 8, 1),
549         make_tuple(&wrapper_vertical_16_sse2,
550                    &wrapper_vertical_16_c, 8, 1),
551         make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
552                    &vpx_highbd_lpf_horizontal_4_c, 10, 1),
553         make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
554                    &vpx_highbd_lpf_vertical_4_c, 10, 1),
555         make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
556                    &vpx_highbd_lpf_horizontal_8_c, 10, 1),
557         make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
558                    &vpx_highbd_lpf_horizontal_16_c, 10, 1),
559         make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
560                    &vpx_highbd_lpf_horizontal_16_c, 10, 2),
561         make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
562                    &vpx_highbd_lpf_vertical_8_c, 10, 1),
563         make_tuple(&wrapper_vertical_16_sse2,
564                    &wrapper_vertical_16_c, 10, 1),
565         make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
566                    &vpx_highbd_lpf_horizontal_4_c, 12, 1),
567         make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
568                    &vpx_highbd_lpf_vertical_4_c, 12, 1),
569         make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
570                    &vpx_highbd_lpf_horizontal_8_c, 12, 1),
571         make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
572                    &vpx_highbd_lpf_horizontal_16_c, 12, 1),
573         make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
574                    &vpx_highbd_lpf_horizontal_16_c, 12, 2),
575         make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
576                    &vpx_highbd_lpf_vertical_8_c, 12, 1),
577         make_tuple(&wrapper_vertical_16_sse2,
578                    &wrapper_vertical_16_c, 12, 1),
579         make_tuple(&wrapper_vertical_16_dual_sse2,
580                    &wrapper_vertical_16_dual_c, 8, 1),
581         make_tuple(&wrapper_vertical_16_dual_sse2,
582                    &wrapper_vertical_16_dual_c, 10, 1),
583         make_tuple(&wrapper_vertical_16_dual_sse2,
584                    &wrapper_vertical_16_dual_c, 12, 1)));
585 #else
586 INSTANTIATE_TEST_CASE_P(
587     SSE2, Loop8Test6Param,
588     ::testing::Values(
589         make_tuple(&vpx_lpf_horizontal_8_sse2, &vpx_lpf_horizontal_8_c, 8, 1),
590         make_tuple(&vpx_lpf_horizontal_16_sse2, &vpx_lpf_horizontal_16_c, 8, 1),
591         make_tuple(&vpx_lpf_horizontal_16_sse2, &vpx_lpf_horizontal_16_c, 8, 2),
592         make_tuple(&vpx_lpf_vertical_8_sse2, &vpx_lpf_vertical_8_c, 8, 1),
593         make_tuple(&wrapper_vertical_16_sse2, &wrapper_vertical_16_c, 8, 1)));
594 #endif  // CONFIG_VP9_HIGHBITDEPTH
595 #endif
596
597 #if HAVE_AVX2 && (!CONFIG_VP9_HIGHBITDEPTH)
598 INSTANTIATE_TEST_CASE_P(
599     AVX2, Loop8Test6Param,
600     ::testing::Values(
601         make_tuple(&vpx_lpf_horizontal_16_avx2, &vpx_lpf_horizontal_16_c, 8, 1),
602         make_tuple(&vpx_lpf_horizontal_16_avx2, &vpx_lpf_horizontal_16_c, 8,
603                    2)));
604 #endif
605
606 #if HAVE_SSE2
607 #if CONFIG_VP9_HIGHBITDEPTH
608 INSTANTIATE_TEST_CASE_P(
609     SSE2, Loop8Test9Param,
610     ::testing::Values(
611         make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
612                    &vpx_highbd_lpf_horizontal_4_dual_c, 8),
613         make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
614                    &vpx_highbd_lpf_horizontal_8_dual_c, 8),
615         make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2,
616                    &vpx_highbd_lpf_vertical_4_dual_c, 8),
617         make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
618                    &vpx_highbd_lpf_vertical_8_dual_c, 8),
619         make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
620                    &vpx_highbd_lpf_horizontal_4_dual_c, 10),
621         make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
622                    &vpx_highbd_lpf_horizontal_8_dual_c, 10),
623         make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2,
624                    &vpx_highbd_lpf_vertical_4_dual_c, 10),
625         make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
626                    &vpx_highbd_lpf_vertical_8_dual_c, 10),
627         make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
628                    &vpx_highbd_lpf_horizontal_4_dual_c, 12),
629         make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
630                    &vpx_highbd_lpf_horizontal_8_dual_c, 12),
631         make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2,
632                    &vpx_highbd_lpf_vertical_4_dual_c, 12),
633         make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
634                    &vpx_highbd_lpf_vertical_8_dual_c, 12)));
635 #else
636 INSTANTIATE_TEST_CASE_P(
637     SSE2, Loop8Test9Param,
638     ::testing::Values(
639         make_tuple(&vpx_lpf_horizontal_4_dual_sse2,
640                    &vpx_lpf_horizontal_4_dual_c, 8),
641         make_tuple(&vpx_lpf_horizontal_8_dual_sse2,
642                    &vpx_lpf_horizontal_8_dual_c, 8),
643         make_tuple(&vpx_lpf_vertical_4_dual_sse2,
644                    &vpx_lpf_vertical_4_dual_c, 8),
645         make_tuple(&vpx_lpf_vertical_8_dual_sse2,
646                    &vpx_lpf_vertical_8_dual_c, 8)));
647 #endif  // CONFIG_VP9_HIGHBITDEPTH
648 #endif
649
650 #if HAVE_NEON
651 #if CONFIG_VP9_HIGHBITDEPTH
652 // No neon high bitdepth functions.
653 #else
654 INSTANTIATE_TEST_CASE_P(
655     NEON, Loop8Test6Param,
656     ::testing::Values(
657 #if HAVE_NEON_ASM
658 // Using #if inside the macro is unsupported on MSVS but the tests are not
659 // currently built for MSVS with ARM and NEON.
660         make_tuple(&vpx_lpf_horizontal_16_neon,
661                    &vpx_lpf_horizontal_16_c, 8, 1),
662         make_tuple(&vpx_lpf_horizontal_16_neon,
663                    &vpx_lpf_horizontal_16_c, 8, 2),
664         make_tuple(&wrapper_vertical_16_neon,
665                    &wrapper_vertical_16_c, 8, 1),
666         make_tuple(&wrapper_vertical_16_dual_neon,
667                    &wrapper_vertical_16_dual_c, 8, 1),
668 #endif  // HAVE_NEON_ASM
669         make_tuple(&vpx_lpf_horizontal_8_neon,
670                    &vpx_lpf_horizontal_8_c, 8, 1),
671         make_tuple(&vpx_lpf_vertical_8_neon,
672                    &vpx_lpf_vertical_8_c, 8, 1),
673         make_tuple(&vpx_lpf_horizontal_4_neon,
674                    &vpx_lpf_horizontal_4_c, 8, 1),
675         make_tuple(&vpx_lpf_vertical_4_neon,
676                    &vpx_lpf_vertical_4_c, 8, 1)));
677 INSTANTIATE_TEST_CASE_P(
678     NEON, Loop8Test9Param,
679     ::testing::Values(
680 #if HAVE_NEON_ASM
681         make_tuple(&vpx_lpf_horizontal_8_dual_neon,
682                    &vpx_lpf_horizontal_8_dual_c, 8),
683         make_tuple(&vpx_lpf_vertical_8_dual_neon,
684                    &vpx_lpf_vertical_8_dual_c, 8),
685 #endif  // HAVE_NEON_ASM
686         make_tuple(&vpx_lpf_horizontal_4_dual_neon,
687                    &vpx_lpf_horizontal_4_dual_c, 8),
688         make_tuple(&vpx_lpf_vertical_4_dual_neon,
689                    &vpx_lpf_vertical_4_dual_c, 8)));
690 #endif  // CONFIG_VP9_HIGHBITDEPTH
691 #endif  // HAVE_NEON
692
693 #if HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
694 INSTANTIATE_TEST_CASE_P(
695     MSA, Loop8Test6Param,
696     ::testing::Values(
697         make_tuple(&vpx_lpf_horizontal_8_msa, &vpx_lpf_horizontal_8_c, 8, 1),
698         make_tuple(&vpx_lpf_horizontal_16_msa, &vpx_lpf_horizontal_16_c, 8, 1),
699         make_tuple(&vpx_lpf_horizontal_16_msa, &vpx_lpf_horizontal_16_c, 8, 2),
700         make_tuple(&vpx_lpf_vertical_8_msa, &vpx_lpf_vertical_8_c, 8, 1),
701         make_tuple(&wrapper_vertical_16_msa, &wrapper_vertical_16_c, 8, 1)));
702
703 INSTANTIATE_TEST_CASE_P(
704     MSA, Loop8Test9Param,
705     ::testing::Values(
706         make_tuple(&vpx_lpf_horizontal_4_dual_msa,
707                    &vpx_lpf_horizontal_4_dual_c, 8),
708         make_tuple(&vpx_lpf_horizontal_8_dual_msa,
709                    &vpx_lpf_horizontal_8_dual_c, 8),
710         make_tuple(&vpx_lpf_vertical_4_dual_msa,
711                    &vpx_lpf_vertical_4_dual_c, 8),
712         make_tuple(&vpx_lpf_vertical_8_dual_msa,
713                    &vpx_lpf_vertical_8_dual_c, 8)));
714 #endif  // HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
715
716 }  // namespace