]> granicus.if.org Git - libvpx/blob - test/partial_idct_test.cc
Add high bitdepth 4x4 idct NEON intrinsics
[libvpx] / test / partial_idct_test.cc
1 /*
2  *  Copyright (c) 2013 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 <math.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15 #include <limits>
16
17 #include "third_party/googletest/src/include/gtest/gtest.h"
18
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"
29
30 using libvpx_test::ACMRandom;
31
32 namespace {
33
34 typedef void (*FwdTxfmFunc)(const int16_t *in, tran_low_t *out, int stride);
35
36 #if CONFIG_VP9_HIGHBITDEPTH
37 typedef uint16_t Pixel;
38 typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride,
39                             int bd);
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
44
45 typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, InvTxfmFunc, TX_SIZE, int,
46                         int>
47     PartialInvTxfmParam;
48 const int kMaxNumCoeffs = 1024;
49 const int kCountTestBlock = 1000;
50
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) {
58     return 23625 - 1;
59   }
60 #else
61   (void)a;
62 #endif
63   return std::numeric_limits<int16_t>::max();
64 }
65
66 int16_t MinSupportedCoeff(InvTxfmFunc a) {
67   (void)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) {
71     return -23625 + 1;
72   }
73 #endif  // !CONFIG_EMULATE_HARDWARE
74   return std::numeric_limits<int16_t>::min();
75 }
76
77 class PartialIDctTest : public ::testing::TestWithParam<PartialInvTxfmParam> {
78  public:
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;
89
90     switch (tx_size_) {
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;
96     }
97
98     // Randomize stride_ to a value less than or equal to 1024
99     stride_ = rnd_(1024) + 1;
100     if (stride_ < size_) {
101       stride_ = size_;
102     }
103     // Align stride_ to 16 if it's bigger than 16.
104     if (stride_ > 16) {
105       stride_ &= ~15;
106     }
107
108     input_block_size_ = size_ * size_;
109     output_block_size_ = size_ * stride_;
110
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_));
117   }
118
119   virtual void TearDown() {
120     vpx_free(input_block_);
121     input_block_ = NULL;
122     vpx_free(output_block_);
123     output_block_ = NULL;
124     vpx_free(output_block_ref_);
125     output_block_ref_ = NULL;
126     libvpx_test::ClearSystemState();
127   }
128
129   void InitMem() {
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_;
133     }
134   }
135
136   void InitInput() {
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;
145         coeff = 0;
146       }
147       input_block_[vp9_default_scan_orders[tx_size_].scan[j]] = coeff;
148     }
149   }
150
151   void Exec(InvTxfmFunc func, void *out) {
152 #if CONFIG_VP9_HIGHBITDEPTH
153     func(input_block_, CONVERT_TO_BYTEPTR(out), stride_, bit_depth_);
154 #else
155     func(input_block_, reinterpret_cast<uint8_t *>(out), stride_);
156 #endif
157   }
158
159  protected:
160   int last_nonzero_;
161   TX_SIZE tx_size_;
162   tran_low_t *input_block_;
163   Pixel *output_block_;
164   Pixel *output_block_ref_;
165   int size_;
166   int stride_;
167   int input_block_size_;
168   int output_block_size_;
169   int bit_depth_;
170   int mask_;
171   FwdTxfmFunc ftxfm_;
172   InvTxfmFunc full_itxfm_;
173   InvTxfmFunc partial_itxfm_;
174   ACMRandom rnd_;
175 };
176
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]);
180
181   for (int i = 0; i < kCountTestBlock; ++i) {
182     InitMem();
183
184     ACMRandom rnd(ACMRandom::DeterministicSeed());
185
186     for (int j = 0; j < kCountTestBlock; ++j) {
187       // Initialize a test block with input range [-mask_, mask_].
188       if (j == 0) {
189         for (int k = 0; k < input_block_size_; ++k) {
190           input_extreme_block[k] = mask_;
191         }
192       } else if (j == 1) {
193         for (int k = 0; k < input_block_size_; ++k) {
194           input_extreme_block[k] = -mask_;
195         }
196       } else {
197         for (int k = 0; k < input_block_size_; ++k) {
198           input_extreme_block[k] = rnd.Rand8() % 2 ? mask_ : -mask_;
199         }
200       }
201
202       ftxfm_(input_extreme_block, output_ref_block, size_);
203
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;
209       }
210     }
211
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";
217   }
218 }
219
220 TEST_P(PartialIDctTest, ResultsMatch) {
221   for (int i = 0; i < kCountTestBlock; ++i) {
222     InitMem();
223     InitInput();
224
225     ASM_REGISTER_STATE_CHECK(Exec(full_itxfm_, output_block_ref_));
226     ASM_REGISTER_STATE_CHECK(Exec(partial_itxfm_, output_block_));
227
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";
231   }
232 }
233
234 TEST_P(PartialIDctTest, AddOutputBlock) {
235   for (int i = 0; i < kCountTestBlock; ++i) {
236     InitMem();
237     for (int j = 0; j < last_nonzero_; ++j) {
238       input_block_[vp9_default_scan_orders[tx_size_].scan[j]] = 10;
239     }
240
241     ASM_REGISTER_STATE_CHECK(Exec(full_itxfm_, output_block_ref_));
242     ASM_REGISTER_STATE_CHECK(Exec(partial_itxfm_, output_block_));
243
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.";
247   }
248 }
249
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;
258
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;
263
264       ASM_REGISTER_STATE_CHECK(Exec(full_itxfm_, output_block_ref_));
265       ASM_REGISTER_STATE_CHECK(Exec(partial_itxfm_, output_block_));
266
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
270           << ".";
271     }
272   }
273 }
274
275 TEST_P(PartialIDctTest, DISABLED_Speed) {
276   // Keep runtime stable with transform size.
277   const int kCountSpeedTestBlock = 500000000 / input_block_size_;
278   InitMem();
279   InitInput();
280
281   for (int i = 0; i < kCountSpeedTestBlock; ++i) {
282     ASM_REGISTER_STATE_CHECK(Exec(full_itxfm_, output_block_ref_));
283   }
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_);
288   }
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);
295
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";
299 }
300
301 using std::tr1::make_tuple;
302
303 #if CONFIG_VP9_HIGHBITDEPTH
304
305 INSTANTIATE_TEST_CASE_P(
306     C, PartialIDctTest,
307     ::testing::Values(
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)));
374
375 #if HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
376 INSTANTIATE_TEST_CASE_P(
377     SSE2, PartialIDctTest,
378     ::testing::Values(
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
416
417 #if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
418 INSTANTIATE_TEST_CASE_P(
419     NEON, PartialIDctTest,
420     ::testing::Values(
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
434
435 #else  // !CONFIG_VP9_HIGHBITDEPTH
436
437 INSTANTIATE_TEST_CASE_P(
438     C, PartialIDctTest,
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)));
463
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,
469                                  8),
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
493
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,
500                                  8),
501                       make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
502                                  &vpx_idct32x32_1024_add_sse2, TX_32X32, 135,
503                                  8),
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
525
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,
531                                  8),
532                       make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
533                                  &vpx_idct32x32_135_add_ssse3, TX_32X32, 135,
534                                  8),
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
542
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,
549                                  8),
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
573
574 #endif  // CONFIG_VP9_HIGHBITDEPTH
575
576 }  // namespace