blob: 100dc2a6cc85f31b50047a1f56a1881cca31f68b [file] [log] [blame]
Deb Mukherjee931ed512014-09-17 16:55:05 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Deb Mukherjee931ed512014-09-17 16:55:05 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * 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.
Johann123e8a62017-12-28 14:40:49 -080010 */
Deb Mukherjee931ed512014-09-17 16:55:05 -070011
12#include <cmath>
13#include <cstdlib>
14#include <string>
15
Tom Finegan7a07ece2017-02-07 17:14:05 -080016#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
Jingning Han097d59c2015-07-29 14:51:36 -070017
Yaowu Xuf883b422016-08-30 14:01:10 -070018#include "./aom_config.h"
19#include "./aom_dsp_rtcd.h"
Deb Mukherjee931ed512014-09-17 16:55:05 -070020#include "test/acm_random.h"
21#include "test/clear_system_state.h"
22#include "test/register_state_check.h"
23#include "test/util.h"
Tom Finegan17ce8b12017-02-08 12:46:31 -080024#include "av1/common/av1_loopfilter.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070025#include "av1/common/entropy.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070026#include "aom/aom_integer.h"
Deb Mukherjee931ed512014-09-17 16:55:05 -070027
Yaowu Xuc27fc142016-08-22 16:08:15 -070028using libaom_test::ACMRandom;
Deb Mukherjee931ed512014-09-17 16:55:05 -070029
30namespace {
31// Horizontally and Vertically need 32x32: 8 Coeffs preceeding filtered section
32// 16 Coefs within filtered section
33// 8 Coeffs following filtered section
34const int kNumCoeffs = 1024;
35
36const int number_of_iterations = 10000;
37
Yi Luo6ae00542017-08-03 17:08:20 -070038const int kSpeedTestNum = 500000;
39
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +010040#define LOOP_PARAM \
41 int p, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh
42#define DUAL_LOOP_PARAM \
43 int p, const uint8_t *blimit0, const uint8_t *limit0, \
44 const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, \
45 const uint8_t *thresh1
Linfeng Zhang5b0f0b82016-08-04 13:22:39 -070046
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +010047typedef void (*loop_op_t)(uint8_t *s, LOOP_PARAM);
48typedef void (*dual_loop_op_t)(uint8_t *s, DUAL_LOOP_PARAM);
49typedef void (*hbdloop_op_t)(uint16_t *s, LOOP_PARAM, int bd);
50typedef void (*hbddual_loop_op_t)(uint16_t *s, DUAL_LOOP_PARAM, int bd);
Deb Mukherjee931ed512014-09-17 16:55:05 -070051
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +010052typedef std::tr1::tuple<hbdloop_op_t, hbdloop_op_t, int> hbdloop_param_t;
53typedef std::tr1::tuple<hbddual_loop_op_t, hbddual_loop_op_t, int>
54 hbddual_loop_param_t;
55typedef std::tr1::tuple<loop_op_t, loop_op_t, int> loop_param_t;
56typedef std::tr1::tuple<dual_loop_op_t, dual_loop_op_t, int> dual_loop_param_t;
Deb Mukherjee931ed512014-09-17 16:55:05 -070057
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +010058template <typename Pixel_t, int PIXEL_WIDTH_t>
59void InitInput(Pixel_t *s, Pixel_t *ref_s, ACMRandom *rnd, const uint8_t limit,
Linfeng Zhang5b0f0b82016-08-04 13:22:39 -070060 const int mask, const int32_t p, const int i) {
61 uint16_t tmp_s[kNumCoeffs];
62
63 for (int j = 0; j < kNumCoeffs;) {
64 const uint8_t val = rnd->Rand8();
65 if (val & 0x80) { // 50% chance to choose a new value.
66 tmp_s[j] = rnd->Rand16();
67 j++;
68 } else { // 50% chance to repeat previous value in row X times.
69 int k = 0;
70 while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
71 if (j < 1) {
72 tmp_s[j] = rnd->Rand16();
73 } else if (val & 0x20) { // Increment by a value within the limit.
74 tmp_s[j] = tmp_s[j - 1] + (limit - 1);
75 } else { // Decrement by a value within the limit.
76 tmp_s[j] = tmp_s[j - 1] - (limit - 1);
77 }
78 j++;
79 }
80 }
81 }
82
83 for (int j = 0; j < kNumCoeffs;) {
84 const uint8_t val = rnd->Rand8();
85 if (val & 0x80) {
86 j++;
87 } else { // 50% chance to repeat previous value in column X times.
88 int k = 0;
89 while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
90 if (j < 1) {
91 tmp_s[j] = rnd->Rand16();
92 } else if (val & 0x20) { // Increment by a value within the limit.
93 tmp_s[(j % 32) * 32 + j / 32] =
94 tmp_s[((j - 1) % 32) * 32 + (j - 1) / 32] + (limit - 1);
95 } else { // Decrement by a value within the limit.
96 tmp_s[(j % 32) * 32 + j / 32] =
97 tmp_s[((j - 1) % 32) * 32 + (j - 1) / 32] - (limit - 1);
98 }
99 j++;
100 }
101 }
102 }
103
104 for (int j = 0; j < kNumCoeffs; j++) {
105 if (i % 2) {
106 s[j] = tmp_s[j] & mask;
107 } else {
108 s[j] = tmp_s[p * (j % p) + j / p] & mask;
109 }
110 ref_s[j] = s[j];
111 }
112}
113
James Zern360c4912017-12-20 12:59:11 -0800114uint8_t GetOuterThresh(ACMRandom *rnd) {
115 return static_cast<uint8_t>(rnd->PseudoUniform(3 * MAX_LOOP_FILTER + 5));
116}
117
118uint8_t GetInnerThresh(ACMRandom *rnd) {
119 return static_cast<uint8_t>(rnd->PseudoUniform(MAX_LOOP_FILTER + 1));
120}
121
122uint8_t GetHevThresh(ACMRandom *rnd) {
123 return static_cast<uint8_t>(rnd->PseudoUniform(MAX_LOOP_FILTER + 1) >> 4);
124}
125
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100126template <typename func_type_t, typename params_t>
127class LoopTestParam : public ::testing::TestWithParam<params_t> {
Deb Mukherjee931ed512014-09-17 16:55:05 -0700128 public:
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100129 virtual ~LoopTestParam() {}
Deb Mukherjee931ed512014-09-17 16:55:05 -0700130 virtual void SetUp() {
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100131 loopfilter_op_ = std::tr1::get<0>(this->GetParam());
132 ref_loopfilter_op_ = std::tr1::get<1>(this->GetParam());
133 bit_depth_ = std::tr1::get<2>(this->GetParam());
Deb Mukherjee931ed512014-09-17 16:55:05 -0700134 mask_ = (1 << bit_depth_) - 1;
135 }
136
Yaowu Xuc27fc142016-08-22 16:08:15 -0700137 virtual void TearDown() { libaom_test::ClearSystemState(); }
Deb Mukherjee931ed512014-09-17 16:55:05 -0700138
139 protected:
140 int bit_depth_;
141 int mask_;
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100142 func_type_t loopfilter_op_;
143 func_type_t ref_loopfilter_op_;
Deb Mukherjee931ed512014-09-17 16:55:05 -0700144};
145
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100146void call_filter(uint16_t *s, LOOP_PARAM, int bd, hbdloop_op_t op) {
147 op(s, p, blimit, limit, thresh, bd);
148}
149void call_filter(uint8_t *s, LOOP_PARAM, int bd, loop_op_t op) {
150 (void)bd;
151 op(s, p, blimit, limit, thresh);
152}
153void call_dualfilter(uint16_t *s, DUAL_LOOP_PARAM, int bd,
154 hbddual_loop_op_t op) {
155 op(s, p, blimit0, limit0, thresh0, blimit1, limit1, thresh1, bd);
156}
157void call_dualfilter(uint8_t *s, DUAL_LOOP_PARAM, int bd, dual_loop_op_t op) {
158 (void)bd;
159 op(s, p, blimit0, limit0, thresh0, blimit1, limit1, thresh1);
Deb Mukherjee931ed512014-09-17 16:55:05 -0700160};
161
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100162typedef LoopTestParam<hbdloop_op_t, hbdloop_param_t> Loop8Test6Param_hbd;
163typedef LoopTestParam<loop_op_t, loop_param_t> Loop8Test6Param_lbd;
164typedef LoopTestParam<hbddual_loop_op_t, hbddual_loop_param_t>
165 Loop8Test9Param_hbd;
166typedef LoopTestParam<dual_loop_op_t, dual_loop_param_t> Loop8Test9Param_lbd;
Deb Mukherjee931ed512014-09-17 16:55:05 -0700167
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100168#define OPCHECK(a, b) \
169 ACMRandom rnd(ACMRandom::DeterministicSeed()); \
170 const int count_test_block = number_of_iterations; \
171 const int32_t p = kNumCoeffs / 32; \
172 DECLARE_ALIGNED(b, a, s[kNumCoeffs]); \
173 DECLARE_ALIGNED(b, a, ref_s[kNumCoeffs]); \
174 int err_count_total = 0; \
175 int first_failure = -1; \
176 for (int i = 0; i < count_test_block; ++i) { \
177 int err_count = 0; \
178 uint8_t tmp = GetOuterThresh(&rnd); \
179 DECLARE_ALIGNED(16, const uint8_t, \
180 blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
181 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
182 tmp = GetInnerThresh(&rnd); \
183 DECLARE_ALIGNED(16, const uint8_t, \
184 limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
185 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
186 tmp = GetHevThresh(&rnd); \
187 DECLARE_ALIGNED(16, const uint8_t, \
188 thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
189 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
190 InitInput<a, b>(s, ref_s, &rnd, *limit, mask_, p, i); \
191 call_filter(ref_s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_, \
192 ref_loopfilter_op_); \
193 ASM_REGISTER_STATE_CHECK(call_filter(s + 8 + p * 8, p, blimit, limit, \
194 thresh, bit_depth_, loopfilter_op_)); \
195 for (int j = 0; j < kNumCoeffs; ++j) { \
196 err_count += ref_s[j] != s[j]; \
197 } \
198 if (err_count && !err_count_total) { \
199 first_failure = i; \
200 } \
201 err_count_total += err_count; \
202 } \
203 EXPECT_EQ(0, err_count_total) \
204 << "Error: Loop8Test6Param, C output doesn't match SIMD " \
205 "loopfilter output. " \
Deb Mukherjee931ed512014-09-17 16:55:05 -0700206 << "First failed at test case " << first_failure;
Deb Mukherjee931ed512014-09-17 16:55:05 -0700207
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100208TEST_P(Loop8Test6Param_hbd, OperationCheck) { OPCHECK(uint16_t, 16); }
209TEST_P(Loop8Test6Param_lbd, OperationCheck) { OPCHECK(uint8_t, 8); }
Deb Mukherjee072ed172014-12-03 16:26:48 -0800210
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100211#define VALCHECK(a, b) \
212 ACMRandom rnd(ACMRandom::DeterministicSeed()); \
213 const int count_test_block = number_of_iterations; \
214 DECLARE_ALIGNED(b, a, s[kNumCoeffs]); \
215 DECLARE_ALIGNED(b, a, ref_s[kNumCoeffs]); \
216 int err_count_total = 0; \
217 int first_failure = -1; \
218 for (int i = 0; i < count_test_block; ++i) { \
219 int err_count = 0; \
220 uint8_t tmp = GetOuterThresh(&rnd); \
221 DECLARE_ALIGNED(16, const uint8_t, \
222 blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
223 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
224 tmp = GetInnerThresh(&rnd); \
225 DECLARE_ALIGNED(16, const uint8_t, \
226 limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
227 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
228 tmp = GetHevThresh(&rnd); \
229 DECLARE_ALIGNED(16, const uint8_t, \
230 thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
231 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
232 int32_t p = kNumCoeffs / 32; \
233 for (int j = 0; j < kNumCoeffs; ++j) { \
234 s[j] = rnd.Rand16() & mask_; \
235 ref_s[j] = s[j]; \
236 } \
237 call_filter(ref_s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_, \
238 ref_loopfilter_op_); \
239 ASM_REGISTER_STATE_CHECK(call_filter(s + 8 + p * 8, p, blimit, limit, \
240 thresh, bit_depth_, loopfilter_op_)); \
241 for (int j = 0; j < kNumCoeffs; ++j) { \
242 err_count += ref_s[j] != s[j]; \
243 } \
244 if (err_count && !err_count_total) { \
245 first_failure = i; \
246 } \
247 err_count_total += err_count; \
248 } \
249 EXPECT_EQ(0, err_count_total) \
250 << "Error: Loop8Test6Param, C output doesn't match SIMD " \
251 "loopfilter output. " \
Deb Mukherjee931ed512014-09-17 16:55:05 -0700252 << "First failed at test case " << first_failure;
Deb Mukherjee931ed512014-09-17 16:55:05 -0700253
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100254TEST_P(Loop8Test6Param_hbd, ValueCheck) { VALCHECK(uint16_t, 16); }
255TEST_P(Loop8Test6Param_lbd, ValueCheck) { VALCHECK(uint8_t, 8); }
Yi Luo6ae00542017-08-03 17:08:20 -0700256
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100257#define SPEEDCHECK(a, b) \
258 ACMRandom rnd(ACMRandom::DeterministicSeed()); \
259 const int count_test_block = kSpeedTestNum; \
260 const int32_t bd = bit_depth_; \
261 DECLARE_ALIGNED(b, a, s[kNumCoeffs]); \
262 uint8_t tmp = GetOuterThresh(&rnd); \
263 DECLARE_ALIGNED(16, const uint8_t, \
264 blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
265 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
266 tmp = GetInnerThresh(&rnd); \
267 DECLARE_ALIGNED(16, const uint8_t, \
268 limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
269 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
270 tmp = GetHevThresh(&rnd); \
271 DECLARE_ALIGNED(16, const uint8_t, \
272 thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
273 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
274 int32_t p = kNumCoeffs / 32; \
275 for (int j = 0; j < kNumCoeffs; ++j) { \
276 s[j] = rnd.Rand16() & mask_; \
277 } \
278 for (int i = 0; i < count_test_block; ++i) { \
279 call_filter(s + 8 + p * 8, p, blimit, limit, thresh, bd, loopfilter_op_); \
Yi Luo6ae00542017-08-03 17:08:20 -0700280 }
281
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100282TEST_P(Loop8Test6Param_hbd, DISABLED_Speed) { SPEEDCHECK(uint16_t, 16); }
283TEST_P(Loop8Test6Param_lbd, DISABLED_Speed) { SPEEDCHECK(uint8_t, 8); }
Yi Luo6ae00542017-08-03 17:08:20 -0700284
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100285#define OPCHECKd(a, b) \
286 ACMRandom rnd(ACMRandom::DeterministicSeed()); \
287 const int count_test_block = number_of_iterations; \
288 DECLARE_ALIGNED(b, a, s[kNumCoeffs]); \
289 DECLARE_ALIGNED(b, a, ref_s[kNumCoeffs]); \
290 int err_count_total = 0; \
291 int first_failure = -1; \
292 for (int i = 0; i < count_test_block; ++i) { \
293 int err_count = 0; \
294 uint8_t tmp = GetOuterThresh(&rnd); \
295 DECLARE_ALIGNED(16, const uint8_t, \
296 blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
297 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
298 tmp = GetInnerThresh(&rnd); \
299 DECLARE_ALIGNED(16, const uint8_t, \
300 limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
301 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
302 tmp = GetHevThresh(&rnd); \
303 DECLARE_ALIGNED(16, const uint8_t, \
304 thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
305 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
306 tmp = GetOuterThresh(&rnd); \
307 DECLARE_ALIGNED(16, const uint8_t, \
308 blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
309 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
310 tmp = GetInnerThresh(&rnd); \
311 DECLARE_ALIGNED(16, const uint8_t, \
312 limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
313 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
314 tmp = GetHevThresh(&rnd); \
315 DECLARE_ALIGNED(16, const uint8_t, \
316 thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
317 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
318 int32_t p = kNumCoeffs / 32; \
319 const uint8_t limit = *limit0 < *limit1 ? *limit0 : *limit1; \
320 InitInput<a, b>(s, ref_s, &rnd, limit, mask_, p, i); \
321 call_dualfilter(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1, \
322 limit1, thresh1, bit_depth_, ref_loopfilter_op_); \
323 ASM_REGISTER_STATE_CHECK( \
324 call_dualfilter(s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1, \
325 limit1, thresh1, bit_depth_, loopfilter_op_)); \
326 for (int j = 0; j < kNumCoeffs; ++j) { \
327 err_count += ref_s[j] != s[j]; \
328 } \
329 if (err_count && !err_count_total) { \
330 first_failure = i; \
331 } \
332 err_count_total += err_count; \
333 } \
334 EXPECT_EQ(0, err_count_total) \
335 << "Error: Loop8Test9Param, C output doesn't match SIMD " \
336 "loopfilter output. " \
Deb Mukherjee931ed512014-09-17 16:55:05 -0700337 << "First failed at test case " << first_failure;
Deb Mukherjee931ed512014-09-17 16:55:05 -0700338
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100339TEST_P(Loop8Test9Param_hbd, OperationCheck) { OPCHECKd(uint16_t, 16); }
340TEST_P(Loop8Test9Param_lbd, OperationCheck) { OPCHECKd(uint8_t, 8); }
Linfeng Zhang5b0f0b82016-08-04 13:22:39 -0700341
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100342#define VALCHECKd(a, b) \
343 ACMRandom rnd(ACMRandom::DeterministicSeed()); \
344 const int count_test_block = number_of_iterations; \
345 DECLARE_ALIGNED(b, a, s[kNumCoeffs]); \
346 DECLARE_ALIGNED(b, a, ref_s[kNumCoeffs]); \
347 int err_count_total = 0; \
348 int first_failure = -1; \
349 for (int i = 0; i < count_test_block; ++i) { \
350 int err_count = 0; \
351 uint8_t tmp = GetOuterThresh(&rnd); \
352 DECLARE_ALIGNED(16, const uint8_t, \
353 blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
354 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
355 tmp = GetInnerThresh(&rnd); \
356 DECLARE_ALIGNED(16, const uint8_t, \
357 limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
358 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
359 tmp = GetHevThresh(&rnd); \
360 DECLARE_ALIGNED(16, const uint8_t, \
361 thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
362 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
363 tmp = GetOuterThresh(&rnd); \
364 DECLARE_ALIGNED(16, const uint8_t, \
365 blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
366 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
367 tmp = GetInnerThresh(&rnd); \
368 DECLARE_ALIGNED(16, const uint8_t, \
369 limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
370 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
371 tmp = GetHevThresh(&rnd); \
372 DECLARE_ALIGNED(16, const uint8_t, \
373 thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
374 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
375 int32_t p = kNumCoeffs / 32; \
376 for (int j = 0; j < kNumCoeffs; ++j) { \
377 s[j] = rnd.Rand16() & mask_; \
378 ref_s[j] = s[j]; \
379 } \
380 call_dualfilter(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1, \
381 limit1, thresh1, bit_depth_, ref_loopfilter_op_); \
382 ASM_REGISTER_STATE_CHECK( \
383 call_dualfilter(s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1, \
384 limit1, thresh1, bit_depth_, loopfilter_op_)); \
385 for (int j = 0; j < kNumCoeffs; ++j) { \
386 err_count += ref_s[j] != s[j]; \
387 } \
388 if (err_count && !err_count_total) { \
389 first_failure = i; \
390 } \
391 err_count_total += err_count; \
392 } \
393 EXPECT_EQ(0, err_count_total) \
394 << "Error: Loop8Test9Param, C output doesn't match SIMD " \
395 "loopfilter output. " \
Deb Mukherjee931ed512014-09-17 16:55:05 -0700396 << "First failed at test case " << first_failure;
Deb Mukherjee931ed512014-09-17 16:55:05 -0700397
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100398TEST_P(Loop8Test9Param_hbd, ValueCheck) { VALCHECKd(uint16_t, 16); }
399TEST_P(Loop8Test9Param_lbd, ValueCheck) { VALCHECKd(uint8_t, 8); }
Yi Luo6ae00542017-08-03 17:08:20 -0700400
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100401#define SPEEDCHECKd(a, b) \
402 ACMRandom rnd(ACMRandom::DeterministicSeed()); \
403 const int count_test_block = kSpeedTestNum; \
404 DECLARE_ALIGNED(b, a, s[kNumCoeffs]); \
405 uint8_t tmp = GetOuterThresh(&rnd); \
406 DECLARE_ALIGNED(16, const uint8_t, \
407 blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
408 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
409 tmp = GetInnerThresh(&rnd); \
410 DECLARE_ALIGNED(16, const uint8_t, \
411 limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
412 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
413 tmp = GetHevThresh(&rnd); \
414 DECLARE_ALIGNED(16, const uint8_t, \
415 thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
416 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
417 tmp = GetOuterThresh(&rnd); \
418 DECLARE_ALIGNED(16, const uint8_t, \
419 blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
420 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
421 tmp = GetInnerThresh(&rnd); \
422 DECLARE_ALIGNED(16, const uint8_t, \
423 limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
424 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
425 tmp = GetHevThresh(&rnd); \
426 DECLARE_ALIGNED(16, const uint8_t, \
427 thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, \
428 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp }; \
429 int32_t p = kNumCoeffs / 32; \
430 for (int j = 0; j < kNumCoeffs; ++j) { \
431 s[j] = rnd.Rand16() & mask_; \
432 } \
433 for (int i = 0; i < count_test_block; ++i) { \
434 call_dualfilter(s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1, \
435 limit1, thresh1, bit_depth_, loopfilter_op_); \
Yi Luo6ae00542017-08-03 17:08:20 -0700436 }
437
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100438TEST_P(Loop8Test9Param_hbd, DISABLED_Speed) { SPEEDCHECKd(uint16_t, 16); }
439TEST_P(Loop8Test9Param_lbd, DISABLED_Speed) { SPEEDCHECKd(uint8_t, 8); }
Yi Luo6ae00542017-08-03 17:08:20 -0700440
Deb Mukherjee931ed512014-09-17 16:55:05 -0700441using std::tr1::make_tuple;
442
Yi Luo6f5569f2017-08-18 10:30:56 -0700443#if HAVE_SSE2
Yaowu Xu1fd71052017-06-19 15:59:00 -0700444
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100445const hbdloop_param_t kHbdLoop8Test6[] = {
Yaowu Xu1fd71052017-06-19 15:59:00 -0700446 make_tuple(&aom_highbd_lpf_horizontal_4_sse2, &aom_highbd_lpf_horizontal_4_c,
447 8),
448 make_tuple(&aom_highbd_lpf_vertical_4_sse2, &aom_highbd_lpf_vertical_4_c, 8),
449 make_tuple(&aom_highbd_lpf_horizontal_8_sse2, &aom_highbd_lpf_horizontal_8_c,
450 8),
Ryan26802752018-02-20 10:29:05 -0800451 make_tuple(&aom_highbd_lpf_horizontal_14_sse2,
452 &aom_highbd_lpf_horizontal_14_c, 8),
453 make_tuple(&aom_highbd_lpf_horizontal_14_dual_sse2,
454 &aom_highbd_lpf_horizontal_14_dual_c, 8),
Yaowu Xu1fd71052017-06-19 15:59:00 -0700455 make_tuple(&aom_highbd_lpf_vertical_8_sse2, &aom_highbd_lpf_vertical_8_c, 8),
Ryan26802752018-02-20 10:29:05 -0800456 make_tuple(&aom_highbd_lpf_vertical_14_sse2, &aom_highbd_lpf_vertical_14_c,
Yaowu Xu1fd71052017-06-19 15:59:00 -0700457 8),
458 make_tuple(&aom_highbd_lpf_horizontal_4_sse2, &aom_highbd_lpf_horizontal_4_c,
459 10),
460 make_tuple(&aom_highbd_lpf_vertical_4_sse2, &aom_highbd_lpf_vertical_4_c, 10),
461 make_tuple(&aom_highbd_lpf_horizontal_8_sse2, &aom_highbd_lpf_horizontal_8_c,
462 10),
Ryan26802752018-02-20 10:29:05 -0800463 make_tuple(&aom_highbd_lpf_horizontal_14_sse2,
464 &aom_highbd_lpf_horizontal_14_c, 10),
465 make_tuple(&aom_highbd_lpf_horizontal_14_dual_sse2,
466 &aom_highbd_lpf_horizontal_14_dual_c, 10),
Yaowu Xu1fd71052017-06-19 15:59:00 -0700467 make_tuple(&aom_highbd_lpf_vertical_8_sse2, &aom_highbd_lpf_vertical_8_c, 10),
Ryan26802752018-02-20 10:29:05 -0800468 make_tuple(&aom_highbd_lpf_vertical_14_sse2, &aom_highbd_lpf_vertical_14_c,
Yaowu Xu1fd71052017-06-19 15:59:00 -0700469 10),
470 make_tuple(&aom_highbd_lpf_horizontal_4_sse2, &aom_highbd_lpf_horizontal_4_c,
471 12),
472 make_tuple(&aom_highbd_lpf_vertical_4_sse2, &aom_highbd_lpf_vertical_4_c, 12),
473 make_tuple(&aom_highbd_lpf_horizontal_8_sse2, &aom_highbd_lpf_horizontal_8_c,
474 12),
Ryan26802752018-02-20 10:29:05 -0800475 make_tuple(&aom_highbd_lpf_horizontal_14_sse2,
476 &aom_highbd_lpf_horizontal_14_c, 12),
477 make_tuple(&aom_highbd_lpf_horizontal_14_dual_sse2,
478 &aom_highbd_lpf_horizontal_14_dual_c, 12),
479 make_tuple(&aom_highbd_lpf_vertical_14_sse2, &aom_highbd_lpf_vertical_14_c,
Maxym Dmytrychenkod6a7dd12018-02-09 22:35:03 +0100480 12),
Ryan26802752018-02-20 10:29:05 -0800481 make_tuple(&aom_highbd_lpf_vertical_14_dual_sse2,
482 &aom_highbd_lpf_vertical_14_dual_c, 8),
483 make_tuple(&aom_highbd_lpf_vertical_14_dual_sse2,
484 &aom_highbd_lpf_vertical_14_dual_c, 10),
485 make_tuple(&aom_highbd_lpf_vertical_14_dual_sse2,
486 &aom_highbd_lpf_vertical_14_dual_c, 12),
Ola Hugossonbda536a2017-10-19 22:34:13 +0200487 make_tuple(&aom_highbd_lpf_vertical_8_sse2, &aom_highbd_lpf_vertical_8_c, 12)
Yaowu Xu1fd71052017-06-19 15:59:00 -0700488};
489
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100490INSTANTIATE_TEST_CASE_P(SSE2, Loop8Test6Param_hbd,
Yaowu Xu1fd71052017-06-19 15:59:00 -0700491 ::testing::ValuesIn(kHbdLoop8Test6));
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100492
493const loop_param_t kLoop8Test6[] = {
494 make_tuple(&aom_lpf_horizontal_4_sse2, &aom_lpf_horizontal_4_c, 8),
495 make_tuple(&aom_lpf_horizontal_8_sse2, &aom_lpf_horizontal_8_c, 8),
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100496 make_tuple(&aom_lpf_horizontal_6_sse2, &aom_lpf_horizontal_6_c, 8),
497 make_tuple(&aom_lpf_vertical_6_sse2, &aom_lpf_vertical_6_c, 8),
Ryan26802752018-02-20 10:29:05 -0800498 make_tuple(&aom_lpf_horizontal_14_sse2, &aom_lpf_horizontal_14_c, 8),
499 make_tuple(&aom_lpf_horizontal_14_dual_sse2, &aom_lpf_horizontal_14_dual_c,
Maxym Dmytrychenkod6a7dd12018-02-09 22:35:03 +0100500 8),
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100501 make_tuple(&aom_lpf_vertical_4_sse2, &aom_lpf_vertical_4_c, 8),
502 make_tuple(&aom_lpf_vertical_8_sse2, &aom_lpf_vertical_8_c, 8),
Ryan26802752018-02-20 10:29:05 -0800503 make_tuple(&aom_lpf_vertical_14_sse2, &aom_lpf_vertical_14_c, 8),
504 make_tuple(&aom_lpf_vertical_14_dual_sse2, &aom_lpf_vertical_14_dual_c, 8)
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100505};
506
507INSTANTIATE_TEST_CASE_P(SSE2, Loop8Test6Param_lbd,
508 ::testing::ValuesIn(kLoop8Test6));
509
Yi Luo6f5569f2017-08-18 10:30:56 -0700510#endif // HAVE_SSE2
Deb Mukherjee27dce0f2014-11-07 10:19:46 -0800511
Yi Luo6f5569f2017-08-18 10:30:56 -0700512#if HAVE_SSE2
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100513const hbddual_loop_param_t kHbdLoop8Test9[] = {
Yaowu Xu1fd71052017-06-19 15:59:00 -0700514 make_tuple(&aom_highbd_lpf_horizontal_4_dual_sse2,
515 &aom_highbd_lpf_horizontal_4_dual_c, 8),
516 make_tuple(&aom_highbd_lpf_horizontal_8_dual_sse2,
517 &aom_highbd_lpf_horizontal_8_dual_c, 8),
518 make_tuple(&aom_highbd_lpf_vertical_4_dual_sse2,
519 &aom_highbd_lpf_vertical_4_dual_c, 8),
520 make_tuple(&aom_highbd_lpf_vertical_8_dual_sse2,
521 &aom_highbd_lpf_vertical_8_dual_c, 8),
522 make_tuple(&aom_highbd_lpf_horizontal_4_dual_sse2,
523 &aom_highbd_lpf_horizontal_4_dual_c, 10),
524 make_tuple(&aom_highbd_lpf_horizontal_8_dual_sse2,
525 &aom_highbd_lpf_horizontal_8_dual_c, 10),
526 make_tuple(&aom_highbd_lpf_vertical_4_dual_sse2,
527 &aom_highbd_lpf_vertical_4_dual_c, 10),
528 make_tuple(&aom_highbd_lpf_vertical_8_dual_sse2,
529 &aom_highbd_lpf_vertical_8_dual_c, 10),
530 make_tuple(&aom_highbd_lpf_horizontal_4_dual_sse2,
531 &aom_highbd_lpf_horizontal_4_dual_c, 12),
532 make_tuple(&aom_highbd_lpf_horizontal_8_dual_sse2,
533 &aom_highbd_lpf_horizontal_8_dual_c, 12),
534 make_tuple(&aom_highbd_lpf_vertical_4_dual_sse2,
535 &aom_highbd_lpf_vertical_4_dual_c, 12),
536 make_tuple(&aom_highbd_lpf_vertical_8_dual_sse2,
537 &aom_highbd_lpf_vertical_8_dual_c, 12)
538};
539
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100540INSTANTIATE_TEST_CASE_P(SSE2, Loop8Test9Param_hbd,
Yaowu Xu1fd71052017-06-19 15:59:00 -0700541 ::testing::ValuesIn(kHbdLoop8Test9));
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100542
Yi Luo6f5569f2017-08-18 10:30:56 -0700543#endif // HAVE_SSE2
levytamar8286175a52014-10-16 16:56:37 -0700544
Yi Luo6f5569f2017-08-18 10:30:56 -0700545#if HAVE_AVX2
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100546const hbddual_loop_param_t kHbdLoop8Test9Avx2[] = {
Yi Luo6ae00542017-08-03 17:08:20 -0700547 make_tuple(&aom_highbd_lpf_horizontal_4_dual_avx2,
548 &aom_highbd_lpf_horizontal_4_dual_c, 8),
549 make_tuple(&aom_highbd_lpf_horizontal_4_dual_avx2,
550 &aom_highbd_lpf_horizontal_4_dual_c, 10),
551 make_tuple(&aom_highbd_lpf_horizontal_4_dual_avx2,
552 &aom_highbd_lpf_horizontal_4_dual_c, 12),
553 make_tuple(&aom_highbd_lpf_horizontal_8_dual_avx2,
554 &aom_highbd_lpf_horizontal_8_dual_c, 8),
555 make_tuple(&aom_highbd_lpf_horizontal_8_dual_avx2,
556 &aom_highbd_lpf_horizontal_8_dual_c, 10),
557 make_tuple(&aom_highbd_lpf_horizontal_8_dual_avx2,
558 &aom_highbd_lpf_horizontal_8_dual_c, 12),
559 make_tuple(&aom_highbd_lpf_vertical_4_dual_avx2,
560 &aom_highbd_lpf_vertical_4_dual_c, 8),
561 make_tuple(&aom_highbd_lpf_vertical_4_dual_avx2,
562 &aom_highbd_lpf_vertical_4_dual_c, 10),
563 make_tuple(&aom_highbd_lpf_vertical_4_dual_avx2,
564 &aom_highbd_lpf_vertical_4_dual_c, 12),
565 make_tuple(&aom_highbd_lpf_vertical_8_dual_avx2,
566 &aom_highbd_lpf_vertical_8_dual_c, 8),
567 make_tuple(&aom_highbd_lpf_vertical_8_dual_avx2,
568 &aom_highbd_lpf_vertical_8_dual_c, 10),
569 make_tuple(&aom_highbd_lpf_vertical_8_dual_avx2,
570 &aom_highbd_lpf_vertical_8_dual_c, 12),
571};
572
Maxym Dmytrychenkoae6e6bc2018-01-25 16:42:36 +0100573INSTANTIATE_TEST_CASE_P(AVX2, Loop8Test9Param_hbd,
Yi Luo6ae00542017-08-03 17:08:20 -0700574 ::testing::ValuesIn(kHbdLoop8Test9Avx2));
575#endif
Deb Mukherjee931ed512014-09-17 16:55:05 -0700576} // namespace