blob: 4976b03c8a571b25a5829cc370c0c0efc933cd35 [file] [log] [blame]
Yi Luo04cef492017-07-11 16:51:50 -07001/*
2 * Copyright (c) 2017, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12#include <assert.h>
13
14#include "./av1_rtcd.h"
Angie Chiange47125e2017-08-04 11:12:19 -070015#include "aom/aom_integer.h"
16#include "aom_ports/aom_timer.h"
Yi Luo04cef492017-07-11 16:51:50 -070017#include "test/acm_random.h"
18#include "test/clear_system_state.h"
19#include "test/register_state_check.h"
20#include "test/util.h"
21#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
Yi Luo04cef492017-07-11 16:51:50 -070022
23using libaom_test::ACMRandom;
24
25namespace {
26#define CONVOLVE_ROUNDING_PARAM \
27 const int32_t *src, int src_stride, uint8_t *dst, int dst_stride, int w, \
28 int h, int bits
29
30typedef void (*ConvolveRoundFunc)(CONVOLVE_ROUNDING_PARAM);
31
32typedef void (*ConvolveRoundFuncHbd)(CONVOLVE_ROUNDING_PARAM, int bd);
33
34template <ConvolveRoundFuncHbd fn>
35void highbd_convolve_rounding_8(CONVOLVE_ROUNDING_PARAM) {
36 const int bd = 8;
37 fn(src, src_stride, dst, dst_stride, w, h, bits, bd);
38}
39
40template <ConvolveRoundFuncHbd fn>
41void highbd_convolve_rounding_10(CONVOLVE_ROUNDING_PARAM) {
42 const int bd = 10;
43 fn(src, src_stride, dst, dst_stride, w, h, bits, bd);
44}
45
46template <ConvolveRoundFuncHbd fn>
47void highbd_convolve_rounding_12(CONVOLVE_ROUNDING_PARAM) {
48 const int bd = 12;
49 fn(src, src_stride, dst, dst_stride, w, h, bits, bd);
50}
51
52typedef enum { LOWBITDEPTH_TEST, HIGHBITDEPTH_TEST } DataPathType;
53
54using std::tr1::tuple;
55
56typedef tuple<ConvolveRoundFunc, ConvolveRoundFunc, DataPathType>
57 ConvolveRoundParam;
58
59const int kTestNum = 5000;
60
61class ConvolveRoundTest : public ::testing::TestWithParam<ConvolveRoundParam> {
62 protected:
63 ConvolveRoundTest()
64 : func_ref_(GET_PARAM(0)), func_(GET_PARAM(1)), data_path_(GET_PARAM(2)) {
65 }
66 virtual ~ConvolveRoundTest() {}
67
68 virtual void SetUp() {
69 const size_t block_size = 128 * 128;
70 src_ = reinterpret_cast<int32_t *>(
Angie Chiange47125e2017-08-04 11:12:19 -070071 aom_memalign(16, block_size * sizeof(*src_)));
72 dst_ref_ = reinterpret_cast<uint16_t *>(
73 aom_memalign(16, block_size * sizeof(*dst_ref_)));
74 dst_ = reinterpret_cast<uint16_t *>(
75 aom_memalign(16, block_size * sizeof(*dst_)));
Yi Luo04cef492017-07-11 16:51:50 -070076 }
77
Angie Chiange47125e2017-08-04 11:12:19 -070078 virtual void TearDown() {
79 aom_free(src_);
80 aom_free(dst_ref_);
81 aom_free(dst_);
82 }
Yi Luo04cef492017-07-11 16:51:50 -070083
84 void ConvolveRoundingRun() {
85 int test_num = 0;
86 const int src_stride = 128;
87 const int dst_stride = 128;
88 int bits = 13;
89 uint8_t *dst = 0;
90 uint8_t *dst_ref = 0;
Yi Luo04cef492017-07-11 16:51:50 -070091
92 if (data_path_ == LOWBITDEPTH_TEST) {
93 dst = reinterpret_cast<uint8_t *>(dst_);
94 dst_ref = reinterpret_cast<uint8_t *>(dst_ref_);
95#if CONFIG_HIGHBITDEPTH
96 } else if (data_path_ == HIGHBITDEPTH_TEST) {
97 dst = CONVERT_TO_BYTEPTR(dst_);
98 dst_ref = CONVERT_TO_BYTEPTR(dst_ref_);
99#endif
100 } else {
101 assert(0);
102 }
103
104 while (test_num < kTestNum) {
105 int block_size = test_num % BLOCK_SIZES_ALL;
106 int w = block_size_wide[block_size];
107 int h = block_size_high[block_size];
108
109 if (test_num % 2 == 0)
110 bits -= 1;
111 else
112 bits += 1;
113
114 GenerateBufferWithRandom(src_, src_stride, bits, w, h);
115
116 func_ref_(src_, src_stride, dst_ref, dst_stride, w, h, bits);
Angie Chiang3cb5e392017-08-03 16:11:02 -0700117 ASM_REGISTER_STATE_CHECK(
118 func_(src_, src_stride, dst, dst_stride, w, h, bits));
Yi Luo04cef492017-07-11 16:51:50 -0700119
Angie Chiange47125e2017-08-04 11:12:19 -0700120 if (data_path_ == LOWBITDEPTH_TEST) {
121 for (int r = 0; r < h; ++r) {
122 for (int c = 0; c < w; ++c) {
123 ASSERT_EQ(dst_ref[r * dst_stride + c], dst[r * dst_stride + c])
124 << "Mismatch at r: " << r << " c: " << c << " w: " << w
125 << " h: " << h << " test: " << test_num;
126 }
127 }
128 } else {
129 for (int r = 0; r < h; ++r) {
130 for (int c = 0; c < w; ++c) {
131 ASSERT_EQ(dst_ref_[r * dst_stride + c], dst_[r * dst_stride + c])
132 << "Mismatch at r: " << r << " c: " << c << " w: " << w
133 << " h: " << h << " test: " << test_num;
134 }
Yi Luo04cef492017-07-11 16:51:50 -0700135 }
136 }
137
138 test_num++;
139 }
140 }
141
142 void GenerateBufferWithRandom(int32_t *src, int src_stride, int bits, int w,
143 int h) {
144 int32_t number;
145 for (int r = 0; r < h; ++r) {
146 for (int c = 0; c < w; ++c) {
147 number = static_cast<int32_t>(rand_.Rand31());
148 number %= 1 << (bits + 9);
149 src[r * src_stride + c] = number;
150 }
151 }
152 }
153
154 ACMRandom rand_;
155 int32_t *src_;
156 uint16_t *dst_ref_;
157 uint16_t *dst_;
158
159 ConvolveRoundFunc func_ref_;
160 ConvolveRoundFunc func_;
161 DataPathType data_path_;
162};
163
164TEST_P(ConvolveRoundTest, BitExactCheck) { ConvolveRoundingRun(); }
165
166using std::tr1::make_tuple;
167
168#if HAVE_AVX2
Angie Chiang7346ca12017-07-26 16:01:06 -0700169#if CONFIG_HIGHBITDEPTH
Yi Luo04cef492017-07-11 16:51:50 -0700170const ConvolveRoundParam kConvRndParamArray[] = {
171 make_tuple(&av1_convolve_rounding_c, &av1_convolve_rounding_avx2,
172 LOWBITDEPTH_TEST),
173 make_tuple(&highbd_convolve_rounding_8<av1_highbd_convolve_rounding_c>,
174 &highbd_convolve_rounding_8<av1_highbd_convolve_rounding_avx2>,
175 HIGHBITDEPTH_TEST),
176 make_tuple(&highbd_convolve_rounding_10<av1_highbd_convolve_rounding_c>,
177 &highbd_convolve_rounding_10<av1_highbd_convolve_rounding_avx2>,
178 HIGHBITDEPTH_TEST),
179 make_tuple(&highbd_convolve_rounding_12<av1_highbd_convolve_rounding_c>,
180 &highbd_convolve_rounding_12<av1_highbd_convolve_rounding_avx2>,
181 HIGHBITDEPTH_TEST)
182};
Angie Chiang7346ca12017-07-26 16:01:06 -0700183#else
184const ConvolveRoundParam kConvRndParamArray[] = { make_tuple(
185 &av1_convolve_rounding_c, &av1_convolve_rounding_avx2, LOWBITDEPTH_TEST) };
186#endif
Yi Luo04cef492017-07-11 16:51:50 -0700187
188INSTANTIATE_TEST_CASE_P(AVX2, ConvolveRoundTest,
189 ::testing::ValuesIn(kConvRndParamArray));
190#endif // HAVE_AVX2
191} // namespace