lpf_test.cc 32 KB

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