blob: 24d7bb3302fc8ed63d905367de33baf7be349e58 [file] [log] [blame]
Steinar Midtskogenbe668e92016-08-05 12:12:38 +02001/*
2 * Copyright (c) 2016, 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 <cstdlib>
13#include <string>
14
15#include "third_party/googletest/src/include/gtest/gtest.h"
16
17#include "./aom_config.h"
18#include "./aom_dsp_rtcd.h"
19#include "aom_ports/aom_timer.h"
20#include "test/acm_random.h"
21#include "test/clear_system_state.h"
22#include "test/register_state_check.h"
23#include "test/util.h"
24
25using libaom_test::ACMRandom;
26
27namespace {
28
Steinar Midtskogene8224c72016-08-24 13:00:04 +020029typedef void (*clpf_block_t)(const uint8_t *src, uint8_t *dst, int sstride,
30 int dstride, int x0, int y0, int sizex, int sizey,
31 int width, int height, unsigned int strength);
Steinar Midtskogenbe668e92016-08-05 12:12:38 +020032
33typedef std::tr1::tuple<clpf_block_t, clpf_block_t, int, int>
34 clpf_block_param_t;
35
36class ClpfBlockTest : public ::testing::TestWithParam<clpf_block_param_t> {
37 public:
38 virtual ~ClpfBlockTest() {}
39 virtual void SetUp() {
40 clpf = GET_PARAM(0);
41 ref_clpf = GET_PARAM(1);
42 sizex = GET_PARAM(2);
43 sizey = GET_PARAM(3);
44 }
45
46 virtual void TearDown() { libaom_test::ClearSystemState(); }
47
48 protected:
49 int sizex;
50 int sizey;
51 clpf_block_t clpf;
52 clpf_block_t ref_clpf;
53};
54
55typedef ClpfBlockTest ClpfSpeedTest;
56
Steinar Midtskogen3dbd55a2016-09-09 15:23:35 +020057#if CONFIG_AOM_HIGHBITDEPTH
58typedef void (*clpf_block_hbd_t)(const uint16_t *src, uint16_t *dst,
59 int sstride, int dstride, int x0, int y0,
60 int sizex, int sizey, int width, int height,
61 unsigned int strength);
Steinar Midtskogenbe668e92016-08-05 12:12:38 +020062
Steinar Midtskogen3dbd55a2016-09-09 15:23:35 +020063typedef std::tr1::tuple<clpf_block_hbd_t, clpf_block_hbd_t, int, int>
64 clpf_block_hbd_param_t;
65
66class ClpfBlockHbdTest
67 : public ::testing::TestWithParam<clpf_block_hbd_param_t> {
68 public:
69 virtual ~ClpfBlockHbdTest() {}
70 virtual void SetUp() {
71 clpf = GET_PARAM(0);
72 ref_clpf = GET_PARAM(1);
73 sizex = GET_PARAM(2);
74 sizey = GET_PARAM(3);
75 }
76
77 virtual void TearDown() { libaom_test::ClearSystemState(); }
78
79 protected:
80 int sizex;
81 int sizey;
82 clpf_block_hbd_t clpf;
83 clpf_block_hbd_t ref_clpf;
84};
85
86typedef ClpfBlockHbdTest ClpfHbdSpeedTest;
87#endif
88
89template <typename pixel>
90void test_clpf(int w, int h, int depth, int iterations,
91 void (*clpf)(const pixel *src, pixel *dst, int sstride,
92 int dstride, int x0, int y0, int sizex, int sizey,
93 int width, int height, unsigned int strength),
94 void (*ref_clpf)(const pixel *src, pixel *dst, int sstride,
95 int dstride, int x0, int y0, int sizex,
96 int sizey, int width, int height,
97 unsigned int strength)) {
98 const int size = 24;
99 ACMRandom rnd(ACMRandom::DeterministicSeed());
100 DECLARE_ALIGNED(16, pixel, s[size * size]);
101 DECLARE_ALIGNED(16, pixel, d[size * size]);
102 DECLARE_ALIGNED(16, pixel, ref_d[size * size]);
103 memset(ref_d, 0, size * size * sizeof(*ref_d));
104 memset(d, 0, size * size * sizeof(*d));
105
106 int error = 0, pos = 0, strength = 0, xpos = 0, ypos = 0;
107 int bits, level, count;
Steinar Midtskogenbe668e92016-08-05 12:12:38 +0200108
109 // Test every combination of:
Steinar Midtskogen3dbd55a2016-09-09 15:23:35 +0200110 // * Input with up to <depth> bits of noise
111 // * Noise level around every value from 0 to (1<<depth)-1
Steinar Midtskogenbe668e92016-08-05 12:12:38 +0200112 // * Blocks anywhere in the frame (along all egdes and also fully inside)
113 // * All strengths
Steinar Midtskogen3dbd55a2016-09-09 15:23:35 +0200114 // If clpf and ref_clpf are the same, we're just testing speed
115 for (count = 0; count < iterations; count++) {
116 for (level = 0; level < (1 << depth) && !error; level++) {
117 for (bits = 1; bits <= depth && !error; bits++) {
118 for (int i = 0; i < size * size; i++)
119 s[i] = clamp((rnd.Rand16() & ((1 << bits) - 1)) + level, 0,
120 (1 << depth) - 1);
Steinar Midtskogenbe668e92016-08-05 12:12:38 +0200121
Steinar Midtskogen3dbd55a2016-09-09 15:23:35 +0200122 for (ypos = 0; ypos < size && !error; ypos += h * !error) {
123 for (xpos = 0; xpos < size && !error; xpos += w * !error) {
124 for (strength = depth - 8; strength < depth - 5 && !error;
125 strength += !error) {
126 ref_clpf(s, ref_d, size, size, xpos, ypos, w, h, size, size,
127 1 << strength);
128 if (clpf != ref_clpf)
129 ASM_REGISTER_STATE_CHECK(clpf(s, d, size, size, xpos, ypos, w,
130 h, size, size, 1 << strength));
131 if (ref_clpf != clpf)
132 for (pos = 0; pos < size * size && !error; pos++) {
133 error = ref_d[pos] != d[pos];
134 }
Steinar Midtskogenbe668e92016-08-05 12:12:38 +0200135 }
136 }
137 }
138 }
139 }
140 }
141
Steinar Midtskogenee54e5f2016-09-09 17:30:21 +0200142 pos--;
Steinar Midtskogenbe668e92016-08-05 12:12:38 +0200143 EXPECT_EQ(0, error)
144 << "Error: ClpfBlockTest, SIMD and C mismatch." << std::endl
145 << "First error at " << pos % size << "," << pos / size << " ("
146 << (int16_t)ref_d[pos] << " != " << (int16_t)d[pos] << ") " << std::endl
147 << "strength: " << (1 << strength) << std::endl
148 << "xpos: " << xpos << std::endl
149 << "ypos: " << ypos << std::endl
Steinar Midtskogenecf9a0c2016-09-13 16:37:13 +0200150 << "w: " << w << std::endl
151 << "h: " << h << std::endl
Steinar Midtskogenbe668e92016-08-05 12:12:38 +0200152 << "A=" << (pos > size ? (int16_t)s[pos - size] : -1) << std::endl
153 << "B=" << (pos % size - 2 >= 0 ? (int16_t)s[pos - 2] : -1) << std::endl
154 << "C=" << (pos % size - 1 >= 0 ? (int16_t)s[pos - 1] : -1) << std::endl
155 << "X=" << (int16_t)s[pos] << std::endl
156 << "D=" << (pos % size + 1 < size ? (int16_t)s[pos + 1] : -1) << std::endl
157 << "E=" << (pos % size + 2 < size ? (int16_t)s[pos + 2] : -1) << std::endl
158 << "F=" << (pos + size < size * size ? (int16_t)s[pos + size] : -1)
159 << std::endl;
160}
161
Steinar Midtskogen3dbd55a2016-09-09 15:23:35 +0200162template <typename pixel>
163void test_clpf_speed(int w, int h, int depth, int iterations,
164 void (*clpf)(const pixel *src, pixel *dst, int sstride,
165 int dstride, int x0, int y0, int sizex,
166 int sizey, int width, int height,
167 unsigned int strength),
168 void (*ref_clpf)(const pixel *src, pixel *dst, int sstride,
169 int dstride, int x0, int y0, int sizex,
170 int sizey, int width, int height,
171 unsigned int strength)) {
Steinar Midtskogenbe668e92016-08-05 12:12:38 +0200172 aom_usec_timer ref_timer;
173 aom_usec_timer timer;
174
175 aom_usec_timer_start(&ref_timer);
Steinar Midtskogen3dbd55a2016-09-09 15:23:35 +0200176 test_clpf(w, h, depth, iterations, ref_clpf, ref_clpf);
Steinar Midtskogenbe668e92016-08-05 12:12:38 +0200177 aom_usec_timer_mark(&ref_timer);
178 int ref_elapsed_time = aom_usec_timer_elapsed(&ref_timer);
179
180 aom_usec_timer_start(&timer);
Steinar Midtskogen3dbd55a2016-09-09 15:23:35 +0200181 test_clpf(w, h, depth, iterations, clpf, clpf);
Steinar Midtskogenbe668e92016-08-05 12:12:38 +0200182 aom_usec_timer_mark(&timer);
183 int elapsed_time = aom_usec_timer_elapsed(&timer);
184
185#if 0
186 std::cout << "[ ] C time = " << ref_elapsed_time / 1000
187 << " ms, SIMD time = " << elapsed_time / 1000 << " ms" << std::endl;
188#endif
189
190 EXPECT_GT(ref_elapsed_time, elapsed_time)
191 << "Error: ClpfSpeedTest, SIMD slower than C." << std::endl
Steinar Midtskogen61161412016-09-26 21:48:09 +0200192 << "C time: " << ref_elapsed_time << " us" << std::endl
193 << "SIMD time: " << elapsed_time << " us" << std::endl;
Steinar Midtskogenbe668e92016-08-05 12:12:38 +0200194}
195
Steinar Midtskogen3dbd55a2016-09-09 15:23:35 +0200196TEST_P(ClpfBlockTest, TestSIMDNoMismatch) {
197 test_clpf(sizex, sizey, 8, 1, clpf, ref_clpf);
198}
199
200TEST_P(ClpfSpeedTest, TestSpeed) {
201 test_clpf_speed(sizex, sizey, 8, 16, clpf, ref_clpf);
202}
203
204#if CONFIG_AOM_HIGHBITDEPTH
205TEST_P(ClpfBlockHbdTest, TestSIMDNoMismatch) {
206 test_clpf(sizex, sizey, 12, 1, clpf, ref_clpf);
207}
208
209TEST_P(ClpfHbdSpeedTest, TestSpeed) {
210 test_clpf_speed(sizex, sizey, 12, 1, clpf, ref_clpf);
211}
212#endif
213
Steinar Midtskogenbe668e92016-08-05 12:12:38 +0200214using std::tr1::make_tuple;
215
216// Test all supported architectures and block sizes
217#if HAVE_SSE2
218INSTANTIATE_TEST_CASE_P(
219 SSE2, ClpfBlockTest,
220 ::testing::Values(make_tuple(&aom_clpf_block_sse2, &aom_clpf_block_c, 8, 8),
221 make_tuple(&aom_clpf_block_sse2, &aom_clpf_block_c, 8, 4),
222 make_tuple(&aom_clpf_block_sse2, &aom_clpf_block_c, 4, 8),
223 make_tuple(&aom_clpf_block_sse2, &aom_clpf_block_c, 4,
224 4)));
225#endif
226
227#if HAVE_SSSE3
228INSTANTIATE_TEST_CASE_P(
229 SSSE3, ClpfBlockTest,
230 ::testing::Values(
231 make_tuple(&aom_clpf_block_ssse3, &aom_clpf_block_c, 8, 8),
232 make_tuple(&aom_clpf_block_ssse3, &aom_clpf_block_c, 8, 4),
233 make_tuple(&aom_clpf_block_ssse3, &aom_clpf_block_c, 4, 8),
234 make_tuple(&aom_clpf_block_ssse3, &aom_clpf_block_c, 4, 4)));
235#endif
236
237#if HAVE_SSE4_1
238INSTANTIATE_TEST_CASE_P(
239 SSSE4_1, ClpfBlockTest,
240 ::testing::Values(
241 make_tuple(&aom_clpf_block_sse4_1, &aom_clpf_block_c, 8, 8),
242 make_tuple(&aom_clpf_block_sse4_1, &aom_clpf_block_c, 8, 4),
243 make_tuple(&aom_clpf_block_sse4_1, &aom_clpf_block_c, 4, 8),
244 make_tuple(&aom_clpf_block_sse4_1, &aom_clpf_block_c, 4, 4)));
245#endif
246
247#if HAVE_NEON
248INSTANTIATE_TEST_CASE_P(
249 NEON, ClpfBlockTest,
250 ::testing::Values(make_tuple(&aom_clpf_block_neon, &aom_clpf_block_c, 8, 8),
251 make_tuple(&aom_clpf_block_neon, &aom_clpf_block_c, 8, 4),
252 make_tuple(&aom_clpf_block_neon, &aom_clpf_block_c, 4, 8),
253 make_tuple(&aom_clpf_block_neon, &aom_clpf_block_c, 4,
254 4)));
255#endif
256
Steinar Midtskogen3dbd55a2016-09-09 15:23:35 +0200257#if CONFIG_AOM_HIGHBITDEPTH
258#if HAVE_SSE2
259INSTANTIATE_TEST_CASE_P(
260 SSE2, ClpfBlockHbdTest,
261 ::testing::Values(
262 make_tuple(&aom_clpf_block_hbd_sse2, &aom_clpf_block_hbd_c, 8, 8),
263 make_tuple(&aom_clpf_block_hbd_sse2, &aom_clpf_block_hbd_c, 8, 4),
264 make_tuple(&aom_clpf_block_hbd_sse2, &aom_clpf_block_hbd_c, 4, 8),
265 make_tuple(&aom_clpf_block_hbd_sse2, &aom_clpf_block_hbd_c, 4, 4)));
266#endif
267
268#if HAVE_SSSE3
269INSTANTIATE_TEST_CASE_P(
270 SSSE3, ClpfBlockHbdTest,
271 ::testing::Values(
272 make_tuple(&aom_clpf_block_hbd_ssse3, &aom_clpf_block_hbd_c, 8, 8),
273 make_tuple(&aom_clpf_block_hbd_ssse3, &aom_clpf_block_hbd_c, 8, 4),
274 make_tuple(&aom_clpf_block_hbd_ssse3, &aom_clpf_block_hbd_c, 4, 8),
275 make_tuple(&aom_clpf_block_hbd_ssse3, &aom_clpf_block_hbd_c, 4, 4)));
276#endif
277
278#if HAVE_SSE4_1
279INSTANTIATE_TEST_CASE_P(
280 SSSE4_1, ClpfBlockHbdTest,
281 ::testing::Values(
282 make_tuple(&aom_clpf_block_hbd_sse4_1, &aom_clpf_block_hbd_c, 8, 8),
283 make_tuple(&aom_clpf_block_hbd_sse4_1, &aom_clpf_block_hbd_c, 8, 4),
284 make_tuple(&aom_clpf_block_hbd_sse4_1, &aom_clpf_block_hbd_c, 4, 8),
285 make_tuple(&aom_clpf_block_hbd_sse4_1, &aom_clpf_block_hbd_c, 4, 4)));
286#endif
287
288#if HAVE_NEON
289INSTANTIATE_TEST_CASE_P(
290 NEON, ClpfBlockHbdTest,
291 ::testing::Values(
292 make_tuple(&aom_clpf_block_hbd_neon, &aom_clpf_block_hbd_c, 8, 8),
293 make_tuple(&aom_clpf_block_hbd_neon, &aom_clpf_block_hbd_c, 8, 4),
294 make_tuple(&aom_clpf_block_hbd_neon, &aom_clpf_block_hbd_c, 4, 8),
295 make_tuple(&aom_clpf_block_hbd_neon, &aom_clpf_block_hbd_c, 4, 4)));
296#endif
297#endif
298
Steinar Midtskogenbe668e92016-08-05 12:12:38 +0200299// Test speed for all supported architectures
300#if HAVE_SSE2
301INSTANTIATE_TEST_CASE_P(SSE2, ClpfSpeedTest,
302 ::testing::Values(make_tuple(&aom_clpf_block_sse2,
303 &aom_clpf_block_c, 8, 8)));
304#endif
305
306#if HAVE_SSSE3
307INSTANTIATE_TEST_CASE_P(SSSE3, ClpfSpeedTest,
308 ::testing::Values(make_tuple(&aom_clpf_block_ssse3,
309 &aom_clpf_block_c, 8, 8)));
310#endif
311
312#if HAVE_SSE4_1
313INSTANTIATE_TEST_CASE_P(SSSE4_1, ClpfSpeedTest,
314 ::testing::Values(make_tuple(&aom_clpf_block_ssse3,
315 &aom_clpf_block_c, 8, 8)));
316#endif
317
318#if HAVE_NEON
319INSTANTIATE_TEST_CASE_P(NEON, ClpfSpeedTest,
320 ::testing::Values(make_tuple(&aom_clpf_block_neon,
321 &aom_clpf_block_c, 8, 8)));
322#endif
Steinar Midtskogen3dbd55a2016-09-09 15:23:35 +0200323
324#if CONFIG_AOM_HIGHBITDEPTH
325#if HAVE_SSE2
326INSTANTIATE_TEST_CASE_P(SSE2, ClpfHbdSpeedTest,
327 ::testing::Values(make_tuple(&aom_clpf_block_hbd_sse2,
328 &aom_clpf_block_hbd_c, 8,
329 8)));
330#endif
331
332#if HAVE_SSSE3
333INSTANTIATE_TEST_CASE_P(SSSE3, ClpfHbdSpeedTest,
334 ::testing::Values(make_tuple(&aom_clpf_block_hbd_ssse3,
335 &aom_clpf_block_hbd_c, 8,
336 8)));
337#endif
338
339#if HAVE_SSE4_1
340INSTANTIATE_TEST_CASE_P(SSSE4_1, ClpfHbdSpeedTest,
341 ::testing::Values(make_tuple(&aom_clpf_block_hbd_ssse3,
342 &aom_clpf_block_hbd_c, 8,
343 8)));
344#endif
345
346#if HAVE_NEON
347INSTANTIATE_TEST_CASE_P(NEON, ClpfHbdSpeedTest,
348 ::testing::Values(make_tuple(&aom_clpf_block_hbd_neon,
349 &aom_clpf_block_hbd_c, 8,
350 8)));
351#endif
352#endif
353
Steinar Midtskogenbe668e92016-08-05 12:12:38 +0200354} // namespace