2 * Copyright (c) 2013 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.
17 #include "third_party/googletest/src/include/gtest/gtest.h"
19 #include "./vp9_rtcd.h"
20 #include "./vpx_dsp_rtcd.h"
21 #include "test/acm_random.h"
22 #include "test/clear_system_state.h"
23 #include "test/register_state_check.h"
24 #include "test/util.h"
25 #include "vp9/common/vp9_blockd.h"
26 #include "vp9/common/vp9_scan.h"
27 #include "vpx/vpx_integer.h"
28 #include "vpx_ports/vpx_timer.h"
30 using libvpx_test::ACMRandom;
34 typedef void (*FwdTxfmFunc)(const int16_t *in, tran_low_t *out, int stride);
36 #if CONFIG_VP9_HIGHBITDEPTH
37 typedef uint16_t Pixel;
38 typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride,
40 #else // !CONFIG_VP9_HIGHBITDEPTH
41 typedef uint8_t Pixel;
42 typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride);
43 #endif // CONFIG_VP9_HIGHBITDEPTH
45 typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, InvTxfmFunc, TX_SIZE, int,
48 const int kMaxNumCoeffs = 1024;
49 const int kCountTestBlock = 1000;
51 // https://bugs.chromium.org/p/webm/issues/detail?id=1332
52 // The functions specified do not pass with INT16_MIN/MAX. They fail at the
53 // value specified, but pass when 1 is added/subtracted.
54 int16_t MaxSupportedCoeff(InvTxfmFunc a) {
55 #if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_VP9_HIGHBITDEPTH && \
56 !CONFIG_EMULATE_HARDWARE
57 if (a == vpx_idct8x8_64_add_ssse3 || a == vpx_idct8x8_12_add_ssse3) {
63 return std::numeric_limits<int16_t>::max();
66 int16_t MinSupportedCoeff(InvTxfmFunc a) {
68 #if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_VP9_HIGHBITDEPTH && \
69 !CONFIG_EMULATE_HARDWARE
70 if (a == vpx_idct8x8_64_add_ssse3 || a == vpx_idct8x8_12_add_ssse3) {
73 #endif // !CONFIG_EMULATE_HARDWARE
74 return std::numeric_limits<int16_t>::min();
77 class PartialIDctTest : public ::testing::TestWithParam<PartialInvTxfmParam> {
79 virtual ~PartialIDctTest() {}
80 virtual void SetUp() {
81 rnd_.Reset(ACMRandom::DeterministicSeed());
82 ftxfm_ = GET_PARAM(0);
83 full_itxfm_ = GET_PARAM(1);
84 partial_itxfm_ = GET_PARAM(2);
85 tx_size_ = GET_PARAM(3);
86 last_nonzero_ = GET_PARAM(4);
87 bit_depth_ = GET_PARAM(5);
88 mask_ = (1 << bit_depth_) - 1;
91 case TX_4X4: size_ = 4; break;
92 case TX_8X8: size_ = 8; break;
93 case TX_16X16: size_ = 16; break;
94 case TX_32X32: size_ = 32; break;
95 default: FAIL() << "Wrong Size!"; break;
98 // Randomize stride_ to a value less than or equal to 1024
99 stride_ = rnd_(1024) + 1;
100 if (stride_ < size_) {
103 // Align stride_ to 16 if it's bigger than 16.
108 input_block_size_ = size_ * size_;
109 output_block_size_ = size_ * stride_;
111 input_block_ = reinterpret_cast<tran_low_t *>(
112 vpx_memalign(16, sizeof(*input_block_) * input_block_size_));
113 output_block_ = reinterpret_cast<Pixel *>(
114 vpx_memalign(16, sizeof(*output_block_) * output_block_size_));
115 output_block_ref_ = reinterpret_cast<Pixel *>(
116 vpx_memalign(16, sizeof(*output_block_ref_) * output_block_size_));
119 virtual void TearDown() {
120 vpx_free(input_block_);
122 vpx_free(output_block_);
123 output_block_ = NULL;
124 vpx_free(output_block_ref_);
125 output_block_ref_ = NULL;
126 libvpx_test::ClearSystemState();
130 memset(input_block_, 0, sizeof(*input_block_) * input_block_size_);
131 for (int j = 0; j < output_block_size_; ++j) {
132 output_block_[j] = output_block_ref_[j] = rnd_.Rand16() & mask_;
137 const int max_coeff = 32766 / 4;
138 int max_energy_leftover = max_coeff * max_coeff;
139 for (int j = 0; j < last_nonzero_; ++j) {
140 int16_t coeff = static_cast<int16_t>(sqrt(1.0 * max_energy_leftover) *
141 (rnd_.Rand16() - 32768) / 65536);
142 max_energy_leftover -= coeff * coeff;
143 if (max_energy_leftover < 0) {
144 max_energy_leftover = 0;
147 input_block_[vp9_default_scan_orders[tx_size_].scan[j]] = coeff;
151 void Exec(InvTxfmFunc func, void *out) {
152 #if CONFIG_VP9_HIGHBITDEPTH
153 func(input_block_, CONVERT_TO_BYTEPTR(out), stride_, bit_depth_);
155 func(input_block_, reinterpret_cast<uint8_t *>(out), stride_);
162 tran_low_t *input_block_;
163 Pixel *output_block_;
164 Pixel *output_block_ref_;
167 int input_block_size_;
168 int output_block_size_;
172 InvTxfmFunc full_itxfm_;
173 InvTxfmFunc partial_itxfm_;
177 TEST_P(PartialIDctTest, RunQuantCheck) {
178 DECLARE_ALIGNED(16, int16_t, input_extreme_block[kMaxNumCoeffs]);
179 DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kMaxNumCoeffs]);
181 for (int i = 0; i < kCountTestBlock; ++i) {
184 ACMRandom rnd(ACMRandom::DeterministicSeed());
186 for (int j = 0; j < kCountTestBlock; ++j) {
187 // Initialize a test block with input range [-mask_, mask_].
189 for (int k = 0; k < input_block_size_; ++k) {
190 input_extreme_block[k] = mask_;
193 for (int k = 0; k < input_block_size_; ++k) {
194 input_extreme_block[k] = -mask_;
197 for (int k = 0; k < input_block_size_; ++k) {
198 input_extreme_block[k] = rnd.Rand8() % 2 ? mask_ : -mask_;
202 ftxfm_(input_extreme_block, output_ref_block, size_);
204 // quantization with maximum allowed step sizes
205 input_block_[0] = (output_ref_block[0] / 1336) * 1336;
206 for (int k = 1; k < last_nonzero_; ++k) {
207 input_block_[vp9_default_scan_orders[tx_size_].scan[k]] =
208 (output_ref_block[k] / 1828) * 1828;
212 ASM_REGISTER_STATE_CHECK(Exec(full_itxfm_, output_block_ref_));
213 ASM_REGISTER_STATE_CHECK(Exec(partial_itxfm_, output_block_));
214 ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
215 sizeof(*output_block_) * output_block_size_))
216 << "Error: partial inverse transform produces different results";
220 TEST_P(PartialIDctTest, ResultsMatch) {
221 for (int i = 0; i < kCountTestBlock; ++i) {
225 ASM_REGISTER_STATE_CHECK(Exec(full_itxfm_, output_block_ref_));
226 ASM_REGISTER_STATE_CHECK(Exec(partial_itxfm_, output_block_));
228 ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
229 sizeof(*output_block_) * output_block_size_))
230 << "Error: partial inverse transform produces different results";
234 TEST_P(PartialIDctTest, AddOutputBlock) {
235 for (int i = 0; i < kCountTestBlock; ++i) {
237 for (int j = 0; j < last_nonzero_; ++j) {
238 input_block_[vp9_default_scan_orders[tx_size_].scan[j]] = 10;
241 ASM_REGISTER_STATE_CHECK(Exec(full_itxfm_, output_block_ref_));
242 ASM_REGISTER_STATE_CHECK(Exec(partial_itxfm_, output_block_));
244 ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
245 sizeof(*output_block_) * output_block_size_))
246 << "Error: Transform results are not correctly added to output.";
250 TEST_P(PartialIDctTest, SingleExtremeCoeff) {
251 const int16_t max_coeff = MaxSupportedCoeff(partial_itxfm_);
252 const int16_t min_coeff = MinSupportedCoeff(partial_itxfm_);
253 for (int i = 0; i < last_nonzero_; ++i) {
254 memset(input_block_, 0, sizeof(*input_block_) * input_block_size_);
255 // Run once for min and once for max.
256 for (int j = 0; j < 2; ++j) {
257 const int coeff = j ? min_coeff : max_coeff;
259 memset(output_block_, 0, sizeof(*output_block_) * output_block_size_);
260 memset(output_block_ref_, 0,
261 sizeof(*output_block_ref_) * output_block_size_);
262 input_block_[vp9_default_scan_orders[tx_size_].scan[i]] = coeff;
264 ASM_REGISTER_STATE_CHECK(Exec(full_itxfm_, output_block_ref_));
265 ASM_REGISTER_STATE_CHECK(Exec(partial_itxfm_, output_block_));
267 ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
268 sizeof(*output_block_) * output_block_size_))
269 << "Error: Fails with single coeff of " << coeff << " at " << i
275 TEST_P(PartialIDctTest, DISABLED_Speed) {
276 // Keep runtime stable with transform size.
277 const int kCountSpeedTestBlock = 500000000 / input_block_size_;
281 for (int i = 0; i < kCountSpeedTestBlock; ++i) {
282 ASM_REGISTER_STATE_CHECK(Exec(full_itxfm_, output_block_ref_));
284 vpx_usec_timer timer;
285 vpx_usec_timer_start(&timer);
286 for (int i = 0; i < kCountSpeedTestBlock; ++i) {
287 Exec(partial_itxfm_, output_block_);
289 libvpx_test::ClearSystemState();
290 vpx_usec_timer_mark(&timer);
291 const int elapsed_time =
292 static_cast<int>(vpx_usec_timer_elapsed(&timer) / 1000);
293 printf("idct%dx%d_%d (bitdepth %d) time: %5d ms ", size_, size_,
294 last_nonzero_, bit_depth_, elapsed_time);
296 ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
297 sizeof(*output_block_) * output_block_size_))
298 << "Error: partial inverse transform produces different results";
301 using std::tr1::make_tuple;
303 #if CONFIG_VP9_HIGHBITDEPTH
305 INSTANTIATE_TEST_CASE_P(
308 make_tuple(&vpx_highbd_fdct32x32_c, &vpx_highbd_idct32x32_1024_add_c,
309 &vpx_highbd_idct32x32_1024_add_c, TX_32X32, 1024, 8),
310 make_tuple(&vpx_highbd_fdct32x32_c, &vpx_highbd_idct32x32_1024_add_c,
311 &vpx_highbd_idct32x32_1024_add_c, TX_32X32, 1024, 10),
312 make_tuple(&vpx_highbd_fdct32x32_c, &vpx_highbd_idct32x32_1024_add_c,
313 &vpx_highbd_idct32x32_1024_add_c, TX_32X32, 1024, 12),
314 make_tuple(&vpx_highbd_fdct32x32_c, &vpx_highbd_idct32x32_1024_add_c,
315 &vpx_highbd_idct32x32_34_add_c, TX_32X32, 34, 8),
316 make_tuple(&vpx_highbd_fdct32x32_c, &vpx_highbd_idct32x32_1024_add_c,
317 &vpx_highbd_idct32x32_34_add_c, TX_32X32, 34, 10),
318 make_tuple(&vpx_highbd_fdct32x32_c, &vpx_highbd_idct32x32_1024_add_c,
319 &vpx_highbd_idct32x32_34_add_c, TX_32X32, 34, 12),
320 make_tuple(&vpx_highbd_fdct32x32_c, &vpx_highbd_idct32x32_1024_add_c,
321 &vpx_highbd_idct32x32_1_add_c, TX_32X32, 1, 8),
322 make_tuple(&vpx_highbd_fdct32x32_c, &vpx_highbd_idct32x32_1024_add_c,
323 &vpx_highbd_idct32x32_1_add_c, TX_32X32, 1, 10),
324 make_tuple(&vpx_highbd_fdct32x32_c, &vpx_highbd_idct32x32_1024_add_c,
325 &vpx_highbd_idct32x32_1_add_c, TX_32X32, 1, 12),
326 make_tuple(&vpx_highbd_fdct16x16_c, &vpx_highbd_idct16x16_256_add_c,
327 &vpx_highbd_idct16x16_256_add_c, TX_16X16, 256, 8),
328 make_tuple(&vpx_highbd_fdct16x16_c, &vpx_highbd_idct16x16_256_add_c,
329 &vpx_highbd_idct16x16_256_add_c, TX_16X16, 256, 10),
330 make_tuple(&vpx_highbd_fdct16x16_c, &vpx_highbd_idct16x16_256_add_c,
331 &vpx_highbd_idct16x16_256_add_c, TX_16X16, 256, 12),
332 make_tuple(&vpx_highbd_fdct16x16_c, &vpx_highbd_idct16x16_256_add_c,
333 &vpx_highbd_idct16x16_10_add_c, TX_16X16, 10, 8),
334 make_tuple(&vpx_highbd_fdct16x16_c, &vpx_highbd_idct16x16_256_add_c,
335 &vpx_highbd_idct16x16_10_add_c, TX_16X16, 10, 10),
336 make_tuple(&vpx_highbd_fdct16x16_c, &vpx_highbd_idct16x16_256_add_c,
337 &vpx_highbd_idct16x16_10_add_c, TX_16X16, 10, 12),
338 make_tuple(&vpx_highbd_fdct16x16_c, &vpx_highbd_idct16x16_256_add_c,
339 &vpx_highbd_idct16x16_1_add_c, TX_16X16, 1, 8),
340 make_tuple(&vpx_highbd_fdct16x16_c, &vpx_highbd_idct16x16_256_add_c,
341 &vpx_highbd_idct16x16_1_add_c, TX_16X16, 1, 10),
342 make_tuple(&vpx_highbd_fdct16x16_c, &vpx_highbd_idct16x16_256_add_c,
343 &vpx_highbd_idct16x16_1_add_c, TX_16X16, 1, 12),
344 make_tuple(&vpx_highbd_fdct8x8_c, &vpx_highbd_idct8x8_64_add_c,
345 &vpx_highbd_idct8x8_64_add_c, TX_8X8, 64, 8),
346 make_tuple(&vpx_highbd_fdct8x8_c, &vpx_highbd_idct8x8_64_add_c,
347 &vpx_highbd_idct8x8_64_add_c, TX_8X8, 64, 10),
348 make_tuple(&vpx_highbd_fdct8x8_c, &vpx_highbd_idct8x8_64_add_c,
349 &vpx_highbd_idct8x8_64_add_c, TX_8X8, 64, 12),
350 make_tuple(&vpx_highbd_fdct8x8_c, &vpx_highbd_idct8x8_64_add_c,
351 &vpx_highbd_idct8x8_12_add_c, TX_8X8, 12, 8),
352 make_tuple(&vpx_highbd_fdct8x8_c, &vpx_highbd_idct8x8_64_add_c,
353 &vpx_highbd_idct8x8_12_add_c, TX_8X8, 12, 10),
354 make_tuple(&vpx_highbd_fdct8x8_c, &vpx_highbd_idct8x8_64_add_c,
355 &vpx_highbd_idct8x8_12_add_c, TX_8X8, 12, 12),
356 make_tuple(&vpx_highbd_fdct8x8_c, &vpx_highbd_idct8x8_64_add_c,
357 &vpx_highbd_idct8x8_1_add_c, TX_8X8, 1, 8),
358 make_tuple(&vpx_highbd_fdct8x8_c, &vpx_highbd_idct8x8_64_add_c,
359 &vpx_highbd_idct8x8_1_add_c, TX_8X8, 1, 10),
360 make_tuple(&vpx_highbd_fdct8x8_c, &vpx_highbd_idct8x8_64_add_c,
361 &vpx_highbd_idct8x8_1_add_c, TX_8X8, 1, 12),
362 make_tuple(&vpx_highbd_fdct4x4_c, &vpx_highbd_idct4x4_16_add_c,
363 &vpx_highbd_idct4x4_16_add_c, TX_4X4, 16, 8),
364 make_tuple(&vpx_highbd_fdct4x4_c, &vpx_highbd_idct4x4_16_add_c,
365 &vpx_highbd_idct4x4_16_add_c, TX_4X4, 16, 10),
366 make_tuple(&vpx_highbd_fdct4x4_c, &vpx_highbd_idct4x4_16_add_c,
367 &vpx_highbd_idct4x4_16_add_c, TX_4X4, 16, 12),
368 make_tuple(&vpx_highbd_fdct4x4_c, &vpx_highbd_idct4x4_16_add_c,
369 &vpx_highbd_idct4x4_1_add_c, TX_4X4, 1, 8),
370 make_tuple(&vpx_highbd_fdct4x4_c, &vpx_highbd_idct4x4_16_add_c,
371 &vpx_highbd_idct4x4_1_add_c, TX_4X4, 1, 10),
372 make_tuple(&vpx_highbd_fdct4x4_c, &vpx_highbd_idct4x4_16_add_c,
373 &vpx_highbd_idct4x4_1_add_c, TX_4X4, 1, 12)));
375 #if HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
376 INSTANTIATE_TEST_CASE_P(
377 SSE2, PartialIDctTest,
379 make_tuple(&vpx_highbd_fdct32x32_c, &vpx_highbd_idct32x32_1024_add_c,
380 &vpx_highbd_idct32x32_1_add_sse2, TX_32X32, 1, 8),
381 make_tuple(&vpx_highbd_fdct32x32_c, &vpx_highbd_idct32x32_1024_add_c,
382 &vpx_highbd_idct32x32_1_add_sse2, TX_32X32, 1, 10),
383 make_tuple(&vpx_highbd_fdct32x32_c, &vpx_highbd_idct32x32_1024_add_c,
384 &vpx_highbd_idct32x32_1_add_sse2, TX_32X32, 1, 12),
385 make_tuple(&vpx_highbd_fdct16x16_c, &vpx_highbd_idct16x16_256_add_c,
386 &vpx_highbd_idct16x16_256_add_sse2, TX_16X16, 256, 8),
387 make_tuple(&vpx_highbd_fdct16x16_c, &vpx_highbd_idct16x16_256_add_c,
388 &vpx_highbd_idct16x16_256_add_sse2, TX_16X16, 256, 10),
389 make_tuple(&vpx_highbd_fdct16x16_c, &vpx_highbd_idct16x16_256_add_c,
390 &vpx_highbd_idct16x16_256_add_sse2, TX_16X16, 256, 12),
391 make_tuple(&vpx_highbd_fdct16x16_c, &vpx_highbd_idct16x16_256_add_c,
392 &vpx_highbd_idct16x16_10_add_sse2, TX_16X16, 10, 8),
393 make_tuple(&vpx_highbd_fdct16x16_c, &vpx_highbd_idct16x16_256_add_c,
394 &vpx_highbd_idct16x16_10_add_sse2, TX_16X16, 10, 10),
395 make_tuple(&vpx_highbd_fdct16x16_c, &vpx_highbd_idct16x16_256_add_c,
396 &vpx_highbd_idct16x16_10_add_sse2, TX_16X16, 10, 12),
397 make_tuple(&vpx_highbd_fdct8x8_c, &vpx_highbd_idct8x8_64_add_c,
398 &vpx_highbd_idct8x8_64_add_sse2, TX_8X8, 64, 8),
399 make_tuple(&vpx_highbd_fdct8x8_c, &vpx_highbd_idct8x8_64_add_c,
400 &vpx_highbd_idct8x8_64_add_sse2, TX_8X8, 64, 10),
401 make_tuple(&vpx_highbd_fdct8x8_c, &vpx_highbd_idct8x8_64_add_c,
402 &vpx_highbd_idct8x8_64_add_sse2, TX_8X8, 64, 12),
403 make_tuple(&vpx_highbd_fdct8x8_c, &vpx_highbd_idct8x8_64_add_c,
404 &vpx_highbd_idct8x8_12_add_sse2, TX_8X8, 12, 8),
405 make_tuple(&vpx_highbd_fdct8x8_c, &vpx_highbd_idct8x8_64_add_c,
406 &vpx_highbd_idct8x8_12_add_sse2, TX_8X8, 12, 10),
407 make_tuple(&vpx_highbd_fdct8x8_c, &vpx_highbd_idct8x8_64_add_c,
408 &vpx_highbd_idct8x8_12_add_sse2, TX_8X8, 12, 12),
409 make_tuple(&vpx_highbd_fdct4x4_c, &vpx_highbd_idct4x4_16_add_c,
410 &vpx_highbd_idct4x4_16_add_sse2, TX_4X4, 1, 8),
411 make_tuple(&vpx_highbd_fdct4x4_c, &vpx_highbd_idct4x4_16_add_c,
412 &vpx_highbd_idct4x4_16_add_sse2, TX_4X4, 1, 10),
413 make_tuple(&vpx_highbd_fdct4x4_c, &vpx_highbd_idct4x4_16_add_c,
414 &vpx_highbd_idct4x4_16_add_sse2, TX_4X4, 1, 12)));
415 #endif // HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
417 #if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
418 INSTANTIATE_TEST_CASE_P(
419 NEON, PartialIDctTest,
421 make_tuple(&vpx_highbd_fdct4x4_c, &vpx_highbd_idct4x4_16_add_c,
422 &vpx_highbd_idct4x4_16_add_neon, TX_4X4, 16, 8),
423 make_tuple(&vpx_highbd_fdct4x4_c, &vpx_highbd_idct4x4_16_add_c,
424 &vpx_highbd_idct4x4_16_add_neon, TX_4X4, 16, 10),
425 make_tuple(&vpx_highbd_fdct4x4_c, &vpx_highbd_idct4x4_16_add_c,
426 &vpx_highbd_idct4x4_16_add_neon, TX_4X4, 16, 12),
427 make_tuple(&vpx_highbd_fdct4x4_c, &vpx_highbd_idct4x4_1_add_c,
428 &vpx_highbd_idct4x4_1_add_neon, TX_4X4, 1, 8),
429 make_tuple(&vpx_highbd_fdct4x4_c, &vpx_highbd_idct4x4_1_add_c,
430 &vpx_highbd_idct4x4_1_add_neon, TX_4X4, 1, 10),
431 make_tuple(&vpx_highbd_fdct4x4_c, &vpx_highbd_idct4x4_1_add_c,
432 &vpx_highbd_idct4x4_1_add_neon, TX_4X4, 1, 12)));
433 #endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
435 #else // !CONFIG_VP9_HIGHBITDEPTH
437 INSTANTIATE_TEST_CASE_P(
439 ::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
440 &vpx_idct32x32_1024_add_c, TX_32X32, 1024, 8),
441 make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
442 &vpx_idct32x32_135_add_c, TX_32X32, 135, 8),
443 make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
444 &vpx_idct32x32_34_add_c, TX_32X32, 34, 8),
445 make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
446 &vpx_idct32x32_1_add_c, TX_32X32, 1, 8),
447 make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
448 &vpx_idct16x16_256_add_c, TX_16X16, 256, 8),
449 make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
450 &vpx_idct16x16_10_add_c, TX_16X16, 10, 8),
451 make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
452 &vpx_idct16x16_1_add_c, TX_16X16, 1, 8),
453 make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
454 &vpx_idct8x8_64_add_c, TX_8X8, 64, 8),
455 make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
456 &vpx_idct8x8_12_add_c, TX_8X8, 12, 8),
457 make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
458 &vpx_idct8x8_1_add_c, TX_8X8, 1, 8),
459 make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c,
460 &vpx_idct4x4_16_add_c, TX_4X4, 16, 8),
461 make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c,
462 &vpx_idct4x4_1_add_c, TX_4X4, 1, 8)));
464 #if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
465 INSTANTIATE_TEST_CASE_P(
466 NEON, PartialIDctTest,
467 ::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
468 &vpx_idct32x32_1024_add_neon, TX_32X32, 1024,
470 make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
471 &vpx_idct32x32_135_add_neon, TX_32X32, 135, 8),
472 make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
473 &vpx_idct32x32_34_add_neon, TX_32X32, 34, 8),
474 make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
475 &vpx_idct32x32_1_add_neon, TX_32X32, 1, 8),
476 make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
477 &vpx_idct16x16_256_add_neon, TX_16X16, 256, 8),
478 make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
479 &vpx_idct16x16_10_add_neon, TX_16X16, 10, 8),
480 make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
481 &vpx_idct16x16_1_add_neon, TX_16X16, 1, 8),
482 make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
483 &vpx_idct8x8_64_add_neon, TX_8X8, 64, 8),
484 make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
485 &vpx_idct8x8_12_add_neon, TX_8X8, 12, 8),
486 make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
487 &vpx_idct8x8_1_add_neon, TX_8X8, 1, 8),
488 make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c,
489 &vpx_idct4x4_16_add_neon, TX_4X4, 16, 8),
490 make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c,
491 &vpx_idct4x4_1_add_neon, TX_4X4, 1, 8)));
492 #endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
494 #if HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
495 // 32x32_135_ is implemented using the 1024 version.
496 INSTANTIATE_TEST_CASE_P(
497 SSE2, PartialIDctTest,
498 ::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
499 &vpx_idct32x32_1024_add_sse2, TX_32X32, 1024,
501 make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
502 &vpx_idct32x32_1024_add_sse2, TX_32X32, 135,
504 make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
505 &vpx_idct32x32_34_add_sse2, TX_32X32, 34, 8),
506 make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
507 &vpx_idct32x32_1_add_sse2, TX_32X32, 1, 8),
508 make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
509 &vpx_idct16x16_256_add_sse2, TX_16X16, 256, 8),
510 make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
511 &vpx_idct16x16_10_add_sse2, TX_16X16, 10, 8),
512 make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
513 &vpx_idct16x16_1_add_sse2, TX_16X16, 1, 8),
514 make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
515 &vpx_idct8x8_64_add_sse2, TX_8X8, 64, 8),
516 make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
517 &vpx_idct8x8_12_add_sse2, TX_8X8, 12, 8),
518 make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
519 &vpx_idct8x8_1_add_sse2, TX_8X8, 1, 8),
520 make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c,
521 &vpx_idct4x4_16_add_sse2, TX_4X4, 16, 8),
522 make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c,
523 &vpx_idct4x4_1_add_sse2, TX_4X4, 1, 8)));
524 #endif // HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
526 #if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_EMULATE_HARDWARE
527 INSTANTIATE_TEST_CASE_P(
528 SSSE3_64, PartialIDctTest,
529 ::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
530 &vpx_idct32x32_1024_add_ssse3, TX_32X32, 1024,
532 make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
533 &vpx_idct32x32_135_add_ssse3, TX_32X32, 135,
535 make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
536 &vpx_idct32x32_34_add_ssse3, TX_32X32, 34, 8),
537 make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
538 &vpx_idct8x8_64_add_ssse3, TX_8X8, 64, 8),
539 make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
540 &vpx_idct8x8_12_add_ssse3, TX_8X8, 12, 8)));
541 #endif // HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_EMULATE_HARDWARE
543 #if HAVE_MSA && !CONFIG_EMULATE_HARDWARE
544 // 32x32_135_ is implemented using the 1024 version.
545 INSTANTIATE_TEST_CASE_P(
546 MSA, PartialIDctTest,
547 ::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
548 &vpx_idct32x32_1024_add_msa, TX_32X32, 1024,
550 make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
551 &vpx_idct32x32_1024_add_msa, TX_32X32, 135, 8),
552 make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
553 &vpx_idct32x32_34_add_msa, TX_32X32, 34, 8),
554 make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
555 &vpx_idct32x32_1_add_msa, TX_32X32, 1, 8),
556 make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
557 &vpx_idct16x16_256_add_msa, TX_16X16, 256, 8),
558 make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
559 &vpx_idct16x16_10_add_msa, TX_16X16, 10, 8),
560 make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
561 &vpx_idct16x16_1_add_msa, TX_16X16, 1, 8),
562 make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
563 &vpx_idct8x8_64_add_msa, TX_8X8, 64, 8),
564 make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
565 &vpx_idct8x8_12_add_msa, TX_8X8, 10, 8),
566 make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
567 &vpx_idct8x8_1_add_msa, TX_8X8, 1, 8),
568 make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c,
569 &vpx_idct4x4_16_add_msa, TX_4X4, 16, 8),
570 make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c,
571 &vpx_idct4x4_1_add_msa, TX_4X4, 1, 8)));
572 #endif // HAVE_MSA && !CONFIG_EMULATE_HARDWARE
574 #endif // CONFIG_VP9_HIGHBITDEPTH