1 /*
2 * Copyright (c) 2018, 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 <tuple>
13 #include <vector>
14
15 #include "gtest/gtest.h"
16
17 #include "config/aom_config.h"
18 #include "config/aom_dsp_rtcd.h"
19
20 #include "aom_mem/aom_mem.h"
21 #include "aom_ports/aom_timer.h"
22 #include "aom_ports/sanitizer.h"
23 #include "av1/common/blockd.h"
24 #include "av1/common/pred_common.h"
25 #include "av1/common/reconintra.h"
26 #include "test/acm_random.h"
27 #include "test/register_state_check.h"
28 #include "test/util.h"
29
30 namespace {
31
32 const int kNumIntraNeighbourPixels = MAX_TX_SIZE * 2 + 32;
33 const int kIntraPredInputPadding = 16;
34
35 const int kZ1Start = 0;
36 const int kZ2Start = 90;
37 const int kZ3Start = 180;
38
39 const TX_SIZE kTxSize[] = { TX_4X4, TX_8X8, TX_16X16, TX_32X32, TX_64X64,
40 TX_4X8, TX_8X4, TX_8X16, TX_16X8, TX_16X32,
41 TX_32X16, TX_32X64, TX_64X32, TX_4X16, TX_16X4,
42 TX_8X32, TX_32X8, TX_16X64, TX_64X16 };
43
44 const char *const kTxSizeStrings[] = {
45 "TX_4X4", "TX_8X8", "TX_16X16", "TX_32X32", "TX_64X64",
46 "TX_4X8", "TX_8X4", "TX_8X16", "TX_16X8", "TX_16X32",
47 "TX_32X16", "TX_32X64", "TX_64X32", "TX_4X16", "TX_16X4",
48 "TX_8X32", "TX_32X8", "TX_16X64", "TX_64X16"
49 };
50
51 using libaom_test::ACMRandom;
52
53 typedef void (*DrPred_Hbd)(uint16_t *dst, ptrdiff_t stride, int bw, int bh,
54 const uint16_t *above, const uint16_t *left,
55 int upsample_above, int upsample_left, int dx,
56 int dy, int bd);
57
58 typedef void (*DrPred)(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
59 const uint8_t *above, const uint8_t *left,
60 int upsample_above, int upsample_left, int dx, int dy,
61 int bd);
62
63 typedef void (*Z1_Lbd)(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
64 const uint8_t *above, const uint8_t *left,
65 int upsample_above, int dx, int dy);
66 template <Z1_Lbd fn>
z1_wrapper(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left,int upsample_above,int upsample_left,int dx,int dy,int bd)67 void z1_wrapper(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
68 const uint8_t *above, const uint8_t *left, int upsample_above,
69 int upsample_left, int dx, int dy, int bd) {
70 (void)bd;
71 (void)upsample_left;
72 fn(dst, stride, bw, bh, above, left, upsample_above, dx, dy);
73 }
74
75 typedef void (*Z2_Lbd)(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
76 const uint8_t *above, const uint8_t *left,
77 int upsample_above, int upsample_left, int dx, int dy);
78 template <Z2_Lbd fn>
z2_wrapper(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left,int upsample_above,int upsample_left,int dx,int dy,int bd)79 void z2_wrapper(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
80 const uint8_t *above, const uint8_t *left, int upsample_above,
81 int upsample_left, int dx, int dy, int bd) {
82 (void)bd;
83 (void)upsample_left;
84 fn(dst, stride, bw, bh, above, left, upsample_above, upsample_left, dx, dy);
85 }
86
87 typedef void (*Z3_Lbd)(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
88 const uint8_t *above, const uint8_t *left,
89 int upsample_left, int dx, int dy);
90 template <Z3_Lbd fn>
z3_wrapper(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left,int upsample_above,int upsample_left,int dx,int dy,int bd)91 void z3_wrapper(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
92 const uint8_t *above, const uint8_t *left, int upsample_above,
93 int upsample_left, int dx, int dy, int bd) {
94 (void)bd;
95 (void)upsample_above;
96 fn(dst, stride, bw, bh, above, left, upsample_left, dx, dy);
97 }
98
99 typedef void (*Z1_Hbd)(uint16_t *dst, ptrdiff_t stride, int bw, int bh,
100 const uint16_t *above, const uint16_t *left,
101 int upsample_above, int dx, int dy, int bd);
102 template <Z1_Hbd fn>
z1_wrapper_hbd(uint16_t * dst,ptrdiff_t stride,int bw,int bh,const uint16_t * above,const uint16_t * left,int upsample_above,int upsample_left,int dx,int dy,int bd)103 void z1_wrapper_hbd(uint16_t *dst, ptrdiff_t stride, int bw, int bh,
104 const uint16_t *above, const uint16_t *left,
105 int upsample_above, int upsample_left, int dx, int dy,
106 int bd) {
107 (void)bd;
108 (void)upsample_left;
109 fn(dst, stride, bw, bh, above, left, upsample_above, dx, dy, bd);
110 }
111
112 typedef void (*Z2_Hbd)(uint16_t *dst, ptrdiff_t stride, int bw, int bh,
113 const uint16_t *above, const uint16_t *left,
114 int upsample_above, int upsample_left, int dx, int dy,
115 int bd);
116 template <Z2_Hbd fn>
z2_wrapper_hbd(uint16_t * dst,ptrdiff_t stride,int bw,int bh,const uint16_t * above,const uint16_t * left,int upsample_above,int upsample_left,int dx,int dy,int bd)117 void z2_wrapper_hbd(uint16_t *dst, ptrdiff_t stride, int bw, int bh,
118 const uint16_t *above, const uint16_t *left,
119 int upsample_above, int upsample_left, int dx, int dy,
120 int bd) {
121 (void)bd;
122 fn(dst, stride, bw, bh, above, left, upsample_above, upsample_left, dx, dy,
123 bd);
124 }
125
126 typedef void (*Z3_Hbd)(uint16_t *dst, ptrdiff_t stride, int bw, int bh,
127 const uint16_t *above, const uint16_t *left,
128 int upsample_left, int dx, int dy, int bd);
129 template <Z3_Hbd fn>
z3_wrapper_hbd(uint16_t * dst,ptrdiff_t stride,int bw,int bh,const uint16_t * above,const uint16_t * left,int upsample_above,int upsample_left,int dx,int dy,int bd)130 void z3_wrapper_hbd(uint16_t *dst, ptrdiff_t stride, int bw, int bh,
131 const uint16_t *above, const uint16_t *left,
132 int upsample_above, int upsample_left, int dx, int dy,
133 int bd) {
134 (void)bd;
135 (void)upsample_above;
136 fn(dst, stride, bw, bh, above, left, upsample_left, dx, dy, bd);
137 }
138
139 template <typename FuncType>
140 struct DrPredFunc {
DrPredFunc__anon225ddc120111::DrPredFunc141 DrPredFunc(FuncType pred = nullptr, FuncType tst = nullptr,
142 int bit_depth_value = 0, int start_angle_value = 0)
143 : ref_fn(pred), tst_fn(tst), bit_depth(bit_depth_value),
144 start_angle(start_angle_value) {}
145
146 FuncType ref_fn;
147 FuncType tst_fn;
148 int bit_depth;
149 int start_angle;
150 };
151
152 template <typename Pixel, typename FuncType>
153 class DrPredTest : public ::testing::TestWithParam<DrPredFunc<FuncType> > {
154 protected:
155 static const int kMaxNumTests = 10000;
156 static const int kIterations = 10;
157
DrPredTest()158 DrPredTest()
159 : enable_upsample_(0), upsample_above_(0), upsample_left_(0), bw_(0),
160 bh_(0), dx_(1), dy_(1), bd_(8), txsize_(TX_4X4) {
161 params_ = this->GetParam();
162 start_angle_ = params_.start_angle;
163 stop_angle_ = start_angle_ + 90;
164 }
165
166 ~DrPredTest() override = default;
167
Predict(bool speedtest,int tx,const Pixel * above,const Pixel * left,Pixel * dst_ref,Pixel * dst_tst,int dst_stride)168 void Predict(bool speedtest, int tx, const Pixel *above, const Pixel *left,
169 Pixel *dst_ref, Pixel *dst_tst, int dst_stride) {
170 const int kNumTests = speedtest ? kMaxNumTests : 1;
171 aom_usec_timer timer;
172 int tst_time = 0;
173
174 bd_ = params_.bit_depth;
175
176 aom_usec_timer_start(&timer);
177 for (int k = 0; k < kNumTests; ++k) {
178 params_.ref_fn(dst_ref, dst_stride, bw_, bh_, above, left,
179 upsample_above_, upsample_left_, dx_, dy_, bd_);
180 }
181 aom_usec_timer_mark(&timer);
182 const int ref_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
183
184 if (params_.tst_fn) {
185 aom_usec_timer_start(&timer);
186 for (int k = 0; k < kNumTests; ++k) {
187 API_REGISTER_STATE_CHECK(params_.tst_fn(dst_tst, dst_stride, bw_, bh_,
188 above, left, upsample_above_,
189 upsample_left_, dx_, dy_, bd_));
190 }
191 aom_usec_timer_mark(&timer);
192 tst_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
193 } else {
194 for (int r = 0; r < bh_; ++r) {
195 for (int c = 0; c < bw_; ++c) {
196 dst_tst[r * dst_stride + c] = dst_ref[r * dst_stride + c];
197 }
198 }
199 }
200
201 OutputTimes(kNumTests, ref_time, tst_time, tx);
202 }
203
RunTest(bool speedtest,bool needsaturation,int p_angle)204 void RunTest(bool speedtest, bool needsaturation, int p_angle) {
205 bd_ = params_.bit_depth;
206
207 for (int tx = 0; tx < TX_SIZES_ALL; ++tx) {
208 bw_ = tx_size_wide[kTxSize[tx]];
209 bh_ = tx_size_high[kTxSize[tx]];
210
211 if (enable_upsample_) {
212 upsample_above_ =
213 av1_use_intra_edge_upsample(bw_, bh_, p_angle - 90, 0);
214 upsample_left_ =
215 av1_use_intra_edge_upsample(bw_, bh_, p_angle - 180, 0);
216 } else {
217 upsample_above_ = upsample_left_ = 0;
218 }
219
220 // Declare input buffers as local arrays to allow checking for
221 // over-reads.
222 DECLARE_ALIGNED(16, Pixel, left_data[kNumIntraNeighbourPixels]);
223 DECLARE_ALIGNED(16, Pixel, above_data[kNumIntraNeighbourPixels]);
224
225 // We need to allow reading some previous bytes from the input pointers.
226 const Pixel *above = &above_data[kIntraPredInputPadding];
227 const Pixel *left = &left_data[kIntraPredInputPadding];
228
229 if (needsaturation) {
230 const Pixel sat = (1 << bd_) - 1;
231 for (int i = 0; i < kNumIntraNeighbourPixels; ++i) {
232 left_data[i] = sat;
233 above_data[i] = sat;
234 }
235 } else {
236 for (int i = 0; i < kNumIntraNeighbourPixels; ++i) {
237 left_data[i] = rng_.Rand8();
238 above_data[i] = rng_.Rand8();
239 }
240 }
241
242 // Add additional padding to allow detection of over reads/writes when
243 // the transform width is equal to MAX_TX_SIZE.
244 const int dst_stride = MAX_TX_SIZE + 16;
245 std::vector<Pixel> dst_ref(dst_stride * bh_);
246 std::vector<Pixel> dst_tst(dst_stride * bh_);
247
248 for (int r = 0; r < bh_; ++r) {
249 ASAN_POISON_MEMORY_REGION(&dst_ref[r * dst_stride + bw_],
250 (dst_stride - bw_) * sizeof(Pixel));
251 ASAN_POISON_MEMORY_REGION(&dst_tst[r * dst_stride + bw_],
252 (dst_stride - bw_) * sizeof(Pixel));
253 }
254
255 Predict(speedtest, tx, above, left, dst_ref.data(), dst_tst.data(),
256 dst_stride);
257
258 for (int r = 0; r < bh_; ++r) {
259 ASAN_UNPOISON_MEMORY_REGION(&dst_ref[r * dst_stride + bw_],
260 (dst_stride - bw_) * sizeof(Pixel));
261 ASAN_UNPOISON_MEMORY_REGION(&dst_tst[r * dst_stride + bw_],
262 (dst_stride - bw_) * sizeof(Pixel));
263 }
264
265 for (int r = 0; r < bh_; ++r) {
266 for (int c = 0; c < bw_; ++c) {
267 ASSERT_EQ(dst_ref[r * dst_stride + c], dst_tst[r * dst_stride + c])
268 << bw_ << "x" << bh_ << " r: " << r << " c: " << c
269 << " dx: " << dx_ << " dy: " << dy_
270 << " upsample_above: " << upsample_above_
271 << " upsample_left: " << upsample_left_;
272 }
273 }
274 }
275 }
276
OutputTimes(int num_tests,int ref_time,int tst_time,int tx)277 void OutputTimes(int num_tests, int ref_time, int tst_time, int tx) {
278 if (num_tests > 1) {
279 if (params_.tst_fn) {
280 const float x = static_cast<float>(ref_time) / tst_time;
281 printf("\t[%8s] :: ref time %6d, tst time %6d %3.2f\n",
282 kTxSizeStrings[tx], ref_time, tst_time, x);
283 } else {
284 printf("\t[%8s] :: ref time %6d\n", kTxSizeStrings[tx], ref_time);
285 }
286 }
287 }
288
RundrPredTest(const int speed)289 void RundrPredTest(const int speed) {
290 if (params_.tst_fn == nullptr) return;
291 const int angles[] = { 3, 45, 87 };
292 const int start_angle = speed ? 0 : start_angle_;
293 const int stop_angle = speed ? 3 : stop_angle_;
294 for (enable_upsample_ = 0; enable_upsample_ < 2; ++enable_upsample_) {
295 for (int i = start_angle; i < stop_angle; ++i) {
296 const int angle = speed ? angles[i] + start_angle_ : i;
297 dx_ = av1_get_dx(angle);
298 dy_ = av1_get_dy(angle);
299 if (speed) {
300 printf("enable_upsample: %d angle: %d ~~~~~~~~~~~~~~~\n",
301 enable_upsample_, angle);
302 }
303 if (dx_ && dy_) RunTest(speed, false, angle);
304 }
305 }
306 }
307
308 int enable_upsample_;
309 int upsample_above_;
310 int upsample_left_;
311 int bw_;
312 int bh_;
313 int dx_;
314 int dy_;
315 int bd_;
316 TX_SIZE txsize_;
317
318 int start_angle_;
319 int stop_angle_;
320
321 ACMRandom rng_;
322
323 DrPredFunc<FuncType> params_;
324 };
325
326 class LowbdDrPredTest : public DrPredTest<uint8_t, DrPred> {};
327
TEST_P(LowbdDrPredTest,SaturatedValues)328 TEST_P(LowbdDrPredTest, SaturatedValues) {
329 for (enable_upsample_ = 0; enable_upsample_ < 2; ++enable_upsample_) {
330 for (int angle = start_angle_; angle < stop_angle_; ++angle) {
331 dx_ = av1_get_dx(angle);
332 dy_ = av1_get_dy(angle);
333 if (dx_ && dy_) RunTest(false, true, angle);
334 }
335 }
336 }
337
338 using std::make_tuple;
339
340 INSTANTIATE_TEST_SUITE_P(
341 C, LowbdDrPredTest,
342 ::testing::Values(DrPredFunc<DrPred>(&z1_wrapper<av1_dr_prediction_z1_c>,
343 nullptr, AOM_BITS_8, kZ1Start),
344 DrPredFunc<DrPred>(&z2_wrapper<av1_dr_prediction_z2_c>,
345 nullptr, AOM_BITS_8, kZ2Start),
346 DrPredFunc<DrPred>(&z3_wrapper<av1_dr_prediction_z3_c>,
347 nullptr, AOM_BITS_8, kZ3Start)));
348
349 #if CONFIG_AV1_HIGHBITDEPTH
350 class HighbdDrPredTest : public DrPredTest<uint16_t, DrPred_Hbd> {};
351
TEST_P(HighbdDrPredTest,SaturatedValues)352 TEST_P(HighbdDrPredTest, SaturatedValues) {
353 for (enable_upsample_ = 0; enable_upsample_ < 2; ++enable_upsample_) {
354 for (int angle = start_angle_; angle < stop_angle_; ++angle) {
355 dx_ = av1_get_dx(angle);
356 dy_ = av1_get_dy(angle);
357 if (dx_ && dy_) RunTest(false, true, angle);
358 }
359 }
360 }
361
362 INSTANTIATE_TEST_SUITE_P(
363 C, HighbdDrPredTest,
364 ::testing::Values(
365 DrPredFunc<DrPred_Hbd>(&z1_wrapper_hbd<av1_highbd_dr_prediction_z1_c>,
366 nullptr, AOM_BITS_8, kZ1Start),
367 DrPredFunc<DrPred_Hbd>(&z1_wrapper_hbd<av1_highbd_dr_prediction_z1_c>,
368 nullptr, AOM_BITS_10, kZ1Start),
369 DrPredFunc<DrPred_Hbd>(&z1_wrapper_hbd<av1_highbd_dr_prediction_z1_c>,
370 nullptr, AOM_BITS_12, kZ1Start),
371 DrPredFunc<DrPred_Hbd>(&z2_wrapper_hbd<av1_highbd_dr_prediction_z2_c>,
372 nullptr, AOM_BITS_8, kZ2Start),
373 DrPredFunc<DrPred_Hbd>(&z2_wrapper_hbd<av1_highbd_dr_prediction_z2_c>,
374 nullptr, AOM_BITS_10, kZ2Start),
375 DrPredFunc<DrPred_Hbd>(&z2_wrapper_hbd<av1_highbd_dr_prediction_z2_c>,
376 nullptr, AOM_BITS_12, kZ2Start),
377 DrPredFunc<DrPred_Hbd>(&z3_wrapper_hbd<av1_highbd_dr_prediction_z3_c>,
378 nullptr, AOM_BITS_8, kZ3Start),
379 DrPredFunc<DrPred_Hbd>(&z3_wrapper_hbd<av1_highbd_dr_prediction_z3_c>,
380 nullptr, AOM_BITS_10, kZ3Start),
381 DrPredFunc<DrPred_Hbd>(&z3_wrapper_hbd<av1_highbd_dr_prediction_z3_c>,
382 nullptr, AOM_BITS_12, kZ3Start)));
383 #endif // CONFIG_AV1_HIGHBITDEPTH
384
TEST_P(LowbdDrPredTest,OperationCheck)385 TEST_P(LowbdDrPredTest, OperationCheck) { RundrPredTest(0); }
386
TEST_P(LowbdDrPredTest,DISABLED_Speed)387 TEST_P(LowbdDrPredTest, DISABLED_Speed) { RundrPredTest(1); }
388
389 #if CONFIG_AV1_HIGHBITDEPTH
TEST_P(HighbdDrPredTest,OperationCheck)390 TEST_P(HighbdDrPredTest, OperationCheck) {
391 if (params_.tst_fn == nullptr) return;
392 for (enable_upsample_ = 0; enable_upsample_ < 2; ++enable_upsample_) {
393 for (int angle = start_angle_; angle < stop_angle_; angle++) {
394 dx_ = av1_get_dx(angle);
395 dy_ = av1_get_dy(angle);
396 if (dx_ && dy_) RunTest(false, false, angle);
397 }
398 }
399 }
400
TEST_P(HighbdDrPredTest,DISABLED_Speed)401 TEST_P(HighbdDrPredTest, DISABLED_Speed) {
402 const int angles[] = { 3, 45, 87 };
403 for (enable_upsample_ = 0; enable_upsample_ < 2; ++enable_upsample_) {
404 for (int i = 0; i < 3; ++i) {
405 int angle = angles[i] + start_angle_;
406 dx_ = av1_get_dx(angle);
407 dy_ = av1_get_dy(angle);
408 printf("enable_upsample: %d angle: %d ~~~~~~~~~~~~~~~\n",
409 enable_upsample_, angle);
410 if (dx_ && dy_) RunTest(true, false, angle);
411 }
412 }
413 }
414 #endif // CONFIG_AV1_HIGHBITDEPTH
415
416 #if HAVE_SSE4_1
417 INSTANTIATE_TEST_SUITE_P(
418 SSE4_1, LowbdDrPredTest,
419 ::testing::Values(
420 DrPredFunc<DrPred>(&z1_wrapper<av1_dr_prediction_z1_c>,
421 &z1_wrapper<av1_dr_prediction_z1_sse4_1>, AOM_BITS_8,
422 kZ1Start),
423 DrPredFunc<DrPred>(&z2_wrapper<av1_dr_prediction_z2_c>,
424 &z2_wrapper<av1_dr_prediction_z2_sse4_1>, AOM_BITS_8,
425 kZ2Start),
426 DrPredFunc<DrPred>(&z3_wrapper<av1_dr_prediction_z3_c>,
427 &z3_wrapper<av1_dr_prediction_z3_sse4_1>, AOM_BITS_8,
428 kZ3Start)));
429 #endif // HAVE_SSE4_1
430
431 #if HAVE_AVX2
432 INSTANTIATE_TEST_SUITE_P(
433 AVX2, LowbdDrPredTest,
434 ::testing::Values(DrPredFunc<DrPred>(&z1_wrapper<av1_dr_prediction_z1_c>,
435 &z1_wrapper<av1_dr_prediction_z1_avx2>,
436 AOM_BITS_8, kZ1Start),
437 DrPredFunc<DrPred>(&z2_wrapper<av1_dr_prediction_z2_c>,
438 &z2_wrapper<av1_dr_prediction_z2_avx2>,
439 AOM_BITS_8, kZ2Start),
440 DrPredFunc<DrPred>(&z3_wrapper<av1_dr_prediction_z3_c>,
441 &z3_wrapper<av1_dr_prediction_z3_avx2>,
442 AOM_BITS_8, kZ3Start)));
443
444 #if CONFIG_AV1_HIGHBITDEPTH
445 INSTANTIATE_TEST_SUITE_P(
446 AVX2, HighbdDrPredTest,
447 ::testing::Values(DrPredFunc<DrPred_Hbd>(
448 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_c>,
449 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_avx2>,
450 AOM_BITS_8, kZ1Start),
451 DrPredFunc<DrPred_Hbd>(
452 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_c>,
453 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_avx2>,
454 AOM_BITS_10, kZ1Start),
455 DrPredFunc<DrPred_Hbd>(
456 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_c>,
457 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_avx2>,
458 AOM_BITS_12, kZ1Start),
459 DrPredFunc<DrPred_Hbd>(
460 &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_c>,
461 &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_avx2>,
462 AOM_BITS_8, kZ2Start),
463 DrPredFunc<DrPred_Hbd>(
464 &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_c>,
465 &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_avx2>,
466 AOM_BITS_10, kZ2Start),
467 DrPredFunc<DrPred_Hbd>(
468 &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_c>,
469 &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_avx2>,
470 AOM_BITS_12, kZ2Start),
471 DrPredFunc<DrPred_Hbd>(
472 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_c>,
473 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_avx2>,
474 AOM_BITS_8, kZ3Start),
475 DrPredFunc<DrPred_Hbd>(
476 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_c>,
477 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_avx2>,
478 AOM_BITS_10, kZ3Start),
479 DrPredFunc<DrPred_Hbd>(
480 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_c>,
481 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_avx2>,
482 AOM_BITS_12, kZ3Start)));
483 #endif // CONFIG_AV1_HIGHBITDEPTH
484 #endif // HAVE_AVX2
485
486 #if HAVE_NEON
487 #if AOM_ARCH_AARCH64
488 INSTANTIATE_TEST_SUITE_P(
489 NEON, LowbdDrPredTest,
490 ::testing::Values(DrPredFunc<DrPred>(&z1_wrapper<av1_dr_prediction_z1_c>,
491 &z1_wrapper<av1_dr_prediction_z1_neon>,
492 AOM_BITS_8, kZ1Start),
493 DrPredFunc<DrPred>(&z2_wrapper<av1_dr_prediction_z2_c>,
494 &z2_wrapper<av1_dr_prediction_z2_neon>,
495 AOM_BITS_8, kZ2Start),
496 DrPredFunc<DrPred>(&z3_wrapper<av1_dr_prediction_z3_c>,
497 &z3_wrapper<av1_dr_prediction_z3_neon>,
498 AOM_BITS_8, kZ3Start)));
499 #else
500 // TODO(aomedia:349428506): enable av1_highbd_dr_prediction_z2_neon for armv7
501 // after SIGBUS is fixed.
502 INSTANTIATE_TEST_SUITE_P(
503 NEON, LowbdDrPredTest,
504 ::testing::Values(DrPredFunc<DrPred>(&z1_wrapper<av1_dr_prediction_z1_c>,
505 &z1_wrapper<av1_dr_prediction_z1_neon>,
506 AOM_BITS_8, kZ1Start),
507 DrPredFunc<DrPred>(&z3_wrapper<av1_dr_prediction_z3_c>,
508 &z3_wrapper<av1_dr_prediction_z3_neon>,
509 AOM_BITS_8, kZ3Start)));
510 #endif
511
512 #if CONFIG_AV1_HIGHBITDEPTH
513 #if AOM_ARCH_AARCH64
514 INSTANTIATE_TEST_SUITE_P(
515 NEON, HighbdDrPredTest,
516 ::testing::Values(DrPredFunc<DrPred_Hbd>(
517 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_c>,
518 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_neon>,
519 AOM_BITS_8, kZ1Start),
520 DrPredFunc<DrPred_Hbd>(
521 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_c>,
522 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_neon>,
523 AOM_BITS_10, kZ1Start),
524 DrPredFunc<DrPred_Hbd>(
525 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_c>,
526 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_neon>,
527 AOM_BITS_12, kZ1Start),
528 DrPredFunc<DrPred_Hbd>(
529 &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_c>,
530 &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_neon>,
531 AOM_BITS_8, kZ2Start),
532 DrPredFunc<DrPred_Hbd>(
533 &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_c>,
534 &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_neon>,
535 AOM_BITS_10, kZ2Start),
536 DrPredFunc<DrPred_Hbd>(
537 &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_c>,
538 &z2_wrapper_hbd<av1_highbd_dr_prediction_z2_neon>,
539 AOM_BITS_12, kZ2Start),
540 DrPredFunc<DrPred_Hbd>(
541 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_c>,
542 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_neon>,
543 AOM_BITS_8, kZ3Start),
544 DrPredFunc<DrPred_Hbd>(
545 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_c>,
546 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_neon>,
547 AOM_BITS_10, kZ3Start),
548 DrPredFunc<DrPred_Hbd>(
549 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_c>,
550 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_neon>,
551 AOM_BITS_12, kZ3Start)));
552 #else // !AOM_ARCH_AARCH64
553 // TODO(aomedia:349428506): enable av1_highbd_dr_prediction_z2_neon for armv7
554 // after SIGBUS is fixed.
555 INSTANTIATE_TEST_SUITE_P(
556 NEON, HighbdDrPredTest,
557 ::testing::Values(DrPredFunc<DrPred_Hbd>(
558 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_c>,
559 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_neon>,
560 AOM_BITS_8, kZ1Start),
561 DrPredFunc<DrPred_Hbd>(
562 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_c>,
563 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_neon>,
564 AOM_BITS_10, kZ1Start),
565 DrPredFunc<DrPred_Hbd>(
566 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_c>,
567 &z1_wrapper_hbd<av1_highbd_dr_prediction_z1_neon>,
568 AOM_BITS_12, kZ1Start),
569 DrPredFunc<DrPred_Hbd>(
570 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_c>,
571 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_neon>,
572 AOM_BITS_8, kZ3Start),
573 DrPredFunc<DrPred_Hbd>(
574 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_c>,
575 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_neon>,
576 AOM_BITS_10, kZ3Start),
577 DrPredFunc<DrPred_Hbd>(
578 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_c>,
579 &z3_wrapper_hbd<av1_highbd_dr_prediction_z3_neon>,
580 AOM_BITS_12, kZ3Start)));
581 #endif // AOM_ARCH_AARCH64
582 #endif // CONFIG_AV1_HIGHBITDEPTH
583
584 #endif // HAVE_NEON
585
586 } // namespace
587