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 F
, typename T
>
35 class BlendA64Mask1DTest
: public FunctionEquivalenceTest
<F
> {
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
;
44 virtual ~BlendA64Mask1DTest() {}
46 virtual void Execute(const T
*p_src0
, const T
*p_src1
) = 0;
49 w_
= 2 << this->rng_(MAX_SB_SIZE_LOG2
);
50 h_
= 2 << this->rng_(MAX_SB_SIZE_LOG2
);
52 dst_offset_
= this->rng_(33);
53 dst_stride_
= this->rng_(kMaxWidth
+ 1 - w_
) + w_
;
55 src0_offset_
= this->rng_(33);
56 src0_stride_
= this->rng_(kMaxWidth
+ 1 - w_
) + w_
;
58 src1_offset_
= this->rng_(33);
59 src1_stride_
= this->rng_(kMaxWidth
+ 1 - w_
) + w_
;
64 switch (this->rng_(3)) {
65 case 0: // Separate sources
69 case 1: // src0 == dst
71 src0_stride_
= dst_stride_
;
72 src0_offset_
= dst_offset_
;
75 case 2: // src1 == dst
78 src1_stride_
= dst_stride_
;
79 src1_offset_
= dst_offset_
;
84 Execute(p_src0
, p_src1
);
86 for (int r
= 0; r
< h_
; ++r
) {
87 for (int c
= 0; c
< w_
; ++c
) {
88 ASSERT_EQ(dst_ref_
[dst_offset_
+ r
* dst_stride_
+ c
],
89 dst_tst_
[dst_offset_
+ r
* dst_stride_
+ c
]);
100 uint32_t src0_stride_
;
101 uint32_t src0_offset_
;
104 uint32_t src1_stride_
;
105 uint32_t src1_offset_
;
107 uint8_t mask_
[kMaxMaskSize
];
113 //////////////////////////////////////////////////////////////////////////////
115 //////////////////////////////////////////////////////////////////////////////
117 typedef void (*F8B
)(uint8_t *dst
, uint32_t dst_stride
, const uint8_t *src0
,
118 uint32_t src0_stride
, const uint8_t *src1
,
119 uint32_t src1_stride
, const uint8_t *mask
, int w
, int h
);
120 typedef libaom_test::FuncParam
<F8B
> TestFuncs
;
122 class BlendA64Mask1DTest8B
: public BlendA64Mask1DTest
<F8B
, uint8_t> {
124 void Execute(const uint8_t *p_src0
, const uint8_t *p_src1
) {
125 params_
.ref_func(dst_ref_
+ dst_offset_
, dst_stride_
, p_src0
+ src0_offset_
,
126 src0_stride_
, p_src1
+ src1_offset_
, src1_stride_
, mask_
,
128 ASM_REGISTER_STATE_CHECK(params_
.tst_func(
129 dst_tst_
+ dst_offset_
, dst_stride_
, p_src0
+ src0_offset_
,
130 src0_stride_
, p_src1
+ src1_offset_
, src1_stride_
, mask_
, w_
, h_
));
134 TEST_P(BlendA64Mask1DTest8B
, RandomValues
) {
135 for (int iter
= 0; iter
< kIterations
&& !HasFatalFailure(); ++iter
) {
136 for (int i
= 0; i
< kBufSize
; ++i
) {
137 dst_ref_
[i
] = rng_
.Rand8();
138 dst_tst_
[i
] = rng_
.Rand8();
140 src0_
[i
] = rng_
.Rand8();
141 src1_
[i
] = rng_
.Rand8();
144 for (int i
= 0; i
< kMaxMaskSize
; ++i
)
145 mask_
[i
] = rng_(AOM_BLEND_A64_MAX_ALPHA
+ 1);
151 TEST_P(BlendA64Mask1DTest8B
, ExtremeValues
) {
152 for (int iter
= 0; iter
< kIterations
&& !HasFatalFailure(); ++iter
) {
153 for (int i
= 0; i
< kBufSize
; ++i
) {
154 dst_ref_
[i
] = rng_(2) + 254;
155 dst_tst_
[i
] = rng_(2) + 254;
156 src0_
[i
] = rng_(2) + 254;
157 src1_
[i
] = rng_(2) + 254;
160 for (int i
= 0; i
< kMaxMaskSize
; ++i
)
161 mask_
[i
] = rng_(2) + AOM_BLEND_A64_MAX_ALPHA
- 1;
167 static void blend_a64_hmask_ref(uint8_t *dst
, uint32_t dst_stride
,
168 const uint8_t *src0
, uint32_t src0_stride
,
169 const uint8_t *src1
, uint32_t src1_stride
,
170 const uint8_t *mask
, int w
, int h
) {
171 uint8_t mask2d
[BlendA64Mask1DTest8B::kMaxMaskSize
]
172 [BlendA64Mask1DTest8B::kMaxMaskSize
];
174 for (int row
= 0; row
< h
; ++row
)
175 for (int col
= 0; col
< w
; ++col
) mask2d
[row
][col
] = mask
[col
];
177 aom_blend_a64_mask_c(dst
, dst_stride
, src0
, src0_stride
, src1
, src1_stride
,
178 &mask2d
[0][0], BlendA64Mask1DTest8B::kMaxMaskSize
, w
, h
,
182 static void blend_a64_vmask_ref(uint8_t *dst
, uint32_t dst_stride
,
183 const uint8_t *src0
, uint32_t src0_stride
,
184 const uint8_t *src1
, uint32_t src1_stride
,
185 const uint8_t *mask
, int w
, int h
) {
186 uint8_t mask2d
[BlendA64Mask1DTest8B::kMaxMaskSize
]
187 [BlendA64Mask1DTest8B::kMaxMaskSize
];
189 for (int row
= 0; row
< h
; ++row
)
190 for (int col
= 0; col
< w
; ++col
) mask2d
[row
][col
] = mask
[row
];
192 aom_blend_a64_mask_c(dst
, dst_stride
, src0
, src0_stride
, src1
, src1_stride
,
193 &mask2d
[0][0], BlendA64Mask1DTest8B::kMaxMaskSize
, w
, h
,
197 INSTANTIATE_TEST_CASE_P(
198 C
, BlendA64Mask1DTest8B
,
199 ::testing::Values(TestFuncs(blend_a64_hmask_ref
, aom_blend_a64_hmask_c
),
200 TestFuncs(blend_a64_vmask_ref
, aom_blend_a64_vmask_c
)));
203 INSTANTIATE_TEST_CASE_P(
204 SSE4_1
, BlendA64Mask1DTest8B
,
206 TestFuncs(blend_a64_hmask_ref
, aom_blend_a64_hmask_sse4_1
),
207 TestFuncs(blend_a64_vmask_ref
, aom_blend_a64_vmask_sse4_1
)));
208 #endif // HAVE_SSE4_1
211 INSTANTIATE_TEST_CASE_P(NEON
, BlendA64Mask1DTest8B
,
212 ::testing::Values(TestFuncs(blend_a64_hmask_ref
,
213 aom_blend_a64_hmask_neon
),
214 TestFuncs(blend_a64_vmask_ref
,
215 aom_blend_a64_vmask_neon
)));
218 //////////////////////////////////////////////////////////////////////////////
219 // High bit-depth version
220 //////////////////////////////////////////////////////////////////////////////
222 typedef void (*FHBD
)(uint8_t *dst
, uint32_t dst_stride
, const uint8_t *src0
,
223 uint32_t src0_stride
, const uint8_t *src1
,
224 uint32_t src1_stride
, const uint8_t *mask
, int w
, int h
,
226 typedef libaom_test::FuncParam
<FHBD
> TestFuncsHBD
;
228 class BlendA64Mask1DTestHBD
: public BlendA64Mask1DTest
<FHBD
, uint16_t> {
230 void Execute(const uint16_t *p_src0
, const uint16_t *p_src1
) {
231 params_
.ref_func(CONVERT_TO_BYTEPTR(dst_ref_
+ dst_offset_
), dst_stride_
,
232 CONVERT_TO_BYTEPTR(p_src0
+ src0_offset_
), src0_stride_
,
233 CONVERT_TO_BYTEPTR(p_src1
+ src1_offset_
), src1_stride_
,
234 mask_
, w_
, h_
, bit_depth_
);
235 ASM_REGISTER_STATE_CHECK(params_
.tst_func(
236 CONVERT_TO_BYTEPTR(dst_tst_
+ dst_offset_
), dst_stride_
,
237 CONVERT_TO_BYTEPTR(p_src0
+ src0_offset_
), src0_stride_
,
238 CONVERT_TO_BYTEPTR(p_src1
+ src1_offset_
), src1_stride_
, mask_
, w_
, h_
,
245 TEST_P(BlendA64Mask1DTestHBD
, RandomValues
) {
246 for (int iter
= 0; iter
< kIterations
&& !HasFatalFailure(); ++iter
) {
248 case 0: bit_depth_
= 8; break;
249 case 1: bit_depth_
= 10; break;
250 default: bit_depth_
= 12; break;
253 const int hi
= 1 << bit_depth_
;
255 for (int i
= 0; i
< kBufSize
; ++i
) {
256 dst_ref_
[i
] = rng_(hi
);
257 dst_tst_
[i
] = rng_(hi
);
262 for (int i
= 0; i
< kMaxMaskSize
; ++i
)
263 mask_
[i
] = rng_(AOM_BLEND_A64_MAX_ALPHA
+ 1);
269 TEST_P(BlendA64Mask1DTestHBD
, ExtremeValues
) {
270 for (int iter
= 0; iter
< 1000 && !HasFatalFailure(); ++iter
) {
272 case 0: bit_depth_
= 8; break;
273 case 1: bit_depth_
= 10; break;
274 default: bit_depth_
= 12; break;
277 const int hi
= 1 << bit_depth_
;
278 const int lo
= hi
- 2;
280 for (int i
= 0; i
< kBufSize
; ++i
) {
281 dst_ref_
[i
] = rng_(hi
- lo
) + lo
;
282 dst_tst_
[i
] = rng_(hi
- lo
) + lo
;
283 src0_
[i
] = rng_(hi
- lo
) + lo
;
284 src1_
[i
] = rng_(hi
- lo
) + lo
;
287 for (int i
= 0; i
< kMaxMaskSize
; ++i
)
288 mask_
[i
] = rng_(2) + AOM_BLEND_A64_MAX_ALPHA
- 1;
294 static void highbd_blend_a64_hmask_ref(
295 uint8_t *dst
, uint32_t dst_stride
, const uint8_t *src0
,
296 uint32_t src0_stride
, const uint8_t *src1
, uint32_t src1_stride
,
297 const uint8_t *mask
, int w
, int h
, int bd
) {
298 uint8_t mask2d
[BlendA64Mask1DTestHBD::kMaxMaskSize
]
299 [BlendA64Mask1DTestHBD::kMaxMaskSize
];
301 for (int row
= 0; row
< h
; ++row
)
302 for (int col
= 0; col
< w
; ++col
) mask2d
[row
][col
] = mask
[col
];
304 aom_highbd_blend_a64_mask_c(
305 dst
, dst_stride
, src0
, src0_stride
, src1
, src1_stride
, &mask2d
[0][0],
306 BlendA64Mask1DTestHBD::kMaxMaskSize
, w
, h
, 0, 0, bd
);
309 static void highbd_blend_a64_vmask_ref(
310 uint8_t *dst
, uint32_t dst_stride
, const uint8_t *src0
,
311 uint32_t src0_stride
, const uint8_t *src1
, uint32_t src1_stride
,
312 const uint8_t *mask
, int w
, int h
, int bd
) {
313 uint8_t mask2d
[BlendA64Mask1DTestHBD::kMaxMaskSize
]
314 [BlendA64Mask1DTestHBD::kMaxMaskSize
];
316 for (int row
= 0; row
< h
; ++row
)
317 for (int col
= 0; col
< w
; ++col
) mask2d
[row
][col
] = mask
[row
];
319 aom_highbd_blend_a64_mask_c(
320 dst
, dst_stride
, src0
, src0_stride
, src1
, src1_stride
, &mask2d
[0][0],
321 BlendA64Mask1DTestHBD::kMaxMaskSize
, w
, h
, 0, 0, bd
);
324 INSTANTIATE_TEST_CASE_P(
325 C
, BlendA64Mask1DTestHBD
,
326 ::testing::Values(TestFuncsHBD(highbd_blend_a64_hmask_ref
,
327 aom_highbd_blend_a64_hmask_c
),
328 TestFuncsHBD(highbd_blend_a64_vmask_ref
,
329 aom_highbd_blend_a64_vmask_c
)));
332 INSTANTIATE_TEST_CASE_P(
333 SSE4_1
, BlendA64Mask1DTestHBD
,
334 ::testing::Values(TestFuncsHBD(highbd_blend_a64_hmask_ref
,
335 aom_highbd_blend_a64_hmask_sse4_1
),
336 TestFuncsHBD(highbd_blend_a64_vmask_ref
,
337 aom_highbd_blend_a64_vmask_sse4_1
)));
338 #endif // HAVE_SSE4_1