1/*
2 *  Copyright (c) 2012 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
12#include <string.h>
13#include <limits.h>
14#include <stdio.h>
15
16#include "./vpx_config.h"
17#if CONFIG_VP8_ENCODER
18#include "./vp8_rtcd.h"
19#endif
20#if CONFIG_VP9_ENCODER
21#include "./vp9_rtcd.h"
22#endif
23#include "vpx_mem/vpx_mem.h"
24
25#include "test/acm_random.h"
26#include "test/clear_system_state.h"
27#include "test/register_state_check.h"
28#include "test/util.h"
29#include "third_party/googletest/src/include/gtest/gtest.h"
30
31
32#if CONFIG_VP8_ENCODER
33typedef unsigned int (*SadMxNFunc)(const unsigned char *source_ptr,
34                                   int source_stride,
35                                   const unsigned char *reference_ptr,
36                                   int reference_stride,
37                                   unsigned int max_sad);
38typedef std::tr1::tuple<int, int, SadMxNFunc> SadMxNParam;
39#endif
40#if CONFIG_VP9_ENCODER
41typedef unsigned int (*SadMxNVp9Func)(const unsigned char *source_ptr,
42                                      int source_stride,
43                                      const unsigned char *reference_ptr,
44                                      int reference_stride);
45typedef std::tr1::tuple<int, int, SadMxNVp9Func> SadMxNVp9Param;
46#endif
47
48typedef void (*SadMxNx4Func)(const uint8_t *src_ptr,
49                             int src_stride,
50                             const unsigned char *const ref_ptr[],
51                             int ref_stride,
52                             unsigned int *sad_array);
53typedef std::tr1::tuple<int, int, SadMxNx4Func> SadMxNx4Param;
54
55using libvpx_test::ACMRandom;
56
57namespace {
58class SADTestBase : public ::testing::Test {
59 public:
60  SADTestBase(int width, int height) : width_(width), height_(height) {}
61
62  static void SetUpTestCase() {
63    source_data_ = reinterpret_cast<uint8_t*>(
64        vpx_memalign(kDataAlignment, kDataBlockSize));
65    reference_data_ = reinterpret_cast<uint8_t*>(
66        vpx_memalign(kDataAlignment, kDataBufferSize));
67  }
68
69  static void TearDownTestCase() {
70    vpx_free(source_data_);
71    source_data_ = NULL;
72    vpx_free(reference_data_);
73    reference_data_ = NULL;
74  }
75
76  virtual void TearDown() {
77    libvpx_test::ClearSystemState();
78  }
79
80 protected:
81  // Handle blocks up to 4 blocks 64x64 with stride up to 128
82  static const int kDataAlignment = 16;
83  static const int kDataBlockSize = 64 * 128;
84  static const int kDataBufferSize = 4 * kDataBlockSize;
85
86  virtual void SetUp() {
87    source_stride_ = (width_ + 31) & ~31;
88    reference_stride_ = width_ * 2;
89    rnd_.Reset(ACMRandom::DeterministicSeed());
90  }
91
92  virtual uint8_t* GetReference(int block_idx) {
93    return reference_data_ + block_idx * kDataBlockSize;
94  }
95
96  // Sum of Absolute Differences. Given two blocks, calculate the absolute
97  // difference between two pixels in the same relative location; accumulate.
98  unsigned int ReferenceSAD(unsigned int max_sad, int block_idx) {
99    unsigned int sad = 0;
100    const uint8_t* const reference = GetReference(block_idx);
101
102    for (int h = 0; h < height_; ++h) {
103      for (int w = 0; w < width_; ++w) {
104        sad += abs(source_data_[h * source_stride_ + w]
105               - reference[h * reference_stride_ + w]);
106      }
107      if (sad > max_sad) {
108        break;
109      }
110    }
111    return sad;
112  }
113
114  void FillConstant(uint8_t *data, int stride, uint8_t fill_constant) {
115    for (int h = 0; h < height_; ++h) {
116      for (int w = 0; w < width_; ++w) {
117        data[h * stride + w] = fill_constant;
118      }
119    }
120  }
121
122  void FillRandom(uint8_t *data, int stride) {
123    for (int h = 0; h < height_; ++h) {
124      for (int w = 0; w < width_; ++w) {
125        data[h * stride + w] = rnd_.Rand8();
126      }
127    }
128  }
129
130  int width_, height_;
131  static uint8_t* source_data_;
132  int source_stride_;
133  static uint8_t* reference_data_;
134  int reference_stride_;
135
136  ACMRandom rnd_;
137};
138
139class SADx4Test
140    : public SADTestBase,
141      public ::testing::WithParamInterface<SadMxNx4Param> {
142 public:
143  SADx4Test() : SADTestBase(GET_PARAM(0), GET_PARAM(1)) {}
144
145 protected:
146  void SADs(unsigned int *results) {
147    const uint8_t* refs[] = {GetReference(0), GetReference(1),
148                             GetReference(2), GetReference(3)};
149
150    ASM_REGISTER_STATE_CHECK(GET_PARAM(2)(source_data_, source_stride_,
151                                          refs, reference_stride_,
152                                          results));
153  }
154
155  void CheckSADs() {
156    unsigned int reference_sad, exp_sad[4];
157
158    SADs(exp_sad);
159    for (int block = 0; block < 4; ++block) {
160      reference_sad = ReferenceSAD(UINT_MAX, block);
161
162      EXPECT_EQ(reference_sad, exp_sad[block]) << "block " << block;
163    }
164  }
165};
166
167#if CONFIG_VP8_ENCODER
168class SADTest
169    : public SADTestBase,
170      public ::testing::WithParamInterface<SadMxNParam> {
171 public:
172  SADTest() : SADTestBase(GET_PARAM(0), GET_PARAM(1)) {}
173
174 protected:
175  unsigned int SAD(unsigned int max_sad, int block_idx) {
176    unsigned int ret;
177    const uint8_t* const reference = GetReference(block_idx);
178
179    ASM_REGISTER_STATE_CHECK(ret = GET_PARAM(2)(source_data_, source_stride_,
180                                                reference, reference_stride_,
181                                                max_sad));
182    return ret;
183  }
184
185  void CheckSAD(unsigned int max_sad) {
186    const unsigned int reference_sad = ReferenceSAD(max_sad, 0);
187    const unsigned int exp_sad = SAD(max_sad, 0);
188
189    if (reference_sad <= max_sad) {
190      ASSERT_EQ(exp_sad, reference_sad);
191    } else {
192      // Alternative implementations are not required to check max_sad
193      ASSERT_GE(exp_sad, reference_sad);
194    }
195  }
196};
197#endif  // CONFIG_VP8_ENCODER
198
199#if CONFIG_VP9_ENCODER
200class SADVP9Test
201    : public SADTestBase,
202      public ::testing::WithParamInterface<SadMxNVp9Param> {
203 public:
204  SADVP9Test() : SADTestBase(GET_PARAM(0), GET_PARAM(1)) {}
205
206 protected:
207  unsigned int SAD(int block_idx) {
208    unsigned int ret;
209    const uint8_t* const reference = GetReference(block_idx);
210
211    ASM_REGISTER_STATE_CHECK(ret = GET_PARAM(2)(source_data_, source_stride_,
212                                                reference, reference_stride_));
213    return ret;
214  }
215
216  void CheckSAD() {
217    const unsigned int reference_sad = ReferenceSAD(UINT_MAX, 0);
218    const unsigned int exp_sad = SAD(0);
219
220    ASSERT_EQ(reference_sad, exp_sad);
221  }
222};
223#endif  // CONFIG_VP9_ENCODER
224
225uint8_t* SADTestBase::source_data_ = NULL;
226uint8_t* SADTestBase::reference_data_ = NULL;
227
228#if CONFIG_VP8_ENCODER
229TEST_P(SADTest, MaxRef) {
230  FillConstant(source_data_, source_stride_, 0);
231  FillConstant(reference_data_, reference_stride_, 255);
232  CheckSAD(UINT_MAX);
233}
234
235TEST_P(SADTest, MaxSrc) {
236  FillConstant(source_data_, source_stride_, 255);
237  FillConstant(reference_data_, reference_stride_, 0);
238  CheckSAD(UINT_MAX);
239}
240
241TEST_P(SADTest, ShortRef) {
242  int tmp_stride = reference_stride_;
243  reference_stride_ >>= 1;
244  FillRandom(source_data_, source_stride_);
245  FillRandom(reference_data_, reference_stride_);
246  CheckSAD(UINT_MAX);
247  reference_stride_ = tmp_stride;
248}
249
250TEST_P(SADTest, UnalignedRef) {
251  // The reference frame, but not the source frame, may be unaligned for
252  // certain types of searches.
253  const int tmp_stride = reference_stride_;
254  reference_stride_ -= 1;
255  FillRandom(source_data_, source_stride_);
256  FillRandom(reference_data_, reference_stride_);
257  CheckSAD(UINT_MAX);
258  reference_stride_ = tmp_stride;
259}
260
261TEST_P(SADTest, ShortSrc) {
262  const int tmp_stride = source_stride_;
263  source_stride_ >>= 1;
264  FillRandom(source_data_, source_stride_);
265  FillRandom(reference_data_, reference_stride_);
266  CheckSAD(UINT_MAX);
267  source_stride_ = tmp_stride;
268}
269
270TEST_P(SADTest, MaxSAD) {
271  // Verify that, when max_sad is set, the implementation does not return a
272  // value lower than the reference.
273  FillConstant(source_data_, source_stride_, 255);
274  FillConstant(reference_data_, reference_stride_, 0);
275  CheckSAD(128);
276}
277#endif  // CONFIG_VP8_ENCODER
278
279#if CONFIG_VP9_ENCODER
280TEST_P(SADVP9Test, MaxRef) {
281  FillConstant(source_data_, source_stride_, 0);
282  FillConstant(reference_data_, reference_stride_, 255);
283  CheckSAD();
284}
285
286TEST_P(SADVP9Test, MaxSrc) {
287  FillConstant(source_data_, source_stride_, 255);
288  FillConstant(reference_data_, reference_stride_, 0);
289  CheckSAD();
290}
291
292TEST_P(SADVP9Test, ShortRef) {
293  const int tmp_stride = reference_stride_;
294  reference_stride_ >>= 1;
295  FillRandom(source_data_, source_stride_);
296  FillRandom(reference_data_, reference_stride_);
297  CheckSAD();
298  reference_stride_ = tmp_stride;
299}
300
301TEST_P(SADVP9Test, UnalignedRef) {
302  // The reference frame, but not the source frame, may be unaligned for
303  // certain types of searches.
304  const int tmp_stride = reference_stride_;
305  reference_stride_ -= 1;
306  FillRandom(source_data_, source_stride_);
307  FillRandom(reference_data_, reference_stride_);
308  CheckSAD();
309  reference_stride_ = tmp_stride;
310}
311
312TEST_P(SADVP9Test, ShortSrc) {
313  const int tmp_stride = source_stride_;
314  source_stride_ >>= 1;
315  FillRandom(source_data_, source_stride_);
316  FillRandom(reference_data_, reference_stride_);
317  CheckSAD();
318  source_stride_ = tmp_stride;
319}
320#endif  // CONFIG_VP9_ENCODER
321
322TEST_P(SADx4Test, MaxRef) {
323  FillConstant(source_data_, source_stride_, 0);
324  FillConstant(GetReference(0), reference_stride_, 255);
325  FillConstant(GetReference(1), reference_stride_, 255);
326  FillConstant(GetReference(2), reference_stride_, 255);
327  FillConstant(GetReference(3), reference_stride_, 255);
328  CheckSADs();
329}
330
331TEST_P(SADx4Test, MaxSrc) {
332  FillConstant(source_data_, source_stride_, 255);
333  FillConstant(GetReference(0), reference_stride_, 0);
334  FillConstant(GetReference(1), reference_stride_, 0);
335  FillConstant(GetReference(2), reference_stride_, 0);
336  FillConstant(GetReference(3), reference_stride_, 0);
337  CheckSADs();
338}
339
340TEST_P(SADx4Test, ShortRef) {
341  int tmp_stride = reference_stride_;
342  reference_stride_ >>= 1;
343  FillRandom(source_data_, source_stride_);
344  FillRandom(GetReference(0), reference_stride_);
345  FillRandom(GetReference(1), reference_stride_);
346  FillRandom(GetReference(2), reference_stride_);
347  FillRandom(GetReference(3), reference_stride_);
348  CheckSADs();
349  reference_stride_ = tmp_stride;
350}
351
352TEST_P(SADx4Test, UnalignedRef) {
353  // The reference frame, but not the source frame, may be unaligned for
354  // certain types of searches.
355  int tmp_stride = reference_stride_;
356  reference_stride_ -= 1;
357  FillRandom(source_data_, source_stride_);
358  FillRandom(GetReference(0), reference_stride_);
359  FillRandom(GetReference(1), reference_stride_);
360  FillRandom(GetReference(2), reference_stride_);
361  FillRandom(GetReference(3), reference_stride_);
362  CheckSADs();
363  reference_stride_ = tmp_stride;
364}
365
366TEST_P(SADx4Test, ShortSrc) {
367  int tmp_stride = source_stride_;
368  source_stride_ >>= 1;
369  FillRandom(source_data_, source_stride_);
370  FillRandom(GetReference(0), reference_stride_);
371  FillRandom(GetReference(1), reference_stride_);
372  FillRandom(GetReference(2), reference_stride_);
373  FillRandom(GetReference(3), reference_stride_);
374  CheckSADs();
375  source_stride_ = tmp_stride;
376}
377
378using std::tr1::make_tuple;
379
380//------------------------------------------------------------------------------
381// C functions
382#if CONFIG_VP8_ENCODER
383const SadMxNFunc sad_16x16_c = vp8_sad16x16_c;
384const SadMxNFunc sad_8x16_c = vp8_sad8x16_c;
385const SadMxNFunc sad_16x8_c = vp8_sad16x8_c;
386const SadMxNFunc sad_8x8_c = vp8_sad8x8_c;
387const SadMxNFunc sad_4x4_c = vp8_sad4x4_c;
388const SadMxNParam c_tests[] = {
389  make_tuple(16, 16, sad_16x16_c),
390  make_tuple(8, 16, sad_8x16_c),
391  make_tuple(16, 8, sad_16x8_c),
392  make_tuple(8, 8, sad_8x8_c),
393  make_tuple(4, 4, sad_4x4_c),
394};
395INSTANTIATE_TEST_CASE_P(C, SADTest, ::testing::ValuesIn(c_tests));
396#endif  // CONFIG_VP8_ENCODER
397
398#if CONFIG_VP9_ENCODER
399const SadMxNVp9Func sad_64x64_c_vp9 = vp9_sad64x64_c;
400const SadMxNVp9Func sad_32x32_c_vp9 = vp9_sad32x32_c;
401const SadMxNVp9Func sad_16x16_c_vp9 = vp9_sad16x16_c;
402const SadMxNVp9Func sad_8x16_c_vp9 = vp9_sad8x16_c;
403const SadMxNVp9Func sad_16x8_c_vp9 = vp9_sad16x8_c;
404const SadMxNVp9Func sad_8x8_c_vp9 = vp9_sad8x8_c;
405const SadMxNVp9Func sad_8x4_c_vp9 = vp9_sad8x4_c;
406const SadMxNVp9Func sad_4x8_c_vp9 = vp9_sad4x8_c;
407const SadMxNVp9Func sad_4x4_c_vp9 = vp9_sad4x4_c;
408const SadMxNVp9Param c_vp9_tests[] = {
409  make_tuple(64, 64, sad_64x64_c_vp9),
410  make_tuple(32, 32, sad_32x32_c_vp9),
411  make_tuple(16, 16, sad_16x16_c_vp9),
412  make_tuple(8, 16, sad_8x16_c_vp9),
413  make_tuple(16, 8, sad_16x8_c_vp9),
414  make_tuple(8, 8, sad_8x8_c_vp9),
415  make_tuple(8, 4, sad_8x4_c_vp9),
416  make_tuple(4, 8, sad_4x8_c_vp9),
417  make_tuple(4, 4, sad_4x4_c_vp9),
418};
419INSTANTIATE_TEST_CASE_P(C, SADVP9Test, ::testing::ValuesIn(c_vp9_tests));
420
421const SadMxNx4Func sad_64x64x4d_c = vp9_sad64x64x4d_c;
422const SadMxNx4Func sad_64x32x4d_c = vp9_sad64x32x4d_c;
423const SadMxNx4Func sad_32x64x4d_c = vp9_sad32x64x4d_c;
424const SadMxNx4Func sad_32x32x4d_c = vp9_sad32x32x4d_c;
425const SadMxNx4Func sad_32x16x4d_c = vp9_sad32x16x4d_c;
426const SadMxNx4Func sad_16x32x4d_c = vp9_sad16x32x4d_c;
427const SadMxNx4Func sad_16x16x4d_c = vp9_sad16x16x4d_c;
428const SadMxNx4Func sad_16x8x4d_c = vp9_sad16x8x4d_c;
429const SadMxNx4Func sad_8x16x4d_c = vp9_sad8x16x4d_c;
430const SadMxNx4Func sad_8x8x4d_c = vp9_sad8x8x4d_c;
431const SadMxNx4Func sad_8x4x4d_c = vp9_sad8x4x4d_c;
432const SadMxNx4Func sad_4x8x4d_c = vp9_sad4x8x4d_c;
433const SadMxNx4Func sad_4x4x4d_c = vp9_sad4x4x4d_c;
434INSTANTIATE_TEST_CASE_P(C, SADx4Test, ::testing::Values(
435                        make_tuple(64, 64, sad_64x64x4d_c),
436                        make_tuple(64, 32, sad_64x32x4d_c),
437                        make_tuple(32, 64, sad_32x64x4d_c),
438                        make_tuple(32, 32, sad_32x32x4d_c),
439                        make_tuple(32, 16, sad_32x16x4d_c),
440                        make_tuple(16, 32, sad_16x32x4d_c),
441                        make_tuple(16, 16, sad_16x16x4d_c),
442                        make_tuple(16, 8, sad_16x8x4d_c),
443                        make_tuple(8, 16, sad_8x16x4d_c),
444                        make_tuple(8, 8, sad_8x8x4d_c),
445                        make_tuple(8, 4, sad_8x4x4d_c),
446                        make_tuple(4, 8, sad_4x8x4d_c),
447                        make_tuple(4, 4, sad_4x4x4d_c)));
448#endif  // CONFIG_VP9_ENCODER
449
450//------------------------------------------------------------------------------
451// ARM functions
452#if HAVE_MEDIA
453#if CONFIG_VP8_ENCODER
454const SadMxNFunc sad_16x16_armv6 = vp8_sad16x16_armv6;
455INSTANTIATE_TEST_CASE_P(MEDIA, SADTest, ::testing::Values(
456                        make_tuple(16, 16, sad_16x16_armv6)));
457#endif  // CONFIG_VP8_ENCODER
458#endif  // HAVE_MEDIA
459
460#if HAVE_NEON
461#if CONFIG_VP8_ENCODER
462const SadMxNFunc sad_16x16_neon = vp8_sad16x16_neon;
463const SadMxNFunc sad_8x16_neon = vp8_sad8x16_neon;
464const SadMxNFunc sad_16x8_neon = vp8_sad16x8_neon;
465const SadMxNFunc sad_8x8_neon = vp8_sad8x8_neon;
466const SadMxNFunc sad_4x4_neon = vp8_sad4x4_neon;
467INSTANTIATE_TEST_CASE_P(NEON, SADTest, ::testing::Values(
468                        make_tuple(16, 16, sad_16x16_neon),
469                        make_tuple(8, 16, sad_8x16_neon),
470                        make_tuple(16, 8, sad_16x8_neon),
471                        make_tuple(8, 8, sad_8x8_neon),
472                        make_tuple(4, 4, sad_4x4_neon)));
473#endif  // CONFIG_VP8_ENCODER
474#if CONFIG_VP9_ENCODER
475const SadMxNVp9Func sad_64x64_neon_vp9 = vp9_sad64x64_neon;
476const SadMxNVp9Func sad_32x32_neon_vp9 = vp9_sad32x32_neon;
477const SadMxNVp9Func sad_16x16_neon_vp9 = vp9_sad16x16_neon;
478const SadMxNVp9Func sad_8x8_neon_vp9 = vp9_sad8x8_neon;
479const SadMxNVp9Param neon_vp9_tests[] = {
480  make_tuple(64, 64, sad_64x64_neon_vp9),
481  make_tuple(32, 32, sad_32x32_neon_vp9),
482  make_tuple(16, 16, sad_16x16_neon_vp9),
483  make_tuple(8, 8, sad_8x8_neon_vp9),
484};
485INSTANTIATE_TEST_CASE_P(NEON, SADVP9Test, ::testing::ValuesIn(neon_vp9_tests));
486#endif  // CONFIG_VP9_ENCODER
487#endif  // HAVE_NEON
488
489//------------------------------------------------------------------------------
490// x86 functions
491#if HAVE_MMX
492#if CONFIG_VP8_ENCODER
493const SadMxNFunc sad_16x16_mmx = vp8_sad16x16_mmx;
494const SadMxNFunc sad_8x16_mmx = vp8_sad8x16_mmx;
495const SadMxNFunc sad_16x8_mmx = vp8_sad16x8_mmx;
496const SadMxNFunc sad_8x8_mmx = vp8_sad8x8_mmx;
497const SadMxNFunc sad_4x4_mmx = vp8_sad4x4_mmx;
498const SadMxNParam mmx_tests[] = {
499  make_tuple(16, 16, sad_16x16_mmx),
500  make_tuple(8, 16, sad_8x16_mmx),
501  make_tuple(16, 8, sad_16x8_mmx),
502  make_tuple(8, 8, sad_8x8_mmx),
503  make_tuple(4, 4, sad_4x4_mmx),
504};
505INSTANTIATE_TEST_CASE_P(MMX, SADTest, ::testing::ValuesIn(mmx_tests));
506#endif  // CONFIG_VP8_ENCODER
507
508#endif  // HAVE_MMX
509
510#if HAVE_SSE
511#if CONFIG_VP9_ENCODER
512#if CONFIG_USE_X86INC
513const SadMxNVp9Func sad_4x4_sse_vp9 = vp9_sad4x4_sse;
514const SadMxNVp9Func sad_4x8_sse_vp9 = vp9_sad4x8_sse;
515INSTANTIATE_TEST_CASE_P(SSE, SADVP9Test, ::testing::Values(
516                        make_tuple(4, 4, sad_4x4_sse_vp9),
517                        make_tuple(4, 8, sad_4x8_sse_vp9)));
518
519const SadMxNx4Func sad_4x8x4d_sse = vp9_sad4x8x4d_sse;
520const SadMxNx4Func sad_4x4x4d_sse = vp9_sad4x4x4d_sse;
521INSTANTIATE_TEST_CASE_P(SSE, SADx4Test, ::testing::Values(
522                        make_tuple(4, 8, sad_4x8x4d_sse),
523                        make_tuple(4, 4, sad_4x4x4d_sse)));
524#endif  // CONFIG_USE_X86INC
525#endif  // CONFIG_VP9_ENCODER
526#endif  // HAVE_SSE
527
528#if HAVE_SSE2
529#if CONFIG_VP8_ENCODER
530const SadMxNFunc sad_16x16_wmt = vp8_sad16x16_wmt;
531const SadMxNFunc sad_8x16_wmt = vp8_sad8x16_wmt;
532const SadMxNFunc sad_16x8_wmt = vp8_sad16x8_wmt;
533const SadMxNFunc sad_8x8_wmt = vp8_sad8x8_wmt;
534const SadMxNFunc sad_4x4_wmt = vp8_sad4x4_wmt;
535const SadMxNParam sse2_tests[] = {
536  make_tuple(16, 16, sad_16x16_wmt),
537  make_tuple(8, 16, sad_8x16_wmt),
538  make_tuple(16, 8, sad_16x8_wmt),
539  make_tuple(8, 8, sad_8x8_wmt),
540  make_tuple(4, 4, sad_4x4_wmt),
541};
542INSTANTIATE_TEST_CASE_P(SSE2, SADTest, ::testing::ValuesIn(sse2_tests));
543#endif  // CONFIG_VP8_ENCODER
544
545#if CONFIG_VP9_ENCODER
546#if CONFIG_USE_X86INC
547const SadMxNVp9Func sad_64x64_sse2_vp9 = vp9_sad64x64_sse2;
548const SadMxNVp9Func sad_64x32_sse2_vp9 = vp9_sad64x32_sse2;
549const SadMxNVp9Func sad_32x64_sse2_vp9 = vp9_sad32x64_sse2;
550const SadMxNVp9Func sad_32x32_sse2_vp9 = vp9_sad32x32_sse2;
551const SadMxNVp9Func sad_32x16_sse2_vp9 = vp9_sad32x16_sse2;
552const SadMxNVp9Func sad_16x32_sse2_vp9 = vp9_sad16x32_sse2;
553const SadMxNVp9Func sad_16x16_sse2_vp9 = vp9_sad16x16_sse2;
554const SadMxNVp9Func sad_16x8_sse2_vp9 = vp9_sad16x8_sse2;
555const SadMxNVp9Func sad_8x16_sse2_vp9 = vp9_sad8x16_sse2;
556const SadMxNVp9Func sad_8x8_sse2_vp9 = vp9_sad8x8_sse2;
557const SadMxNVp9Func sad_8x4_sse2_vp9 = vp9_sad8x4_sse2;
558const SadMxNVp9Param sse2_vp9_tests[] = {
559  make_tuple(64, 64, sad_64x64_sse2_vp9),
560  make_tuple(64, 32, sad_64x32_sse2_vp9),
561  make_tuple(32, 64, sad_32x64_sse2_vp9),
562  make_tuple(32, 32, sad_32x32_sse2_vp9),
563  make_tuple(32, 16, sad_32x16_sse2_vp9),
564  make_tuple(16, 32, sad_16x32_sse2_vp9),
565  make_tuple(16, 16, sad_16x16_sse2_vp9),
566  make_tuple(16, 8, sad_16x8_sse2_vp9),
567  make_tuple(8, 16, sad_8x16_sse2_vp9),
568  make_tuple(8, 8, sad_8x8_sse2_vp9),
569  make_tuple(8, 4, sad_8x4_sse2_vp9),
570};
571INSTANTIATE_TEST_CASE_P(SSE2, SADVP9Test, ::testing::ValuesIn(sse2_vp9_tests));
572
573const SadMxNx4Func sad_64x64x4d_sse2 = vp9_sad64x64x4d_sse2;
574const SadMxNx4Func sad_64x32x4d_sse2 = vp9_sad64x32x4d_sse2;
575const SadMxNx4Func sad_32x64x4d_sse2 = vp9_sad32x64x4d_sse2;
576const SadMxNx4Func sad_32x32x4d_sse2 = vp9_sad32x32x4d_sse2;
577const SadMxNx4Func sad_32x16x4d_sse2 = vp9_sad32x16x4d_sse2;
578const SadMxNx4Func sad_16x32x4d_sse2 = vp9_sad16x32x4d_sse2;
579const SadMxNx4Func sad_16x16x4d_sse2 = vp9_sad16x16x4d_sse2;
580const SadMxNx4Func sad_16x8x4d_sse2 = vp9_sad16x8x4d_sse2;
581const SadMxNx4Func sad_8x16x4d_sse2 = vp9_sad8x16x4d_sse2;
582const SadMxNx4Func sad_8x8x4d_sse2 = vp9_sad8x8x4d_sse2;
583const SadMxNx4Func sad_8x4x4d_sse2 = vp9_sad8x4x4d_sse2;
584INSTANTIATE_TEST_CASE_P(SSE2, SADx4Test, ::testing::Values(
585                        make_tuple(64, 64, sad_64x64x4d_sse2),
586                        make_tuple(64, 32, sad_64x32x4d_sse2),
587                        make_tuple(32, 64, sad_32x64x4d_sse2),
588                        make_tuple(32, 32, sad_32x32x4d_sse2),
589                        make_tuple(32, 16, sad_32x16x4d_sse2),
590                        make_tuple(16, 32, sad_16x32x4d_sse2),
591                        make_tuple(16, 16, sad_16x16x4d_sse2),
592                        make_tuple(16, 8, sad_16x8x4d_sse2),
593                        make_tuple(8, 16, sad_8x16x4d_sse2),
594                        make_tuple(8, 8, sad_8x8x4d_sse2),
595                        make_tuple(8, 4, sad_8x4x4d_sse2)));
596#endif  // CONFIG_USE_X86INC
597#endif  // CONFIG_VP9_ENCODER
598#endif  // HAVE_SSE2
599
600#if HAVE_SSE3
601#if CONFIG_VP8_ENCODER
602const SadMxNx4Func sad_16x16x4d_sse3 = vp8_sad16x16x4d_sse3;
603const SadMxNx4Func sad_16x8x4d_sse3 = vp8_sad16x8x4d_sse3;
604const SadMxNx4Func sad_8x16x4d_sse3 = vp8_sad8x16x4d_sse3;
605const SadMxNx4Func sad_8x8x4d_sse3 = vp8_sad8x8x4d_sse3;
606const SadMxNx4Func sad_4x4x4d_sse3 = vp8_sad4x4x4d_sse3;
607INSTANTIATE_TEST_CASE_P(SSE3, SADx4Test, ::testing::Values(
608                        make_tuple(16, 16, sad_16x16x4d_sse3),
609                        make_tuple(16, 8, sad_16x8x4d_sse3),
610                        make_tuple(8, 16, sad_8x16x4d_sse3),
611                        make_tuple(8, 8, sad_8x8x4d_sse3),
612                        make_tuple(4, 4, sad_4x4x4d_sse3)));
613#endif  // CONFIG_VP8_ENCODER
614#endif  // HAVE_SSE3
615
616#if HAVE_SSSE3
617#if CONFIG_USE_X86INC
618#if CONFIG_VP8_ENCODER
619const SadMxNFunc sad_16x16_sse3 = vp8_sad16x16_sse3;
620INSTANTIATE_TEST_CASE_P(SSE3, SADTest, ::testing::Values(
621                        make_tuple(16, 16, sad_16x16_sse3)));
622#endif  // CONFIG_VP8_ENCODER
623#endif  // CONFIG_USE_X86INC
624#endif  // HAVE_SSSE3
625
626#if HAVE_AVX2
627#if CONFIG_VP9_ENCODER
628const SadMxNx4Func sad_64x64x4d_avx2 = vp9_sad64x64x4d_avx2;
629const SadMxNx4Func sad_32x32x4d_avx2 = vp9_sad32x32x4d_avx2;
630INSTANTIATE_TEST_CASE_P(AVX2, SADx4Test, ::testing::Values(
631                        make_tuple(32, 32, sad_32x32x4d_avx2),
632                        make_tuple(64, 64, sad_64x64x4d_avx2)));
633#endif  // CONFIG_VP9_ENCODER
634#endif  // HAVE_AVX2
635
636}  // namespace
637