blob: f6e770b6513064a2ad8a9e4dbb13b2c3974fbf26 [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
Debargha Mukherjee2ccf4b92018-02-27 17:30:46 -080079#if CONFIG_AV1
Debargha Mukherjee7a160ac2017-10-07 22:29:43 -070080#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
Debargha Mukherjee2ccf4b92018-02-27 17:30:46 -080085#endif // CONFIG_AV1
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 Chiangb1372892016-12-01 15:06:06 -0800592 const InterpFilterParams filter_params =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800593 av1_get_interp_filter_params(filter);
Angie Chiangb1372892016-12-01 15:06:06 -0800594 if (filter_params.taps != SUBPEL_TAPS) continue;
John Koleszara9ebbcc2013-04-18 13:05:38 -0700595 for (int i = 0; i < kNumFilters; i++) {
596 const int p0 = filters[i][0] + filters[i][1];
597 const int p1 = filters[i][2] + filters[i][3];
598 const int p2 = filters[i][4] + filters[i][5];
599 const int p3 = filters[i][6] + filters[i][7];
600 EXPECT_LE(p0, 128);
601 EXPECT_LE(p1, 128);
602 EXPECT_LE(p2, 128);
603 EXPECT_LE(p3, 128);
604 EXPECT_LE(p0 + p3, 128);
605 EXPECT_LE(p0 + p3 + p1, 128);
606 EXPECT_LE(p0 + p3 + p1 + p2, 128);
607 EXPECT_EQ(p0 + p1 + p2 + p3, 128);
608 }
609 }
610}
John Koleszar557a1b22013-02-20 16:13:01 -0800611
John Koleszar04c24072013-02-20 16:32:02 -0800612const int16_t kInvalidFilter[8] = { 0 };
613
John Koleszar5ca6a362013-01-25 09:47:09 -0800614TEST_P(ConvolveTest, MatchesReferenceSubpixelFilter) {
clang-format3a826f12016-08-11 17:46:05 -0700615 uint8_t *const in = input();
616 uint8_t *const out = output();
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700617 uint8_t ref8[kOutputStride * kMaxDimension];
618 uint16_t ref16[kOutputStride * kMaxDimension];
clang-format3a826f12016-08-11 17:46:05 -0700619 uint8_t *ref;
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700620 if (UUT_->use_highbd_ == 0) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700621 ref = ref8;
622 } else {
623 ref = CONVERT_TO_BYTEPTR(ref16);
624 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800625
John Koleszar557a1b22013-02-20 16:13:01 -0800626 for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
Urvang Joshia9b174b2017-02-17 11:50:12 -0800627 const InterpFilter filter = (InterpFilter)filter_bank;
Dmitry Kovalev3d4ed272014-04-21 14:15:35 -0700628 const InterpKernel *filters =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800629 (const InterpKernel *)av1_get_interp_filter_kernel(filter);
Angie Chiangb1372892016-12-01 15:06:06 -0800630 const InterpFilterParams filter_params =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800631 av1_get_interp_filter_params(filter);
Angie Chiangb1372892016-12-01 15:06:06 -0800632 if (filter_params.taps != SUBPEL_TAPS) continue;
Dmitry Kovalev021eaab2014-05-14 16:21:41 -0700633
John Koleszar557a1b22013-02-20 16:13:01 -0800634 for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) {
635 for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) {
clang-format3a826f12016-08-11 17:46:05 -0700636 wrapper_filter_block2d_8_c(in, kInputStride, filters[filter_x],
637 filters[filter_y], ref, kOutputStride,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700638 Width(), Height());
John Koleszar5ca6a362013-01-25 09:47:09 -0800639
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700640 if (filter_x && filter_y)
clang-format3a826f12016-08-11 17:46:05 -0700641 ASM_REGISTER_STATE_CHECK(UUT_->hv8_(
642 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
643 filters[filter_y], 16, Width(), Height()));
John Koleszar557a1b22013-02-20 16:13:01 -0800644 else if (filter_y)
James Zern29e1b1a2014-07-09 21:02:02 -0700645 ASM_REGISTER_STATE_CHECK(
clang-format3a826f12016-08-11 17:46:05 -0700646 UUT_->v8_(in, kInputStride, out, kOutputStride, kInvalidFilter,
647 16, filters[filter_y], 16, Width(), Height()));
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700648 else if (filter_x)
James Zern29e1b1a2014-07-09 21:02:02 -0700649 ASM_REGISTER_STATE_CHECK(
clang-format3a826f12016-08-11 17:46:05 -0700650 UUT_->h8_(in, kInputStride, out, kOutputStride, filters[filter_x],
651 16, kInvalidFilter, 16, Width(), Height()));
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700652 else
653 ASM_REGISTER_STATE_CHECK(
clang-format3a826f12016-08-11 17:46:05 -0700654 UUT_->copy_(in, kInputStride, out, kOutputStride, kInvalidFilter,
655 0, kInvalidFilter, 0, Width(), Height()));
John Koleszar5ca6a362013-01-25 09:47:09 -0800656
John Koleszar557a1b22013-02-20 16:13:01 -0800657 CheckGuardBlocks();
John Koleszar5ca6a362013-01-25 09:47:09 -0800658
John Koleszar557a1b22013-02-20 16:13:01 -0800659 for (int y = 0; y < Height(); ++y)
660 for (int x = 0; x < Width(); ++x)
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700661 ASSERT_EQ(lookup(ref, y * kOutputStride + x),
662 lookup(out, y * kOutputStride + x))
John Koleszar557a1b22013-02-20 16:13:01 -0800663 << "mismatch at (" << x << "," << y << "), "
clang-format3a826f12016-08-11 17:46:05 -0700664 << "filters (" << filter_bank << "," << filter_x << ","
665 << filter_y << ")";
John Koleszar557a1b22013-02-20 16:13:01 -0800666 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800667 }
668 }
669}
670
671TEST_P(ConvolveTest, MatchesReferenceAveragingSubpixelFilter) {
clang-format3a826f12016-08-11 17:46:05 -0700672 uint8_t *const in = input();
673 uint8_t *const out = output();
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700674 uint8_t ref8[kOutputStride * kMaxDimension];
675 uint16_t ref16[kOutputStride * kMaxDimension];
clang-format3a826f12016-08-11 17:46:05 -0700676 uint8_t *ref;
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700677 if (UUT_->use_highbd_ == 0) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700678 ref = ref8;
679 } else {
680 ref = CONVERT_TO_BYTEPTR(ref16);
681 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800682
683 // Populate ref and out with some random data
Yaowu Xuc27fc142016-08-22 16:08:15 -0700684 ::libaom_test::ACMRandom prng;
John Koleszar5ca6a362013-01-25 09:47:09 -0800685 for (int y = 0; y < Height(); ++y) {
686 for (int x = 0; x < Width(); ++x) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700687 uint16_t r;
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700688 if (UUT_->use_highbd_ == 0 || UUT_->use_highbd_ == 8) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700689 r = prng.Rand8Extremes();
690 } else {
691 r = prng.Rand16() & mask_;
692 }
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700693 assign_val(out, y * kOutputStride + x, r);
694 assign_val(ref, y * kOutputStride + x, r);
John Koleszar5ca6a362013-01-25 09:47:09 -0800695 }
696 }
697
John Koleszar557a1b22013-02-20 16:13:01 -0800698 for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
Urvang Joshia9b174b2017-02-17 11:50:12 -0800699 const InterpFilter filter = (InterpFilter)filter_bank;
Dmitry Kovalev3d4ed272014-04-21 14:15:35 -0700700 const InterpKernel *filters =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800701 (const InterpKernel *)av1_get_interp_filter_kernel(filter);
Angie Chiangb1372892016-12-01 15:06:06 -0800702 const InterpFilterParams filter_params =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800703 av1_get_interp_filter_params(filter);
Angie Chiangb1372892016-12-01 15:06:06 -0800704 if (filter_params.taps != SUBPEL_TAPS) continue;
John Koleszar5ca6a362013-01-25 09:47:09 -0800705
John Koleszar557a1b22013-02-20 16:13:01 -0800706 for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) {
707 for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) {
clang-format3a826f12016-08-11 17:46:05 -0700708 wrapper_filter_average_block2d_8_c(in, kInputStride, filters[filter_x],
709 filters[filter_y], ref,
710 kOutputStride, Width(), Height());
John Koleszar5ca6a362013-01-25 09:47:09 -0800711
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700712 if (filter_x && filter_y)
clang-format3a826f12016-08-11 17:46:05 -0700713 ASM_REGISTER_STATE_CHECK(UUT_->hv8_avg_(
714 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
715 filters[filter_y], 16, Width(), Height()));
John Koleszar557a1b22013-02-20 16:13:01 -0800716 else if (filter_y)
clang-format3a826f12016-08-11 17:46:05 -0700717 ASM_REGISTER_STATE_CHECK(UUT_->v8_avg_(
718 in, kInputStride, out, kOutputStride, kInvalidFilter, 16,
719 filters[filter_y], 16, Width(), Height()));
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700720 else if (filter_x)
clang-format3a826f12016-08-11 17:46:05 -0700721 ASM_REGISTER_STATE_CHECK(UUT_->h8_avg_(
722 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
723 kInvalidFilter, 16, Width(), Height()));
John Koleszar557a1b22013-02-20 16:13:01 -0800724 else
James Zern29e1b1a2014-07-09 21:02:02 -0700725 ASM_REGISTER_STATE_CHECK(
clang-format3a826f12016-08-11 17:46:05 -0700726 UUT_->avg_(in, kInputStride, out, kOutputStride, kInvalidFilter,
727 0, kInvalidFilter, 0, Width(), Height()));
John Koleszar5ca6a362013-01-25 09:47:09 -0800728
John Koleszar557a1b22013-02-20 16:13:01 -0800729 CheckGuardBlocks();
John Koleszar5ca6a362013-01-25 09:47:09 -0800730
John Koleszar557a1b22013-02-20 16:13:01 -0800731 for (int y = 0; y < Height(); ++y)
732 for (int x = 0; x < Width(); ++x)
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700733 ASSERT_EQ(lookup(ref, y * kOutputStride + x),
734 lookup(out, y * kOutputStride + x))
John Koleszar557a1b22013-02-20 16:13:01 -0800735 << "mismatch at (" << x << "," << y << "), "
clang-format3a826f12016-08-11 17:46:05 -0700736 << "filters (" << filter_bank << "," << filter_x << ","
737 << filter_y << ")";
John Koleszar557a1b22013-02-20 16:13:01 -0800738 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800739 }
740 }
741}
742
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700743TEST_P(ConvolveTest, FilterExtremes) {
744 uint8_t *const in = input();
745 uint8_t *const out = output();
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700746 uint8_t ref8[kOutputStride * kMaxDimension];
747 uint16_t ref16[kOutputStride * kMaxDimension];
748 uint8_t *ref;
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700749 if (UUT_->use_highbd_ == 0) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700750 ref = ref8;
751 } else {
752 ref = CONVERT_TO_BYTEPTR(ref16);
753 }
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700754
755 // Populate ref and out with some random data
Yaowu Xuc27fc142016-08-22 16:08:15 -0700756 ::libaom_test::ACMRandom prng;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700757 for (int y = 0; y < Height(); ++y) {
758 for (int x = 0; x < Width(); ++x) {
759 uint16_t r;
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700760 if (UUT_->use_highbd_ == 0 || UUT_->use_highbd_ == 8) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700761 r = prng.Rand8Extremes();
762 } else {
763 r = prng.Rand16() & mask_;
764 }
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700765 assign_val(out, y * kOutputStride + x, r);
766 assign_val(ref, y * kOutputStride + x, r);
767 }
768 }
769
770 for (int axis = 0; axis < 2; axis++) {
771 int seed_val = 0;
772 while (seed_val < 256) {
773 for (int y = 0; y < 8; ++y) {
774 for (int x = 0; x < 8; ++x) {
clang-format3a826f12016-08-11 17:46:05 -0700775 assign_val(in, y * kOutputStride + x - SUBPEL_TAPS / 2 + 1,
776 ((seed_val >> (axis ? y : x)) & 1) * mask_);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700777 if (axis) seed_val++;
778 }
779 if (axis)
clang-format3a826f12016-08-11 17:46:05 -0700780 seed_val -= 8;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700781 else
782 seed_val++;
783 }
784 if (axis) seed_val += 8;
785
786 for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
Urvang Joshia9b174b2017-02-17 11:50:12 -0800787 const InterpFilter filter = (InterpFilter)filter_bank;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700788 const InterpKernel *filters =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800789 (const InterpKernel *)av1_get_interp_filter_kernel(filter);
Angie Chiangb1372892016-12-01 15:06:06 -0800790 const InterpFilterParams filter_params =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800791 av1_get_interp_filter_params(filter);
Angie Chiangb1372892016-12-01 15:06:06 -0800792 if (filter_params.taps != SUBPEL_TAPS) continue;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700793 for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) {
794 for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) {
clang-format3a826f12016-08-11 17:46:05 -0700795 wrapper_filter_block2d_8_c(in, kInputStride, filters[filter_x],
796 filters[filter_y], ref, kOutputStride,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700797 Width(), Height());
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700798 if (filter_x && filter_y)
clang-format3a826f12016-08-11 17:46:05 -0700799 ASM_REGISTER_STATE_CHECK(UUT_->hv8_(
800 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
801 filters[filter_y], 16, Width(), Height()));
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700802 else if (filter_y)
clang-format3a826f12016-08-11 17:46:05 -0700803 ASM_REGISTER_STATE_CHECK(UUT_->v8_(
804 in, kInputStride, out, kOutputStride, kInvalidFilter, 16,
805 filters[filter_y], 16, Width(), Height()));
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700806 else if (filter_x)
clang-format3a826f12016-08-11 17:46:05 -0700807 ASM_REGISTER_STATE_CHECK(UUT_->h8_(
808 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
809 kInvalidFilter, 16, Width(), Height()));
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700810 else
clang-format3a826f12016-08-11 17:46:05 -0700811 ASM_REGISTER_STATE_CHECK(UUT_->copy_(
812 in, kInputStride, out, kOutputStride, kInvalidFilter, 0,
813 kInvalidFilter, 0, Width(), Height()));
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700814
815 for (int y = 0; y < Height(); ++y)
816 for (int x = 0; x < Width(); ++x)
817 ASSERT_EQ(lookup(ref, y * kOutputStride + x),
818 lookup(out, y * kOutputStride + x))
819 << "mismatch at (" << x << "," << y << "), "
clang-format3a826f12016-08-11 17:46:05 -0700820 << "filters (" << filter_bank << "," << filter_x << ","
821 << filter_y << ")";
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700822 }
823 }
824 }
825 }
826 }
827}
828
Tero Rintaluomae326cec2013-08-22 11:29:19 +0300829/* This test exercises that enough rows and columns are filtered with every
830 possible initial fractional positions and scaling steps. */
831TEST_P(ConvolveTest, CheckScalingFiltering) {
clang-format3a826f12016-08-11 17:46:05 -0700832 uint8_t *const in = input();
833 uint8_t *const out = output();
Angie Chiangb1372892016-12-01 15:06:06 -0800834 const InterpKernel *const eighttap =
835 (const InterpKernel *)av1_get_interp_filter_kernel(EIGHTTAP_REGULAR);
Tero Rintaluomae326cec2013-08-22 11:29:19 +0300836
837 SetConstantInput(127);
838
839 for (int frac = 0; frac < 16; ++frac) {
840 for (int step = 1; step <= 32; ++step) {
841 /* Test the horizontal and vertical filters in combination. */
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700842 ASM_REGISTER_STATE_CHECK(UUT_->shv8_(in, kInputStride, out, kOutputStride,
clang-format3a826f12016-08-11 17:46:05 -0700843 eighttap[frac], step, eighttap[frac],
844 step, Width(), Height()));
Tero Rintaluomae326cec2013-08-22 11:29:19 +0300845
846 CheckGuardBlocks();
847
848 for (int y = 0; y < Height(); ++y) {
849 for (int x = 0; x < Width(); ++x) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700850 ASSERT_EQ(lookup(in, y * kInputStride + x),
851 lookup(out, y * kOutputStride + x))
clang-format3a826f12016-08-11 17:46:05 -0700852 << "x == " << x << ", y == " << y << ", frac == " << frac
853 << ", step == " << step;
Tero Rintaluomae326cec2013-08-22 11:29:19 +0300854 }
855 }
856 }
857 }
858}
859
Yi Luoa4d87992017-04-14 17:44:26 -0700860TEST_P(ConvolveTest, DISABLED_Copy_Speed) {
861 const uint8_t *const in = input();
862 uint8_t *const out = output();
863 const int kNumTests = 5000000;
864 const int width = Width();
865 const int height = Height();
866 aom_usec_timer timer;
867
868 aom_usec_timer_start(&timer);
869 for (int n = 0; n < kNumTests; ++n) {
870 UUT_->copy_(in, kInputStride, out, kOutputStride, NULL, 0, NULL, 0, width,
871 height);
872 }
873 aom_usec_timer_mark(&timer);
874
875 const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
876 printf("convolve_copy_%dx%d_%d: %d us\n", width, height,
877 UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
878}
879
880TEST_P(ConvolveTest, DISABLED_Avg_Speed) {
881 const uint8_t *const in = input();
882 uint8_t *const out = output();
883 const int kNumTests = 5000000;
884 const int width = Width();
885 const int height = Height();
886 aom_usec_timer timer;
887
888 aom_usec_timer_start(&timer);
889 for (int n = 0; n < kNumTests; ++n) {
890 UUT_->avg_(in, kInputStride, out, kOutputStride, NULL, 0, NULL, 0, width,
891 height);
892 }
893 aom_usec_timer_mark(&timer);
894
895 const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
896 printf("convolve_avg_%dx%d_%d: %d us\n", width, height,
897 UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
898}
899
Yi Luo9d247352017-03-16 12:31:46 -0700900TEST_P(ConvolveTest, DISABLED_Speed) {
901 uint8_t *const in = input();
902 uint8_t *const out = output();
Yi Luo9d247352017-03-16 12:31:46 -0700903 uint8_t ref8[kOutputStride * kMaxDimension];
904 uint16_t ref16[kOutputStride * kMaxDimension];
905 uint8_t *ref;
906 if (UUT_->use_highbd_ == 0) {
907 ref = ref8;
908 } else {
909 ref = CONVERT_TO_BYTEPTR(ref16);
910 }
Yi Luo9d247352017-03-16 12:31:46 -0700911
912 // Populate ref and out with some random data
913 ::libaom_test::ACMRandom prng;
914 for (int y = 0; y < Height(); ++y) {
915 for (int x = 0; x < Width(); ++x) {
916 uint16_t r;
Yi Luo9d247352017-03-16 12:31:46 -0700917 if (UUT_->use_highbd_ == 0 || UUT_->use_highbd_ == 8) {
918 r = prng.Rand8Extremes();
919 } else {
920 r = prng.Rand16() & mask_;
921 }
Yi Luo9d247352017-03-16 12:31:46 -0700922 assign_val(out, y * kOutputStride + x, r);
923 assign_val(ref, y * kOutputStride + x, r);
924 }
925 }
926
927 const InterpFilter filter = (InterpFilter)1;
928 const InterpKernel *filters =
929 (const InterpKernel *)av1_get_interp_filter_kernel(filter);
930 wrapper_filter_average_block2d_8_c(in, kInputStride, filters[1], filters[1],
931 out, kOutputStride, Width(), Height());
932
933 aom_usec_timer timer;
934 int tests_num = 1000;
935
936 aom_usec_timer_start(&timer);
937 while (tests_num > 0) {
938 for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
939 const InterpFilter filter = (InterpFilter)filter_bank;
940 const InterpKernel *filters =
941 (const InterpKernel *)av1_get_interp_filter_kernel(filter);
Yi Luo9d247352017-03-16 12:31:46 -0700942 const InterpFilterParams filter_params =
943 av1_get_interp_filter_params(filter);
944 if (filter_params.taps != SUBPEL_TAPS) continue;
Yi Luo9d247352017-03-16 12:31:46 -0700945
946 for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) {
947 for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) {
948 if (filter_x && filter_y)
949 ASM_REGISTER_STATE_CHECK(UUT_->hv8_(
950 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
951 filters[filter_y], 16, Width(), Height()));
952 if (filter_y)
953 ASM_REGISTER_STATE_CHECK(
954 UUT_->v8_(in, kInputStride, out, kOutputStride, kInvalidFilter,
955 16, filters[filter_y], 16, Width(), Height()));
956 else if (filter_x)
957 ASM_REGISTER_STATE_CHECK(UUT_->h8_(
958 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
959 kInvalidFilter, 16, Width(), Height()));
960 }
961 }
962 }
963 tests_num--;
964 }
965 aom_usec_timer_mark(&timer);
966
967 const int elapsed_time =
968 static_cast<int>(aom_usec_timer_elapsed(&timer) / 1000);
969 printf("%dx%d (bitdepth %d) time: %5d ms\n", Width(), Height(),
970 UUT_->use_highbd_, elapsed_time);
971}
972
John Koleszar5ca6a362013-01-25 09:47:09 -0800973using std::tr1::make_tuple;
974
clang-format3a826f12016-08-11 17:46:05 -0700975#define WRAP(func, bd) \
976 void wrap_##func##_##bd( \
977 const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, \
978 ptrdiff_t dst_stride, const int16_t *filter_x, int filter_x_stride, \
979 const int16_t *filter_y, int filter_y_stride, int w, int h) { \
Yaowu Xuf883b422016-08-30 14:01:10 -0700980 aom_highbd_##func(src, src_stride, dst, dst_stride, filter_x, \
clang-format3a826f12016-08-11 17:46:05 -0700981 filter_x_stride, filter_y, filter_y_stride, w, h, bd); \
982 }
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700983#if HAVE_SSE2 && ARCH_X86_64
Alex Converse0c00af12015-10-06 15:59:03 -0700984WRAP(convolve_copy_sse2, 8)
985WRAP(convolve_avg_sse2, 8)
986WRAP(convolve_copy_sse2, 10)
987WRAP(convolve_avg_sse2, 10)
988WRAP(convolve_copy_sse2, 12)
989WRAP(convolve_avg_sse2, 12)
Alex Converse7e779382015-10-09 11:42:05 -0700990WRAP(convolve8_horiz_sse2, 8)
991WRAP(convolve8_avg_horiz_sse2, 8)
992WRAP(convolve8_vert_sse2, 8)
993WRAP(convolve8_avg_vert_sse2, 8)
994WRAP(convolve8_sse2, 8)
995WRAP(convolve8_avg_sse2, 8)
996WRAP(convolve8_horiz_sse2, 10)
997WRAP(convolve8_avg_horiz_sse2, 10)
998WRAP(convolve8_vert_sse2, 10)
999WRAP(convolve8_avg_vert_sse2, 10)
1000WRAP(convolve8_sse2, 10)
1001WRAP(convolve8_avg_sse2, 10)
1002WRAP(convolve8_horiz_sse2, 12)
1003WRAP(convolve8_avg_horiz_sse2, 12)
1004WRAP(convolve8_vert_sse2, 12)
1005WRAP(convolve8_avg_vert_sse2, 12)
1006WRAP(convolve8_sse2, 12)
1007WRAP(convolve8_avg_sse2, 12)
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001008#endif // HAVE_SSE2 && ARCH_X86_64
1009
Alex Converse7e779382015-10-09 11:42:05 -07001010WRAP(convolve_copy_c, 8)
1011WRAP(convolve_avg_c, 8)
1012WRAP(convolve8_horiz_c, 8)
1013WRAP(convolve8_avg_horiz_c, 8)
1014WRAP(convolve8_vert_c, 8)
1015WRAP(convolve8_avg_vert_c, 8)
1016WRAP(convolve8_c, 8)
1017WRAP(convolve8_avg_c, 8)
1018WRAP(convolve_copy_c, 10)
1019WRAP(convolve_avg_c, 10)
1020WRAP(convolve8_horiz_c, 10)
1021WRAP(convolve8_avg_horiz_c, 10)
1022WRAP(convolve8_vert_c, 10)
1023WRAP(convolve8_avg_vert_c, 10)
1024WRAP(convolve8_c, 10)
1025WRAP(convolve8_avg_c, 10)
1026WRAP(convolve_copy_c, 12)
1027WRAP(convolve_avg_c, 12)
1028WRAP(convolve8_horiz_c, 12)
1029WRAP(convolve8_avg_horiz_c, 12)
1030WRAP(convolve8_vert_c, 12)
1031WRAP(convolve8_avg_vert_c, 12)
1032WRAP(convolve8_c, 12)
1033WRAP(convolve8_avg_c, 12)
Yi Luo9d247352017-03-16 12:31:46 -07001034
1035#if HAVE_AVX2
1036WRAP(convolve_copy_avx2, 8)
1037WRAP(convolve_avg_avx2, 8)
1038WRAP(convolve8_horiz_avx2, 8)
1039WRAP(convolve8_avg_horiz_avx2, 8)
1040WRAP(convolve8_vert_avx2, 8)
1041WRAP(convolve8_avg_vert_avx2, 8)
1042WRAP(convolve8_avx2, 8)
1043WRAP(convolve8_avg_avx2, 8)
1044
1045WRAP(convolve_copy_avx2, 10)
1046WRAP(convolve_avg_avx2, 10)
1047WRAP(convolve8_avx2, 10)
1048WRAP(convolve8_horiz_avx2, 10)
1049WRAP(convolve8_vert_avx2, 10)
1050WRAP(convolve8_avg_avx2, 10)
1051WRAP(convolve8_avg_horiz_avx2, 10)
1052WRAP(convolve8_avg_vert_avx2, 10)
1053
1054WRAP(convolve_copy_avx2, 12)
1055WRAP(convolve_avg_avx2, 12)
1056WRAP(convolve8_avx2, 12)
1057WRAP(convolve8_horiz_avx2, 12)
1058WRAP(convolve8_vert_avx2, 12)
1059WRAP(convolve8_avg_avx2, 12)
1060WRAP(convolve8_avg_horiz_avx2, 12)
1061WRAP(convolve8_avg_vert_avx2, 12)
1062#endif // HAVE_AVX2
1063
Alex Converse7e779382015-10-09 11:42:05 -07001064#undef WRAP
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001065
1066const ConvolveFunctions convolve8_c(
clang-format3a826f12016-08-11 17:46:05 -07001067 wrap_convolve_copy_c_8, wrap_convolve_avg_c_8, wrap_convolve8_horiz_c_8,
1068 wrap_convolve8_avg_horiz_c_8, wrap_convolve8_vert_c_8,
1069 wrap_convolve8_avg_vert_c_8, wrap_convolve8_c_8, wrap_convolve8_avg_c_8,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001070 wrap_convolve8_horiz_c_8, wrap_convolve8_avg_horiz_c_8,
clang-format3a826f12016-08-11 17:46:05 -07001071 wrap_convolve8_vert_c_8, wrap_convolve8_avg_vert_c_8, wrap_convolve8_c_8,
1072 wrap_convolve8_avg_c_8, 8);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001073const ConvolveFunctions convolve10_c(
clang-format3a826f12016-08-11 17:46:05 -07001074 wrap_convolve_copy_c_10, wrap_convolve_avg_c_10, wrap_convolve8_horiz_c_10,
1075 wrap_convolve8_avg_horiz_c_10, wrap_convolve8_vert_c_10,
1076 wrap_convolve8_avg_vert_c_10, wrap_convolve8_c_10, wrap_convolve8_avg_c_10,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001077 wrap_convolve8_horiz_c_10, wrap_convolve8_avg_horiz_c_10,
clang-format3a826f12016-08-11 17:46:05 -07001078 wrap_convolve8_vert_c_10, wrap_convolve8_avg_vert_c_10, wrap_convolve8_c_10,
1079 wrap_convolve8_avg_c_10, 10);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001080const ConvolveFunctions convolve12_c(
clang-format3a826f12016-08-11 17:46:05 -07001081 wrap_convolve_copy_c_12, wrap_convolve_avg_c_12, wrap_convolve8_horiz_c_12,
1082 wrap_convolve8_avg_horiz_c_12, wrap_convolve8_vert_c_12,
1083 wrap_convolve8_avg_vert_c_12, wrap_convolve8_c_12, wrap_convolve8_avg_c_12,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001084 wrap_convolve8_horiz_c_12, wrap_convolve8_avg_horiz_c_12,
clang-format3a826f12016-08-11 17:46:05 -07001085 wrap_convolve8_vert_c_12, wrap_convolve8_avg_vert_c_12, wrap_convolve8_c_12,
1086 wrap_convolve8_avg_c_12, 12);
Alex Conversef03e2382016-04-26 18:09:40 -07001087const ConvolveParam kArrayConvolve_c[] = {
clang-format3a826f12016-08-11 17:46:05 -07001088 ALL_SIZES(convolve8_c), ALL_SIZES(convolve10_c), ALL_SIZES(convolve12_c)
Alex Conversef03e2382016-04-26 18:09:40 -07001089};
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001090
clang-format3a826f12016-08-11 17:46:05 -07001091INSTANTIATE_TEST_CASE_P(C, ConvolveTest, ::testing::ValuesIn(kArrayConvolve_c));
John Koleszar29d47ac2013-02-07 17:00:37 -08001092
Deb Mukherjee10783d42014-09-02 16:34:09 -07001093#if HAVE_SSE2 && ARCH_X86_64
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001094const ConvolveFunctions convolve8_sse2(
Alex Converse0c00af12015-10-06 15:59:03 -07001095 wrap_convolve_copy_sse2_8, wrap_convolve_avg_sse2_8,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001096 wrap_convolve8_horiz_sse2_8, wrap_convolve8_avg_horiz_sse2_8,
1097 wrap_convolve8_vert_sse2_8, wrap_convolve8_avg_vert_sse2_8,
Scott LaVarnway4e6b5072015-08-05 10:47:06 -07001098 wrap_convolve8_sse2_8, wrap_convolve8_avg_sse2_8,
1099 wrap_convolve8_horiz_sse2_8, wrap_convolve8_avg_horiz_sse2_8,
1100 wrap_convolve8_vert_sse2_8, wrap_convolve8_avg_vert_sse2_8,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001101 wrap_convolve8_sse2_8, wrap_convolve8_avg_sse2_8, 8);
Deb Mukherjee27dce0f2014-11-07 10:19:46 -08001102const ConvolveFunctions convolve10_sse2(
Alex Converse0c00af12015-10-06 15:59:03 -07001103 wrap_convolve_copy_sse2_10, wrap_convolve_avg_sse2_10,
Deb Mukherjee27dce0f2014-11-07 10:19:46 -08001104 wrap_convolve8_horiz_sse2_10, wrap_convolve8_avg_horiz_sse2_10,
1105 wrap_convolve8_vert_sse2_10, wrap_convolve8_avg_vert_sse2_10,
Scott LaVarnway4e6b5072015-08-05 10:47:06 -07001106 wrap_convolve8_sse2_10, wrap_convolve8_avg_sse2_10,
1107 wrap_convolve8_horiz_sse2_10, wrap_convolve8_avg_horiz_sse2_10,
1108 wrap_convolve8_vert_sse2_10, wrap_convolve8_avg_vert_sse2_10,
Deb Mukherjee27dce0f2014-11-07 10:19:46 -08001109 wrap_convolve8_sse2_10, wrap_convolve8_avg_sse2_10, 10);
1110const ConvolveFunctions convolve12_sse2(
Alex Converse0c00af12015-10-06 15:59:03 -07001111 wrap_convolve_copy_sse2_12, wrap_convolve_avg_sse2_12,
Deb Mukherjee27dce0f2014-11-07 10:19:46 -08001112 wrap_convolve8_horiz_sse2_12, wrap_convolve8_avg_horiz_sse2_12,
1113 wrap_convolve8_vert_sse2_12, wrap_convolve8_avg_vert_sse2_12,
Scott LaVarnway4e6b5072015-08-05 10:47:06 -07001114 wrap_convolve8_sse2_12, wrap_convolve8_avg_sse2_12,
1115 wrap_convolve8_horiz_sse2_12, wrap_convolve8_avg_horiz_sse2_12,
1116 wrap_convolve8_vert_sse2_12, wrap_convolve8_avg_vert_sse2_12,
Deb Mukherjee27dce0f2014-11-07 10:19:46 -08001117 wrap_convolve8_sse2_12, wrap_convolve8_avg_sse2_12, 12);
clang-format3a826f12016-08-11 17:46:05 -07001118const ConvolveParam kArrayConvolve_sse2[] = { ALL_SIZES(convolve8_sse2),
1119 ALL_SIZES(convolve10_sse2),
1120 ALL_SIZES(convolve12_sse2) };
Alex Conversef03e2382016-04-26 18:09:40 -07001121INSTANTIATE_TEST_CASE_P(SSE2, ConvolveTest,
1122 ::testing::ValuesIn(kArrayConvolve_sse2));
Deb Mukherjee10783d42014-09-02 16:34:09 -07001123#endif
Yunqing Wang3fb728c2013-10-10 13:51:35 -07001124
John Koleszar29d47ac2013-02-07 17:00:37 -08001125#if HAVE_SSSE3
1126const ConvolveFunctions convolve8_ssse3(
Yaowu Xuf883b422016-08-30 14:01:10 -07001127 aom_convolve_copy_c, aom_convolve_avg_c, aom_convolve8_horiz_ssse3,
1128 aom_convolve8_avg_horiz_ssse3, aom_convolve8_vert_ssse3,
1129 aom_convolve8_avg_vert_ssse3, aom_convolve8_ssse3, aom_convolve8_avg_ssse3,
1130 aom_scaled_horiz_c, aom_scaled_avg_horiz_c, aom_scaled_vert_c,
1131 aom_scaled_avg_vert_c, aom_scaled_2d_ssse3, aom_scaled_avg_2d_c, 0);
John Koleszar29d47ac2013-02-07 17:00:37 -08001132
Alex Conversef03e2382016-04-26 18:09:40 -07001133const ConvolveParam kArrayConvolve8_ssse3[] = { ALL_SIZES(convolve8_ssse3) };
1134INSTANTIATE_TEST_CASE_P(SSSE3, ConvolveTest,
1135 ::testing::ValuesIn(kArrayConvolve8_ssse3));
John Koleszar29d47ac2013-02-07 17:00:37 -08001136#endif
Johann158c80c2013-05-23 12:50:41 -07001137
Yi Luo9d247352017-03-16 12:31:46 -07001138#if HAVE_AVX2
Yi Luo9d247352017-03-16 12:31:46 -07001139const ConvolveFunctions convolve8_avx2(
1140 wrap_convolve_copy_avx2_8, wrap_convolve_avg_avx2_8,
1141 wrap_convolve8_horiz_avx2_8, wrap_convolve8_avg_horiz_avx2_8,
1142 wrap_convolve8_vert_avx2_8, wrap_convolve8_avg_vert_avx2_8,
1143 wrap_convolve8_avx2_8, wrap_convolve8_avg_avx2_8, wrap_convolve8_horiz_c_8,
1144 wrap_convolve8_avg_horiz_c_8, wrap_convolve8_vert_c_8,
1145 wrap_convolve8_avg_vert_c_8, wrap_convolve8_c_8, wrap_convolve8_avg_c_8, 8);
1146const ConvolveFunctions convolve10_avx2(
1147 wrap_convolve_copy_avx2_10, wrap_convolve_avg_avx2_10,
1148 wrap_convolve8_horiz_avx2_10, wrap_convolve8_avg_horiz_avx2_10,
1149 wrap_convolve8_vert_avx2_10, wrap_convolve8_avg_vert_avx2_10,
1150 wrap_convolve8_avx2_10, wrap_convolve8_avg_avx2_10,
1151 wrap_convolve8_horiz_c_10, wrap_convolve8_avg_horiz_c_10,
1152 wrap_convolve8_vert_c_10, wrap_convolve8_avg_vert_c_10, wrap_convolve8_c_10,
1153 wrap_convolve8_avg_c_10, 10);
1154const ConvolveFunctions convolve12_avx2(
1155 wrap_convolve_copy_avx2_12, wrap_convolve_avg_avx2_12,
1156 wrap_convolve8_horiz_avx2_12, wrap_convolve8_avg_horiz_avx2_12,
1157 wrap_convolve8_vert_avx2_12, wrap_convolve8_avg_vert_avx2_12,
1158 wrap_convolve8_avx2_12, wrap_convolve8_avg_avx2_12,
1159 wrap_convolve8_horiz_c_12, wrap_convolve8_avg_horiz_c_12,
1160 wrap_convolve8_vert_c_12, wrap_convolve8_avg_vert_c_12, wrap_convolve8_c_12,
1161 wrap_convolve8_avg_c_12, 12);
Debargha Mukherjee7a160ac2017-10-07 22:29:43 -07001162const ConvolveParam kArrayConvolve8_avx2[] = { ALL_SIZES_64(convolve8_avx2),
1163 ALL_SIZES_64(convolve10_avx2),
1164 ALL_SIZES_64(convolve12_avx2) };
Alex Conversef03e2382016-04-26 18:09:40 -07001165INSTANTIATE_TEST_CASE_P(AVX2, ConvolveTest,
1166 ::testing::ValuesIn(kArrayConvolve8_avx2));
Yi Luo9d247352017-03-16 12:31:46 -07001167#endif // HAVE_AVX2
Yunqing Wang4f0943b2014-05-27 10:36:56 -07001168
Geza Lore938b8df2016-03-04 15:55:48 +00001169// TODO(any): Make NEON versions support 128x128 128x64 64x128 block sizes
Debargha Mukherjee2ccf4b92018-02-27 17:30:46 -08001170#if HAVE_NEON && !(CONFIG_AV1)
Johannce239312014-05-07 11:01:31 -07001171#if HAVE_NEON_ASM
Johann158c80c2013-05-23 12:50:41 -07001172const ConvolveFunctions convolve8_neon(
Yaowu Xuf883b422016-08-30 14:01:10 -07001173 aom_convolve_copy_neon, aom_convolve_avg_neon, aom_convolve8_horiz_neon,
1174 aom_convolve8_avg_horiz_neon, aom_convolve8_vert_neon,
1175 aom_convolve8_avg_vert_neon, aom_convolve8_neon, aom_convolve8_avg_neon,
1176 aom_scaled_horiz_c, aom_scaled_avg_horiz_c, aom_scaled_vert_c,
1177 aom_scaled_avg_vert_c, aom_scaled_2d_c, aom_scaled_avg_2d_c, 0);
clang-format3a826f12016-08-11 17:46:05 -07001178#else // HAVE_NEON
Scott LaVarnway617382a2014-09-10 09:49:34 -07001179const ConvolveFunctions convolve8_neon(
Yaowu Xuf883b422016-08-30 14:01:10 -07001180 aom_convolve_copy_neon, aom_convolve_avg_neon, aom_convolve8_horiz_neon,
1181 aom_convolve8_avg_horiz_neon, aom_convolve8_vert_neon,
1182 aom_convolve8_avg_vert_neon, aom_convolve8_neon, aom_convolve8_avg_neon,
1183 aom_scaled_horiz_c, aom_scaled_avg_horiz_c, aom_scaled_vert_c,
1184 aom_scaled_avg_vert_c, aom_scaled_2d_c, aom_scaled_avg_2d_c, 0);
Scott LaVarnway617382a2014-09-10 09:49:34 -07001185#endif // HAVE_NEON_ASM
Johann158c80c2013-05-23 12:50:41 -07001186
Debargha Mukherjee7a160ac2017-10-07 22:29:43 -07001187const ConvolveParam kArrayConvolve8_neon[] = { ALL_SIZES_64(convolve8_neon) };
Alex Conversef03e2382016-04-26 18:09:40 -07001188INSTANTIATE_TEST_CASE_P(NEON, ConvolveTest,
1189 ::testing::ValuesIn(kArrayConvolve8_neon));
Debargha Mukherjee2ccf4b92018-02-27 17:30:46 -08001190#endif // HAVE_NEON && !(CONFIG_AV1)
Parag Salasakar40edab52013-09-13 15:18:32 +05301191
Geza Lore938b8df2016-03-04 15:55:48 +00001192// TODO(any): Make DSPR2 versions support 128x128 128x64 64x128 block sizes
Debargha Mukherjee2ccf4b92018-02-27 17:30:46 -08001193#if HAVE_DSPR2 && !(CONFIG_AV1)
Parag Salasakar40edab52013-09-13 15:18:32 +05301194const ConvolveFunctions convolve8_dspr2(
Yaowu Xuf883b422016-08-30 14:01:10 -07001195 aom_convolve_copy_dspr2, aom_convolve_avg_dspr2, aom_convolve8_horiz_dspr2,
1196 aom_convolve8_avg_horiz_dspr2, aom_convolve8_vert_dspr2,
1197 aom_convolve8_avg_vert_dspr2, aom_convolve8_dspr2, aom_convolve8_avg_dspr2,
1198 aom_scaled_horiz_c, aom_scaled_avg_horiz_c, aom_scaled_vert_c,
1199 aom_scaled_avg_vert_c, aom_scaled_2d_c, aom_scaled_avg_2d_c, 0);
Parag Salasakar40edab52013-09-13 15:18:32 +05301200
Debargha Mukherjee7a160ac2017-10-07 22:29:43 -07001201const ConvolveParam kArrayConvolve8_dspr2[] = { ALL_SIZES_64(convolve8_dspr2) };
Alex Conversef03e2382016-04-26 18:09:40 -07001202INSTANTIATE_TEST_CASE_P(DSPR2, ConvolveTest,
1203 ::testing::ValuesIn(kArrayConvolve8_dspr2));
Debargha Mukherjee2ccf4b92018-02-27 17:30:46 -08001204#endif // HAVE_DSPR2 && !(CONFIG_AV1)
Parag Salasakar27d083c2015-04-16 11:03:24 +05301205
Geza Lore938b8df2016-03-04 15:55:48 +00001206// TODO(any): Make MSA versions support 128x128 128x64 64x128 block sizes
Debargha Mukherjee2ccf4b92018-02-27 17:30:46 -08001207#if HAVE_MSA && !(CONFIG_AV1)
Parag Salasakar27d083c2015-04-16 11:03:24 +05301208const ConvolveFunctions convolve8_msa(
Yaowu Xuf883b422016-08-30 14:01:10 -07001209 aom_convolve_copy_msa, aom_convolve_avg_msa, aom_convolve8_horiz_msa,
1210 aom_convolve8_avg_horiz_msa, aom_convolve8_vert_msa,
1211 aom_convolve8_avg_vert_msa, aom_convolve8_msa, aom_convolve8_avg_msa,
1212 aom_scaled_horiz_c, aom_scaled_avg_horiz_c, aom_scaled_vert_c,
1213 aom_scaled_avg_vert_c, aom_scaled_2d_c, aom_scaled_avg_2d_c, 0);
Parag Salasakar27d083c2015-04-16 11:03:24 +05301214
Debargha Mukherjee7a160ac2017-10-07 22:29:43 -07001215const ConvolveParam kArrayConvolve8_msa[] = { ALL_SIZES_64(convolve8_msa) };
Alex Conversef03e2382016-04-26 18:09:40 -07001216INSTANTIATE_TEST_CASE_P(MSA, ConvolveTest,
1217 ::testing::ValuesIn(kArrayConvolve8_msa));
Debargha Mukherjee2ccf4b92018-02-27 17:30:46 -08001218#endif // HAVE_MSA && !(CONFIG_AV1)
James Zern8fb48af2013-05-02 13:08:19 -07001219} // namespace