blob: 21c3721fe6740fa7eb883ce95b30b30bcfdb281c [file] [log] [blame]
Geza Lorea661bc82016-05-20 16:33:12 +01001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Geza Lorea661bc82016-05-20 16:33:12 +01003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * 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.
Geza Lorea661bc82016-05-20 16:33:12 +010010 */
11
12#include <math.h>
13#include <stdlib.h>
14#include <string.h>
15
Tom Finegan7a07ece2017-02-07 17:14:05 -080016#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
Geza Lorea661bc82016-05-20 16:33:12 +010017#include "test/register_state_check.h"
Geza Lorea661bc82016-05-20 16:33:12 +010018#include "test/function_equivalence_test.h"
Geza Lorea661bc82016-05-20 16:33:12 +010019
Yaowu Xuf883b422016-08-30 14:01:10 -070020#include "./aom_config.h"
21#include "./aom_dsp_rtcd.h"
22#include "aom/aom_integer.h"
Geza Lorea661bc82016-05-20 16:33:12 +010023
Yaowu Xuf883b422016-08-30 14:01:10 -070024#include "./av1_rtcd.h"
Geza Lorea661bc82016-05-20 16:33:12 +010025
Yaowu Xuc27fc142016-08-22 16:08:15 -070026#include "av1/common/enums.h"
Geza Lorea661bc82016-05-20 16:33:12 +010027
Yaowu Xuc27fc142016-08-22 16:08:15 -070028#include "aom_dsp/blend.h"
Geza Lorebfa59b42016-07-11 12:43:47 +010029
Yaowu Xuc27fc142016-08-22 16:08:15 -070030using libaom_test::FunctionEquivalenceTest;
Geza Lorea661bc82016-05-20 16:33:12 +010031
32namespace {
33
clang-format3a826f12016-08-11 17:46:05 -070034template <typename F, typename T>
Geza Lorebfa59b42016-07-11 12:43:47 +010035class BlendA64MaskTest : public FunctionEquivalenceTest<F> {
Geza Lorea661bc82016-05-20 16:33:12 +010036 protected:
Geza Loree6f8c172016-07-06 15:54:29 +010037 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;
43
Geza Lorebfa59b42016-07-11 12:43:47 +010044 virtual ~BlendA64MaskTest() {}
Geza Lorea661bc82016-05-20 16:33:12 +010045
Geza Lorebfa59b42016-07-11 12:43:47 +010046 virtual void Execute(const T *p_src0, const T *p_src1) = 0;
Geza Lorea661bc82016-05-20 16:33:12 +010047
48 void Common() {
Geza Lorea3f7ddc2016-07-12 15:26:36 +010049 w_ = 1 << this->rng_(MAX_SB_SIZE_LOG2 + 1);
50 h_ = 1 << this->rng_(MAX_SB_SIZE_LOG2 + 1);
Geza Lorea661bc82016-05-20 16:33:12 +010051
Geza Lorea3f7ddc2016-07-12 15:26:36 +010052 subx_ = this->rng_(2);
53 suby_ = this->rng_(2);
Geza Lorea661bc82016-05-20 16:33:12 +010054
Geza Lorea3f7ddc2016-07-12 15:26:36 +010055 dst_offset_ = this->rng_(33);
56 dst_stride_ = this->rng_(kMaxWidth + 1 - w_) + w_;
Geza Lorea661bc82016-05-20 16:33:12 +010057
Geza Lorea3f7ddc2016-07-12 15:26:36 +010058 src0_offset_ = this->rng_(33);
59 src0_stride_ = this->rng_(kMaxWidth + 1 - w_) + w_;
Geza Lorea661bc82016-05-20 16:33:12 +010060
Geza Lorea3f7ddc2016-07-12 15:26:36 +010061 src1_offset_ = this->rng_(33);
62 src1_stride_ = this->rng_(kMaxWidth + 1 - w_) + w_;
Geza Lorea661bc82016-05-20 16:33:12 +010063
clang-format3a826f12016-08-11 17:46:05 -070064 mask_stride_ =
65 this->rng_(kMaxWidth + 1 - w_ * (subx_ ? 2 : 1)) + w_ * (subx_ ? 2 : 1);
Geza Lorea661bc82016-05-20 16:33:12 +010066
67 T *p_src0;
68 T *p_src1;
69
Geza Lorea3f7ddc2016-07-12 15:26:36 +010070 switch (this->rng_(3)) {
clang-format3a826f12016-08-11 17:46:05 -070071 case 0: // Separate sources
Geza Loree6f8c172016-07-06 15:54:29 +010072 p_src0 = src0_;
73 p_src1 = src1_;
Geza Lorea661bc82016-05-20 16:33:12 +010074 break;
clang-format3a826f12016-08-11 17:46:05 -070075 case 1: // src0 == dst
Geza Loree6f8c172016-07-06 15:54:29 +010076 p_src0 = dst_tst_;
77 src0_stride_ = dst_stride_;
78 src0_offset_ = dst_offset_;
79 p_src1 = src1_;
Geza Lorea661bc82016-05-20 16:33:12 +010080 break;
clang-format3a826f12016-08-11 17:46:05 -070081 case 2: // src1 == dst
Geza Loree6f8c172016-07-06 15:54:29 +010082 p_src0 = src0_;
83 p_src1 = dst_tst_;
84 src1_stride_ = dst_stride_;
85 src1_offset_ = dst_offset_;
Geza Lorea661bc82016-05-20 16:33:12 +010086 break;
clang-format3a826f12016-08-11 17:46:05 -070087 default: FAIL();
Geza Lorea661bc82016-05-20 16:33:12 +010088 }
89
Geza Lorea661bc82016-05-20 16:33:12 +010090 Execute(p_src0, p_src1);
91
clang-format3a826f12016-08-11 17:46:05 -070092 for (int r = 0; r < h_; ++r) {
93 for (int c = 0; c < w_; ++c) {
Geza Loree6f8c172016-07-06 15:54:29 +010094 ASSERT_EQ(dst_ref_[dst_offset_ + r * dst_stride_ + c],
95 dst_tst_[dst_offset_ + r * dst_stride_ + c]);
96 }
97 }
Geza Lorea661bc82016-05-20 16:33:12 +010098 }
99
Geza Loree6f8c172016-07-06 15:54:29 +0100100 T dst_ref_[kBufSize];
101 T dst_tst_[kBufSize];
Jingning Han91ae5d92016-08-26 11:24:36 -0700102 uint32_t dst_stride_;
103 uint32_t dst_offset_;
Geza Lorea661bc82016-05-20 16:33:12 +0100104
Geza Loree6f8c172016-07-06 15:54:29 +0100105 T src0_[kBufSize];
Jingning Han91ae5d92016-08-26 11:24:36 -0700106 uint32_t src0_stride_;
107 uint32_t src0_offset_;
Geza Lorea661bc82016-05-20 16:33:12 +0100108
Geza Loree6f8c172016-07-06 15:54:29 +0100109 T src1_[kBufSize];
Jingning Han91ae5d92016-08-26 11:24:36 -0700110 uint32_t src1_stride_;
111 uint32_t src1_offset_;
Geza Lorea661bc82016-05-20 16:33:12 +0100112
Geza Loree6f8c172016-07-06 15:54:29 +0100113 uint8_t mask_[kMaxMaskSize];
114 size_t mask_stride_;
Geza Lorea661bc82016-05-20 16:33:12 +0100115
Geza Loree6f8c172016-07-06 15:54:29 +0100116 int w_;
117 int h_;
Geza Lorea661bc82016-05-20 16:33:12 +0100118
Jingning Han91ae5d92016-08-26 11:24:36 -0700119 int suby_;
120 int subx_;
Geza Lorea661bc82016-05-20 16:33:12 +0100121};
122
123//////////////////////////////////////////////////////////////////////////////
124// 8 bit version
125//////////////////////////////////////////////////////////////////////////////
126
clang-format3a826f12016-08-11 17:46:05 -0700127typedef void (*F8B)(uint8_t *dst, uint32_t dst_stride, const uint8_t *src0,
128 uint32_t src0_stride, const uint8_t *src1,
129 uint32_t src1_stride, const uint8_t *mask,
130 uint32_t mask_stride, int h, int w, int suby, int subx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700131typedef libaom_test::FuncParam<F8B> TestFuncs;
Geza Lorea661bc82016-05-20 16:33:12 +0100132
Geza Lorebfa59b42016-07-11 12:43:47 +0100133class BlendA64MaskTest8B : public BlendA64MaskTest<F8B, uint8_t> {
Geza Lorea661bc82016-05-20 16:33:12 +0100134 protected:
Geza Lorebfa59b42016-07-11 12:43:47 +0100135 void Execute(const uint8_t *p_src0, const uint8_t *p_src1) {
clang-format3a826f12016-08-11 17:46:05 -0700136 params_.ref_func(dst_ref_ + dst_offset_, dst_stride_, p_src0 + src0_offset_,
137 src0_stride_, p_src1 + src1_offset_, src1_stride_, mask_,
138 kMaxMaskWidth, h_, w_, suby_, subx_);
139 ASM_REGISTER_STATE_CHECK(params_.tst_func(
140 dst_tst_ + dst_offset_, dst_stride_, p_src0 + src0_offset_,
141 src0_stride_, p_src1 + src1_offset_, src1_stride_, mask_, kMaxMaskWidth,
142 h_, w_, suby_, subx_));
Geza Lorea661bc82016-05-20 16:33:12 +0100143 }
144};
145
Geza Lorebfa59b42016-07-11 12:43:47 +0100146TEST_P(BlendA64MaskTest8B, RandomValues) {
clang-format3a826f12016-08-11 17:46:05 -0700147 for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
148 for (int i = 0; i < kBufSize; ++i) {
Geza Loree6f8c172016-07-06 15:54:29 +0100149 dst_ref_[i] = rng_.Rand8();
150 dst_tst_[i] = rng_.Rand8();
Geza Lorea661bc82016-05-20 16:33:12 +0100151
Geza Loree6f8c172016-07-06 15:54:29 +0100152 src0_[i] = rng_.Rand8();
153 src1_[i] = rng_.Rand8();
154 }
Geza Lorea661bc82016-05-20 16:33:12 +0100155
clang-format3a826f12016-08-11 17:46:05 -0700156 for (int i = 0; i < kMaxMaskSize; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -0700157 mask_[i] = rng_(AOM_BLEND_A64_MAX_ALPHA + 1);
Geza Lorea661bc82016-05-20 16:33:12 +0100158
159 Common();
160 }
161}
162
Geza Lorebfa59b42016-07-11 12:43:47 +0100163TEST_P(BlendA64MaskTest8B, ExtremeValues) {
clang-format3a826f12016-08-11 17:46:05 -0700164 for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
165 for (int i = 0; i < kBufSize; ++i) {
Geza Loree6f8c172016-07-06 15:54:29 +0100166 dst_ref_[i] = rng_(2) + 254;
167 dst_tst_[i] = rng_(2) + 254;
168 src0_[i] = rng_(2) + 254;
169 src1_[i] = rng_(2) + 254;
170 }
Geza Lorea661bc82016-05-20 16:33:12 +0100171
clang-format3a826f12016-08-11 17:46:05 -0700172 for (int i = 0; i < kMaxMaskSize; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -0700173 mask_[i] = rng_(2) + AOM_BLEND_A64_MAX_ALPHA - 1;
Geza Lorea661bc82016-05-20 16:33:12 +0100174
175 Common();
176 }
177}
178
179#if HAVE_SSE4_1
Yaowu Xu685039d2016-12-07 10:56:39 -0800180INSTANTIATE_TEST_CASE_P(SSE4_1, BlendA64MaskTest8B,
clang-format3a826f12016-08-11 17:46:05 -0700181 ::testing::Values(TestFuncs(
Yaowu Xuf883b422016-08-30 14:01:10 -0700182 aom_blend_a64_mask_c, aom_blend_a64_mask_sse4_1)));
Geza Lorea661bc82016-05-20 16:33:12 +0100183#endif // HAVE_SSE4_1
184
Yaowu Xuf883b422016-08-30 14:01:10 -0700185#if CONFIG_AOM_HIGHBITDEPTH
Geza Lorea661bc82016-05-20 16:33:12 +0100186//////////////////////////////////////////////////////////////////////////////
187// High bit-depth version
188//////////////////////////////////////////////////////////////////////////////
189
clang-format3a826f12016-08-11 17:46:05 -0700190typedef void (*FHBD)(uint8_t *dst, uint32_t dst_stride, const uint8_t *src0,
191 uint32_t src0_stride, const uint8_t *src1,
192 uint32_t src1_stride, const uint8_t *mask,
193 uint32_t mask_stride, int h, int w, int suby, int subx,
194 int bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700195typedef libaom_test::FuncParam<FHBD> TestFuncsHBD;
Geza Lorea661bc82016-05-20 16:33:12 +0100196
Geza Lorebfa59b42016-07-11 12:43:47 +0100197class BlendA64MaskTestHBD : public BlendA64MaskTest<FHBD, uint16_t> {
Geza Lorea661bc82016-05-20 16:33:12 +0100198 protected:
Geza Lorebfa59b42016-07-11 12:43:47 +0100199 void Execute(const uint16_t *p_src0, const uint16_t *p_src1) {
Geza Lorea3f7ddc2016-07-12 15:26:36 +0100200 params_.ref_func(CONVERT_TO_BYTEPTR(dst_ref_ + dst_offset_), dst_stride_,
201 CONVERT_TO_BYTEPTR(p_src0 + src0_offset_), src0_stride_,
202 CONVERT_TO_BYTEPTR(p_src1 + src1_offset_), src1_stride_,
203 mask_, kMaxMaskWidth, h_, w_, suby_, subx_, bit_depth_);
204 ASM_REGISTER_STATE_CHECK(params_.tst_func(
205 CONVERT_TO_BYTEPTR(dst_tst_ + dst_offset_), dst_stride_,
206 CONVERT_TO_BYTEPTR(p_src0 + src0_offset_), src0_stride_,
clang-format3a826f12016-08-11 17:46:05 -0700207 CONVERT_TO_BYTEPTR(p_src1 + src1_offset_), src1_stride_, mask_,
208 kMaxMaskWidth, h_, w_, suby_, subx_, bit_depth_));
Geza Lorea661bc82016-05-20 16:33:12 +0100209 }
210
Geza Loree6f8c172016-07-06 15:54:29 +0100211 int bit_depth_;
Geza Lorea661bc82016-05-20 16:33:12 +0100212};
213
Geza Lorebfa59b42016-07-11 12:43:47 +0100214TEST_P(BlendA64MaskTestHBD, RandomValues) {
clang-format3a826f12016-08-11 17:46:05 -0700215 for (int iter = 0; iter < kIterations && !HasFatalFailure(); ++iter) {
Geza Loree6f8c172016-07-06 15:54:29 +0100216 switch (rng_(3)) {
clang-format3a826f12016-08-11 17:46:05 -0700217 case 0: bit_depth_ = 8; break;
218 case 1: bit_depth_ = 10; break;
219 default: bit_depth_ = 12; break;
Geza Loree6f8c172016-07-06 15:54:29 +0100220 }
Geza Lorea661bc82016-05-20 16:33:12 +0100221
Geza Loree6f8c172016-07-06 15:54:29 +0100222 const int hi = 1 << bit_depth_;
Geza Lorea661bc82016-05-20 16:33:12 +0100223
clang-format3a826f12016-08-11 17:46:05 -0700224 for (int i = 0; i < kBufSize; ++i) {
Geza Loree6f8c172016-07-06 15:54:29 +0100225 dst_ref_[i] = rng_(hi);
226 dst_tst_[i] = rng_(hi);
227 src0_[i] = rng_(hi);
228 src1_[i] = rng_(hi);
229 }
Geza Lorea661bc82016-05-20 16:33:12 +0100230
clang-format3a826f12016-08-11 17:46:05 -0700231 for (int i = 0; i < kMaxMaskSize; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -0700232 mask_[i] = rng_(AOM_BLEND_A64_MAX_ALPHA + 1);
Geza Lorea661bc82016-05-20 16:33:12 +0100233
234 Common();
235 }
236}
237
Geza Lorebfa59b42016-07-11 12:43:47 +0100238TEST_P(BlendA64MaskTestHBD, ExtremeValues) {
clang-format3a826f12016-08-11 17:46:05 -0700239 for (int iter = 0; iter < 1000 && !HasFatalFailure(); ++iter) {
Geza Loree6f8c172016-07-06 15:54:29 +0100240 switch (rng_(3)) {
clang-format3a826f12016-08-11 17:46:05 -0700241 case 0: bit_depth_ = 8; break;
242 case 1: bit_depth_ = 10; break;
243 default: bit_depth_ = 12; break;
Geza Loree6f8c172016-07-06 15:54:29 +0100244 }
Geza Lorea661bc82016-05-20 16:33:12 +0100245
Geza Loree6f8c172016-07-06 15:54:29 +0100246 const int hi = 1 << bit_depth_;
Geza Lorea661bc82016-05-20 16:33:12 +0100247 const int lo = hi - 2;
248
clang-format3a826f12016-08-11 17:46:05 -0700249 for (int i = 0; i < kBufSize; ++i) {
Geza Loree6f8c172016-07-06 15:54:29 +0100250 dst_ref_[i] = rng_(hi - lo) + lo;
251 dst_tst_[i] = rng_(hi - lo) + lo;
252 src0_[i] = rng_(hi - lo) + lo;
253 src1_[i] = rng_(hi - lo) + lo;
254 }
Geza Lorea661bc82016-05-20 16:33:12 +0100255
clang-format3a826f12016-08-11 17:46:05 -0700256 for (int i = 0; i < kMaxMaskSize; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -0700257 mask_[i] = rng_(2) + AOM_BLEND_A64_MAX_ALPHA - 1;
Geza Lorea661bc82016-05-20 16:33:12 +0100258
259 Common();
260 }
261}
262
263#if HAVE_SSE4_1
264INSTANTIATE_TEST_CASE_P(
Yaowu Xu685039d2016-12-07 10:56:39 -0800265 SSE4_1, BlendA64MaskTestHBD,
Yaowu Xuf883b422016-08-30 14:01:10 -0700266 ::testing::Values(TestFuncsHBD(aom_highbd_blend_a64_mask_c,
267 aom_highbd_blend_a64_mask_sse4_1)));
Geza Lorea661bc82016-05-20 16:33:12 +0100268#endif // HAVE_SSE4_1
Yaowu Xuf883b422016-08-30 14:01:10 -0700269#endif // CONFIG_AOM_HIGHBITDEPTH
Geza Lorea661bc82016-05-20 16:33:12 +0100270} // namespace