2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
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.
16 #include "third_party/googletest/src/googletest/include/gtest/gtest.h"
17 #include "test/register_state_check.h"
18 #include "test/function_equivalence_test.h"
20 #include "config/aom_config.h"
21 #include "config/aom_dsp_rtcd.h"
22 #include "config/av1_rtcd.h"
24 #include "aom/aom_integer.h"
26 #include "av1/common/enums.h"
28 #include "aom_dsp/blend.h"
30 using libaom_test::FunctionEquivalenceTest
;
34 template <typename BlendA64Func
, typename SrcPixel
, typename DstPixel
>
35 class BlendA64MaskTest
: public FunctionEquivalenceTest
<BlendA64Func
> {
37 static const int kIterations
= 10000;
38 static const int kMaxWidth
= MAX_SB_SIZE
* 5; // * 5 to cover longer strides
39 static const int kMaxHeight
= MAX_SB_SIZE
;
40 static const int kBufSize
= kMaxWidth
* kMaxHeight
;
41 static const int kMaxMaskWidth
= 2 * MAX_SB_SIZE
;
42 static const int kMaxMaskSize
= kMaxMaskWidth
* kMaxMaskWidth
;
44 virtual ~BlendA64MaskTest() {}
46 virtual void Execute(const SrcPixel
*p_src0
, const SrcPixel
*p_src1
) = 0;
48 template <typename Pixel
>
49 void GetSources(Pixel
**src0
, Pixel
**src1
, Pixel
* /*dst*/) {
50 switch (this->rng_(3)) {
51 case 0: // Separate sources
55 case 1: // src0 == dst
57 src0_stride_
= dst_stride_
;
58 src0_offset_
= dst_offset_
;
61 case 2: // src1 == dst
64 src1_stride_
= dst_stride_
;
65 src1_offset_
= dst_offset_
;
71 void GetSources(uint16_t **src0
, uint16_t **src1
, uint8_t * /*dst*/) {
76 uint8_t Rand1() { return this->rng_
.Rand8() & 1; }
79 w_
= 4 << this->rng_(MAX_SB_SIZE_LOG2
- 1);
80 h_
= 4 << this->rng_(MAX_SB_SIZE_LOG2
- 1);
85 dst_offset_
= this->rng_(33);
86 dst_stride_
= this->rng_(kMaxWidth
+ 1 - w_
) + w_
;
88 src0_offset_
= this->rng_(33);
89 src0_stride_
= this->rng_(kMaxWidth
+ 1 - w_
) + w_
;
91 src1_offset_
= this->rng_(33);
92 src1_stride_
= this->rng_(kMaxWidth
+ 1 - w_
) + w_
;
95 this->rng_(kMaxWidth
+ 1 - w_
* (subx_
? 2 : 1)) + w_
* (subx_
? 2 : 1);
103 GetSources(&p_src0
, &p_src1
, &dst_ref_
[0]);
105 Execute(p_src0
, p_src1
);
107 for (int r
= 0; r
< h_
; ++r
) {
108 for (int c
= 0; c
< w_
; ++c
) {
109 ASSERT_EQ(dst_ref_
[dst_offset_
+ r
* dst_stride_
+ c
],
110 dst_tst_
[dst_offset_
+ r
* dst_stride_
+ c
])
111 << w_
<< "x" << h_
<< " r: " << r
<< " c: " << c
;
116 DstPixel dst_ref_
[kBufSize
];
117 DstPixel dst_tst_
[kBufSize
];
118 uint32_t dst_stride_
;
119 uint32_t dst_offset_
;
121 SrcPixel src0_
[kBufSize
];
122 uint32_t src0_stride_
;
123 uint32_t src0_offset_
;
125 SrcPixel src1_
[kBufSize
];
126 uint32_t src1_stride_
;
127 uint32_t src1_offset_
;
129 uint8_t mask_
[kMaxMaskSize
];
139 //////////////////////////////////////////////////////////////////////////////
141 //////////////////////////////////////////////////////////////////////////////
143 typedef void (*F8B
)(uint8_t *dst
, uint32_t dst_stride
, const uint8_t *src0
,
144 uint32_t src0_stride
, const uint8_t *src1
,
145 uint32_t src1_stride
, const uint8_t *mask
,
146 uint32_t mask_stride
, int w
, int h
, int subx
, int suby
);
147 typedef libaom_test::FuncParam
<F8B
> TestFuncs
;
149 class BlendA64MaskTest8B
: public BlendA64MaskTest
<F8B
, uint8_t, uint8_t> {
151 void Execute(const uint8_t *p_src0
, const uint8_t *p_src1
) {
152 params_
.ref_func(dst_ref_
+ dst_offset_
, dst_stride_
, p_src0
+ src0_offset_
,
153 src0_stride_
, p_src1
+ src1_offset_
, src1_stride_
, mask_
,
154 kMaxMaskWidth
, w_
, h_
, subx_
, suby_
);
155 ASM_REGISTER_STATE_CHECK(params_
.tst_func(
156 dst_tst_
+ dst_offset_
, dst_stride_
, p_src0
+ src0_offset_
,
157 src0_stride_
, p_src1
+ src1_offset_
, src1_stride_
, mask_
, kMaxMaskWidth
,
158 w_
, h_
, subx_
, suby_
));
162 TEST_P(BlendA64MaskTest8B
, RandomValues
) {
163 for (int iter
= 0; iter
< kIterations
&& !HasFatalFailure(); ++iter
) {
164 for (int i
= 0; i
< kBufSize
; ++i
) {
165 dst_ref_
[i
] = rng_
.Rand8();
166 dst_tst_
[i
] = rng_
.Rand8();
168 src0_
[i
] = rng_
.Rand8();
169 src1_
[i
] = rng_
.Rand8();
172 for (int i
= 0; i
< kMaxMaskSize
; ++i
)
173 mask_
[i
] = rng_(AOM_BLEND_A64_MAX_ALPHA
+ 1);
179 TEST_P(BlendA64MaskTest8B
, ExtremeValues
) {
180 for (int iter
= 0; iter
< kIterations
&& !HasFatalFailure(); ++iter
) {
181 for (int i
= 0; i
< kBufSize
; ++i
) {
182 dst_ref_
[i
] = rng_(2) + 254;
183 dst_tst_
[i
] = rng_(2) + 254;
184 src0_
[i
] = rng_(2) + 254;
185 src1_
[i
] = rng_(2) + 254;
188 for (int i
= 0; i
< kMaxMaskSize
; ++i
)
189 mask_
[i
] = rng_(2) + AOM_BLEND_A64_MAX_ALPHA
- 1;
196 INSTANTIATE_TEST_CASE_P(SSE4_1
, BlendA64MaskTest8B
,
197 ::testing::Values(TestFuncs(
198 aom_blend_a64_mask_c
, aom_blend_a64_mask_sse4_1
)));
199 #endif // HAVE_SSE4_1
201 //////////////////////////////////////////////////////////////////////////////
202 // 8 bit _d16 version
203 //////////////////////////////////////////////////////////////////////////////
205 typedef void (*F8B_D16
)(uint8_t *dst
, uint32_t dst_stride
, const uint16_t *src0
,
206 uint32_t src0_stride
, const uint16_t *src1
,
207 uint32_t src1_stride
, const uint8_t *mask
,
208 uint32_t mask_stride
, int w
, int h
, int subx
, int suby
,
209 ConvolveParams
*conv_params
);
210 typedef libaom_test::FuncParam
<F8B_D16
> TestFuncs_d16
;
212 class BlendA64MaskTest8B_d16
213 : public BlendA64MaskTest
<F8B_D16
, uint16_t, uint8_t> {
215 // max number of bits used by the source
216 static const int kSrcMaxBitsMask
= 0x3fff;
218 void Execute(const uint16_t *p_src0
, const uint16_t *p_src1
) {
219 ConvolveParams conv_params
;
220 conv_params
.round_0
= ROUND0_BITS
;
221 conv_params
.round_1
= COMPOUND_ROUND1_BITS
;
222 params_
.ref_func(dst_ref_
+ dst_offset_
, dst_stride_
, p_src0
+ src0_offset_
,
223 src0_stride_
, p_src1
+ src1_offset_
, src1_stride_
, mask_
,
224 kMaxMaskWidth
, w_
, h_
, subx_
, suby_
, &conv_params
);
225 ASM_REGISTER_STATE_CHECK(params_
.tst_func(
226 dst_tst_
+ dst_offset_
, dst_stride_
, p_src0
+ src0_offset_
,
227 src0_stride_
, p_src1
+ src1_offset_
, src1_stride_
, mask_
, kMaxMaskWidth
,
228 w_
, h_
, subx_
, suby_
, &conv_params
));
232 TEST_P(BlendA64MaskTest8B_d16
, RandomValues
) {
233 for (int iter
= 0; iter
< kIterations
&& !HasFatalFailure(); ++iter
) {
234 for (int i
= 0; i
< kBufSize
; ++i
) {
235 dst_ref_
[i
] = rng_
.Rand8();
236 dst_tst_
[i
] = rng_
.Rand8();
238 src0_
[i
] = rng_
.Rand16() & kSrcMaxBitsMask
;
239 src1_
[i
] = rng_
.Rand16() & kSrcMaxBitsMask
;
242 for (int i
= 0; i
< kMaxMaskSize
; ++i
)
243 mask_
[i
] = rng_(AOM_BLEND_A64_MAX_ALPHA
+ 1);
249 TEST_P(BlendA64MaskTest8B_d16
, ExtremeValues
) {
250 for (int iter
= 0; iter
< kIterations
&& !HasFatalFailure(); ++iter
) {
251 for (int i
= 0; i
< kBufSize
; ++i
) {
255 src0_
[i
] = kSrcMaxBitsMask
;
256 src1_
[i
] = kSrcMaxBitsMask
;
259 for (int i
= 0; i
< kMaxMaskSize
; ++i
)
260 mask_
[i
] = AOM_BLEND_A64_MAX_ALPHA
- 1;
267 INSTANTIATE_TEST_CASE_P(
268 SSE4_1
, BlendA64MaskTest8B_d16
,
269 ::testing::Values(TestFuncs_d16(aom_lowbd_blend_a64_d16_mask_c
,
270 aom_lowbd_blend_a64_d16_mask_sse4_1
)));
271 #endif // HAVE_SSE4_1
273 //////////////////////////////////////////////////////////////////////////////
274 // High bit-depth version
275 //////////////////////////////////////////////////////////////////////////////
277 typedef void (*FHBD
)(uint8_t *dst
, uint32_t dst_stride
, const uint8_t *src0
,
278 uint32_t src0_stride
, const uint8_t *src1
,
279 uint32_t src1_stride
, const uint8_t *mask
,
280 uint32_t mask_stride
, int w
, int h
, int subx
, int suby
,
282 typedef libaom_test::FuncParam
<FHBD
> TestFuncsHBD
;
284 class BlendA64MaskTestHBD
: public BlendA64MaskTest
<FHBD
, uint16_t, uint16_t> {
286 void Execute(const uint16_t *p_src0
, const uint16_t *p_src1
) {
287 params_
.ref_func(CONVERT_TO_BYTEPTR(dst_ref_
+ dst_offset_
), dst_stride_
,
288 CONVERT_TO_BYTEPTR(p_src0
+ src0_offset_
), src0_stride_
,
289 CONVERT_TO_BYTEPTR(p_src1
+ src1_offset_
), src1_stride_
,
290 mask_
, kMaxMaskWidth
, w_
, h_
, subx_
, suby_
, bit_depth_
);
291 ASM_REGISTER_STATE_CHECK(params_
.tst_func(
292 CONVERT_TO_BYTEPTR(dst_tst_
+ dst_offset_
), dst_stride_
,
293 CONVERT_TO_BYTEPTR(p_src0
+ src0_offset_
), src0_stride_
,
294 CONVERT_TO_BYTEPTR(p_src1
+ src1_offset_
), src1_stride_
, mask_
,
295 kMaxMaskWidth
, w_
, h_
, subx_
, suby_
, bit_depth_
));
301 TEST_P(BlendA64MaskTestHBD
, RandomValues
) {
302 for (int iter
= 0; iter
< kIterations
&& !HasFatalFailure(); ++iter
) {
304 case 0: bit_depth_
= 8; break;
305 case 1: bit_depth_
= 10; break;
306 default: bit_depth_
= 12; break;
309 const int hi
= 1 << bit_depth_
;
311 for (int i
= 0; i
< kBufSize
; ++i
) {
312 dst_ref_
[i
] = rng_(hi
);
313 dst_tst_
[i
] = rng_(hi
);
318 for (int i
= 0; i
< kMaxMaskSize
; ++i
)
319 mask_
[i
] = rng_(AOM_BLEND_A64_MAX_ALPHA
+ 1);
325 TEST_P(BlendA64MaskTestHBD
, ExtremeValues
) {
326 for (int iter
= 0; iter
< 1000 && !HasFatalFailure(); ++iter
) {
328 case 0: bit_depth_
= 8; break;
329 case 1: bit_depth_
= 10; break;
330 default: bit_depth_
= 12; break;
333 const int hi
= 1 << bit_depth_
;
334 const int lo
= hi
- 2;
336 for (int i
= 0; i
< kBufSize
; ++i
) {
337 dst_ref_
[i
] = rng_(hi
- lo
) + lo
;
338 dst_tst_
[i
] = rng_(hi
- lo
) + lo
;
339 src0_
[i
] = rng_(hi
- lo
) + lo
;
340 src1_
[i
] = rng_(hi
- lo
) + lo
;
343 for (int i
= 0; i
< kMaxMaskSize
; ++i
)
344 mask_
[i
] = rng_(2) + AOM_BLEND_A64_MAX_ALPHA
- 1;
351 INSTANTIATE_TEST_CASE_P(
352 SSE4_1
, BlendA64MaskTestHBD
,
353 ::testing::Values(TestFuncsHBD(aom_highbd_blend_a64_mask_c
,
354 aom_highbd_blend_a64_mask_sse4_1
)));
355 #endif // HAVE_SSE4_1
357 //////////////////////////////////////////////////////////////////////////////
359 //////////////////////////////////////////////////////////////////////////////
361 typedef void (*FHBD_D16
)(uint8_t *dst
, uint32_t dst_stride
,
362 const CONV_BUF_TYPE
*src0
, uint32_t src0_stride
,
363 const CONV_BUF_TYPE
*src1
, uint32_t src1_stride
,
364 const uint8_t *mask
, uint32_t mask_stride
, int w
,
365 int h
, int subx
, int suby
, ConvolveParams
*conv_params
,
367 typedef libaom_test::FuncParam
<FHBD_D16
> TestFuncsHBD_d16
;
369 class BlendA64MaskTestHBD_d16
370 : public BlendA64MaskTest
<FHBD_D16
, uint16_t, uint16_t> {
372 // max number of bits used by the source
373 static const int kSrcMaxBitsMask
= (1 << 14) - 1;
374 static const int kSrcMaxBitsMaskHBD
= (1 << 16) - 1;
376 void Execute(const uint16_t *p_src0
, const uint16_t *p_src1
) {
377 ConvolveParams conv_params
;
378 conv_params
.round_0
= (bit_depth_
== 12) ? ROUND0_BITS
+ 2 : ROUND0_BITS
;
379 conv_params
.round_1
= COMPOUND_ROUND1_BITS
;
381 params_
.ref_func(CONVERT_TO_BYTEPTR(dst_ref_
+ dst_offset_
), dst_stride_
,
382 p_src0
+ src0_offset_
, src0_stride_
, p_src1
+ src1_offset_
,
383 src1_stride_
, mask_
, kMaxMaskWidth
, w_
, h_
, subx_
, suby_
,
384 &conv_params
, bit_depth_
);
385 if (params_
.tst_func
) {
386 ASM_REGISTER_STATE_CHECK(params_
.tst_func(
387 CONVERT_TO_BYTEPTR(dst_tst_
+ dst_offset_
), dst_stride_
,
388 p_src0
+ src0_offset_
, src0_stride_
, p_src1
+ src1_offset_
,
389 src1_stride_
, mask_
, kMaxMaskWidth
, w_
, h_
, subx_
, suby_
,
390 &conv_params
, bit_depth_
));
395 int src_max_bits_mask_
;
398 TEST_P(BlendA64MaskTestHBD_d16
, RandomValues
) {
399 if (params_
.tst_func
== NULL
) return;
400 for (int iter
= 0; iter
< kIterations
&& !HasFatalFailure(); ++iter
) {
402 case 0: bit_depth_
= 8; break;
403 case 1: bit_depth_
= 10; break;
404 default: bit_depth_
= 12; break;
407 (bit_depth_
== 8) ? kSrcMaxBitsMask
: kSrcMaxBitsMaskHBD
;
409 for (int i
= 0; i
< kBufSize
; ++i
) {
410 dst_ref_
[i
] = rng_
.Rand8();
411 dst_tst_
[i
] = rng_
.Rand8();
413 src0_
[i
] = rng_
.Rand16() & src_max_bits_mask_
;
414 src1_
[i
] = rng_
.Rand16() & src_max_bits_mask_
;
417 for (int i
= 0; i
< kMaxMaskSize
; ++i
)
418 mask_
[i
] = rng_(AOM_BLEND_A64_MAX_ALPHA
+ 1);
424 TEST_P(BlendA64MaskTestHBD_d16
, SaturatedValues
) {
425 for (bit_depth_
= 8; bit_depth_
<= 12; bit_depth_
+= 2) {
427 (bit_depth_
== 8) ? kSrcMaxBitsMask
: kSrcMaxBitsMaskHBD
;
429 for (int i
= 0; i
< kBufSize
; ++i
) {
431 dst_tst_
[i
] = (1 << bit_depth_
) - 1;
433 src0_
[i
] = src_max_bits_mask_
;
434 src1_
[i
] = src_max_bits_mask_
;
437 for (int i
= 0; i
< kMaxMaskSize
; ++i
) mask_
[i
] = AOM_BLEND_A64_MAX_ALPHA
;
443 INSTANTIATE_TEST_CASE_P(
444 C
, BlendA64MaskTestHBD_d16
,
445 ::testing::Values(TestFuncsHBD_d16(aom_highbd_blend_a64_d16_mask_c
, NULL
)));
447 // TODO(slavarnway): Enable the following in the avx2 commit. (56501)
450 INSTANTIATE_TEST_CASE_P(
451 SSE4_1
, BlendA64MaskTestHBD
,
452 ::testing::Values(TestFuncsHBD(aom_highbd_blend_a64_mask_c
,
453 aom_highbd_blend_a64_mask_avx2
)));