lpf_test.cc 32 KB

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