blob: 1e0b5ad9852994e21e5d3c686daa5dc05347bc08 [file] [log] [blame]
John Koleszar5ca6a362013-01-25 09:47:09 -08001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
John Koleszar5ca6a362013-01-25 09:47:09 -08003 *
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.
Johann123e8a62017-12-28 14:40:49 -080010 */
John Koleszar5ca6a362013-01-25 09:47:09 -080011
Tero Rintaluomae326cec2013-08-22 11:29:19 +030012#include <string.h>
Jingning Han097d59c2015-07-29 14:51:36 -070013
Tom Finegan7a07ece2017-02-07 17:14:05 -080014#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
John Koleszar5ca6a362013-01-25 09:47:09 -080015
Yaowu Xuf883b422016-08-30 14:01:10 -070016#include "./aom_config.h"
17#include "./aom_dsp_rtcd.h"
Jingning Han097d59c2015-07-29 14:51:36 -070018#include "test/acm_random.h"
19#include "test/clear_system_state.h"
20#include "test/register_state_check.h"
21#include "test/util.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070022#include "aom_dsp/aom_dsp_common.h"
23#include "aom_dsp/aom_filter.h"
24#include "aom_mem/aom_mem.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070025#include "aom_ports/mem.h"
Yi Luo9d247352017-03-16 12:31:46 -070026#include "aom_ports/aom_timer.h"
Angie Chiangb1372892016-12-01 15:06:06 -080027#include "av1/common/filter.h"
John Koleszar5ca6a362013-01-25 09:47:09 -080028
29namespace {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -070030
Geza Lore552d5cd2016-03-07 13:46:39 +000031static const unsigned int kMaxDimension = MAX_SB_SIZE;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -070032
James Zerndfc4e8f2014-07-16 18:48:20 -070033typedef void (*ConvolveFunc)(const uint8_t *src, ptrdiff_t src_stride,
34 uint8_t *dst, ptrdiff_t dst_stride,
35 const int16_t *filter_x, int filter_x_stride,
36 const int16_t *filter_y, int filter_y_stride,
37 int w, int h);
John Koleszar5ca6a362013-01-25 09:47:09 -080038
39struct ConvolveFunctions {
clang-format3a826f12016-08-11 17:46:05 -070040 ConvolveFunctions(ConvolveFunc copy, ConvolveFunc avg, ConvolveFunc h8,
41 ConvolveFunc h8_avg, ConvolveFunc v8, ConvolveFunc v8_avg,
42 ConvolveFunc hv8, ConvolveFunc hv8_avg, ConvolveFunc sh8,
43 ConvolveFunc sh8_avg, ConvolveFunc sv8,
44 ConvolveFunc sv8_avg, ConvolveFunc shv8,
45 ConvolveFunc shv8_avg, int bd)
Johann1c3594c2014-12-09 12:05:15 -080046 : copy_(copy), avg_(avg), h8_(h8), v8_(v8), hv8_(hv8), h8_avg_(h8_avg),
Scott LaVarnway4e6b5072015-08-05 10:47:06 -070047 v8_avg_(v8_avg), hv8_avg_(hv8_avg), sh8_(sh8), sv8_(sv8), shv8_(shv8),
48 sh8_avg_(sh8_avg), sv8_avg_(sv8_avg), shv8_avg_(shv8_avg),
49 use_highbd_(bd) {}
John Koleszar5ca6a362013-01-25 09:47:09 -080050
Johann1c3594c2014-12-09 12:05:15 -080051 ConvolveFunc copy_;
52 ConvolveFunc avg_;
James Zerndfc4e8f2014-07-16 18:48:20 -070053 ConvolveFunc h8_;
54 ConvolveFunc v8_;
55 ConvolveFunc hv8_;
56 ConvolveFunc h8_avg_;
57 ConvolveFunc v8_avg_;
58 ConvolveFunc hv8_avg_;
clang-format3a826f12016-08-11 17:46:05 -070059 ConvolveFunc sh8_; // scaled horiz
60 ConvolveFunc sv8_; // scaled vert
61 ConvolveFunc shv8_; // scaled horiz/vert
62 ConvolveFunc sh8_avg_; // scaled avg horiz
63 ConvolveFunc sv8_avg_; // scaled avg vert
64 ConvolveFunc shv8_avg_; // scaled avg horiz/vert
Deb Mukherjee1929c9b2014-10-08 12:43:22 -070065 int use_highbd_; // 0 if high bitdepth not used, else the actual bit depth.
John Koleszar5ca6a362013-01-25 09:47:09 -080066};
67
James Zerndfc4e8f2014-07-16 18:48:20 -070068typedef std::tr1::tuple<int, int, const ConvolveFunctions *> ConvolveParam;
Joshua Litt51490e52013-11-18 17:07:55 -080069
Debargha Mukherjee7a160ac2017-10-07 22:29:43 -070070#define ALL_SIZES_64(convolve_fn) \
clang-format3a826f12016-08-11 17:46:05 -070071 make_tuple(4, 4, &convolve_fn), make_tuple(8, 4, &convolve_fn), \
72 make_tuple(4, 8, &convolve_fn), make_tuple(8, 8, &convolve_fn), \
73 make_tuple(16, 8, &convolve_fn), make_tuple(8, 16, &convolve_fn), \
74 make_tuple(16, 16, &convolve_fn), make_tuple(32, 16, &convolve_fn), \
75 make_tuple(16, 32, &convolve_fn), make_tuple(32, 32, &convolve_fn), \
76 make_tuple(64, 32, &convolve_fn), make_tuple(32, 64, &convolve_fn), \
77 make_tuple(64, 64, &convolve_fn)
Debargha Mukherjee7a160ac2017-10-07 22:29:43 -070078
79#if CONFIG_AV1 && CONFIG_EXT_PARTITION
80#define ALL_SIZES(convolve_fn) \
81 make_tuple(128, 64, &convolve_fn), make_tuple(64, 128, &convolve_fn), \
82 make_tuple(128, 128, &convolve_fn), ALL_SIZES_64(convolve_fn)
83#else
84#define ALL_SIZES ALL_SIZES_64
Yaowu Xuf883b422016-08-30 14:01:10 -070085#endif // CONFIG_AV1 && CONFIG_EXT_PARTITION
Alex Conversef03e2382016-04-26 18:09:40 -070086
John Koleszar5ca6a362013-01-25 09:47:09 -080087// Reference 8-tap subpixel filter, slightly modified to fit into this test.
Yaowu Xuf883b422016-08-30 14:01:10 -070088#define AV1_FILTER_WEIGHT 128
89#define AV1_FILTER_SHIFT 7
clang-format3a826f12016-08-11 17:46:05 -070090uint8_t clip_pixel(int x) { return x < 0 ? 0 : x > 255 ? 255 : x; }
John Koleszar5ca6a362013-01-25 09:47:09 -080091
Yaowu Xu032573d2017-04-24 15:04:17 -070092void filter_block2d_8_c(const uint8_t *src_ptr, unsigned int src_stride,
clang-format3a826f12016-08-11 17:46:05 -070093 const int16_t *HFilter, const int16_t *VFilter,
94 uint8_t *dst_ptr, unsigned int dst_stride,
95 unsigned int output_width, unsigned int output_height) {
John Koleszar5ca6a362013-01-25 09:47:09 -080096 // Between passes, we use an intermediate buffer whose height is extended to
97 // have enough horizontally filtered values as input for the vertical pass.
98 // This buffer is allocated to be big enough for the largest block type we
99 // support.
100 const int kInterp_Extend = 4;
101 const unsigned int intermediate_height =
James Zern8fb48af2013-05-02 13:08:19 -0700102 (kInterp_Extend - 1) + output_height + kInterp_Extend;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700103 unsigned int i, j;
John Koleszar5ca6a362013-01-25 09:47:09 -0800104
Sarah Parkere57473a2017-04-27 16:19:56 -0700105 assert(intermediate_height > 7);
106
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700107 // Size of intermediate_buffer is max_intermediate_height * filter_max_width,
108 // where max_intermediate_height = (kInterp_Extend - 1) + filter_max_height
109 // + kInterp_Extend
110 // = 3 + 16 + 4
111 // = 23
112 // and filter_max_width = 16
113 //
clang-format3a826f12016-08-11 17:46:05 -0700114 uint8_t intermediate_buffer[(kMaxDimension + 8) * kMaxDimension];
Tom Finegan6042d682016-05-06 09:43:37 -0700115 const int intermediate_next_stride =
116 1 - static_cast<int>(intermediate_height * output_width);
John Koleszar5ca6a362013-01-25 09:47:09 -0800117
118 // Horizontal pass (src -> transposed intermediate).
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700119 uint8_t *output_ptr = intermediate_buffer;
120 const int src_next_row_stride = src_stride - output_width;
121 src_ptr -= (kInterp_Extend - 1) * src_stride + (kInterp_Extend - 1);
122 for (i = 0; i < intermediate_height; ++i) {
123 for (j = 0; j < output_width; ++j) {
124 // Apply filter...
clang-format3a826f12016-08-11 17:46:05 -0700125 const int temp = (src_ptr[0] * HFilter[0]) + (src_ptr[1] * HFilter[1]) +
126 (src_ptr[2] * HFilter[2]) + (src_ptr[3] * HFilter[3]) +
127 (src_ptr[4] * HFilter[4]) + (src_ptr[5] * HFilter[5]) +
128 (src_ptr[6] * HFilter[6]) + (src_ptr[7] * HFilter[7]) +
Yaowu Xuf883b422016-08-30 14:01:10 -0700129 (AV1_FILTER_WEIGHT >> 1); // Rounding
John Koleszar5ca6a362013-01-25 09:47:09 -0800130
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700131 // Normalize back to 0-255...
Yaowu Xuf883b422016-08-30 14:01:10 -0700132 *output_ptr = clip_pixel(temp >> AV1_FILTER_SHIFT);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700133 ++src_ptr;
134 output_ptr += intermediate_height;
John Koleszar5ca6a362013-01-25 09:47:09 -0800135 }
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700136 src_ptr += src_next_row_stride;
137 output_ptr += intermediate_next_stride;
John Koleszar5ca6a362013-01-25 09:47:09 -0800138 }
139
140 // Vertical pass (transposed intermediate -> dst).
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700141 src_ptr = intermediate_buffer;
142 const int dst_next_row_stride = dst_stride - output_width;
143 for (i = 0; i < output_height; ++i) {
144 for (j = 0; j < output_width; ++j) {
145 // Apply filter...
clang-format3a826f12016-08-11 17:46:05 -0700146 const int temp = (src_ptr[0] * VFilter[0]) + (src_ptr[1] * VFilter[1]) +
147 (src_ptr[2] * VFilter[2]) + (src_ptr[3] * VFilter[3]) +
148 (src_ptr[4] * VFilter[4]) + (src_ptr[5] * VFilter[5]) +
149 (src_ptr[6] * VFilter[6]) + (src_ptr[7] * VFilter[7]) +
Yaowu Xuf883b422016-08-30 14:01:10 -0700150 (AV1_FILTER_WEIGHT >> 1); // Rounding
John Koleszar5ca6a362013-01-25 09:47:09 -0800151
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700152 // Normalize back to 0-255...
Yaowu Xuf883b422016-08-30 14:01:10 -0700153 *dst_ptr++ = clip_pixel(temp >> AV1_FILTER_SHIFT);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700154 src_ptr += intermediate_height;
John Koleszar5ca6a362013-01-25 09:47:09 -0800155 }
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700156 src_ptr += intermediate_next_stride;
157 dst_ptr += dst_next_row_stride;
John Koleszar5ca6a362013-01-25 09:47:09 -0800158 }
159}
160
clang-format3a826f12016-08-11 17:46:05 -0700161void block2d_average_c(uint8_t *src, unsigned int src_stride,
162 uint8_t *output_ptr, unsigned int output_stride,
163 unsigned int output_width, unsigned int output_height) {
John Koleszar5ca6a362013-01-25 09:47:09 -0800164 unsigned int i, j;
165 for (i = 0; i < output_height; ++i) {
166 for (j = 0; j < output_width; ++j) {
167 output_ptr[j] = (output_ptr[j] + src[i * src_stride + j] + 1) >> 1;
168 }
169 output_ptr += output_stride;
170 }
171}
172
James Zern8fb48af2013-05-02 13:08:19 -0700173void filter_average_block2d_8_c(const uint8_t *src_ptr,
174 const unsigned int src_stride,
clang-format3a826f12016-08-11 17:46:05 -0700175 const int16_t *HFilter, const int16_t *VFilter,
176 uint8_t *dst_ptr, unsigned int dst_stride,
James Zern8fb48af2013-05-02 13:08:19 -0700177 unsigned int output_width,
178 unsigned int output_height) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700179 uint8_t tmp[kMaxDimension * kMaxDimension];
John Koleszar5ca6a362013-01-25 09:47:09 -0800180
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700181 assert(output_width <= kMaxDimension);
182 assert(output_height <= kMaxDimension);
Geza Lore938b8df2016-03-04 15:55:48 +0000183 filter_block2d_8_c(src_ptr, src_stride, HFilter, VFilter, tmp, kMaxDimension,
John Koleszar5ca6a362013-01-25 09:47:09 -0800184 output_width, output_height);
clang-format3a826f12016-08-11 17:46:05 -0700185 block2d_average_c(tmp, kMaxDimension, dst_ptr, dst_stride, output_width,
186 output_height);
John Koleszar5ca6a362013-01-25 09:47:09 -0800187}
188
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700189void highbd_filter_block2d_8_c(const uint16_t *src_ptr,
190 const unsigned int src_stride,
clang-format3a826f12016-08-11 17:46:05 -0700191 const int16_t *HFilter, const int16_t *VFilter,
192 uint16_t *dst_ptr, unsigned int dst_stride,
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700193 unsigned int output_width,
clang-format3a826f12016-08-11 17:46:05 -0700194 unsigned int output_height, int bd) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700195 // Between passes, we use an intermediate buffer whose height is extended to
196 // have enough horizontally filtered values as input for the vertical pass.
197 // This buffer is allocated to be big enough for the largest block type we
198 // support.
199 const int kInterp_Extend = 4;
200 const unsigned int intermediate_height =
201 (kInterp_Extend - 1) + output_height + kInterp_Extend;
202
203 /* Size of intermediate_buffer is max_intermediate_height * filter_max_width,
204 * where max_intermediate_height = (kInterp_Extend - 1) + filter_max_height
205 * + kInterp_Extend
206 * = 3 + 16 + 4
207 * = 23
208 * and filter_max_width = 16
209 */
Sebastien Alaiwan92400ab2017-03-14 10:39:29 +0100210 uint16_t intermediate_buffer[(kMaxDimension + 8) * kMaxDimension] = { 0 };
Tom Finegan9a56a5e2016-05-13 09:42:58 -0700211 const int intermediate_next_stride =
212 1 - static_cast<int>(intermediate_height * output_width);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700213
214 // Horizontal pass (src -> transposed intermediate).
215 {
216 uint16_t *output_ptr = intermediate_buffer;
217 const int src_next_row_stride = src_stride - output_width;
218 unsigned int i, j;
219 src_ptr -= (kInterp_Extend - 1) * src_stride + (kInterp_Extend - 1);
220 for (i = 0; i < intermediate_height; ++i) {
221 for (j = 0; j < output_width; ++j) {
222 // Apply filter...
clang-format3a826f12016-08-11 17:46:05 -0700223 const int temp = (src_ptr[0] * HFilter[0]) + (src_ptr[1] * HFilter[1]) +
224 (src_ptr[2] * HFilter[2]) + (src_ptr[3] * HFilter[3]) +
225 (src_ptr[4] * HFilter[4]) + (src_ptr[5] * HFilter[5]) +
226 (src_ptr[6] * HFilter[6]) + (src_ptr[7] * HFilter[7]) +
Yaowu Xuf883b422016-08-30 14:01:10 -0700227 (AV1_FILTER_WEIGHT >> 1); // Rounding
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700228
229 // Normalize back to 0-255...
Yaowu Xuf883b422016-08-30 14:01:10 -0700230 *output_ptr = clip_pixel_highbd(temp >> AV1_FILTER_SHIFT, bd);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700231 ++src_ptr;
232 output_ptr += intermediate_height;
233 }
234 src_ptr += src_next_row_stride;
235 output_ptr += intermediate_next_stride;
236 }
237 }
238
239 // Vertical pass (transposed intermediate -> dst).
240 {
Urvang Joshi88a03bb2016-10-17 14:34:48 -0700241 const uint16_t *interm_ptr = intermediate_buffer;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700242 const int dst_next_row_stride = dst_stride - output_width;
243 unsigned int i, j;
244 for (i = 0; i < output_height; ++i) {
245 for (j = 0; j < output_width; ++j) {
246 // Apply filter...
Urvang Joshi88a03bb2016-10-17 14:34:48 -0700247 const int temp =
248 (interm_ptr[0] * VFilter[0]) + (interm_ptr[1] * VFilter[1]) +
249 (interm_ptr[2] * VFilter[2]) + (interm_ptr[3] * VFilter[3]) +
250 (interm_ptr[4] * VFilter[4]) + (interm_ptr[5] * VFilter[5]) +
251 (interm_ptr[6] * VFilter[6]) + (interm_ptr[7] * VFilter[7]) +
252 (AV1_FILTER_WEIGHT >> 1); // Rounding
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700253
254 // Normalize back to 0-255...
Yaowu Xuf883b422016-08-30 14:01:10 -0700255 *dst_ptr++ = clip_pixel_highbd(temp >> AV1_FILTER_SHIFT, bd);
Urvang Joshi88a03bb2016-10-17 14:34:48 -0700256 interm_ptr += intermediate_height;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700257 }
Urvang Joshi88a03bb2016-10-17 14:34:48 -0700258 interm_ptr += intermediate_next_stride;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700259 dst_ptr += dst_next_row_stride;
260 }
261 }
262}
263
clang-format3a826f12016-08-11 17:46:05 -0700264void highbd_block2d_average_c(uint16_t *src, unsigned int src_stride,
265 uint16_t *output_ptr, unsigned int output_stride,
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700266 unsigned int output_width,
James Zerncffef112016-02-11 18:27:00 -0800267 unsigned int output_height) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700268 unsigned int i, j;
269 for (i = 0; i < output_height; ++i) {
270 for (j = 0; j < output_width; ++j) {
271 output_ptr[j] = (output_ptr[j] + src[i * src_stride + j] + 1) >> 1;
272 }
273 output_ptr += output_stride;
274 }
275}
276
clang-format3a826f12016-08-11 17:46:05 -0700277void highbd_filter_average_block2d_8_c(
Yaowu Xu032573d2017-04-24 15:04:17 -0700278 const uint16_t *src_ptr, unsigned int src_stride, const int16_t *HFilter,
279 const int16_t *VFilter, uint16_t *dst_ptr, unsigned int dst_stride,
280 unsigned int output_width, unsigned int output_height, int bd) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700281 uint16_t tmp[kMaxDimension * kMaxDimension];
282
283 assert(output_width <= kMaxDimension);
284 assert(output_height <= kMaxDimension);
clang-format3a826f12016-08-11 17:46:05 -0700285 highbd_filter_block2d_8_c(src_ptr, src_stride, HFilter, VFilter, tmp,
286 kMaxDimension, output_width, output_height, bd);
Geza Lore938b8df2016-03-04 15:55:48 +0000287 highbd_block2d_average_c(tmp, kMaxDimension, dst_ptr, dst_stride,
James Zerncffef112016-02-11 18:27:00 -0800288 output_width, output_height);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700289}
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700290
James Zerndfc4e8f2014-07-16 18:48:20 -0700291class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
John Koleszar29d47ac2013-02-07 17:00:37 -0800292 public:
293 static void SetUpTestCase() {
294 // Force input_ to be unaligned, output to be 16 byte aligned.
clang-format3a826f12016-08-11 17:46:05 -0700295 input_ = reinterpret_cast<uint8_t *>(
Yaowu Xuf883b422016-08-30 14:01:10 -0700296 aom_memalign(kDataAlignment, kInputBufferSize + 1)) +
clang-format3a826f12016-08-11 17:46:05 -0700297 1;
298 output_ = reinterpret_cast<uint8_t *>(
Yaowu Xuf883b422016-08-30 14:01:10 -0700299 aom_memalign(kDataAlignment, kOutputBufferSize));
clang-format3a826f12016-08-11 17:46:05 -0700300 output_ref_ = reinterpret_cast<uint8_t *>(
Yaowu Xuf883b422016-08-30 14:01:10 -0700301 aom_memalign(kDataAlignment, kOutputBufferSize));
Yaowu Xuf883b422016-08-30 14:01:10 -0700302 input16_ = reinterpret_cast<uint16_t *>(aom_memalign(
clang-format3a826f12016-08-11 17:46:05 -0700303 kDataAlignment, (kInputBufferSize + 1) * sizeof(uint16_t))) +
304 1;
305 output16_ = reinterpret_cast<uint16_t *>(
Yaowu Xuf883b422016-08-30 14:01:10 -0700306 aom_memalign(kDataAlignment, (kOutputBufferSize) * sizeof(uint16_t)));
clang-format3a826f12016-08-11 17:46:05 -0700307 output16_ref_ = reinterpret_cast<uint16_t *>(
Yaowu Xuf883b422016-08-30 14:01:10 -0700308 aom_memalign(kDataAlignment, (kOutputBufferSize) * sizeof(uint16_t)));
John Koleszar29d47ac2013-02-07 17:00:37 -0800309 }
310
Yaowu Xuc27fc142016-08-22 16:08:15 -0700311 virtual void TearDown() { libaom_test::ClearSystemState(); }
Jim Bankoski18d32362014-12-12 06:18:56 -0800312
John Koleszar29d47ac2013-02-07 17:00:37 -0800313 static void TearDownTestCase() {
Yaowu Xuf883b422016-08-30 14:01:10 -0700314 aom_free(input_ - 1);
John Koleszar29d47ac2013-02-07 17:00:37 -0800315 input_ = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700316 aom_free(output_);
John Koleszar29d47ac2013-02-07 17:00:37 -0800317 output_ = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700318 aom_free(output_ref_);
Johann1c3594c2014-12-09 12:05:15 -0800319 output_ref_ = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700320 aom_free(input16_ - 1);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700321 input16_ = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700322 aom_free(output16_);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700323 output16_ = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700324 aom_free(output16_ref_);
Johann1c3594c2014-12-09 12:05:15 -0800325 output16_ref_ = NULL;
John Koleszar29d47ac2013-02-07 17:00:37 -0800326 }
327
James Zern8fb48af2013-05-02 13:08:19 -0700328 protected:
329 static const int kDataAlignment = 16;
clang-format3a826f12016-08-11 17:46:05 -0700330 static const int kOuterBlockSize = 4 * kMaxDimension;
James Zern8fb48af2013-05-02 13:08:19 -0700331 static const int kInputStride = kOuterBlockSize;
332 static const int kOutputStride = kOuterBlockSize;
James Zern8fb48af2013-05-02 13:08:19 -0700333 static const int kInputBufferSize = kOuterBlockSize * kOuterBlockSize;
334 static const int kOutputBufferSize = kOuterBlockSize * kOuterBlockSize;
John Koleszar5ca6a362013-01-25 09:47:09 -0800335
James Zern8fb48af2013-05-02 13:08:19 -0700336 int Width() const { return GET_PARAM(0); }
337 int Height() const { return GET_PARAM(1); }
338 int BorderLeft() const {
339 const int center = (kOuterBlockSize - Width()) / 2;
340 return (center + (kDataAlignment - 1)) & ~(kDataAlignment - 1);
341 }
342 int BorderTop() const { return (kOuterBlockSize - Height()) / 2; }
John Koleszar5ca6a362013-01-25 09:47:09 -0800343
James Zern8fb48af2013-05-02 13:08:19 -0700344 bool IsIndexInBorder(int i) {
345 return (i < BorderTop() * kOuterBlockSize ||
346 i >= (BorderTop() + Height()) * kOuterBlockSize ||
347 i % kOuterBlockSize < BorderLeft() ||
348 i % kOuterBlockSize >= (BorderLeft() + Width()));
349 }
350
351 virtual void SetUp() {
352 UUT_ = GET_PARAM(2);
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700353 if (UUT_->use_highbd_ != 0)
354 mask_ = (1 << UUT_->use_highbd_) - 1;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700355 else
356 mask_ = 255;
Johann158c80c2013-05-23 12:50:41 -0700357 /* Set up guard blocks for an inner block centered in the outer block */
James Zern8fb48af2013-05-02 13:08:19 -0700358 for (int i = 0; i < kOutputBufferSize; ++i) {
Yaowu Xu5ab58722017-05-11 09:39:31 -0700359 if (IsIndexInBorder(i)) {
James Zern8fb48af2013-05-02 13:08:19 -0700360 output_[i] = 255;
Yaowu Xu5ab58722017-05-11 09:39:31 -0700361 output16_[i] = mask_;
Yaowu Xu5ab58722017-05-11 09:39:31 -0700362 } else {
James Zern8fb48af2013-05-02 13:08:19 -0700363 output_[i] = 0;
Yaowu Xu5ab58722017-05-11 09:39:31 -0700364 output16_[i] = 0;
Yaowu Xu5ab58722017-05-11 09:39:31 -0700365 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800366 }
367
Yaowu Xuc27fc142016-08-22 16:08:15 -0700368 ::libaom_test::ACMRandom prng;
Yaowu Xu077144d2014-05-23 12:23:29 -0700369 for (int i = 0; i < kInputBufferSize; ++i) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700370 if (i & 1) {
Yaowu Xu077144d2014-05-23 12:23:29 -0700371 input_[i] = 255;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700372 input16_[i] = mask_;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700373 } else {
Yaowu Xu077144d2014-05-23 12:23:29 -0700374 input_[i] = prng.Rand8Extremes();
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700375 input16_[i] = prng.Rand16() & mask_;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700376 }
Yaowu Xu077144d2014-05-23 12:23:29 -0700377 }
James Zern8fb48af2013-05-02 13:08:19 -0700378 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800379
Tero Rintaluomae326cec2013-08-22 11:29:19 +0300380 void SetConstantInput(int value) {
381 memset(input_, value, kInputBufferSize);
Yaowu Xuf883b422016-08-30 14:01:10 -0700382 aom_memset16(input16_, value, kInputBufferSize);
Tero Rintaluomae326cec2013-08-22 11:29:19 +0300383 }
384
Johann1c3594c2014-12-09 12:05:15 -0800385 void CopyOutputToRef() {
James Zernf274c212015-04-23 20:42:19 -0700386 memcpy(output_ref_, output_, kOutputBufferSize);
Yaowu Xuc648a9f2016-10-10 17:39:29 -0700387 // Copy 16-bit pixels values. The effective number of bytes is double.
388 memcpy(output16_ref_, output16_, sizeof(output16_[0]) * kOutputBufferSize);
Johann1c3594c2014-12-09 12:05:15 -0800389 }
390
James Zern8fb48af2013-05-02 13:08:19 -0700391 void CheckGuardBlocks() {
392 for (int i = 0; i < kOutputBufferSize; ++i) {
Sebastien Alaiwan7d701682017-10-04 10:07:24 +0200393 if (IsIndexInBorder(i)) {
394 EXPECT_EQ(255, output_[i]);
395 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800396 }
James Zern8fb48af2013-05-02 13:08:19 -0700397 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800398
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700399 uint8_t *input() const {
Johann2967bf32016-06-22 16:08:10 -0700400 const int offset = BorderTop() * kOuterBlockSize + BorderLeft();
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700401 if (UUT_->use_highbd_ == 0) {
Johann2967bf32016-06-22 16:08:10 -0700402 return input_ + offset;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700403 } else {
Johann2967bf32016-06-22 16:08:10 -0700404 return CONVERT_TO_BYTEPTR(input16_) + offset;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700405 }
James Zern8fb48af2013-05-02 13:08:19 -0700406 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800407
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700408 uint8_t *output() const {
Johann2967bf32016-06-22 16:08:10 -0700409 const int offset = BorderTop() * kOuterBlockSize + BorderLeft();
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700410 if (UUT_->use_highbd_ == 0) {
Johann2967bf32016-06-22 16:08:10 -0700411 return output_ + offset;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700412 } else {
Johann2967bf32016-06-22 16:08:10 -0700413 return CONVERT_TO_BYTEPTR(output16_) + offset;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700414 }
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700415 }
416
Johann1c3594c2014-12-09 12:05:15 -0800417 uint8_t *output_ref() const {
Johann2967bf32016-06-22 16:08:10 -0700418 const int offset = BorderTop() * kOuterBlockSize + BorderLeft();
Johann1c3594c2014-12-09 12:05:15 -0800419 if (UUT_->use_highbd_ == 0) {
Johann2967bf32016-06-22 16:08:10 -0700420 return output_ref_ + offset;
Johann1c3594c2014-12-09 12:05:15 -0800421 } else {
Johann2967bf32016-06-22 16:08:10 -0700422 return CONVERT_TO_BYTEPTR(output16_ref_) + offset;
Johann1c3594c2014-12-09 12:05:15 -0800423 }
Johann1c3594c2014-12-09 12:05:15 -0800424 }
425
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700426 uint16_t lookup(uint8_t *list, int index) const {
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700427 if (UUT_->use_highbd_ == 0) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700428 return list[index];
429 } else {
430 return CONVERT_TO_SHORTPTR(list)[index];
431 }
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700432 }
433
434 void assign_val(uint8_t *list, int index, uint16_t val) const {
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700435 if (UUT_->use_highbd_ == 0) {
clang-format3a826f12016-08-11 17:46:05 -0700436 list[index] = (uint8_t)val;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700437 } else {
438 CONVERT_TO_SHORTPTR(list)[index] = val;
439 }
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700440 }
441
clang-format3a826f12016-08-11 17:46:05 -0700442 void wrapper_filter_average_block2d_8_c(
Yaowu Xu032573d2017-04-24 15:04:17 -0700443 const uint8_t *src_ptr, unsigned int src_stride, const int16_t *HFilter,
444 const int16_t *VFilter, uint8_t *dst_ptr, unsigned int dst_stride,
445 unsigned int output_width, unsigned int output_height) {
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700446 if (UUT_->use_highbd_ == 0) {
clang-format3a826f12016-08-11 17:46:05 -0700447 filter_average_block2d_8_c(src_ptr, src_stride, HFilter, VFilter, dst_ptr,
448 dst_stride, output_width, output_height);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700449 } else {
clang-format3a826f12016-08-11 17:46:05 -0700450 highbd_filter_average_block2d_8_c(
451 CONVERT_TO_SHORTPTR(src_ptr), src_stride, HFilter, VFilter,
452 CONVERT_TO_SHORTPTR(dst_ptr), dst_stride, output_width, output_height,
453 UUT_->use_highbd_);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700454 }
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700455 }
456
Yaowu Xu032573d2017-04-24 15:04:17 -0700457 void wrapper_filter_block2d_8_c(
458 const uint8_t *src_ptr, unsigned int src_stride, const int16_t *HFilter,
459 const int16_t *VFilter, uint8_t *dst_ptr, unsigned int dst_stride,
460 unsigned int output_width, unsigned int output_height) {
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700461 if (UUT_->use_highbd_ == 0) {
clang-format3a826f12016-08-11 17:46:05 -0700462 filter_block2d_8_c(src_ptr, src_stride, HFilter, VFilter, dst_ptr,
463 dst_stride, output_width, output_height);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700464 } else {
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700465 highbd_filter_block2d_8_c(CONVERT_TO_SHORTPTR(src_ptr), src_stride,
clang-format3a826f12016-08-11 17:46:05 -0700466 HFilter, VFilter, CONVERT_TO_SHORTPTR(dst_ptr),
467 dst_stride, output_width, output_height,
468 UUT_->use_highbd_);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700469 }
James Zern8fb48af2013-05-02 13:08:19 -0700470 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800471
clang-format3a826f12016-08-11 17:46:05 -0700472 const ConvolveFunctions *UUT_;
473 static uint8_t *input_;
474 static uint8_t *output_;
475 static uint8_t *output_ref_;
clang-format3a826f12016-08-11 17:46:05 -0700476 static uint16_t *input16_;
477 static uint16_t *output16_;
478 static uint16_t *output16_ref_;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700479 int mask_;
John Koleszar5ca6a362013-01-25 09:47:09 -0800480};
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700481
clang-format3a826f12016-08-11 17:46:05 -0700482uint8_t *ConvolveTest::input_ = NULL;
483uint8_t *ConvolveTest::output_ = NULL;
484uint8_t *ConvolveTest::output_ref_ = NULL;
clang-format3a826f12016-08-11 17:46:05 -0700485uint16_t *ConvolveTest::input16_ = NULL;
486uint16_t *ConvolveTest::output16_ = NULL;
487uint16_t *ConvolveTest::output16_ref_ = NULL;
John Koleszar5ca6a362013-01-25 09:47:09 -0800488
clang-format3a826f12016-08-11 17:46:05 -0700489TEST_P(ConvolveTest, GuardBlocks) { CheckGuardBlocks(); }
John Koleszar5ca6a362013-01-25 09:47:09 -0800490
Johann1c3594c2014-12-09 12:05:15 -0800491TEST_P(ConvolveTest, Copy) {
clang-format3a826f12016-08-11 17:46:05 -0700492 uint8_t *const in = input();
493 uint8_t *const out = output();
Johann1c3594c2014-12-09 12:05:15 -0800494
clang-format3a826f12016-08-11 17:46:05 -0700495 ASM_REGISTER_STATE_CHECK(UUT_->copy_(in, kInputStride, out, kOutputStride,
496 NULL, 0, NULL, 0, Width(), Height()));
Johann1c3594c2014-12-09 12:05:15 -0800497
498 CheckGuardBlocks();
499
500 for (int y = 0; y < Height(); ++y)
501 for (int x = 0; x < Width(); ++x)
502 ASSERT_EQ(lookup(out, y * kOutputStride + x),
503 lookup(in, y * kInputStride + x))
504 << "(" << x << "," << y << ")";
505}
506
507TEST_P(ConvolveTest, Avg) {
clang-format3a826f12016-08-11 17:46:05 -0700508 uint8_t *const in = input();
509 uint8_t *const out = output();
510 uint8_t *const out_ref = output_ref();
Johann1c3594c2014-12-09 12:05:15 -0800511 CopyOutputToRef();
512
clang-format3a826f12016-08-11 17:46:05 -0700513 ASM_REGISTER_STATE_CHECK(UUT_->avg_(in, kInputStride, out, kOutputStride,
514 NULL, 0, NULL, 0, Width(), Height()));
Johann1c3594c2014-12-09 12:05:15 -0800515
516 CheckGuardBlocks();
517
518 for (int y = 0; y < Height(); ++y)
519 for (int x = 0; x < Width(); ++x)
520 ASSERT_EQ(lookup(out, y * kOutputStride + x),
521 ROUND_POWER_OF_TWO(lookup(in, y * kInputStride + x) +
clang-format3a826f12016-08-11 17:46:05 -0700522 lookup(out_ref, y * kOutputStride + x),
523 1))
Johann1c3594c2014-12-09 12:05:15 -0800524 << "(" << x << "," << y << ")";
525}
526
John Koleszar5ca6a362013-01-25 09:47:09 -0800527TEST_P(ConvolveTest, CopyHoriz) {
clang-format3a826f12016-08-11 17:46:05 -0700528 uint8_t *const in = input();
529 uint8_t *const out = output();
530 DECLARE_ALIGNED(256, const int16_t,
531 filter8[8]) = { 0, 0, 0, 128, 0, 0, 0, 0 };
John Koleszar5ca6a362013-01-25 09:47:09 -0800532
clang-format3a826f12016-08-11 17:46:05 -0700533 ASM_REGISTER_STATE_CHECK(UUT_->sh8_(in, kInputStride, out, kOutputStride,
534 filter8, 16, filter8, 16, Width(),
535 Height()));
John Koleszar5ca6a362013-01-25 09:47:09 -0800536
537 CheckGuardBlocks();
538
539 for (int y = 0; y < Height(); ++y)
540 for (int x = 0; x < Width(); ++x)
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700541 ASSERT_EQ(lookup(out, y * kOutputStride + x),
542 lookup(in, y * kInputStride + x))
John Koleszar5ca6a362013-01-25 09:47:09 -0800543 << "(" << x << "," << y << ")";
544}
545
546TEST_P(ConvolveTest, CopyVert) {
clang-format3a826f12016-08-11 17:46:05 -0700547 uint8_t *const in = input();
548 uint8_t *const out = output();
549 DECLARE_ALIGNED(256, const int16_t,
550 filter8[8]) = { 0, 0, 0, 128, 0, 0, 0, 0 };
John Koleszar5ca6a362013-01-25 09:47:09 -0800551
clang-format3a826f12016-08-11 17:46:05 -0700552 ASM_REGISTER_STATE_CHECK(UUT_->sv8_(in, kInputStride, out, kOutputStride,
553 filter8, 16, filter8, 16, Width(),
554 Height()));
John Koleszar5ca6a362013-01-25 09:47:09 -0800555
556 CheckGuardBlocks();
557
558 for (int y = 0; y < Height(); ++y)
559 for (int x = 0; x < Width(); ++x)
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700560 ASSERT_EQ(lookup(out, y * kOutputStride + x),
561 lookup(in, y * kInputStride + x))
John Koleszar5ca6a362013-01-25 09:47:09 -0800562 << "(" << x << "," << y << ")";
563}
564
565TEST_P(ConvolveTest, Copy2D) {
clang-format3a826f12016-08-11 17:46:05 -0700566 uint8_t *const in = input();
567 uint8_t *const out = output();
568 DECLARE_ALIGNED(256, const int16_t,
569 filter8[8]) = { 0, 0, 0, 128, 0, 0, 0, 0 };
John Koleszar5ca6a362013-01-25 09:47:09 -0800570
clang-format3a826f12016-08-11 17:46:05 -0700571 ASM_REGISTER_STATE_CHECK(UUT_->shv8_(in, kInputStride, out, kOutputStride,
572 filter8, 16, filter8, 16, Width(),
573 Height()));
John Koleszar5ca6a362013-01-25 09:47:09 -0800574
575 CheckGuardBlocks();
576
577 for (int y = 0; y < Height(); ++y)
578 for (int x = 0; x < Width(); ++x)
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700579 ASSERT_EQ(lookup(out, y * kOutputStride + x),
580 lookup(in, y * kInputStride + x))
John Koleszar5ca6a362013-01-25 09:47:09 -0800581 << "(" << x << "," << y << ")";
582}
583
Angie Chiangb1372892016-12-01 15:06:06 -0800584const int kNumFilterBanks = SWITCHABLE_FILTERS;
John Koleszara9ebbcc2013-04-18 13:05:38 -0700585const int kNumFilters = 16;
586
587TEST(ConvolveTest, FiltersWontSaturateWhenAddedPairwise) {
588 for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
Urvang Joshia9b174b2017-02-17 11:50:12 -0800589 const InterpFilter filter = (InterpFilter)filter_bank;
Dmitry Kovalev3d4ed272014-04-21 14:15:35 -0700590 const InterpKernel *filters =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800591 (const InterpKernel *)av1_get_interp_filter_kernel(filter);
Angie Chiang1733f6b2017-01-05 09:52:20 -0800592#if CONFIG_DUAL_FILTER
Angie Chiangb1372892016-12-01 15:06:06 -0800593 const InterpFilterParams filter_params =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800594 av1_get_interp_filter_params(filter);
Angie Chiangb1372892016-12-01 15:06:06 -0800595 if (filter_params.taps != SUBPEL_TAPS) continue;
596#endif
John Koleszara9ebbcc2013-04-18 13:05:38 -0700597 for (int i = 0; i < kNumFilters; i++) {
598 const int p0 = filters[i][0] + filters[i][1];
599 const int p1 = filters[i][2] + filters[i][3];
600 const int p2 = filters[i][4] + filters[i][5];
601 const int p3 = filters[i][6] + filters[i][7];
602 EXPECT_LE(p0, 128);
603 EXPECT_LE(p1, 128);
604 EXPECT_LE(p2, 128);
605 EXPECT_LE(p3, 128);
606 EXPECT_LE(p0 + p3, 128);
607 EXPECT_LE(p0 + p3 + p1, 128);
608 EXPECT_LE(p0 + p3 + p1 + p2, 128);
609 EXPECT_EQ(p0 + p1 + p2 + p3, 128);
610 }
611 }
612}
John Koleszar557a1b22013-02-20 16:13:01 -0800613
John Koleszar04c24072013-02-20 16:32:02 -0800614const int16_t kInvalidFilter[8] = { 0 };
615
John Koleszar5ca6a362013-01-25 09:47:09 -0800616TEST_P(ConvolveTest, MatchesReferenceSubpixelFilter) {
clang-format3a826f12016-08-11 17:46:05 -0700617 uint8_t *const in = input();
618 uint8_t *const out = output();
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700619 uint8_t ref8[kOutputStride * kMaxDimension];
620 uint16_t ref16[kOutputStride * kMaxDimension];
clang-format3a826f12016-08-11 17:46:05 -0700621 uint8_t *ref;
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700622 if (UUT_->use_highbd_ == 0) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700623 ref = ref8;
624 } else {
625 ref = CONVERT_TO_BYTEPTR(ref16);
626 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800627
John Koleszar557a1b22013-02-20 16:13:01 -0800628 for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
Urvang Joshia9b174b2017-02-17 11:50:12 -0800629 const InterpFilter filter = (InterpFilter)filter_bank;
Dmitry Kovalev3d4ed272014-04-21 14:15:35 -0700630 const InterpKernel *filters =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800631 (const InterpKernel *)av1_get_interp_filter_kernel(filter);
Angie Chiang1733f6b2017-01-05 09:52:20 -0800632#if CONFIG_DUAL_FILTER
Angie Chiangb1372892016-12-01 15:06:06 -0800633 const InterpFilterParams filter_params =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800634 av1_get_interp_filter_params(filter);
Angie Chiangb1372892016-12-01 15:06:06 -0800635 if (filter_params.taps != SUBPEL_TAPS) continue;
636#endif
Dmitry Kovalev021eaab2014-05-14 16:21:41 -0700637
John Koleszar557a1b22013-02-20 16:13:01 -0800638 for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) {
639 for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) {
clang-format3a826f12016-08-11 17:46:05 -0700640 wrapper_filter_block2d_8_c(in, kInputStride, filters[filter_x],
641 filters[filter_y], ref, kOutputStride,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700642 Width(), Height());
John Koleszar5ca6a362013-01-25 09:47:09 -0800643
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700644 if (filter_x && filter_y)
clang-format3a826f12016-08-11 17:46:05 -0700645 ASM_REGISTER_STATE_CHECK(UUT_->hv8_(
646 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
647 filters[filter_y], 16, Width(), Height()));
John Koleszar557a1b22013-02-20 16:13:01 -0800648 else if (filter_y)
James Zern29e1b1a2014-07-09 21:02:02 -0700649 ASM_REGISTER_STATE_CHECK(
clang-format3a826f12016-08-11 17:46:05 -0700650 UUT_->v8_(in, kInputStride, out, kOutputStride, kInvalidFilter,
651 16, filters[filter_y], 16, Width(), Height()));
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700652 else if (filter_x)
James Zern29e1b1a2014-07-09 21:02:02 -0700653 ASM_REGISTER_STATE_CHECK(
clang-format3a826f12016-08-11 17:46:05 -0700654 UUT_->h8_(in, kInputStride, out, kOutputStride, filters[filter_x],
655 16, kInvalidFilter, 16, Width(), Height()));
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700656 else
657 ASM_REGISTER_STATE_CHECK(
clang-format3a826f12016-08-11 17:46:05 -0700658 UUT_->copy_(in, kInputStride, out, kOutputStride, kInvalidFilter,
659 0, kInvalidFilter, 0, Width(), Height()));
John Koleszar5ca6a362013-01-25 09:47:09 -0800660
John Koleszar557a1b22013-02-20 16:13:01 -0800661 CheckGuardBlocks();
John Koleszar5ca6a362013-01-25 09:47:09 -0800662
John Koleszar557a1b22013-02-20 16:13:01 -0800663 for (int y = 0; y < Height(); ++y)
664 for (int x = 0; x < Width(); ++x)
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700665 ASSERT_EQ(lookup(ref, y * kOutputStride + x),
666 lookup(out, y * kOutputStride + x))
John Koleszar557a1b22013-02-20 16:13:01 -0800667 << "mismatch at (" << x << "," << y << "), "
clang-format3a826f12016-08-11 17:46:05 -0700668 << "filters (" << filter_bank << "," << filter_x << ","
669 << filter_y << ")";
John Koleszar557a1b22013-02-20 16:13:01 -0800670 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800671 }
672 }
673}
674
675TEST_P(ConvolveTest, MatchesReferenceAveragingSubpixelFilter) {
clang-format3a826f12016-08-11 17:46:05 -0700676 uint8_t *const in = input();
677 uint8_t *const out = output();
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700678 uint8_t ref8[kOutputStride * kMaxDimension];
679 uint16_t ref16[kOutputStride * kMaxDimension];
clang-format3a826f12016-08-11 17:46:05 -0700680 uint8_t *ref;
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700681 if (UUT_->use_highbd_ == 0) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700682 ref = ref8;
683 } else {
684 ref = CONVERT_TO_BYTEPTR(ref16);
685 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800686
687 // Populate ref and out with some random data
Yaowu Xuc27fc142016-08-22 16:08:15 -0700688 ::libaom_test::ACMRandom prng;
John Koleszar5ca6a362013-01-25 09:47:09 -0800689 for (int y = 0; y < Height(); ++y) {
690 for (int x = 0; x < Width(); ++x) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700691 uint16_t r;
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700692 if (UUT_->use_highbd_ == 0 || UUT_->use_highbd_ == 8) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700693 r = prng.Rand8Extremes();
694 } else {
695 r = prng.Rand16() & mask_;
696 }
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700697 assign_val(out, y * kOutputStride + x, r);
698 assign_val(ref, y * kOutputStride + x, r);
John Koleszar5ca6a362013-01-25 09:47:09 -0800699 }
700 }
701
John Koleszar557a1b22013-02-20 16:13:01 -0800702 for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
Urvang Joshia9b174b2017-02-17 11:50:12 -0800703 const InterpFilter filter = (InterpFilter)filter_bank;
Dmitry Kovalev3d4ed272014-04-21 14:15:35 -0700704 const InterpKernel *filters =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800705 (const InterpKernel *)av1_get_interp_filter_kernel(filter);
Angie Chiang1733f6b2017-01-05 09:52:20 -0800706#if CONFIG_DUAL_FILTER
Angie Chiangb1372892016-12-01 15:06:06 -0800707 const InterpFilterParams filter_params =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800708 av1_get_interp_filter_params(filter);
Angie Chiangb1372892016-12-01 15:06:06 -0800709 if (filter_params.taps != SUBPEL_TAPS) continue;
710#endif
John Koleszar5ca6a362013-01-25 09:47:09 -0800711
John Koleszar557a1b22013-02-20 16:13:01 -0800712 for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) {
713 for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) {
clang-format3a826f12016-08-11 17:46:05 -0700714 wrapper_filter_average_block2d_8_c(in, kInputStride, filters[filter_x],
715 filters[filter_y], ref,
716 kOutputStride, Width(), Height());
John Koleszar5ca6a362013-01-25 09:47:09 -0800717
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700718 if (filter_x && filter_y)
clang-format3a826f12016-08-11 17:46:05 -0700719 ASM_REGISTER_STATE_CHECK(UUT_->hv8_avg_(
720 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
721 filters[filter_y], 16, Width(), Height()));
John Koleszar557a1b22013-02-20 16:13:01 -0800722 else if (filter_y)
clang-format3a826f12016-08-11 17:46:05 -0700723 ASM_REGISTER_STATE_CHECK(UUT_->v8_avg_(
724 in, kInputStride, out, kOutputStride, kInvalidFilter, 16,
725 filters[filter_y], 16, Width(), Height()));
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700726 else if (filter_x)
clang-format3a826f12016-08-11 17:46:05 -0700727 ASM_REGISTER_STATE_CHECK(UUT_->h8_avg_(
728 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
729 kInvalidFilter, 16, Width(), Height()));
John Koleszar557a1b22013-02-20 16:13:01 -0800730 else
James Zern29e1b1a2014-07-09 21:02:02 -0700731 ASM_REGISTER_STATE_CHECK(
clang-format3a826f12016-08-11 17:46:05 -0700732 UUT_->avg_(in, kInputStride, out, kOutputStride, kInvalidFilter,
733 0, kInvalidFilter, 0, Width(), Height()));
John Koleszar5ca6a362013-01-25 09:47:09 -0800734
John Koleszar557a1b22013-02-20 16:13:01 -0800735 CheckGuardBlocks();
John Koleszar5ca6a362013-01-25 09:47:09 -0800736
John Koleszar557a1b22013-02-20 16:13:01 -0800737 for (int y = 0; y < Height(); ++y)
738 for (int x = 0; x < Width(); ++x)
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700739 ASSERT_EQ(lookup(ref, y * kOutputStride + x),
740 lookup(out, y * kOutputStride + x))
John Koleszar557a1b22013-02-20 16:13:01 -0800741 << "mismatch at (" << x << "," << y << "), "
clang-format3a826f12016-08-11 17:46:05 -0700742 << "filters (" << filter_bank << "," << filter_x << ","
743 << filter_y << ")";
John Koleszar557a1b22013-02-20 16:13:01 -0800744 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800745 }
746 }
747}
748
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700749TEST_P(ConvolveTest, FilterExtremes) {
750 uint8_t *const in = input();
751 uint8_t *const out = output();
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700752 uint8_t ref8[kOutputStride * kMaxDimension];
753 uint16_t ref16[kOutputStride * kMaxDimension];
754 uint8_t *ref;
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700755 if (UUT_->use_highbd_ == 0) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700756 ref = ref8;
757 } else {
758 ref = CONVERT_TO_BYTEPTR(ref16);
759 }
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700760
761 // Populate ref and out with some random data
Yaowu Xuc27fc142016-08-22 16:08:15 -0700762 ::libaom_test::ACMRandom prng;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700763 for (int y = 0; y < Height(); ++y) {
764 for (int x = 0; x < Width(); ++x) {
765 uint16_t r;
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700766 if (UUT_->use_highbd_ == 0 || UUT_->use_highbd_ == 8) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700767 r = prng.Rand8Extremes();
768 } else {
769 r = prng.Rand16() & mask_;
770 }
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700771 assign_val(out, y * kOutputStride + x, r);
772 assign_val(ref, y * kOutputStride + x, r);
773 }
774 }
775
776 for (int axis = 0; axis < 2; axis++) {
777 int seed_val = 0;
778 while (seed_val < 256) {
779 for (int y = 0; y < 8; ++y) {
780 for (int x = 0; x < 8; ++x) {
clang-format3a826f12016-08-11 17:46:05 -0700781 assign_val(in, y * kOutputStride + x - SUBPEL_TAPS / 2 + 1,
782 ((seed_val >> (axis ? y : x)) & 1) * mask_);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700783 if (axis) seed_val++;
784 }
785 if (axis)
clang-format3a826f12016-08-11 17:46:05 -0700786 seed_val -= 8;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700787 else
788 seed_val++;
789 }
790 if (axis) seed_val += 8;
791
792 for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
Urvang Joshia9b174b2017-02-17 11:50:12 -0800793 const InterpFilter filter = (InterpFilter)filter_bank;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700794 const InterpKernel *filters =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800795 (const InterpKernel *)av1_get_interp_filter_kernel(filter);
Angie Chiang1733f6b2017-01-05 09:52:20 -0800796#if CONFIG_DUAL_FILTER
Angie Chiangb1372892016-12-01 15:06:06 -0800797 const InterpFilterParams filter_params =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800798 av1_get_interp_filter_params(filter);
Angie Chiangb1372892016-12-01 15:06:06 -0800799 if (filter_params.taps != SUBPEL_TAPS) continue;
800#endif
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700801 for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) {
802 for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) {
clang-format3a826f12016-08-11 17:46:05 -0700803 wrapper_filter_block2d_8_c(in, kInputStride, filters[filter_x],
804 filters[filter_y], ref, kOutputStride,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700805 Width(), Height());
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700806 if (filter_x && filter_y)
clang-format3a826f12016-08-11 17:46:05 -0700807 ASM_REGISTER_STATE_CHECK(UUT_->hv8_(
808 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
809 filters[filter_y], 16, Width(), Height()));
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700810 else if (filter_y)
clang-format3a826f12016-08-11 17:46:05 -0700811 ASM_REGISTER_STATE_CHECK(UUT_->v8_(
812 in, kInputStride, out, kOutputStride, kInvalidFilter, 16,
813 filters[filter_y], 16, Width(), Height()));
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700814 else if (filter_x)
clang-format3a826f12016-08-11 17:46:05 -0700815 ASM_REGISTER_STATE_CHECK(UUT_->h8_(
816 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
817 kInvalidFilter, 16, Width(), Height()));
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700818 else
clang-format3a826f12016-08-11 17:46:05 -0700819 ASM_REGISTER_STATE_CHECK(UUT_->copy_(
820 in, kInputStride, out, kOutputStride, kInvalidFilter, 0,
821 kInvalidFilter, 0, Width(), Height()));
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700822
823 for (int y = 0; y < Height(); ++y)
824 for (int x = 0; x < Width(); ++x)
825 ASSERT_EQ(lookup(ref, y * kOutputStride + x),
826 lookup(out, y * kOutputStride + x))
827 << "mismatch at (" << x << "," << y << "), "
clang-format3a826f12016-08-11 17:46:05 -0700828 << "filters (" << filter_bank << "," << filter_x << ","
829 << filter_y << ")";
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700830 }
831 }
832 }
833 }
834 }
835}
836
Tero Rintaluomae326cec2013-08-22 11:29:19 +0300837/* This test exercises that enough rows and columns are filtered with every
838 possible initial fractional positions and scaling steps. */
839TEST_P(ConvolveTest, CheckScalingFiltering) {
clang-format3a826f12016-08-11 17:46:05 -0700840 uint8_t *const in = input();
841 uint8_t *const out = output();
Angie Chiangb1372892016-12-01 15:06:06 -0800842 const InterpKernel *const eighttap =
843 (const InterpKernel *)av1_get_interp_filter_kernel(EIGHTTAP_REGULAR);
Tero Rintaluomae326cec2013-08-22 11:29:19 +0300844
845 SetConstantInput(127);
846
847 for (int frac = 0; frac < 16; ++frac) {
848 for (int step = 1; step <= 32; ++step) {
849 /* Test the horizontal and vertical filters in combination. */
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700850 ASM_REGISTER_STATE_CHECK(UUT_->shv8_(in, kInputStride, out, kOutputStride,
clang-format3a826f12016-08-11 17:46:05 -0700851 eighttap[frac], step, eighttap[frac],
852 step, Width(), Height()));
Tero Rintaluomae326cec2013-08-22 11:29:19 +0300853
854 CheckGuardBlocks();
855
856 for (int y = 0; y < Height(); ++y) {
857 for (int x = 0; x < Width(); ++x) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700858 ASSERT_EQ(lookup(in, y * kInputStride + x),
859 lookup(out, y * kOutputStride + x))
clang-format3a826f12016-08-11 17:46:05 -0700860 << "x == " << x << ", y == " << y << ", frac == " << frac
861 << ", step == " << step;
Tero Rintaluomae326cec2013-08-22 11:29:19 +0300862 }
863 }
864 }
865 }
866}
867
Yi Luoa4d87992017-04-14 17:44:26 -0700868TEST_P(ConvolveTest, DISABLED_Copy_Speed) {
869 const uint8_t *const in = input();
870 uint8_t *const out = output();
871 const int kNumTests = 5000000;
872 const int width = Width();
873 const int height = Height();
874 aom_usec_timer timer;
875
876 aom_usec_timer_start(&timer);
877 for (int n = 0; n < kNumTests; ++n) {
878 UUT_->copy_(in, kInputStride, out, kOutputStride, NULL, 0, NULL, 0, width,
879 height);
880 }
881 aom_usec_timer_mark(&timer);
882
883 const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
884 printf("convolve_copy_%dx%d_%d: %d us\n", width, height,
885 UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
886}
887
888TEST_P(ConvolveTest, DISABLED_Avg_Speed) {
889 const uint8_t *const in = input();
890 uint8_t *const out = output();
891 const int kNumTests = 5000000;
892 const int width = Width();
893 const int height = Height();
894 aom_usec_timer timer;
895
896 aom_usec_timer_start(&timer);
897 for (int n = 0; n < kNumTests; ++n) {
898 UUT_->avg_(in, kInputStride, out, kOutputStride, NULL, 0, NULL, 0, width,
899 height);
900 }
901 aom_usec_timer_mark(&timer);
902
903 const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
904 printf("convolve_avg_%dx%d_%d: %d us\n", width, height,
905 UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
906}
907
Yi Luo9d247352017-03-16 12:31:46 -0700908TEST_P(ConvolveTest, DISABLED_Speed) {
909 uint8_t *const in = input();
910 uint8_t *const out = output();
Yi Luo9d247352017-03-16 12:31:46 -0700911 uint8_t ref8[kOutputStride * kMaxDimension];
912 uint16_t ref16[kOutputStride * kMaxDimension];
913 uint8_t *ref;
914 if (UUT_->use_highbd_ == 0) {
915 ref = ref8;
916 } else {
917 ref = CONVERT_TO_BYTEPTR(ref16);
918 }
Yi Luo9d247352017-03-16 12:31:46 -0700919
920 // Populate ref and out with some random data
921 ::libaom_test::ACMRandom prng;
922 for (int y = 0; y < Height(); ++y) {
923 for (int x = 0; x < Width(); ++x) {
924 uint16_t r;
Yi Luo9d247352017-03-16 12:31:46 -0700925 if (UUT_->use_highbd_ == 0 || UUT_->use_highbd_ == 8) {
926 r = prng.Rand8Extremes();
927 } else {
928 r = prng.Rand16() & mask_;
929 }
Yi Luo9d247352017-03-16 12:31:46 -0700930 assign_val(out, y * kOutputStride + x, r);
931 assign_val(ref, y * kOutputStride + x, r);
932 }
933 }
934
935 const InterpFilter filter = (InterpFilter)1;
936 const InterpKernel *filters =
937 (const InterpKernel *)av1_get_interp_filter_kernel(filter);
938 wrapper_filter_average_block2d_8_c(in, kInputStride, filters[1], filters[1],
939 out, kOutputStride, Width(), Height());
940
941 aom_usec_timer timer;
942 int tests_num = 1000;
943
944 aom_usec_timer_start(&timer);
945 while (tests_num > 0) {
946 for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
947 const InterpFilter filter = (InterpFilter)filter_bank;
948 const InterpKernel *filters =
949 (const InterpKernel *)av1_get_interp_filter_kernel(filter);
950#if CONFIG_DUAL_FILTER
951 const InterpFilterParams filter_params =
952 av1_get_interp_filter_params(filter);
953 if (filter_params.taps != SUBPEL_TAPS) continue;
954#endif
955
956 for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) {
957 for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) {
958 if (filter_x && filter_y)
959 ASM_REGISTER_STATE_CHECK(UUT_->hv8_(
960 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
961 filters[filter_y], 16, Width(), Height()));
962 if (filter_y)
963 ASM_REGISTER_STATE_CHECK(
964 UUT_->v8_(in, kInputStride, out, kOutputStride, kInvalidFilter,
965 16, filters[filter_y], 16, Width(), Height()));
966 else if (filter_x)
967 ASM_REGISTER_STATE_CHECK(UUT_->h8_(
968 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
969 kInvalidFilter, 16, Width(), Height()));
970 }
971 }
972 }
973 tests_num--;
974 }
975 aom_usec_timer_mark(&timer);
976
977 const int elapsed_time =
978 static_cast<int>(aom_usec_timer_elapsed(&timer) / 1000);
979 printf("%dx%d (bitdepth %d) time: %5d ms\n", Width(), Height(),
980 UUT_->use_highbd_, elapsed_time);
981}
982
John Koleszar5ca6a362013-01-25 09:47:09 -0800983using std::tr1::make_tuple;
984
clang-format3a826f12016-08-11 17:46:05 -0700985#define WRAP(func, bd) \
986 void wrap_##func##_##bd( \
987 const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, \
988 ptrdiff_t dst_stride, const int16_t *filter_x, int filter_x_stride, \
989 const int16_t *filter_y, int filter_y_stride, int w, int h) { \
Yaowu Xuf883b422016-08-30 14:01:10 -0700990 aom_highbd_##func(src, src_stride, dst, dst_stride, filter_x, \
clang-format3a826f12016-08-11 17:46:05 -0700991 filter_x_stride, filter_y, filter_y_stride, w, h, bd); \
992 }
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700993#if HAVE_SSE2 && ARCH_X86_64
Alex Converse0c00af12015-10-06 15:59:03 -0700994WRAP(convolve_copy_sse2, 8)
995WRAP(convolve_avg_sse2, 8)
996WRAP(convolve_copy_sse2, 10)
997WRAP(convolve_avg_sse2, 10)
998WRAP(convolve_copy_sse2, 12)
999WRAP(convolve_avg_sse2, 12)
Alex Converse7e779382015-10-09 11:42:05 -07001000WRAP(convolve8_horiz_sse2, 8)
1001WRAP(convolve8_avg_horiz_sse2, 8)
1002WRAP(convolve8_vert_sse2, 8)
1003WRAP(convolve8_avg_vert_sse2, 8)
1004WRAP(convolve8_sse2, 8)
1005WRAP(convolve8_avg_sse2, 8)
1006WRAP(convolve8_horiz_sse2, 10)
1007WRAP(convolve8_avg_horiz_sse2, 10)
1008WRAP(convolve8_vert_sse2, 10)
1009WRAP(convolve8_avg_vert_sse2, 10)
1010WRAP(convolve8_sse2, 10)
1011WRAP(convolve8_avg_sse2, 10)
1012WRAP(convolve8_horiz_sse2, 12)
1013WRAP(convolve8_avg_horiz_sse2, 12)
1014WRAP(convolve8_vert_sse2, 12)
1015WRAP(convolve8_avg_vert_sse2, 12)
1016WRAP(convolve8_sse2, 12)
1017WRAP(convolve8_avg_sse2, 12)
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001018#endif // HAVE_SSE2 && ARCH_X86_64
1019
Alex Converse7e779382015-10-09 11:42:05 -07001020WRAP(convolve_copy_c, 8)
1021WRAP(convolve_avg_c, 8)
1022WRAP(convolve8_horiz_c, 8)
1023WRAP(convolve8_avg_horiz_c, 8)
1024WRAP(convolve8_vert_c, 8)
1025WRAP(convolve8_avg_vert_c, 8)
1026WRAP(convolve8_c, 8)
1027WRAP(convolve8_avg_c, 8)
1028WRAP(convolve_copy_c, 10)
1029WRAP(convolve_avg_c, 10)
1030WRAP(convolve8_horiz_c, 10)
1031WRAP(convolve8_avg_horiz_c, 10)
1032WRAP(convolve8_vert_c, 10)
1033WRAP(convolve8_avg_vert_c, 10)
1034WRAP(convolve8_c, 10)
1035WRAP(convolve8_avg_c, 10)
1036WRAP(convolve_copy_c, 12)
1037WRAP(convolve_avg_c, 12)
1038WRAP(convolve8_horiz_c, 12)
1039WRAP(convolve8_avg_horiz_c, 12)
1040WRAP(convolve8_vert_c, 12)
1041WRAP(convolve8_avg_vert_c, 12)
1042WRAP(convolve8_c, 12)
1043WRAP(convolve8_avg_c, 12)
Yi Luo9d247352017-03-16 12:31:46 -07001044
1045#if HAVE_AVX2
1046WRAP(convolve_copy_avx2, 8)
1047WRAP(convolve_avg_avx2, 8)
1048WRAP(convolve8_horiz_avx2, 8)
1049WRAP(convolve8_avg_horiz_avx2, 8)
1050WRAP(convolve8_vert_avx2, 8)
1051WRAP(convolve8_avg_vert_avx2, 8)
1052WRAP(convolve8_avx2, 8)
1053WRAP(convolve8_avg_avx2, 8)
1054
1055WRAP(convolve_copy_avx2, 10)
1056WRAP(convolve_avg_avx2, 10)
1057WRAP(convolve8_avx2, 10)
1058WRAP(convolve8_horiz_avx2, 10)
1059WRAP(convolve8_vert_avx2, 10)
1060WRAP(convolve8_avg_avx2, 10)
1061WRAP(convolve8_avg_horiz_avx2, 10)
1062WRAP(convolve8_avg_vert_avx2, 10)
1063
1064WRAP(convolve_copy_avx2, 12)
1065WRAP(convolve_avg_avx2, 12)
1066WRAP(convolve8_avx2, 12)
1067WRAP(convolve8_horiz_avx2, 12)
1068WRAP(convolve8_vert_avx2, 12)
1069WRAP(convolve8_avg_avx2, 12)
1070WRAP(convolve8_avg_horiz_avx2, 12)
1071WRAP(convolve8_avg_vert_avx2, 12)
1072#endif // HAVE_AVX2
1073
Alex Converse7e779382015-10-09 11:42:05 -07001074#undef WRAP
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001075
1076const ConvolveFunctions convolve8_c(
clang-format3a826f12016-08-11 17:46:05 -07001077 wrap_convolve_copy_c_8, wrap_convolve_avg_c_8, wrap_convolve8_horiz_c_8,
1078 wrap_convolve8_avg_horiz_c_8, wrap_convolve8_vert_c_8,
1079 wrap_convolve8_avg_vert_c_8, wrap_convolve8_c_8, wrap_convolve8_avg_c_8,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001080 wrap_convolve8_horiz_c_8, wrap_convolve8_avg_horiz_c_8,
clang-format3a826f12016-08-11 17:46:05 -07001081 wrap_convolve8_vert_c_8, wrap_convolve8_avg_vert_c_8, wrap_convolve8_c_8,
1082 wrap_convolve8_avg_c_8, 8);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001083const ConvolveFunctions convolve10_c(
clang-format3a826f12016-08-11 17:46:05 -07001084 wrap_convolve_copy_c_10, wrap_convolve_avg_c_10, wrap_convolve8_horiz_c_10,
1085 wrap_convolve8_avg_horiz_c_10, wrap_convolve8_vert_c_10,
1086 wrap_convolve8_avg_vert_c_10, wrap_convolve8_c_10, wrap_convolve8_avg_c_10,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001087 wrap_convolve8_horiz_c_10, wrap_convolve8_avg_horiz_c_10,
clang-format3a826f12016-08-11 17:46:05 -07001088 wrap_convolve8_vert_c_10, wrap_convolve8_avg_vert_c_10, wrap_convolve8_c_10,
1089 wrap_convolve8_avg_c_10, 10);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001090const ConvolveFunctions convolve12_c(
clang-format3a826f12016-08-11 17:46:05 -07001091 wrap_convolve_copy_c_12, wrap_convolve_avg_c_12, wrap_convolve8_horiz_c_12,
1092 wrap_convolve8_avg_horiz_c_12, wrap_convolve8_vert_c_12,
1093 wrap_convolve8_avg_vert_c_12, wrap_convolve8_c_12, wrap_convolve8_avg_c_12,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001094 wrap_convolve8_horiz_c_12, wrap_convolve8_avg_horiz_c_12,
clang-format3a826f12016-08-11 17:46:05 -07001095 wrap_convolve8_vert_c_12, wrap_convolve8_avg_vert_c_12, wrap_convolve8_c_12,
1096 wrap_convolve8_avg_c_12, 12);
Alex Conversef03e2382016-04-26 18:09:40 -07001097const ConvolveParam kArrayConvolve_c[] = {
clang-format3a826f12016-08-11 17:46:05 -07001098 ALL_SIZES(convolve8_c), ALL_SIZES(convolve10_c), ALL_SIZES(convolve12_c)
Alex Conversef03e2382016-04-26 18:09:40 -07001099};
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001100
clang-format3a826f12016-08-11 17:46:05 -07001101INSTANTIATE_TEST_CASE_P(C, ConvolveTest, ::testing::ValuesIn(kArrayConvolve_c));
John Koleszar29d47ac2013-02-07 17:00:37 -08001102
Deb Mukherjee10783d42014-09-02 16:34:09 -07001103#if HAVE_SSE2 && ARCH_X86_64
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001104const ConvolveFunctions convolve8_sse2(
Alex Converse0c00af12015-10-06 15:59:03 -07001105 wrap_convolve_copy_sse2_8, wrap_convolve_avg_sse2_8,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001106 wrap_convolve8_horiz_sse2_8, wrap_convolve8_avg_horiz_sse2_8,
1107 wrap_convolve8_vert_sse2_8, wrap_convolve8_avg_vert_sse2_8,
Scott LaVarnway4e6b5072015-08-05 10:47:06 -07001108 wrap_convolve8_sse2_8, wrap_convolve8_avg_sse2_8,
1109 wrap_convolve8_horiz_sse2_8, wrap_convolve8_avg_horiz_sse2_8,
1110 wrap_convolve8_vert_sse2_8, wrap_convolve8_avg_vert_sse2_8,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001111 wrap_convolve8_sse2_8, wrap_convolve8_avg_sse2_8, 8);
Deb Mukherjee27dce0f2014-11-07 10:19:46 -08001112const ConvolveFunctions convolve10_sse2(
Alex Converse0c00af12015-10-06 15:59:03 -07001113 wrap_convolve_copy_sse2_10, wrap_convolve_avg_sse2_10,
Deb Mukherjee27dce0f2014-11-07 10:19:46 -08001114 wrap_convolve8_horiz_sse2_10, wrap_convolve8_avg_horiz_sse2_10,
1115 wrap_convolve8_vert_sse2_10, wrap_convolve8_avg_vert_sse2_10,
Scott LaVarnway4e6b5072015-08-05 10:47:06 -07001116 wrap_convolve8_sse2_10, wrap_convolve8_avg_sse2_10,
1117 wrap_convolve8_horiz_sse2_10, wrap_convolve8_avg_horiz_sse2_10,
1118 wrap_convolve8_vert_sse2_10, wrap_convolve8_avg_vert_sse2_10,
Deb Mukherjee27dce0f2014-11-07 10:19:46 -08001119 wrap_convolve8_sse2_10, wrap_convolve8_avg_sse2_10, 10);
1120const ConvolveFunctions convolve12_sse2(
Alex Converse0c00af12015-10-06 15:59:03 -07001121 wrap_convolve_copy_sse2_12, wrap_convolve_avg_sse2_12,
Deb Mukherjee27dce0f2014-11-07 10:19:46 -08001122 wrap_convolve8_horiz_sse2_12, wrap_convolve8_avg_horiz_sse2_12,
1123 wrap_convolve8_vert_sse2_12, wrap_convolve8_avg_vert_sse2_12,
Scott LaVarnway4e6b5072015-08-05 10:47:06 -07001124 wrap_convolve8_sse2_12, wrap_convolve8_avg_sse2_12,
1125 wrap_convolve8_horiz_sse2_12, wrap_convolve8_avg_horiz_sse2_12,
1126 wrap_convolve8_vert_sse2_12, wrap_convolve8_avg_vert_sse2_12,
Deb Mukherjee27dce0f2014-11-07 10:19:46 -08001127 wrap_convolve8_sse2_12, wrap_convolve8_avg_sse2_12, 12);
clang-format3a826f12016-08-11 17:46:05 -07001128const ConvolveParam kArrayConvolve_sse2[] = { ALL_SIZES(convolve8_sse2),
1129 ALL_SIZES(convolve10_sse2),
1130 ALL_SIZES(convolve12_sse2) };
Alex Conversef03e2382016-04-26 18:09:40 -07001131INSTANTIATE_TEST_CASE_P(SSE2, ConvolveTest,
1132 ::testing::ValuesIn(kArrayConvolve_sse2));
Deb Mukherjee10783d42014-09-02 16:34:09 -07001133#endif
Yunqing Wang3fb728c2013-10-10 13:51:35 -07001134
John Koleszar29d47ac2013-02-07 17:00:37 -08001135#if HAVE_SSSE3
1136const ConvolveFunctions convolve8_ssse3(
Yaowu Xuf883b422016-08-30 14:01:10 -07001137 aom_convolve_copy_c, aom_convolve_avg_c, aom_convolve8_horiz_ssse3,
1138 aom_convolve8_avg_horiz_ssse3, aom_convolve8_vert_ssse3,
1139 aom_convolve8_avg_vert_ssse3, aom_convolve8_ssse3, aom_convolve8_avg_ssse3,
1140 aom_scaled_horiz_c, aom_scaled_avg_horiz_c, aom_scaled_vert_c,
1141 aom_scaled_avg_vert_c, aom_scaled_2d_ssse3, aom_scaled_avg_2d_c, 0);
John Koleszar29d47ac2013-02-07 17:00:37 -08001142
Alex Conversef03e2382016-04-26 18:09:40 -07001143const ConvolveParam kArrayConvolve8_ssse3[] = { ALL_SIZES(convolve8_ssse3) };
1144INSTANTIATE_TEST_CASE_P(SSSE3, ConvolveTest,
1145 ::testing::ValuesIn(kArrayConvolve8_ssse3));
John Koleszar29d47ac2013-02-07 17:00:37 -08001146#endif
Johann158c80c2013-05-23 12:50:41 -07001147
Yi Luo9d247352017-03-16 12:31:46 -07001148#if HAVE_AVX2
Yi Luo9d247352017-03-16 12:31:46 -07001149const ConvolveFunctions convolve8_avx2(
1150 wrap_convolve_copy_avx2_8, wrap_convolve_avg_avx2_8,
1151 wrap_convolve8_horiz_avx2_8, wrap_convolve8_avg_horiz_avx2_8,
1152 wrap_convolve8_vert_avx2_8, wrap_convolve8_avg_vert_avx2_8,
1153 wrap_convolve8_avx2_8, wrap_convolve8_avg_avx2_8, wrap_convolve8_horiz_c_8,
1154 wrap_convolve8_avg_horiz_c_8, wrap_convolve8_vert_c_8,
1155 wrap_convolve8_avg_vert_c_8, wrap_convolve8_c_8, wrap_convolve8_avg_c_8, 8);
1156const ConvolveFunctions convolve10_avx2(
1157 wrap_convolve_copy_avx2_10, wrap_convolve_avg_avx2_10,
1158 wrap_convolve8_horiz_avx2_10, wrap_convolve8_avg_horiz_avx2_10,
1159 wrap_convolve8_vert_avx2_10, wrap_convolve8_avg_vert_avx2_10,
1160 wrap_convolve8_avx2_10, wrap_convolve8_avg_avx2_10,
1161 wrap_convolve8_horiz_c_10, wrap_convolve8_avg_horiz_c_10,
1162 wrap_convolve8_vert_c_10, wrap_convolve8_avg_vert_c_10, wrap_convolve8_c_10,
1163 wrap_convolve8_avg_c_10, 10);
1164const ConvolveFunctions convolve12_avx2(
1165 wrap_convolve_copy_avx2_12, wrap_convolve_avg_avx2_12,
1166 wrap_convolve8_horiz_avx2_12, wrap_convolve8_avg_horiz_avx2_12,
1167 wrap_convolve8_vert_avx2_12, wrap_convolve8_avg_vert_avx2_12,
1168 wrap_convolve8_avx2_12, wrap_convolve8_avg_avx2_12,
1169 wrap_convolve8_horiz_c_12, wrap_convolve8_avg_horiz_c_12,
1170 wrap_convolve8_vert_c_12, wrap_convolve8_avg_vert_c_12, wrap_convolve8_c_12,
1171 wrap_convolve8_avg_c_12, 12);
Debargha Mukherjee7a160ac2017-10-07 22:29:43 -07001172const ConvolveParam kArrayConvolve8_avx2[] = { ALL_SIZES_64(convolve8_avx2),
1173 ALL_SIZES_64(convolve10_avx2),
1174 ALL_SIZES_64(convolve12_avx2) };
Alex Conversef03e2382016-04-26 18:09:40 -07001175INSTANTIATE_TEST_CASE_P(AVX2, ConvolveTest,
1176 ::testing::ValuesIn(kArrayConvolve8_avx2));
Yi Luo9d247352017-03-16 12:31:46 -07001177#endif // HAVE_AVX2
Yunqing Wang4f0943b2014-05-27 10:36:56 -07001178
Geza Lore938b8df2016-03-04 15:55:48 +00001179// TODO(any): Make NEON versions support 128x128 128x64 64x128 block sizes
Yaowu Xuf883b422016-08-30 14:01:10 -07001180#if HAVE_NEON && !(CONFIG_AV1 && CONFIG_EXT_PARTITION)
Johannce239312014-05-07 11:01:31 -07001181#if HAVE_NEON_ASM
Johann158c80c2013-05-23 12:50:41 -07001182const ConvolveFunctions convolve8_neon(
Yaowu Xuf883b422016-08-30 14:01:10 -07001183 aom_convolve_copy_neon, aom_convolve_avg_neon, aom_convolve8_horiz_neon,
1184 aom_convolve8_avg_horiz_neon, aom_convolve8_vert_neon,
1185 aom_convolve8_avg_vert_neon, aom_convolve8_neon, aom_convolve8_avg_neon,
1186 aom_scaled_horiz_c, aom_scaled_avg_horiz_c, aom_scaled_vert_c,
1187 aom_scaled_avg_vert_c, aom_scaled_2d_c, aom_scaled_avg_2d_c, 0);
clang-format3a826f12016-08-11 17:46:05 -07001188#else // HAVE_NEON
Scott LaVarnway617382a2014-09-10 09:49:34 -07001189const ConvolveFunctions convolve8_neon(
Yaowu Xuf883b422016-08-30 14:01:10 -07001190 aom_convolve_copy_neon, aom_convolve_avg_neon, aom_convolve8_horiz_neon,
1191 aom_convolve8_avg_horiz_neon, aom_convolve8_vert_neon,
1192 aom_convolve8_avg_vert_neon, aom_convolve8_neon, aom_convolve8_avg_neon,
1193 aom_scaled_horiz_c, aom_scaled_avg_horiz_c, aom_scaled_vert_c,
1194 aom_scaled_avg_vert_c, aom_scaled_2d_c, aom_scaled_avg_2d_c, 0);
Scott LaVarnway617382a2014-09-10 09:49:34 -07001195#endif // HAVE_NEON_ASM
Johann158c80c2013-05-23 12:50:41 -07001196
Debargha Mukherjee7a160ac2017-10-07 22:29:43 -07001197const ConvolveParam kArrayConvolve8_neon[] = { ALL_SIZES_64(convolve8_neon) };
Alex Conversef03e2382016-04-26 18:09:40 -07001198INSTANTIATE_TEST_CASE_P(NEON, ConvolveTest,
1199 ::testing::ValuesIn(kArrayConvolve8_neon));
Debargha Mukherjee7a160ac2017-10-07 22:29:43 -07001200#endif // HAVE_NEON && !(CONFIG_AV1 && CONFIG_EXT_PARTITION)
Parag Salasakar40edab52013-09-13 15:18:32 +05301201
Geza Lore938b8df2016-03-04 15:55:48 +00001202// TODO(any): Make DSPR2 versions support 128x128 128x64 64x128 block sizes
Yaowu Xuf883b422016-08-30 14:01:10 -07001203#if HAVE_DSPR2 && !(CONFIG_AV1 && CONFIG_EXT_PARTITION)
Parag Salasakar40edab52013-09-13 15:18:32 +05301204const ConvolveFunctions convolve8_dspr2(
Yaowu Xuf883b422016-08-30 14:01:10 -07001205 aom_convolve_copy_dspr2, aom_convolve_avg_dspr2, aom_convolve8_horiz_dspr2,
1206 aom_convolve8_avg_horiz_dspr2, aom_convolve8_vert_dspr2,
1207 aom_convolve8_avg_vert_dspr2, aom_convolve8_dspr2, aom_convolve8_avg_dspr2,
1208 aom_scaled_horiz_c, aom_scaled_avg_horiz_c, aom_scaled_vert_c,
1209 aom_scaled_avg_vert_c, aom_scaled_2d_c, aom_scaled_avg_2d_c, 0);
Parag Salasakar40edab52013-09-13 15:18:32 +05301210
Debargha Mukherjee7a160ac2017-10-07 22:29:43 -07001211const ConvolveParam kArrayConvolve8_dspr2[] = { ALL_SIZES_64(convolve8_dspr2) };
Alex Conversef03e2382016-04-26 18:09:40 -07001212INSTANTIATE_TEST_CASE_P(DSPR2, ConvolveTest,
1213 ::testing::ValuesIn(kArrayConvolve8_dspr2));
Debargha Mukherjee7a160ac2017-10-07 22:29:43 -07001214#endif // HAVE_DSPR2 && !(CONFIG_AV1 && CONFIG_EXT_PARTITION)
Parag Salasakar27d083c2015-04-16 11:03:24 +05301215
Geza Lore938b8df2016-03-04 15:55:48 +00001216// TODO(any): Make MSA versions support 128x128 128x64 64x128 block sizes
Yaowu Xuf883b422016-08-30 14:01:10 -07001217#if HAVE_MSA && !(CONFIG_AV1 && CONFIG_EXT_PARTITION)
Parag Salasakar27d083c2015-04-16 11:03:24 +05301218const ConvolveFunctions convolve8_msa(
Yaowu Xuf883b422016-08-30 14:01:10 -07001219 aom_convolve_copy_msa, aom_convolve_avg_msa, aom_convolve8_horiz_msa,
1220 aom_convolve8_avg_horiz_msa, aom_convolve8_vert_msa,
1221 aom_convolve8_avg_vert_msa, aom_convolve8_msa, aom_convolve8_avg_msa,
1222 aom_scaled_horiz_c, aom_scaled_avg_horiz_c, aom_scaled_vert_c,
1223 aom_scaled_avg_vert_c, aom_scaled_2d_c, aom_scaled_avg_2d_c, 0);
Parag Salasakar27d083c2015-04-16 11:03:24 +05301224
Debargha Mukherjee7a160ac2017-10-07 22:29:43 -07001225const ConvolveParam kArrayConvolve8_msa[] = { ALL_SIZES_64(convolve8_msa) };
Alex Conversef03e2382016-04-26 18:09:40 -07001226INSTANTIATE_TEST_CASE_P(MSA, ConvolveTest,
1227 ::testing::ValuesIn(kArrayConvolve8_msa));
Debargha Mukherjee7a160ac2017-10-07 22:29:43 -07001228#endif // HAVE_MSA && !(CONFIG_AV1 && CONFIG_EXT_PARTITION)
James Zern8fb48af2013-05-02 13:08:19 -07001229} // namespace