2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved.
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.
15 #include "third_party/googletest/src/include/gtest/gtest.h"
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"
27 using libvpx_test::ACMRandom;
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;
35 const int number_of_iterations = 10000;
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,
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);
46 typedef void (*loop_op_t)(uint8_t *s, int p, const uint8_t *blimit,
47 const uint8_t *limit, const uint8_t *thresh,
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
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;
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,
63 vpx_highbd_lpf_vertical_16_sse2(s, p, blimit, limit, thresh, bd);
66 void wrapper_vertical_16_c(uint16_t *s, int p, const uint8_t *blimit,
67 const uint8_t *limit, const uint8_t *thresh,
69 vpx_highbd_lpf_vertical_16_c(s, p, blimit, limit, thresh, bd);
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,
75 vpx_highbd_lpf_vertical_16_dual_sse2(s, p, blimit, limit, thresh, bd);
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,
81 vpx_highbd_lpf_vertical_16_dual_c(s, p, blimit, limit, thresh, bd);
84 void wrapper_vertical_16_sse2(uint8_t *s, int p, const uint8_t *blimit,
85 const uint8_t *limit, const uint8_t *thresh,
87 vpx_lpf_vertical_16_sse2(s, p, blimit, limit, thresh);
90 void wrapper_vertical_16_c(uint8_t *s, int p, const uint8_t *blimit,
91 const uint8_t *limit, const uint8_t *thresh,
93 vpx_lpf_vertical_16_c(s, p, blimit, limit, thresh);
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,
99 vpx_lpf_vertical_16_dual_sse2(s, p, blimit, limit, thresh);
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,
105 vpx_lpf_vertical_16_dual_c(s, p, blimit, limit, thresh);
107 #endif // CONFIG_VP9_HIGHBITDEPTH
111 #if CONFIG_VP9_HIGHBITDEPTH
112 // No neon high bitdepth functions.
114 void wrapper_vertical_16_neon(uint8_t *s, int p, const uint8_t *blimit,
115 const uint8_t *limit, const uint8_t *thresh,
117 vpx_lpf_vertical_16_neon(s, p, blimit, limit, thresh);
120 void wrapper_vertical_16_c(uint8_t *s, int p, const uint8_t *blimit,
121 const uint8_t *limit, const uint8_t *thresh,
123 vpx_lpf_vertical_16_c(s, p, blimit, limit, thresh);
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,
129 vpx_lpf_vertical_16_dual_neon(s, p, blimit, limit, thresh);
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,
135 vpx_lpf_vertical_16_dual_c(s, p, blimit, limit, thresh);
137 #endif // CONFIG_VP9_HIGHBITDEPTH
138 #endif // HAVE_NEON_ASM
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,
144 vpx_lpf_vertical_16_msa(s, p, blimit, limit, thresh);
147 void wrapper_vertical_16_c(uint8_t *s, int p, const uint8_t *blimit,
148 const uint8_t *limit, const uint8_t *thresh,
150 vpx_lpf_vertical_16_c(s, p, blimit, limit, thresh);
152 #endif // HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
154 class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> {
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;
165 virtual void TearDown() { libvpx_test::ClearSystemState(); }
171 loop_op_t loopfilter_op_;
172 loop_op_t ref_loopfilter_op_;
175 class Loop8Test9Param : public ::testing::TestWithParam<dualloop8_param_t> {
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;
185 virtual void TearDown() { libvpx_test::ClearSystemState(); }
190 dual_loop_op_t loopfilter_op_;
191 dual_loop_op_t ref_loopfilter_op_;
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]);
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) {
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
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
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
224 int32_t p = kNumCoeffs/32;
226 uint16_t tmp_s[kNumCoeffs];
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();
233 } else { // 50% chance to repeat previous value in row X times
235 while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
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));
247 for (j = 0; j < kNumCoeffs; j++) {
249 s[j] = tmp_s[j] & mask_;
251 s[j] = tmp_s[p * (j % p) + j / p] & mask_;
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));
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
265 for (int j = 0; j < kNumCoeffs; ++j) {
266 err_count += ref_s[j] != s[j];
268 if (err_count && !err_count_total) {
271 err_count_total += err_count;
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;
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]);
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;
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));
297 // memset(lfi->lfthr[lvl].mblim, (2 * (lvl + 2) + block_inside_limit),
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
305 for (int i = 0; i < count_test_block; ++i) {
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
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
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
322 int32_t p = kNumCoeffs / 32;
323 for (int j = 0; j < kNumCoeffs; ++j) {
324 s[j] = rnd.Rand16() & mask_;
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));
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];
339 if (err_count && !err_count_total) {
342 err_count_total += err_count;
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;
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]);
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) {
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
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
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
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
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
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
395 int32_t p = kNumCoeffs / 32;
396 uint16_t tmp_s[kNumCoeffs];
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();
404 } else { // 50% chance to repeat previous value in row X times.
406 while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
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));
418 for (j = 0; j < kNumCoeffs; j++) {
420 s[j] = tmp_s[j] & mask_;
422 s[j] = tmp_s[p * (j % p) + j / p] & mask_;
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));
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];
442 if (err_count && !err_count_total) {
445 err_count_total += err_count;
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;
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]);
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) {
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
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
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
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
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
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
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_;
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));
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];
519 if (err_count && !err_count_total) {
522 err_count_total += err_count;
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;
530 using std::tr1::make_tuple;
533 #if CONFIG_VP9_HIGHBITDEPTH
534 INSTANTIATE_TEST_CASE_P(
535 SSE2, Loop8Test6Param,
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)));
586 INSTANTIATE_TEST_CASE_P(
587 SSE2, Loop8Test6Param,
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
597 #if HAVE_AVX2 && (!CONFIG_VP9_HIGHBITDEPTH)
598 INSTANTIATE_TEST_CASE_P(
599 AVX2, Loop8Test6Param,
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,
607 #if CONFIG_VP9_HIGHBITDEPTH
608 INSTANTIATE_TEST_CASE_P(
609 SSE2, Loop8Test9Param,
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)));
636 INSTANTIATE_TEST_CASE_P(
637 SSE2, Loop8Test9Param,
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
651 #if CONFIG_VP9_HIGHBITDEPTH
652 // No neon high bitdepth functions.
654 INSTANTIATE_TEST_CASE_P(
655 NEON, Loop8Test6Param,
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,
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
693 #if HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
694 INSTANTIATE_TEST_CASE_P(
695 MSA, Loop8Test6Param,
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)));
703 INSTANTIATE_TEST_CASE_P(
704 MSA, Loop8Test9Param,
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)