OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved. |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ |
| 10 |
| 11 #include <cmath> |
| 12 #include <cstdlib> |
| 13 #include <string> |
| 14 |
| 15 #include "third_party/googletest/src/include/gtest/gtest.h" |
| 16 #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 |
| 21 #include "./vpx_config.h" |
| 22 #include "./vp9_rtcd.h" |
| 23 #include "vp9/common/vp9_entropy.h" |
| 24 #include "vpx/vpx_integer.h" |
| 25 |
| 26 using libvpx_test::ACMRandom; |
| 27 |
| 28 namespace { |
| 29 // Horizontally and Vertically need 32x32: 8 Coeffs preceeding filtered section |
| 30 // 16 Coefs within filtered section |
| 31 // 8 Coeffs following filtered section |
| 32 const int kNumCoeffs = 1024; |
| 33 |
| 34 const int number_of_iterations = 10000; |
| 35 |
| 36 #if CONFIG_VP9_HIGHBITDEPTH |
| 37 typedef void (*loop_op_t)(uint16_t *s, int p, const uint8_t *blimit, |
| 38 const uint8_t *limit, const uint8_t *thresh, |
| 39 int count, int bd); |
| 40 typedef void (*dual_loop_op_t)(uint16_t *s, int p, const uint8_t *blimit0, |
| 41 const uint8_t *limit0, const uint8_t *thresh0, |
| 42 const uint8_t *blimit1, const uint8_t *limit1, |
| 43 const uint8_t *thresh1, int bd); |
| 44 #else |
| 45 typedef void (*loop_op_t)(uint8_t *s, int p, const uint8_t *blimit, |
| 46 const uint8_t *limit, const uint8_t *thresh, |
| 47 int count); |
| 48 typedef void (*dual_loop_op_t)(uint8_t *s, int p, const uint8_t *blimit0, |
| 49 const uint8_t *limit0, const uint8_t *thresh0, |
| 50 const uint8_t *blimit1, const uint8_t *limit1, |
| 51 const uint8_t *thresh1); |
| 52 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 53 |
| 54 typedef std::tr1::tuple<loop_op_t, loop_op_t, int> loop8_param_t; |
| 55 typedef std::tr1::tuple<dual_loop_op_t, dual_loop_op_t, int> dualloop8_param_t; |
| 56 |
| 57 #if HAVE_SSE2 |
| 58 #if CONFIG_VP9_HIGHBITDEPTH |
| 59 void wrapper_vertical_16_sse2(uint16_t *s, int p, const uint8_t *blimit, |
| 60 const uint8_t *limit, const uint8_t *thresh, |
| 61 int count, int bd) { |
| 62 vp9_highbd_lpf_vertical_16_sse2(s, p, blimit, limit, thresh, bd); |
| 63 } |
| 64 |
| 65 void wrapper_vertical_16_c(uint16_t *s, int p, const uint8_t *blimit, |
| 66 const uint8_t *limit, const uint8_t *thresh, |
| 67 int count, int bd) { |
| 68 vp9_highbd_lpf_vertical_16_c(s, p, blimit, limit, thresh, bd); |
| 69 } |
| 70 |
| 71 void wrapper_vertical_16_dual_sse2(uint16_t *s, int p, const uint8_t *blimit, |
| 72 const uint8_t *limit, const uint8_t *thresh, |
| 73 int count, int bd) { |
| 74 vp9_highbd_lpf_vertical_16_dual_sse2(s, p, blimit, limit, thresh, bd); |
| 75 } |
| 76 |
| 77 void wrapper_vertical_16_dual_c(uint16_t *s, int p, const uint8_t *blimit, |
| 78 const uint8_t *limit, const uint8_t *thresh, |
| 79 int count, int bd) { |
| 80 vp9_highbd_lpf_vertical_16_dual_c(s, p, blimit, limit, thresh, bd); |
| 81 } |
| 82 #else |
| 83 void wrapper_vertical_16_sse2(uint8_t *s, int p, const uint8_t *blimit, |
| 84 const uint8_t *limit, const uint8_t *thresh, |
| 85 int count) { |
| 86 vp9_lpf_vertical_16_sse2(s, p, blimit, limit, thresh); |
| 87 } |
| 88 |
| 89 void wrapper_vertical_16_c(uint8_t *s, int p, const uint8_t *blimit, |
| 90 const uint8_t *limit, const uint8_t *thresh, |
| 91 int count) { |
| 92 vp9_lpf_vertical_16_c(s, p, blimit, limit, thresh); |
| 93 } |
| 94 |
| 95 void wrapper_vertical_16_dual_sse2(uint8_t *s, int p, const uint8_t *blimit, |
| 96 const uint8_t *limit, const uint8_t *thresh, |
| 97 int count) { |
| 98 vp9_lpf_vertical_16_dual_sse2(s, p, blimit, limit, thresh); |
| 99 } |
| 100 |
| 101 void wrapper_vertical_16_dual_c(uint8_t *s, int p, const uint8_t *blimit, |
| 102 const uint8_t *limit, const uint8_t *thresh, |
| 103 int count) { |
| 104 vp9_lpf_vertical_16_dual_c(s, p, blimit, limit, thresh); |
| 105 } |
| 106 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 107 #endif // HAVE_SSE2 |
| 108 |
| 109 class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> { |
| 110 public: |
| 111 virtual ~Loop8Test6Param() {} |
| 112 virtual void SetUp() { |
| 113 loopfilter_op_ = GET_PARAM(0); |
| 114 ref_loopfilter_op_ = GET_PARAM(1); |
| 115 bit_depth_ = GET_PARAM(2); |
| 116 mask_ = (1 << bit_depth_) - 1; |
| 117 } |
| 118 |
| 119 virtual void TearDown() { libvpx_test::ClearSystemState(); } |
| 120 |
| 121 protected: |
| 122 int bit_depth_; |
| 123 int mask_; |
| 124 loop_op_t loopfilter_op_; |
| 125 loop_op_t ref_loopfilter_op_; |
| 126 }; |
| 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 |
| 138 virtual void TearDown() { libvpx_test::ClearSystemState(); } |
| 139 |
| 140 protected: |
| 141 int bit_depth_; |
| 142 int mask_; |
| 143 dual_loop_op_t loopfilter_op_; |
| 144 dual_loop_op_t ref_loopfilter_op_; |
| 145 }; |
| 146 |
| 147 TEST_P(Loop8Test6Param, OperationCheck) { |
| 148 ACMRandom rnd(ACMRandom::DeterministicSeed()); |
| 149 const int count_test_block = number_of_iterations; |
| 150 #if CONFIG_VP9_HIGHBITDEPTH |
| 151 int32_t bd = bit_depth_; |
| 152 DECLARE_ALIGNED_ARRAY(16, uint16_t, s, kNumCoeffs); |
| 153 DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_s, kNumCoeffs); |
| 154 #else |
| 155 DECLARE_ALIGNED_ARRAY(8, uint8_t, s, kNumCoeffs); |
| 156 DECLARE_ALIGNED_ARRAY(8, uint8_t, ref_s, kNumCoeffs); |
| 157 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 158 int err_count_total = 0; |
| 159 int first_failure = -1; |
| 160 for (int i = 0; i < count_test_block; ++i) { |
| 161 int err_count = 0; |
| 162 uint8_t tmp = rnd.Rand8(); |
| 163 DECLARE_ALIGNED(16, const uint8_t, blimit[16]) = { |
| 164 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 165 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 166 }; |
| 167 tmp = rnd.Rand8(); |
| 168 DECLARE_ALIGNED(16, const uint8_t, limit[16]) = { |
| 169 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 170 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 171 }; |
| 172 tmp = rnd.Rand8(); |
| 173 DECLARE_ALIGNED(16, const uint8_t, thresh[16]) = { |
| 174 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 175 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 176 }; |
| 177 int32_t p = kNumCoeffs/32; |
| 178 int count = 1; |
| 179 |
| 180 uint16_t tmp_s[kNumCoeffs]; |
| 181 int j = 0; |
| 182 while (j < kNumCoeffs) { |
| 183 uint8_t val = rnd.Rand8(); |
| 184 if (val & 0x80) { // 50% chance to choose a new value. |
| 185 tmp_s[j] = rnd.Rand16(); |
| 186 j++; |
| 187 } else { // 50% chance to repeat previous value in row X times |
| 188 int k = 0; |
| 189 while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) { |
| 190 if (j < 1) { |
| 191 tmp_s[j] = rnd.Rand16(); |
| 192 } else if (val & 0x20) { // Increment by an value within the limit |
| 193 tmp_s[j] = (tmp_s[j - 1] + (*limit - 1)); |
| 194 } else { // Decrement by an value within the limit |
| 195 tmp_s[j] = (tmp_s[j - 1] - (*limit - 1)); |
| 196 } |
| 197 j++; |
| 198 } |
| 199 } |
| 200 } |
| 201 for (j = 0; j < kNumCoeffs; j++) { |
| 202 if (i % 2) { |
| 203 s[j] = tmp_s[j] & mask_; |
| 204 } else { |
| 205 s[j] = tmp_s[p * (j % p) + j / p] & mask_; |
| 206 } |
| 207 ref_s[j] = s[j]; |
| 208 } |
| 209 #if CONFIG_VP9_HIGHBITDEPTH |
| 210 ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, count, bd); |
| 211 ASM_REGISTER_STATE_CHECK( |
| 212 loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count, bd)); |
| 213 #else |
| 214 ref_loopfilter_op_(ref_s+8+p*8, p, blimit, limit, thresh, count); |
| 215 ASM_REGISTER_STATE_CHECK( |
| 216 loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count)); |
| 217 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 218 |
| 219 for (int j = 0; j < kNumCoeffs; ++j) { |
| 220 err_count += ref_s[j] != s[j]; |
| 221 } |
| 222 if (err_count && !err_count_total) { |
| 223 first_failure = i; |
| 224 } |
| 225 err_count_total += err_count; |
| 226 } |
| 227 EXPECT_EQ(0, err_count_total) |
| 228 << "Error: Loop8Test6Param, C output doesn't match SSE2 " |
| 229 "loopfilter output. " |
| 230 << "First failed at test case " << first_failure; |
| 231 } |
| 232 |
| 233 TEST_P(Loop8Test6Param, ValueCheck) { |
| 234 ACMRandom rnd(ACMRandom::DeterministicSeed()); |
| 235 const int count_test_block = number_of_iterations; |
| 236 #if CONFIG_VP9_HIGHBITDEPTH |
| 237 const int32_t bd = bit_depth_; |
| 238 DECLARE_ALIGNED_ARRAY(16, uint16_t, s, kNumCoeffs); |
| 239 DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_s, kNumCoeffs); |
| 240 #else |
| 241 DECLARE_ALIGNED_ARRAY(8, uint8_t, s, kNumCoeffs); |
| 242 DECLARE_ALIGNED_ARRAY(8, uint8_t, ref_s, kNumCoeffs); |
| 243 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 244 int err_count_total = 0; |
| 245 int first_failure = -1; |
| 246 for (int i = 0; i < count_test_block; ++i) { |
| 247 int err_count = 0; |
| 248 uint8_t tmp = rnd.Rand8(); |
| 249 DECLARE_ALIGNED(16, const uint8_t, blimit[16]) = { |
| 250 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 251 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 252 }; |
| 253 tmp = rnd.Rand8(); |
| 254 DECLARE_ALIGNED(16, const uint8_t, limit[16]) = { |
| 255 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 256 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 257 }; |
| 258 tmp = rnd.Rand8(); |
| 259 DECLARE_ALIGNED(16, const uint8_t, thresh[16]) = { |
| 260 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 261 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 262 }; |
| 263 int32_t p = kNumCoeffs / 32; |
| 264 int count = 1; |
| 265 for (int j = 0; j < kNumCoeffs; ++j) { |
| 266 s[j] = rnd.Rand16() & mask_; |
| 267 ref_s[j] = s[j]; |
| 268 } |
| 269 #if CONFIG_VP9_HIGHBITDEPTH |
| 270 ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, count, bd); |
| 271 ASM_REGISTER_STATE_CHECK( |
| 272 loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count, bd)); |
| 273 #else |
| 274 ref_loopfilter_op_(ref_s+8+p*8, p, blimit, limit, thresh, count); |
| 275 ASM_REGISTER_STATE_CHECK( |
| 276 loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count)); |
| 277 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 278 for (int j = 0; j < kNumCoeffs; ++j) { |
| 279 err_count += ref_s[j] != s[j]; |
| 280 } |
| 281 if (err_count && !err_count_total) { |
| 282 first_failure = i; |
| 283 } |
| 284 err_count_total += err_count; |
| 285 } |
| 286 EXPECT_EQ(0, err_count_total) |
| 287 << "Error: Loop8Test6Param, C output doesn't match SSE2 " |
| 288 "loopfilter output. " |
| 289 << "First failed at test case " << first_failure; |
| 290 } |
| 291 |
| 292 TEST_P(Loop8Test9Param, OperationCheck) { |
| 293 ACMRandom rnd(ACMRandom::DeterministicSeed()); |
| 294 const int count_test_block = number_of_iterations; |
| 295 #if CONFIG_VP9_HIGHBITDEPTH |
| 296 const int32_t bd = bit_depth_; |
| 297 DECLARE_ALIGNED_ARRAY(16, uint16_t, s, kNumCoeffs); |
| 298 DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_s, kNumCoeffs); |
| 299 #else |
| 300 DECLARE_ALIGNED_ARRAY(8, uint8_t, s, kNumCoeffs); |
| 301 DECLARE_ALIGNED_ARRAY(8, uint8_t, ref_s, kNumCoeffs); |
| 302 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 303 int err_count_total = 0; |
| 304 int first_failure = -1; |
| 305 for (int i = 0; i < count_test_block; ++i) { |
| 306 int err_count = 0; |
| 307 uint8_t tmp = rnd.Rand8(); |
| 308 DECLARE_ALIGNED(16, const uint8_t, blimit0[16]) = { |
| 309 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 310 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 311 }; |
| 312 tmp = rnd.Rand8(); |
| 313 DECLARE_ALIGNED(16, const uint8_t, limit0[16]) = { |
| 314 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 315 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 316 }; |
| 317 tmp = rnd.Rand8(); |
| 318 DECLARE_ALIGNED(16, const uint8_t, thresh0[16]) = { |
| 319 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 320 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 321 }; |
| 322 tmp = rnd.Rand8(); |
| 323 DECLARE_ALIGNED(16, const uint8_t, blimit1[16]) = { |
| 324 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 325 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 326 }; |
| 327 tmp = rnd.Rand8(); |
| 328 DECLARE_ALIGNED(16, const uint8_t, limit1[16]) = { |
| 329 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 330 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 331 }; |
| 332 tmp = rnd.Rand8(); |
| 333 DECLARE_ALIGNED(16, const uint8_t, thresh1[16]) = { |
| 334 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 335 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 336 }; |
| 337 int32_t p = kNumCoeffs / 32; |
| 338 uint16_t tmp_s[kNumCoeffs]; |
| 339 int j = 0; |
| 340 const uint8_t limit = *limit0 < *limit1 ? *limit0 : *limit1; |
| 341 while (j < kNumCoeffs) { |
| 342 uint8_t val = rnd.Rand8(); |
| 343 if (val & 0x80) { // 50% chance to choose a new value. |
| 344 tmp_s[j] = rnd.Rand16(); |
| 345 j++; |
| 346 } else { // 50% chance to repeat previous value in row X times. |
| 347 int k = 0; |
| 348 while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) { |
| 349 if (j < 1) { |
| 350 tmp_s[j] = rnd.Rand16(); |
| 351 } else if (val & 0x20) { // Increment by a value within the limit. |
| 352 tmp_s[j] = (tmp_s[j - 1] + (limit - 1)); |
| 353 } else { // Decrement by an value within the limit. |
| 354 tmp_s[j] = (tmp_s[j - 1] - (limit - 1)); |
| 355 } |
| 356 j++; |
| 357 } |
| 358 } |
| 359 } |
| 360 for (j = 0; j < kNumCoeffs; j++) { |
| 361 if (i % 2) { |
| 362 s[j] = tmp_s[j] & mask_; |
| 363 } else { |
| 364 s[j] = tmp_s[p * (j % p) + j / p] & mask_; |
| 365 } |
| 366 ref_s[j] = s[j]; |
| 367 } |
| 368 #if CONFIG_VP9_HIGHBITDEPTH |
| 369 ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, |
| 370 blimit1, limit1, thresh1, bd); |
| 371 ASM_REGISTER_STATE_CHECK( |
| 372 loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, thresh0, |
| 373 blimit1, limit1, thresh1, bd)); |
| 374 #else |
| 375 ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, |
| 376 blimit1, limit1, thresh1); |
| 377 ASM_REGISTER_STATE_CHECK( |
| 378 loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, thresh0, |
| 379 blimit1, limit1, thresh1)); |
| 380 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 381 for (int j = 0; j < kNumCoeffs; ++j) { |
| 382 err_count += ref_s[j] != s[j]; |
| 383 } |
| 384 if (err_count && !err_count_total) { |
| 385 first_failure = i; |
| 386 } |
| 387 err_count_total += err_count; |
| 388 } |
| 389 EXPECT_EQ(0, err_count_total) |
| 390 << "Error: Loop8Test9Param, C output doesn't match SSE2 " |
| 391 "loopfilter output. " |
| 392 << "First failed at test case " << first_failure; |
| 393 } |
| 394 |
| 395 TEST_P(Loop8Test9Param, ValueCheck) { |
| 396 ACMRandom rnd(ACMRandom::DeterministicSeed()); |
| 397 const int count_test_block = number_of_iterations; |
| 398 #if CONFIG_VP9_HIGHBITDEPTH |
| 399 DECLARE_ALIGNED_ARRAY(16, uint16_t, s, kNumCoeffs); |
| 400 DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_s, kNumCoeffs); |
| 401 #else |
| 402 DECLARE_ALIGNED_ARRAY(8, uint8_t, s, kNumCoeffs); |
| 403 DECLARE_ALIGNED_ARRAY(8, uint8_t, ref_s, kNumCoeffs); |
| 404 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 405 int err_count_total = 0; |
| 406 int first_failure = -1; |
| 407 for (int i = 0; i < count_test_block; ++i) { |
| 408 int err_count = 0; |
| 409 uint8_t tmp = rnd.Rand8(); |
| 410 DECLARE_ALIGNED(16, const uint8_t, blimit0[16]) = { |
| 411 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 412 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 413 }; |
| 414 tmp = rnd.Rand8(); |
| 415 DECLARE_ALIGNED(16, const uint8_t, limit0[16]) = { |
| 416 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 417 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 418 }; |
| 419 tmp = rnd.Rand8(); |
| 420 DECLARE_ALIGNED(16, const uint8_t, thresh0[16]) = { |
| 421 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 422 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 423 }; |
| 424 tmp = rnd.Rand8(); |
| 425 DECLARE_ALIGNED(16, const uint8_t, blimit1[16]) = { |
| 426 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 427 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 428 }; |
| 429 tmp = rnd.Rand8(); |
| 430 DECLARE_ALIGNED(16, const uint8_t, limit1[16]) = { |
| 431 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 432 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 433 }; |
| 434 tmp = rnd.Rand8(); |
| 435 DECLARE_ALIGNED(16, const uint8_t, thresh1[16]) = { |
| 436 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, |
| 437 tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp |
| 438 }; |
| 439 int32_t p = kNumCoeffs / 32; // TODO(pdlf) can we have non-square here? |
| 440 for (int j = 0; j < kNumCoeffs; ++j) { |
| 441 s[j] = rnd.Rand16() & mask_; |
| 442 ref_s[j] = s[j]; |
| 443 } |
| 444 #if CONFIG_VP9_HIGHBITDEPTH |
| 445 const int32_t bd = bit_depth_; |
| 446 ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, |
| 447 blimit1, limit1, thresh1, bd); |
| 448 ASM_REGISTER_STATE_CHECK( |
| 449 loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, |
| 450 thresh0, blimit1, limit1, thresh1, bd)); |
| 451 #else |
| 452 ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, |
| 453 blimit1, limit1, thresh1); |
| 454 ASM_REGISTER_STATE_CHECK( |
| 455 loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, thresh0, |
| 456 blimit1, limit1, thresh1)); |
| 457 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 458 for (int j = 0; j < kNumCoeffs; ++j) { |
| 459 err_count += ref_s[j] != s[j]; |
| 460 } |
| 461 if (err_count && !err_count_total) { |
| 462 first_failure = i; |
| 463 } |
| 464 err_count_total += err_count; |
| 465 } |
| 466 EXPECT_EQ(0, err_count_total) |
| 467 << "Error: Loop8Test9Param, C output doesn't match SSE2" |
| 468 "loopfilter output. " |
| 469 << "First failed at test case " << first_failure; |
| 470 } |
| 471 |
| 472 using std::tr1::make_tuple; |
| 473 |
| 474 #if HAVE_SSE2 |
| 475 #if CONFIG_VP9_HIGHBITDEPTH |
| 476 INSTANTIATE_TEST_CASE_P( |
| 477 SSE2_C_COMPARE_SINGLE, Loop8Test6Param, |
| 478 ::testing::Values( |
| 479 make_tuple(&vp9_highbd_lpf_horizontal_4_sse2, |
| 480 &vp9_highbd_lpf_horizontal_4_c, 8), |
| 481 make_tuple(&vp9_highbd_lpf_vertical_4_sse2, |
| 482 &vp9_highbd_lpf_vertical_4_c, 8), |
| 483 make_tuple(&vp9_highbd_lpf_horizontal_8_sse2, |
| 484 &vp9_highbd_lpf_horizontal_8_c, 8), |
| 485 make_tuple(&vp9_highbd_lpf_horizontal_16_sse2, |
| 486 &vp9_highbd_lpf_horizontal_16_c, 8), |
| 487 make_tuple(&vp9_highbd_lpf_vertical_8_sse2, |
| 488 &vp9_highbd_lpf_vertical_8_c, 8), |
| 489 make_tuple(&wrapper_vertical_16_sse2, |
| 490 &wrapper_vertical_16_c, 8), |
| 491 make_tuple(&vp9_highbd_lpf_horizontal_4_sse2, |
| 492 &vp9_highbd_lpf_horizontal_4_c, 10), |
| 493 make_tuple(&vp9_highbd_lpf_vertical_4_sse2, |
| 494 &vp9_highbd_lpf_vertical_4_c, 10), |
| 495 make_tuple(&vp9_highbd_lpf_horizontal_8_sse2, |
| 496 &vp9_highbd_lpf_horizontal_8_c, 10), |
| 497 make_tuple(&vp9_highbd_lpf_horizontal_16_sse2, |
| 498 &vp9_highbd_lpf_horizontal_16_c, 10), |
| 499 make_tuple(&vp9_highbd_lpf_vertical_8_sse2, |
| 500 &vp9_highbd_lpf_vertical_8_c, 10), |
| 501 make_tuple(&wrapper_vertical_16_sse2, |
| 502 &wrapper_vertical_16_c, 10), |
| 503 make_tuple(&vp9_highbd_lpf_horizontal_4_sse2, |
| 504 &vp9_highbd_lpf_horizontal_4_c, 12), |
| 505 make_tuple(&vp9_highbd_lpf_vertical_4_sse2, |
| 506 &vp9_highbd_lpf_vertical_4_c, 12), |
| 507 make_tuple(&vp9_highbd_lpf_horizontal_8_sse2, |
| 508 &vp9_highbd_lpf_horizontal_8_c, 12), |
| 509 make_tuple(&vp9_highbd_lpf_horizontal_16_sse2, |
| 510 &vp9_highbd_lpf_horizontal_16_c, 12), |
| 511 make_tuple(&vp9_highbd_lpf_vertical_8_sse2, |
| 512 &vp9_highbd_lpf_vertical_8_c, 12), |
| 513 make_tuple(&wrapper_vertical_16_sse2, |
| 514 &wrapper_vertical_16_c, 12))); |
| 515 #else |
| 516 INSTANTIATE_TEST_CASE_P( |
| 517 SSE2_C_COMPARE_SINGLE, Loop8Test6Param, |
| 518 ::testing::Values( |
| 519 make_tuple(&vp9_lpf_horizontal_8_sse2, &vp9_lpf_horizontal_8_c, 8), |
| 520 make_tuple(&vp9_lpf_horizontal_16_sse2, &vp9_lpf_horizontal_16_c, 8), |
| 521 make_tuple(&vp9_lpf_vertical_8_sse2, &vp9_lpf_vertical_8_c, 8))); |
| 522 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 523 #endif |
| 524 |
| 525 #if HAVE_SSE2 |
| 526 #if CONFIG_VP9_HIGHBITDEPTH |
| 527 INSTANTIATE_TEST_CASE_P( |
| 528 SSE2_C_COMPARE_DUAL, Loop8Test6Param, |
| 529 ::testing::Values( |
| 530 make_tuple(&wrapper_vertical_16_dual_sse2, |
| 531 &wrapper_vertical_16_dual_c, 8), |
| 532 make_tuple(&wrapper_vertical_16_dual_sse2, |
| 533 &wrapper_vertical_16_dual_c, 10), |
| 534 make_tuple(&wrapper_vertical_16_dual_sse2, |
| 535 &wrapper_vertical_16_dual_c, 12))); |
| 536 #else |
| 537 INSTANTIATE_TEST_CASE_P( |
| 538 SSE2_C_COMPARE_DUAL, Loop8Test6Param, |
| 539 ::testing::Values( |
| 540 make_tuple(&wrapper_vertical_16_sse2, &wrapper_vertical_16_c, 8))); |
| 541 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 542 #endif // HAVE_SSE2 |
| 543 |
| 544 #if HAVE_SSE2 |
| 545 #if CONFIG_VP9_HIGHBITDEPTH |
| 546 INSTANTIATE_TEST_CASE_P( |
| 547 SSE_C_COMPARE_DUAL, Loop8Test9Param, |
| 548 ::testing::Values( |
| 549 make_tuple(&vp9_highbd_lpf_horizontal_4_dual_sse2, |
| 550 &vp9_highbd_lpf_horizontal_4_dual_c, 8), |
| 551 make_tuple(&vp9_highbd_lpf_horizontal_8_dual_sse2, |
| 552 &vp9_highbd_lpf_horizontal_8_dual_c, 8), |
| 553 make_tuple(&vp9_highbd_lpf_vertical_4_dual_sse2, |
| 554 &vp9_highbd_lpf_vertical_4_dual_c, 8), |
| 555 make_tuple(&vp9_highbd_lpf_vertical_8_dual_sse2, |
| 556 &vp9_highbd_lpf_vertical_8_dual_c, 8), |
| 557 make_tuple(&vp9_highbd_lpf_horizontal_4_dual_sse2, |
| 558 &vp9_highbd_lpf_horizontal_4_dual_c, 10), |
| 559 make_tuple(&vp9_highbd_lpf_horizontal_8_dual_sse2, |
| 560 &vp9_highbd_lpf_horizontal_8_dual_c, 10), |
| 561 make_tuple(&vp9_highbd_lpf_vertical_4_dual_sse2, |
| 562 &vp9_highbd_lpf_vertical_4_dual_c, 10), |
| 563 make_tuple(&vp9_highbd_lpf_vertical_8_dual_sse2, |
| 564 &vp9_highbd_lpf_vertical_8_dual_c, 10), |
| 565 make_tuple(&vp9_highbd_lpf_horizontal_4_dual_sse2, |
| 566 &vp9_highbd_lpf_horizontal_4_dual_c, 12), |
| 567 make_tuple(&vp9_highbd_lpf_horizontal_8_dual_sse2, |
| 568 &vp9_highbd_lpf_horizontal_8_dual_c, 12), |
| 569 make_tuple(&vp9_highbd_lpf_vertical_4_dual_sse2, |
| 570 &vp9_highbd_lpf_vertical_4_dual_c, 12), |
| 571 make_tuple(&vp9_highbd_lpf_vertical_8_dual_sse2, |
| 572 &vp9_highbd_lpf_vertical_8_dual_c, 12))); |
| 573 #else |
| 574 INSTANTIATE_TEST_CASE_P( |
| 575 SSE_C_COMPARE_DUAL, Loop8Test9Param, |
| 576 ::testing::Values( |
| 577 make_tuple(&vp9_lpf_horizontal_4_dual_sse2, |
| 578 &vp9_lpf_horizontal_4_dual_c, 8), |
| 579 make_tuple(&vp9_lpf_horizontal_8_dual_sse2, |
| 580 &vp9_lpf_horizontal_8_dual_c, 8), |
| 581 make_tuple(&vp9_lpf_vertical_4_dual_sse2, |
| 582 &vp9_lpf_vertical_4_dual_c, 8), |
| 583 make_tuple(&vp9_lpf_vertical_8_dual_sse2, |
| 584 &vp9_lpf_vertical_8_dual_c, 8))); |
| 585 #endif // CONFIG_VP9_HIGHBITDEPTH |
| 586 #endif |
| 587 } // namespace |
OLD | NEW |