blob: 3ce9091a213eb033779ea57943cca8602707325d [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.
10*/
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"
Angie Chiangb1372892016-12-01 15:06:06 -080026#include "av1/common/filter.h"
John Koleszar5ca6a362013-01-25 09:47:09 -080027
28namespace {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -070029
Geza Lore552d5cd2016-03-07 13:46:39 +000030static const unsigned int kMaxDimension = MAX_SB_SIZE;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -070031
James Zerndfc4e8f2014-07-16 18:48:20 -070032typedef void (*ConvolveFunc)(const uint8_t *src, ptrdiff_t src_stride,
33 uint8_t *dst, ptrdiff_t dst_stride,
34 const int16_t *filter_x, int filter_x_stride,
35 const int16_t *filter_y, int filter_y_stride,
36 int w, int h);
John Koleszar5ca6a362013-01-25 09:47:09 -080037
38struct ConvolveFunctions {
clang-format3a826f12016-08-11 17:46:05 -070039 ConvolveFunctions(ConvolveFunc copy, ConvolveFunc avg, ConvolveFunc h8,
40 ConvolveFunc h8_avg, ConvolveFunc v8, ConvolveFunc v8_avg,
41 ConvolveFunc hv8, ConvolveFunc hv8_avg, ConvolveFunc sh8,
42 ConvolveFunc sh8_avg, ConvolveFunc sv8,
43 ConvolveFunc sv8_avg, ConvolveFunc shv8,
44 ConvolveFunc shv8_avg, int bd)
Johann1c3594c2014-12-09 12:05:15 -080045 : copy_(copy), avg_(avg), h8_(h8), v8_(v8), hv8_(hv8), h8_avg_(h8_avg),
Scott LaVarnway4e6b5072015-08-05 10:47:06 -070046 v8_avg_(v8_avg), hv8_avg_(hv8_avg), sh8_(sh8), sv8_(sv8), shv8_(shv8),
47 sh8_avg_(sh8_avg), sv8_avg_(sv8_avg), shv8_avg_(shv8_avg),
48 use_highbd_(bd) {}
John Koleszar5ca6a362013-01-25 09:47:09 -080049
Johann1c3594c2014-12-09 12:05:15 -080050 ConvolveFunc copy_;
51 ConvolveFunc avg_;
James Zerndfc4e8f2014-07-16 18:48:20 -070052 ConvolveFunc h8_;
53 ConvolveFunc v8_;
54 ConvolveFunc hv8_;
55 ConvolveFunc h8_avg_;
56 ConvolveFunc v8_avg_;
57 ConvolveFunc hv8_avg_;
clang-format3a826f12016-08-11 17:46:05 -070058 ConvolveFunc sh8_; // scaled horiz
59 ConvolveFunc sv8_; // scaled vert
60 ConvolveFunc shv8_; // scaled horiz/vert
61 ConvolveFunc sh8_avg_; // scaled avg horiz
62 ConvolveFunc sv8_avg_; // scaled avg vert
63 ConvolveFunc shv8_avg_; // scaled avg horiz/vert
Deb Mukherjee1929c9b2014-10-08 12:43:22 -070064 int use_highbd_; // 0 if high bitdepth not used, else the actual bit depth.
John Koleszar5ca6a362013-01-25 09:47:09 -080065};
66
James Zerndfc4e8f2014-07-16 18:48:20 -070067typedef std::tr1::tuple<int, int, const ConvolveFunctions *> ConvolveParam;
Joshua Litt51490e52013-11-18 17:07:55 -080068
Yaowu Xuf883b422016-08-30 14:01:10 -070069#if CONFIG_AV1 && CONFIG_EXT_PARTITION
clang-format3a826f12016-08-11 17:46:05 -070070#define ALL_SIZES(convolve_fn) \
71 make_tuple(128, 64, &convolve_fn), make_tuple(64, 128, &convolve_fn), \
72 make_tuple(128, 128, &convolve_fn), make_tuple(4, 4, &convolve_fn), \
73 make_tuple(8, 4, &convolve_fn), make_tuple(4, 8, &convolve_fn), \
74 make_tuple(8, 8, &convolve_fn), make_tuple(16, 8, &convolve_fn), \
75 make_tuple(8, 16, &convolve_fn), make_tuple(16, 16, &convolve_fn), \
76 make_tuple(32, 16, &convolve_fn), make_tuple(16, 32, &convolve_fn), \
77 make_tuple(32, 32, &convolve_fn), make_tuple(64, 32, &convolve_fn), \
78 make_tuple(32, 64, &convolve_fn), make_tuple(64, 64, &convolve_fn)
Alex Conversef03e2382016-04-26 18:09:40 -070079#else
clang-format3a826f12016-08-11 17:46:05 -070080#define ALL_SIZES(convolve_fn) \
81 make_tuple(4, 4, &convolve_fn), make_tuple(8, 4, &convolve_fn), \
82 make_tuple(4, 8, &convolve_fn), make_tuple(8, 8, &convolve_fn), \
83 make_tuple(16, 8, &convolve_fn), make_tuple(8, 16, &convolve_fn), \
84 make_tuple(16, 16, &convolve_fn), make_tuple(32, 16, &convolve_fn), \
85 make_tuple(16, 32, &convolve_fn), make_tuple(32, 32, &convolve_fn), \
86 make_tuple(64, 32, &convolve_fn), make_tuple(32, 64, &convolve_fn), \
87 make_tuple(64, 64, &convolve_fn)
Yaowu Xuf883b422016-08-30 14:01:10 -070088#endif // CONFIG_AV1 && CONFIG_EXT_PARTITION
Alex Conversef03e2382016-04-26 18:09:40 -070089
John Koleszar5ca6a362013-01-25 09:47:09 -080090// Reference 8-tap subpixel filter, slightly modified to fit into this test.
Yaowu Xuf883b422016-08-30 14:01:10 -070091#define AV1_FILTER_WEIGHT 128
92#define AV1_FILTER_SHIFT 7
clang-format3a826f12016-08-11 17:46:05 -070093uint8_t clip_pixel(int x) { return x < 0 ? 0 : x > 255 ? 255 : x; }
John Koleszar5ca6a362013-01-25 09:47:09 -080094
clang-format3a826f12016-08-11 17:46:05 -070095void filter_block2d_8_c(const uint8_t *src_ptr, const unsigned int src_stride,
96 const int16_t *HFilter, const int16_t *VFilter,
97 uint8_t *dst_ptr, unsigned int dst_stride,
98 unsigned int output_width, unsigned int output_height) {
John Koleszar5ca6a362013-01-25 09:47:09 -080099 // Between passes, we use an intermediate buffer whose height is extended to
100 // have enough horizontally filtered values as input for the vertical pass.
101 // This buffer is allocated to be big enough for the largest block type we
102 // support.
103 const int kInterp_Extend = 4;
104 const unsigned int intermediate_height =
James Zern8fb48af2013-05-02 13:08:19 -0700105 (kInterp_Extend - 1) + output_height + kInterp_Extend;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700106 unsigned int i, j;
John Koleszar5ca6a362013-01-25 09:47:09 -0800107
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700108 // Size of intermediate_buffer is max_intermediate_height * filter_max_width,
109 // where max_intermediate_height = (kInterp_Extend - 1) + filter_max_height
110 // + kInterp_Extend
111 // = 3 + 16 + 4
112 // = 23
113 // and filter_max_width = 16
114 //
clang-format3a826f12016-08-11 17:46:05 -0700115 uint8_t intermediate_buffer[(kMaxDimension + 8) * kMaxDimension];
Tom Finegan6042d682016-05-06 09:43:37 -0700116 const int intermediate_next_stride =
117 1 - static_cast<int>(intermediate_height * output_width);
John Koleszar5ca6a362013-01-25 09:47:09 -0800118
119 // Horizontal pass (src -> transposed intermediate).
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700120 uint8_t *output_ptr = intermediate_buffer;
121 const int src_next_row_stride = src_stride - output_width;
122 src_ptr -= (kInterp_Extend - 1) * src_stride + (kInterp_Extend - 1);
123 for (i = 0; i < intermediate_height; ++i) {
124 for (j = 0; j < output_width; ++j) {
125 // Apply filter...
clang-format3a826f12016-08-11 17:46:05 -0700126 const int temp = (src_ptr[0] * HFilter[0]) + (src_ptr[1] * HFilter[1]) +
127 (src_ptr[2] * HFilter[2]) + (src_ptr[3] * HFilter[3]) +
128 (src_ptr[4] * HFilter[4]) + (src_ptr[5] * HFilter[5]) +
129 (src_ptr[6] * HFilter[6]) + (src_ptr[7] * HFilter[7]) +
Yaowu Xuf883b422016-08-30 14:01:10 -0700130 (AV1_FILTER_WEIGHT >> 1); // Rounding
John Koleszar5ca6a362013-01-25 09:47:09 -0800131
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700132 // Normalize back to 0-255...
Yaowu Xuf883b422016-08-30 14:01:10 -0700133 *output_ptr = clip_pixel(temp >> AV1_FILTER_SHIFT);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700134 ++src_ptr;
135 output_ptr += intermediate_height;
John Koleszar5ca6a362013-01-25 09:47:09 -0800136 }
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700137 src_ptr += src_next_row_stride;
138 output_ptr += intermediate_next_stride;
John Koleszar5ca6a362013-01-25 09:47:09 -0800139 }
140
141 // Vertical pass (transposed intermediate -> dst).
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700142 src_ptr = intermediate_buffer;
143 const int dst_next_row_stride = dst_stride - output_width;
144 for (i = 0; i < output_height; ++i) {
145 for (j = 0; j < output_width; ++j) {
146 // Apply filter...
clang-format3a826f12016-08-11 17:46:05 -0700147 const int temp = (src_ptr[0] * VFilter[0]) + (src_ptr[1] * VFilter[1]) +
148 (src_ptr[2] * VFilter[2]) + (src_ptr[3] * VFilter[3]) +
149 (src_ptr[4] * VFilter[4]) + (src_ptr[5] * VFilter[5]) +
150 (src_ptr[6] * VFilter[6]) + (src_ptr[7] * VFilter[7]) +
Yaowu Xuf883b422016-08-30 14:01:10 -0700151 (AV1_FILTER_WEIGHT >> 1); // Rounding
John Koleszar5ca6a362013-01-25 09:47:09 -0800152
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700153 // Normalize back to 0-255...
Yaowu Xuf883b422016-08-30 14:01:10 -0700154 *dst_ptr++ = clip_pixel(temp >> AV1_FILTER_SHIFT);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700155 src_ptr += intermediate_height;
John Koleszar5ca6a362013-01-25 09:47:09 -0800156 }
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700157 src_ptr += intermediate_next_stride;
158 dst_ptr += dst_next_row_stride;
John Koleszar5ca6a362013-01-25 09:47:09 -0800159 }
160}
161
clang-format3a826f12016-08-11 17:46:05 -0700162void block2d_average_c(uint8_t *src, unsigned int src_stride,
163 uint8_t *output_ptr, unsigned int output_stride,
164 unsigned int output_width, unsigned int output_height) {
John Koleszar5ca6a362013-01-25 09:47:09 -0800165 unsigned int i, j;
166 for (i = 0; i < output_height; ++i) {
167 for (j = 0; j < output_width; ++j) {
168 output_ptr[j] = (output_ptr[j] + src[i * src_stride + j] + 1) >> 1;
169 }
170 output_ptr += output_stride;
171 }
172}
173
James Zern8fb48af2013-05-02 13:08:19 -0700174void filter_average_block2d_8_c(const uint8_t *src_ptr,
175 const unsigned int src_stride,
clang-format3a826f12016-08-11 17:46:05 -0700176 const int16_t *HFilter, const int16_t *VFilter,
177 uint8_t *dst_ptr, unsigned int dst_stride,
James Zern8fb48af2013-05-02 13:08:19 -0700178 unsigned int output_width,
179 unsigned int output_height) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700180 uint8_t tmp[kMaxDimension * kMaxDimension];
John Koleszar5ca6a362013-01-25 09:47:09 -0800181
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700182 assert(output_width <= kMaxDimension);
183 assert(output_height <= kMaxDimension);
Geza Lore938b8df2016-03-04 15:55:48 +0000184 filter_block2d_8_c(src_ptr, src_stride, HFilter, VFilter, tmp, kMaxDimension,
John Koleszar5ca6a362013-01-25 09:47:09 -0800185 output_width, output_height);
clang-format3a826f12016-08-11 17:46:05 -0700186 block2d_average_c(tmp, kMaxDimension, dst_ptr, dst_stride, output_width,
187 output_height);
John Koleszar5ca6a362013-01-25 09:47:09 -0800188}
189
Yaowu Xuf883b422016-08-30 14:01:10 -0700190#if CONFIG_AOM_HIGHBITDEPTH
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700191void highbd_filter_block2d_8_c(const uint16_t *src_ptr,
192 const unsigned int src_stride,
clang-format3a826f12016-08-11 17:46:05 -0700193 const int16_t *HFilter, const int16_t *VFilter,
194 uint16_t *dst_ptr, unsigned int dst_stride,
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700195 unsigned int output_width,
clang-format3a826f12016-08-11 17:46:05 -0700196 unsigned int output_height, int bd) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700197 // Between passes, we use an intermediate buffer whose height is extended to
198 // have enough horizontally filtered values as input for the vertical pass.
199 // This buffer is allocated to be big enough for the largest block type we
200 // support.
201 const int kInterp_Extend = 4;
202 const unsigned int intermediate_height =
203 (kInterp_Extend - 1) + output_height + kInterp_Extend;
204
205 /* Size of intermediate_buffer is max_intermediate_height * filter_max_width,
206 * where max_intermediate_height = (kInterp_Extend - 1) + filter_max_height
207 * + kInterp_Extend
208 * = 3 + 16 + 4
209 * = 23
210 * and filter_max_width = 16
211 */
clang-format3a826f12016-08-11 17:46:05 -0700212 uint16_t intermediate_buffer[(kMaxDimension + 8) * kMaxDimension];
Tom Finegan9a56a5e2016-05-13 09:42:58 -0700213 const int intermediate_next_stride =
214 1 - static_cast<int>(intermediate_height * output_width);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700215
216 // Horizontal pass (src -> transposed intermediate).
217 {
218 uint16_t *output_ptr = intermediate_buffer;
219 const int src_next_row_stride = src_stride - output_width;
220 unsigned int i, j;
221 src_ptr -= (kInterp_Extend - 1) * src_stride + (kInterp_Extend - 1);
222 for (i = 0; i < intermediate_height; ++i) {
223 for (j = 0; j < output_width; ++j) {
224 // Apply filter...
clang-format3a826f12016-08-11 17:46:05 -0700225 const int temp = (src_ptr[0] * HFilter[0]) + (src_ptr[1] * HFilter[1]) +
226 (src_ptr[2] * HFilter[2]) + (src_ptr[3] * HFilter[3]) +
227 (src_ptr[4] * HFilter[4]) + (src_ptr[5] * HFilter[5]) +
228 (src_ptr[6] * HFilter[6]) + (src_ptr[7] * HFilter[7]) +
Yaowu Xuf883b422016-08-30 14:01:10 -0700229 (AV1_FILTER_WEIGHT >> 1); // Rounding
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700230
231 // Normalize back to 0-255...
Yaowu Xuf883b422016-08-30 14:01:10 -0700232 *output_ptr = clip_pixel_highbd(temp >> AV1_FILTER_SHIFT, bd);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700233 ++src_ptr;
234 output_ptr += intermediate_height;
235 }
236 src_ptr += src_next_row_stride;
237 output_ptr += intermediate_next_stride;
238 }
239 }
240
241 // Vertical pass (transposed intermediate -> dst).
242 {
Urvang Joshi88a03bb2016-10-17 14:34:48 -0700243 const uint16_t *interm_ptr = intermediate_buffer;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700244 const int dst_next_row_stride = dst_stride - output_width;
245 unsigned int i, j;
246 for (i = 0; i < output_height; ++i) {
247 for (j = 0; j < output_width; ++j) {
248 // Apply filter...
Urvang Joshi88a03bb2016-10-17 14:34:48 -0700249 const int temp =
250 (interm_ptr[0] * VFilter[0]) + (interm_ptr[1] * VFilter[1]) +
251 (interm_ptr[2] * VFilter[2]) + (interm_ptr[3] * VFilter[3]) +
252 (interm_ptr[4] * VFilter[4]) + (interm_ptr[5] * VFilter[5]) +
253 (interm_ptr[6] * VFilter[6]) + (interm_ptr[7] * VFilter[7]) +
254 (AV1_FILTER_WEIGHT >> 1); // Rounding
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700255
256 // Normalize back to 0-255...
Yaowu Xuf883b422016-08-30 14:01:10 -0700257 *dst_ptr++ = clip_pixel_highbd(temp >> AV1_FILTER_SHIFT, bd);
Urvang Joshi88a03bb2016-10-17 14:34:48 -0700258 interm_ptr += intermediate_height;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700259 }
Urvang Joshi88a03bb2016-10-17 14:34:48 -0700260 interm_ptr += intermediate_next_stride;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700261 dst_ptr += dst_next_row_stride;
262 }
263 }
264}
265
clang-format3a826f12016-08-11 17:46:05 -0700266void highbd_block2d_average_c(uint16_t *src, unsigned int src_stride,
267 uint16_t *output_ptr, unsigned int output_stride,
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700268 unsigned int output_width,
James Zerncffef112016-02-11 18:27:00 -0800269 unsigned int output_height) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700270 unsigned int i, j;
271 for (i = 0; i < output_height; ++i) {
272 for (j = 0; j < output_width; ++j) {
273 output_ptr[j] = (output_ptr[j] + src[i * src_stride + j] + 1) >> 1;
274 }
275 output_ptr += output_stride;
276 }
277}
278
clang-format3a826f12016-08-11 17:46:05 -0700279void highbd_filter_average_block2d_8_c(
280 const uint16_t *src_ptr, const unsigned int src_stride,
281 const int16_t *HFilter, const int16_t *VFilter, uint16_t *dst_ptr,
282 unsigned int dst_stride, unsigned int output_width,
283 unsigned int output_height, int bd) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700284 uint16_t tmp[kMaxDimension * kMaxDimension];
285
286 assert(output_width <= kMaxDimension);
287 assert(output_height <= kMaxDimension);
clang-format3a826f12016-08-11 17:46:05 -0700288 highbd_filter_block2d_8_c(src_ptr, src_stride, HFilter, VFilter, tmp,
289 kMaxDimension, output_width, output_height, bd);
Geza Lore938b8df2016-03-04 15:55:48 +0000290 highbd_block2d_average_c(tmp, kMaxDimension, dst_ptr, dst_stride,
James Zerncffef112016-02-11 18:27:00 -0800291 output_width, output_height);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700292}
Yaowu Xuf883b422016-08-30 14:01:10 -0700293#endif // CONFIG_AOM_HIGHBITDEPTH
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700294
James Zerndfc4e8f2014-07-16 18:48:20 -0700295class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
John Koleszar29d47ac2013-02-07 17:00:37 -0800296 public:
297 static void SetUpTestCase() {
298 // Force input_ to be unaligned, output to be 16 byte aligned.
clang-format3a826f12016-08-11 17:46:05 -0700299 input_ = reinterpret_cast<uint8_t *>(
Yaowu Xuf883b422016-08-30 14:01:10 -0700300 aom_memalign(kDataAlignment, kInputBufferSize + 1)) +
clang-format3a826f12016-08-11 17:46:05 -0700301 1;
302 output_ = reinterpret_cast<uint8_t *>(
Yaowu Xuf883b422016-08-30 14:01:10 -0700303 aom_memalign(kDataAlignment, kOutputBufferSize));
clang-format3a826f12016-08-11 17:46:05 -0700304 output_ref_ = reinterpret_cast<uint8_t *>(
Yaowu Xuf883b422016-08-30 14:01:10 -0700305 aom_memalign(kDataAlignment, kOutputBufferSize));
306#if CONFIG_AOM_HIGHBITDEPTH
307 input16_ = reinterpret_cast<uint16_t *>(aom_memalign(
clang-format3a826f12016-08-11 17:46:05 -0700308 kDataAlignment, (kInputBufferSize + 1) * sizeof(uint16_t))) +
309 1;
310 output16_ = reinterpret_cast<uint16_t *>(
Yaowu Xuf883b422016-08-30 14:01:10 -0700311 aom_memalign(kDataAlignment, (kOutputBufferSize) * sizeof(uint16_t)));
clang-format3a826f12016-08-11 17:46:05 -0700312 output16_ref_ = reinterpret_cast<uint16_t *>(
Yaowu Xuf883b422016-08-30 14:01:10 -0700313 aom_memalign(kDataAlignment, (kOutputBufferSize) * sizeof(uint16_t)));
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700314#endif
John Koleszar29d47ac2013-02-07 17:00:37 -0800315 }
316
Yaowu Xuc27fc142016-08-22 16:08:15 -0700317 virtual void TearDown() { libaom_test::ClearSystemState(); }
Jim Bankoski18d32362014-12-12 06:18:56 -0800318
John Koleszar29d47ac2013-02-07 17:00:37 -0800319 static void TearDownTestCase() {
Yaowu Xuf883b422016-08-30 14:01:10 -0700320 aom_free(input_ - 1);
John Koleszar29d47ac2013-02-07 17:00:37 -0800321 input_ = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700322 aom_free(output_);
John Koleszar29d47ac2013-02-07 17:00:37 -0800323 output_ = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700324 aom_free(output_ref_);
Johann1c3594c2014-12-09 12:05:15 -0800325 output_ref_ = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700326#if CONFIG_AOM_HIGHBITDEPTH
327 aom_free(input16_ - 1);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700328 input16_ = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700329 aom_free(output16_);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700330 output16_ = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700331 aom_free(output16_ref_);
Johann1c3594c2014-12-09 12:05:15 -0800332 output16_ref_ = NULL;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700333#endif
John Koleszar29d47ac2013-02-07 17:00:37 -0800334 }
335
James Zern8fb48af2013-05-02 13:08:19 -0700336 protected:
337 static const int kDataAlignment = 16;
clang-format3a826f12016-08-11 17:46:05 -0700338 static const int kOuterBlockSize = 4 * kMaxDimension;
James Zern8fb48af2013-05-02 13:08:19 -0700339 static const int kInputStride = kOuterBlockSize;
340 static const int kOutputStride = kOuterBlockSize;
James Zern8fb48af2013-05-02 13:08:19 -0700341 static const int kInputBufferSize = kOuterBlockSize * kOuterBlockSize;
342 static const int kOutputBufferSize = kOuterBlockSize * kOuterBlockSize;
John Koleszar5ca6a362013-01-25 09:47:09 -0800343
James Zern8fb48af2013-05-02 13:08:19 -0700344 int Width() const { return GET_PARAM(0); }
345 int Height() const { return GET_PARAM(1); }
346 int BorderLeft() const {
347 const int center = (kOuterBlockSize - Width()) / 2;
348 return (center + (kDataAlignment - 1)) & ~(kDataAlignment - 1);
349 }
350 int BorderTop() const { return (kOuterBlockSize - Height()) / 2; }
John Koleszar5ca6a362013-01-25 09:47:09 -0800351
James Zern8fb48af2013-05-02 13:08:19 -0700352 bool IsIndexInBorder(int i) {
353 return (i < BorderTop() * kOuterBlockSize ||
354 i >= (BorderTop() + Height()) * kOuterBlockSize ||
355 i % kOuterBlockSize < BorderLeft() ||
356 i % kOuterBlockSize >= (BorderLeft() + Width()));
357 }
358
359 virtual void SetUp() {
360 UUT_ = GET_PARAM(2);
Yaowu Xuf883b422016-08-30 14:01:10 -0700361#if CONFIG_AOM_HIGHBITDEPTH
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700362 if (UUT_->use_highbd_ != 0)
363 mask_ = (1 << UUT_->use_highbd_) - 1;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700364 else
365 mask_ = 255;
366#endif
Johann158c80c2013-05-23 12:50:41 -0700367 /* Set up guard blocks for an inner block centered in the outer block */
James Zern8fb48af2013-05-02 13:08:19 -0700368 for (int i = 0; i < kOutputBufferSize; ++i) {
369 if (IsIndexInBorder(i))
370 output_[i] = 255;
371 else
372 output_[i] = 0;
John Koleszar5ca6a362013-01-25 09:47:09 -0800373 }
374
Yaowu Xuc27fc142016-08-22 16:08:15 -0700375 ::libaom_test::ACMRandom prng;
Yaowu Xu077144d2014-05-23 12:23:29 -0700376 for (int i = 0; i < kInputBufferSize; ++i) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700377 if (i & 1) {
Yaowu Xu077144d2014-05-23 12:23:29 -0700378 input_[i] = 255;
Yaowu Xuf883b422016-08-30 14:01:10 -0700379#if CONFIG_AOM_HIGHBITDEPTH
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700380 input16_[i] = mask_;
381#endif
382 } else {
Yaowu Xu077144d2014-05-23 12:23:29 -0700383 input_[i] = prng.Rand8Extremes();
Yaowu Xuf883b422016-08-30 14:01:10 -0700384#if CONFIG_AOM_HIGHBITDEPTH
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700385 input16_[i] = prng.Rand16() & mask_;
386#endif
387 }
Yaowu Xu077144d2014-05-23 12:23:29 -0700388 }
James Zern8fb48af2013-05-02 13:08:19 -0700389 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800390
Tero Rintaluomae326cec2013-08-22 11:29:19 +0300391 void SetConstantInput(int value) {
392 memset(input_, value, kInputBufferSize);
Yaowu Xuf883b422016-08-30 14:01:10 -0700393#if CONFIG_AOM_HIGHBITDEPTH
394 aom_memset16(input16_, value, kInputBufferSize);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700395#endif
Tero Rintaluomae326cec2013-08-22 11:29:19 +0300396 }
397
Johann1c3594c2014-12-09 12:05:15 -0800398 void CopyOutputToRef() {
James Zernf274c212015-04-23 20:42:19 -0700399 memcpy(output_ref_, output_, kOutputBufferSize);
Yaowu Xuf883b422016-08-30 14:01:10 -0700400#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc648a9f2016-10-10 17:39:29 -0700401 // Copy 16-bit pixels values. The effective number of bytes is double.
402 memcpy(output16_ref_, output16_, sizeof(output16_[0]) * kOutputBufferSize);
Johann1c3594c2014-12-09 12:05:15 -0800403#endif
404 }
405
James Zern8fb48af2013-05-02 13:08:19 -0700406 void CheckGuardBlocks() {
407 for (int i = 0; i < kOutputBufferSize; ++i) {
clang-format3a826f12016-08-11 17:46:05 -0700408 if (IsIndexInBorder(i)) EXPECT_EQ(255, output_[i]);
John Koleszar5ca6a362013-01-25 09:47:09 -0800409 }
James Zern8fb48af2013-05-02 13:08:19 -0700410 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800411
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700412 uint8_t *input() const {
Johann2967bf32016-06-22 16:08:10 -0700413 const int offset = BorderTop() * kOuterBlockSize + BorderLeft();
Yaowu Xuf883b422016-08-30 14:01:10 -0700414#if CONFIG_AOM_HIGHBITDEPTH
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700415 if (UUT_->use_highbd_ == 0) {
Johann2967bf32016-06-22 16:08:10 -0700416 return input_ + offset;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700417 } else {
Johann2967bf32016-06-22 16:08:10 -0700418 return CONVERT_TO_BYTEPTR(input16_) + offset;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700419 }
420#else
Johann2967bf32016-06-22 16:08:10 -0700421 return input_ + offset;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700422#endif
James Zern8fb48af2013-05-02 13:08:19 -0700423 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800424
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700425 uint8_t *output() const {
Johann2967bf32016-06-22 16:08:10 -0700426 const int offset = BorderTop() * kOuterBlockSize + BorderLeft();
Yaowu Xuf883b422016-08-30 14:01:10 -0700427#if CONFIG_AOM_HIGHBITDEPTH
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700428 if (UUT_->use_highbd_ == 0) {
Johann2967bf32016-06-22 16:08:10 -0700429 return output_ + offset;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700430 } else {
Johann2967bf32016-06-22 16:08:10 -0700431 return CONVERT_TO_BYTEPTR(output16_) + offset;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700432 }
433#else
Johann2967bf32016-06-22 16:08:10 -0700434 return output_ + offset;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700435#endif
436 }
437
Johann1c3594c2014-12-09 12:05:15 -0800438 uint8_t *output_ref() const {
Johann2967bf32016-06-22 16:08:10 -0700439 const int offset = BorderTop() * kOuterBlockSize + BorderLeft();
Yaowu Xuf883b422016-08-30 14:01:10 -0700440#if CONFIG_AOM_HIGHBITDEPTH
Johann1c3594c2014-12-09 12:05:15 -0800441 if (UUT_->use_highbd_ == 0) {
Johann2967bf32016-06-22 16:08:10 -0700442 return output_ref_ + offset;
Johann1c3594c2014-12-09 12:05:15 -0800443 } else {
Johann2967bf32016-06-22 16:08:10 -0700444 return CONVERT_TO_BYTEPTR(output16_ref_) + offset;
Johann1c3594c2014-12-09 12:05:15 -0800445 }
446#else
Johann2967bf32016-06-22 16:08:10 -0700447 return output_ref_ + offset;
Johann1c3594c2014-12-09 12:05:15 -0800448#endif
449 }
450
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700451 uint16_t lookup(uint8_t *list, int index) const {
Yaowu Xuf883b422016-08-30 14:01:10 -0700452#if CONFIG_AOM_HIGHBITDEPTH
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700453 if (UUT_->use_highbd_ == 0) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700454 return list[index];
455 } else {
456 return CONVERT_TO_SHORTPTR(list)[index];
457 }
458#else
459 return list[index];
460#endif
461 }
462
463 void assign_val(uint8_t *list, int index, uint16_t val) const {
Yaowu Xuf883b422016-08-30 14:01:10 -0700464#if CONFIG_AOM_HIGHBITDEPTH
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700465 if (UUT_->use_highbd_ == 0) {
clang-format3a826f12016-08-11 17:46:05 -0700466 list[index] = (uint8_t)val;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700467 } else {
468 CONVERT_TO_SHORTPTR(list)[index] = val;
469 }
470#else
clang-format3a826f12016-08-11 17:46:05 -0700471 list[index] = (uint8_t)val;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700472#endif
473 }
474
clang-format3a826f12016-08-11 17:46:05 -0700475 void wrapper_filter_average_block2d_8_c(
476 const uint8_t *src_ptr, const unsigned int src_stride,
477 const int16_t *HFilter, const int16_t *VFilter, uint8_t *dst_ptr,
478 unsigned int dst_stride, unsigned int output_width,
479 unsigned int output_height) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700480#if CONFIG_AOM_HIGHBITDEPTH
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700481 if (UUT_->use_highbd_ == 0) {
clang-format3a826f12016-08-11 17:46:05 -0700482 filter_average_block2d_8_c(src_ptr, src_stride, HFilter, VFilter, dst_ptr,
483 dst_stride, output_width, output_height);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700484 } else {
clang-format3a826f12016-08-11 17:46:05 -0700485 highbd_filter_average_block2d_8_c(
486 CONVERT_TO_SHORTPTR(src_ptr), src_stride, HFilter, VFilter,
487 CONVERT_TO_SHORTPTR(dst_ptr), dst_stride, output_width, output_height,
488 UUT_->use_highbd_);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700489 }
490#else
clang-format3a826f12016-08-11 17:46:05 -0700491 filter_average_block2d_8_c(src_ptr, src_stride, HFilter, VFilter, dst_ptr,
492 dst_stride, output_width, output_height);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700493#endif
494 }
495
496 void wrapper_filter_block2d_8_c(const uint8_t *src_ptr,
497 const unsigned int src_stride,
498 const int16_t *HFilter,
clang-format3a826f12016-08-11 17:46:05 -0700499 const int16_t *VFilter, uint8_t *dst_ptr,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700500 unsigned int dst_stride,
501 unsigned int output_width,
502 unsigned int output_height) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700503#if CONFIG_AOM_HIGHBITDEPTH
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700504 if (UUT_->use_highbd_ == 0) {
clang-format3a826f12016-08-11 17:46:05 -0700505 filter_block2d_8_c(src_ptr, src_stride, HFilter, VFilter, dst_ptr,
506 dst_stride, output_width, output_height);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700507 } else {
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700508 highbd_filter_block2d_8_c(CONVERT_TO_SHORTPTR(src_ptr), src_stride,
clang-format3a826f12016-08-11 17:46:05 -0700509 HFilter, VFilter, CONVERT_TO_SHORTPTR(dst_ptr),
510 dst_stride, output_width, output_height,
511 UUT_->use_highbd_);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700512 }
513#else
clang-format3a826f12016-08-11 17:46:05 -0700514 filter_block2d_8_c(src_ptr, src_stride, HFilter, VFilter, dst_ptr,
515 dst_stride, output_width, output_height);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700516#endif
James Zern8fb48af2013-05-02 13:08:19 -0700517 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800518
clang-format3a826f12016-08-11 17:46:05 -0700519 const ConvolveFunctions *UUT_;
520 static uint8_t *input_;
521 static uint8_t *output_;
522 static uint8_t *output_ref_;
Yaowu Xuf883b422016-08-30 14:01:10 -0700523#if CONFIG_AOM_HIGHBITDEPTH
clang-format3a826f12016-08-11 17:46:05 -0700524 static uint16_t *input16_;
525 static uint16_t *output16_;
526 static uint16_t *output16_ref_;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700527 int mask_;
528#endif
John Koleszar5ca6a362013-01-25 09:47:09 -0800529};
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700530
clang-format3a826f12016-08-11 17:46:05 -0700531uint8_t *ConvolveTest::input_ = NULL;
532uint8_t *ConvolveTest::output_ = NULL;
533uint8_t *ConvolveTest::output_ref_ = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700534#if CONFIG_AOM_HIGHBITDEPTH
clang-format3a826f12016-08-11 17:46:05 -0700535uint16_t *ConvolveTest::input16_ = NULL;
536uint16_t *ConvolveTest::output16_ = NULL;
537uint16_t *ConvolveTest::output16_ref_ = NULL;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700538#endif
John Koleszar5ca6a362013-01-25 09:47:09 -0800539
clang-format3a826f12016-08-11 17:46:05 -0700540TEST_P(ConvolveTest, GuardBlocks) { CheckGuardBlocks(); }
John Koleszar5ca6a362013-01-25 09:47:09 -0800541
Johann1c3594c2014-12-09 12:05:15 -0800542TEST_P(ConvolveTest, Copy) {
clang-format3a826f12016-08-11 17:46:05 -0700543 uint8_t *const in = input();
544 uint8_t *const out = output();
Johann1c3594c2014-12-09 12:05:15 -0800545
clang-format3a826f12016-08-11 17:46:05 -0700546 ASM_REGISTER_STATE_CHECK(UUT_->copy_(in, kInputStride, out, kOutputStride,
547 NULL, 0, NULL, 0, Width(), Height()));
Johann1c3594c2014-12-09 12:05:15 -0800548
549 CheckGuardBlocks();
550
551 for (int y = 0; y < Height(); ++y)
552 for (int x = 0; x < Width(); ++x)
553 ASSERT_EQ(lookup(out, y * kOutputStride + x),
554 lookup(in, y * kInputStride + x))
555 << "(" << x << "," << y << ")";
556}
557
558TEST_P(ConvolveTest, Avg) {
clang-format3a826f12016-08-11 17:46:05 -0700559 uint8_t *const in = input();
560 uint8_t *const out = output();
561 uint8_t *const out_ref = output_ref();
Johann1c3594c2014-12-09 12:05:15 -0800562 CopyOutputToRef();
563
clang-format3a826f12016-08-11 17:46:05 -0700564 ASM_REGISTER_STATE_CHECK(UUT_->avg_(in, kInputStride, out, kOutputStride,
565 NULL, 0, NULL, 0, Width(), Height()));
Johann1c3594c2014-12-09 12:05:15 -0800566
567 CheckGuardBlocks();
568
569 for (int y = 0; y < Height(); ++y)
570 for (int x = 0; x < Width(); ++x)
571 ASSERT_EQ(lookup(out, y * kOutputStride + x),
572 ROUND_POWER_OF_TWO(lookup(in, y * kInputStride + x) +
clang-format3a826f12016-08-11 17:46:05 -0700573 lookup(out_ref, y * kOutputStride + x),
574 1))
Johann1c3594c2014-12-09 12:05:15 -0800575 << "(" << x << "," << y << ")";
576}
577
John Koleszar5ca6a362013-01-25 09:47:09 -0800578TEST_P(ConvolveTest, CopyHoriz) {
clang-format3a826f12016-08-11 17:46:05 -0700579 uint8_t *const in = input();
580 uint8_t *const out = output();
581 DECLARE_ALIGNED(256, const int16_t,
582 filter8[8]) = { 0, 0, 0, 128, 0, 0, 0, 0 };
John Koleszar5ca6a362013-01-25 09:47:09 -0800583
clang-format3a826f12016-08-11 17:46:05 -0700584 ASM_REGISTER_STATE_CHECK(UUT_->sh8_(in, kInputStride, out, kOutputStride,
585 filter8, 16, filter8, 16, Width(),
586 Height()));
John Koleszar5ca6a362013-01-25 09:47:09 -0800587
588 CheckGuardBlocks();
589
590 for (int y = 0; y < Height(); ++y)
591 for (int x = 0; x < Width(); ++x)
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700592 ASSERT_EQ(lookup(out, y * kOutputStride + x),
593 lookup(in, y * kInputStride + x))
John Koleszar5ca6a362013-01-25 09:47:09 -0800594 << "(" << x << "," << y << ")";
595}
596
597TEST_P(ConvolveTest, CopyVert) {
clang-format3a826f12016-08-11 17:46:05 -0700598 uint8_t *const in = input();
599 uint8_t *const out = output();
600 DECLARE_ALIGNED(256, const int16_t,
601 filter8[8]) = { 0, 0, 0, 128, 0, 0, 0, 0 };
John Koleszar5ca6a362013-01-25 09:47:09 -0800602
clang-format3a826f12016-08-11 17:46:05 -0700603 ASM_REGISTER_STATE_CHECK(UUT_->sv8_(in, kInputStride, out, kOutputStride,
604 filter8, 16, filter8, 16, Width(),
605 Height()));
John Koleszar5ca6a362013-01-25 09:47:09 -0800606
607 CheckGuardBlocks();
608
609 for (int y = 0; y < Height(); ++y)
610 for (int x = 0; x < Width(); ++x)
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700611 ASSERT_EQ(lookup(out, y * kOutputStride + x),
612 lookup(in, y * kInputStride + x))
John Koleszar5ca6a362013-01-25 09:47:09 -0800613 << "(" << x << "," << y << ")";
614}
615
616TEST_P(ConvolveTest, Copy2D) {
clang-format3a826f12016-08-11 17:46:05 -0700617 uint8_t *const in = input();
618 uint8_t *const out = output();
619 DECLARE_ALIGNED(256, const int16_t,
620 filter8[8]) = { 0, 0, 0, 128, 0, 0, 0, 0 };
John Koleszar5ca6a362013-01-25 09:47:09 -0800621
clang-format3a826f12016-08-11 17:46:05 -0700622 ASM_REGISTER_STATE_CHECK(UUT_->shv8_(in, kInputStride, out, kOutputStride,
623 filter8, 16, filter8, 16, Width(),
624 Height()));
John Koleszar5ca6a362013-01-25 09:47:09 -0800625
626 CheckGuardBlocks();
627
628 for (int y = 0; y < Height(); ++y)
629 for (int x = 0; x < Width(); ++x)
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700630 ASSERT_EQ(lookup(out, y * kOutputStride + x),
631 lookup(in, y * kInputStride + x))
John Koleszar5ca6a362013-01-25 09:47:09 -0800632 << "(" << x << "," << y << ")";
633}
634
Angie Chiangb1372892016-12-01 15:06:06 -0800635const int kNumFilterBanks = SWITCHABLE_FILTERS;
John Koleszara9ebbcc2013-04-18 13:05:38 -0700636const int kNumFilters = 16;
637
638TEST(ConvolveTest, FiltersWontSaturateWhenAddedPairwise) {
639 for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
Urvang Joshia9b174b2017-02-17 11:50:12 -0800640 const InterpFilter filter = (InterpFilter)filter_bank;
Dmitry Kovalev3d4ed272014-04-21 14:15:35 -0700641 const InterpKernel *filters =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800642 (const InterpKernel *)av1_get_interp_filter_kernel(filter);
Angie Chiang1733f6b2017-01-05 09:52:20 -0800643#if CONFIG_DUAL_FILTER
Angie Chiangb1372892016-12-01 15:06:06 -0800644 const InterpFilterParams filter_params =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800645 av1_get_interp_filter_params(filter);
Angie Chiangb1372892016-12-01 15:06:06 -0800646 if (filter_params.taps != SUBPEL_TAPS) continue;
647#endif
John Koleszara9ebbcc2013-04-18 13:05:38 -0700648 for (int i = 0; i < kNumFilters; i++) {
649 const int p0 = filters[i][0] + filters[i][1];
650 const int p1 = filters[i][2] + filters[i][3];
651 const int p2 = filters[i][4] + filters[i][5];
652 const int p3 = filters[i][6] + filters[i][7];
653 EXPECT_LE(p0, 128);
654 EXPECT_LE(p1, 128);
655 EXPECT_LE(p2, 128);
656 EXPECT_LE(p3, 128);
657 EXPECT_LE(p0 + p3, 128);
658 EXPECT_LE(p0 + p3 + p1, 128);
659 EXPECT_LE(p0 + p3 + p1 + p2, 128);
660 EXPECT_EQ(p0 + p1 + p2 + p3, 128);
661 }
662 }
663}
John Koleszar557a1b22013-02-20 16:13:01 -0800664
John Koleszar04c24072013-02-20 16:32:02 -0800665const int16_t kInvalidFilter[8] = { 0 };
666
John Koleszar5ca6a362013-01-25 09:47:09 -0800667TEST_P(ConvolveTest, MatchesReferenceSubpixelFilter) {
clang-format3a826f12016-08-11 17:46:05 -0700668 uint8_t *const in = input();
669 uint8_t *const out = output();
Yaowu Xuf883b422016-08-30 14:01:10 -0700670#if CONFIG_AOM_HIGHBITDEPTH
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700671 uint8_t ref8[kOutputStride * kMaxDimension];
672 uint16_t ref16[kOutputStride * kMaxDimension];
clang-format3a826f12016-08-11 17:46:05 -0700673 uint8_t *ref;
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700674 if (UUT_->use_highbd_ == 0) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700675 ref = ref8;
676 } else {
677 ref = CONVERT_TO_BYTEPTR(ref16);
678 }
679#else
John Koleszar5ca6a362013-01-25 09:47:09 -0800680 uint8_t ref[kOutputStride * kMaxDimension];
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700681#endif
John Koleszar5ca6a362013-01-25 09:47:09 -0800682
John Koleszar557a1b22013-02-20 16:13:01 -0800683 for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
Urvang Joshia9b174b2017-02-17 11:50:12 -0800684 const InterpFilter filter = (InterpFilter)filter_bank;
Dmitry Kovalev3d4ed272014-04-21 14:15:35 -0700685 const InterpKernel *filters =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800686 (const InterpKernel *)av1_get_interp_filter_kernel(filter);
Angie Chiang1733f6b2017-01-05 09:52:20 -0800687#if CONFIG_DUAL_FILTER
Angie Chiangb1372892016-12-01 15:06:06 -0800688 const InterpFilterParams filter_params =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800689 av1_get_interp_filter_params(filter);
Angie Chiangb1372892016-12-01 15:06:06 -0800690 if (filter_params.taps != SUBPEL_TAPS) continue;
691#endif
Dmitry Kovalev021eaab2014-05-14 16:21:41 -0700692
John Koleszar557a1b22013-02-20 16:13:01 -0800693 for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) {
694 for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) {
clang-format3a826f12016-08-11 17:46:05 -0700695 wrapper_filter_block2d_8_c(in, kInputStride, filters[filter_x],
696 filters[filter_y], ref, kOutputStride,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700697 Width(), Height());
John Koleszar5ca6a362013-01-25 09:47:09 -0800698
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700699 if (filter_x && filter_y)
clang-format3a826f12016-08-11 17:46:05 -0700700 ASM_REGISTER_STATE_CHECK(UUT_->hv8_(
701 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
702 filters[filter_y], 16, Width(), Height()));
John Koleszar557a1b22013-02-20 16:13:01 -0800703 else if (filter_y)
James Zern29e1b1a2014-07-09 21:02:02 -0700704 ASM_REGISTER_STATE_CHECK(
clang-format3a826f12016-08-11 17:46:05 -0700705 UUT_->v8_(in, kInputStride, out, kOutputStride, kInvalidFilter,
706 16, filters[filter_y], 16, Width(), Height()));
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700707 else if (filter_x)
James Zern29e1b1a2014-07-09 21:02:02 -0700708 ASM_REGISTER_STATE_CHECK(
clang-format3a826f12016-08-11 17:46:05 -0700709 UUT_->h8_(in, kInputStride, out, kOutputStride, filters[filter_x],
710 16, kInvalidFilter, 16, Width(), Height()));
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700711 else
712 ASM_REGISTER_STATE_CHECK(
clang-format3a826f12016-08-11 17:46:05 -0700713 UUT_->copy_(in, kInputStride, out, kOutputStride, kInvalidFilter,
714 0, kInvalidFilter, 0, Width(), Height()));
John Koleszar5ca6a362013-01-25 09:47:09 -0800715
John Koleszar557a1b22013-02-20 16:13:01 -0800716 CheckGuardBlocks();
John Koleszar5ca6a362013-01-25 09:47:09 -0800717
John Koleszar557a1b22013-02-20 16:13:01 -0800718 for (int y = 0; y < Height(); ++y)
719 for (int x = 0; x < Width(); ++x)
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700720 ASSERT_EQ(lookup(ref, y * kOutputStride + x),
721 lookup(out, y * kOutputStride + x))
John Koleszar557a1b22013-02-20 16:13:01 -0800722 << "mismatch at (" << x << "," << y << "), "
clang-format3a826f12016-08-11 17:46:05 -0700723 << "filters (" << filter_bank << "," << filter_x << ","
724 << filter_y << ")";
John Koleszar557a1b22013-02-20 16:13:01 -0800725 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800726 }
727 }
728}
729
730TEST_P(ConvolveTest, MatchesReferenceAveragingSubpixelFilter) {
clang-format3a826f12016-08-11 17:46:05 -0700731 uint8_t *const in = input();
732 uint8_t *const out = output();
Yaowu Xuf883b422016-08-30 14:01:10 -0700733#if CONFIG_AOM_HIGHBITDEPTH
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700734 uint8_t ref8[kOutputStride * kMaxDimension];
735 uint16_t ref16[kOutputStride * kMaxDimension];
clang-format3a826f12016-08-11 17:46:05 -0700736 uint8_t *ref;
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700737 if (UUT_->use_highbd_ == 0) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700738 ref = ref8;
739 } else {
740 ref = CONVERT_TO_BYTEPTR(ref16);
741 }
742#else
John Koleszar5ca6a362013-01-25 09:47:09 -0800743 uint8_t ref[kOutputStride * kMaxDimension];
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700744#endif
John Koleszar5ca6a362013-01-25 09:47:09 -0800745
746 // Populate ref and out with some random data
Yaowu Xuc27fc142016-08-22 16:08:15 -0700747 ::libaom_test::ACMRandom prng;
John Koleszar5ca6a362013-01-25 09:47:09 -0800748 for (int y = 0; y < Height(); ++y) {
749 for (int x = 0; x < Width(); ++x) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700750 uint16_t r;
Yaowu Xuf883b422016-08-30 14:01:10 -0700751#if CONFIG_AOM_HIGHBITDEPTH
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700752 if (UUT_->use_highbd_ == 0 || UUT_->use_highbd_ == 8) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700753 r = prng.Rand8Extremes();
754 } else {
755 r = prng.Rand16() & mask_;
756 }
757#else
758 r = prng.Rand8Extremes();
759#endif
John Koleszar5ca6a362013-01-25 09:47:09 -0800760
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700761 assign_val(out, y * kOutputStride + x, r);
762 assign_val(ref, y * kOutputStride + x, r);
John Koleszar5ca6a362013-01-25 09:47:09 -0800763 }
764 }
765
John Koleszar557a1b22013-02-20 16:13:01 -0800766 for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
Urvang Joshia9b174b2017-02-17 11:50:12 -0800767 const InterpFilter filter = (InterpFilter)filter_bank;
Dmitry Kovalev3d4ed272014-04-21 14:15:35 -0700768 const InterpKernel *filters =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800769 (const InterpKernel *)av1_get_interp_filter_kernel(filter);
Angie Chiang1733f6b2017-01-05 09:52:20 -0800770#if CONFIG_DUAL_FILTER
Angie Chiangb1372892016-12-01 15:06:06 -0800771 const InterpFilterParams filter_params =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800772 av1_get_interp_filter_params(filter);
Angie Chiangb1372892016-12-01 15:06:06 -0800773 if (filter_params.taps != SUBPEL_TAPS) continue;
774#endif
John Koleszar5ca6a362013-01-25 09:47:09 -0800775
John Koleszar557a1b22013-02-20 16:13:01 -0800776 for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) {
777 for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) {
clang-format3a826f12016-08-11 17:46:05 -0700778 wrapper_filter_average_block2d_8_c(in, kInputStride, filters[filter_x],
779 filters[filter_y], ref,
780 kOutputStride, Width(), Height());
John Koleszar5ca6a362013-01-25 09:47:09 -0800781
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700782 if (filter_x && filter_y)
clang-format3a826f12016-08-11 17:46:05 -0700783 ASM_REGISTER_STATE_CHECK(UUT_->hv8_avg_(
784 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
785 filters[filter_y], 16, Width(), Height()));
John Koleszar557a1b22013-02-20 16:13:01 -0800786 else if (filter_y)
clang-format3a826f12016-08-11 17:46:05 -0700787 ASM_REGISTER_STATE_CHECK(UUT_->v8_avg_(
788 in, kInputStride, out, kOutputStride, kInvalidFilter, 16,
789 filters[filter_y], 16, Width(), Height()));
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700790 else if (filter_x)
clang-format3a826f12016-08-11 17:46:05 -0700791 ASM_REGISTER_STATE_CHECK(UUT_->h8_avg_(
792 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
793 kInvalidFilter, 16, Width(), Height()));
John Koleszar557a1b22013-02-20 16:13:01 -0800794 else
James Zern29e1b1a2014-07-09 21:02:02 -0700795 ASM_REGISTER_STATE_CHECK(
clang-format3a826f12016-08-11 17:46:05 -0700796 UUT_->avg_(in, kInputStride, out, kOutputStride, kInvalidFilter,
797 0, kInvalidFilter, 0, Width(), Height()));
John Koleszar5ca6a362013-01-25 09:47:09 -0800798
John Koleszar557a1b22013-02-20 16:13:01 -0800799 CheckGuardBlocks();
John Koleszar5ca6a362013-01-25 09:47:09 -0800800
John Koleszar557a1b22013-02-20 16:13:01 -0800801 for (int y = 0; y < Height(); ++y)
802 for (int x = 0; x < Width(); ++x)
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700803 ASSERT_EQ(lookup(ref, y * kOutputStride + x),
804 lookup(out, y * kOutputStride + x))
John Koleszar557a1b22013-02-20 16:13:01 -0800805 << "mismatch at (" << x << "," << y << "), "
clang-format3a826f12016-08-11 17:46:05 -0700806 << "filters (" << filter_bank << "," << filter_x << ","
807 << filter_y << ")";
John Koleszar557a1b22013-02-20 16:13:01 -0800808 }
John Koleszar5ca6a362013-01-25 09:47:09 -0800809 }
810 }
811}
812
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700813TEST_P(ConvolveTest, FilterExtremes) {
814 uint8_t *const in = input();
815 uint8_t *const out = output();
Yaowu Xuf883b422016-08-30 14:01:10 -0700816#if CONFIG_AOM_HIGHBITDEPTH
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700817 uint8_t ref8[kOutputStride * kMaxDimension];
818 uint16_t ref16[kOutputStride * kMaxDimension];
819 uint8_t *ref;
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700820 if (UUT_->use_highbd_ == 0) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700821 ref = ref8;
822 } else {
823 ref = CONVERT_TO_BYTEPTR(ref16);
824 }
825#else
826 uint8_t ref[kOutputStride * kMaxDimension];
827#endif
828
829 // Populate ref and out with some random data
Yaowu Xuc27fc142016-08-22 16:08:15 -0700830 ::libaom_test::ACMRandom prng;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700831 for (int y = 0; y < Height(); ++y) {
832 for (int x = 0; x < Width(); ++x) {
833 uint16_t r;
Yaowu Xuf883b422016-08-30 14:01:10 -0700834#if CONFIG_AOM_HIGHBITDEPTH
Deb Mukherjee1929c9b2014-10-08 12:43:22 -0700835 if (UUT_->use_highbd_ == 0 || UUT_->use_highbd_ == 8) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700836 r = prng.Rand8Extremes();
837 } else {
838 r = prng.Rand16() & mask_;
839 }
840#else
841 r = prng.Rand8Extremes();
842#endif
843 assign_val(out, y * kOutputStride + x, r);
844 assign_val(ref, y * kOutputStride + x, r);
845 }
846 }
847
848 for (int axis = 0; axis < 2; axis++) {
849 int seed_val = 0;
850 while (seed_val < 256) {
851 for (int y = 0; y < 8; ++y) {
852 for (int x = 0; x < 8; ++x) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700853#if CONFIG_AOM_HIGHBITDEPTH
clang-format3a826f12016-08-11 17:46:05 -0700854 assign_val(in, y * kOutputStride + x - SUBPEL_TAPS / 2 + 1,
855 ((seed_val >> (axis ? y : x)) & 1) * mask_);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700856#else
clang-format3a826f12016-08-11 17:46:05 -0700857 assign_val(in, y * kOutputStride + x - SUBPEL_TAPS / 2 + 1,
858 ((seed_val >> (axis ? y : x)) & 1) * 255);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700859#endif
860 if (axis) seed_val++;
861 }
862 if (axis)
clang-format3a826f12016-08-11 17:46:05 -0700863 seed_val -= 8;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700864 else
865 seed_val++;
866 }
867 if (axis) seed_val += 8;
868
869 for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
Urvang Joshia9b174b2017-02-17 11:50:12 -0800870 const InterpFilter filter = (InterpFilter)filter_bank;
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700871 const InterpKernel *filters =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800872 (const InterpKernel *)av1_get_interp_filter_kernel(filter);
Angie Chiang1733f6b2017-01-05 09:52:20 -0800873#if CONFIG_DUAL_FILTER
Angie Chiangb1372892016-12-01 15:06:06 -0800874 const InterpFilterParams filter_params =
Urvang Joshia9b174b2017-02-17 11:50:12 -0800875 av1_get_interp_filter_params(filter);
Angie Chiangb1372892016-12-01 15:06:06 -0800876 if (filter_params.taps != SUBPEL_TAPS) continue;
877#endif
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700878 for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) {
879 for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) {
clang-format3a826f12016-08-11 17:46:05 -0700880 wrapper_filter_block2d_8_c(in, kInputStride, filters[filter_x],
881 filters[filter_y], ref, kOutputStride,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700882 Width(), Height());
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700883 if (filter_x && filter_y)
clang-format3a826f12016-08-11 17:46:05 -0700884 ASM_REGISTER_STATE_CHECK(UUT_->hv8_(
885 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
886 filters[filter_y], 16, Width(), Height()));
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700887 else if (filter_y)
clang-format3a826f12016-08-11 17:46:05 -0700888 ASM_REGISTER_STATE_CHECK(UUT_->v8_(
889 in, kInputStride, out, kOutputStride, kInvalidFilter, 16,
890 filters[filter_y], 16, Width(), Height()));
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700891 else if (filter_x)
clang-format3a826f12016-08-11 17:46:05 -0700892 ASM_REGISTER_STATE_CHECK(UUT_->h8_(
893 in, kInputStride, out, kOutputStride, filters[filter_x], 16,
894 kInvalidFilter, 16, Width(), Height()));
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700895 else
clang-format3a826f12016-08-11 17:46:05 -0700896 ASM_REGISTER_STATE_CHECK(UUT_->copy_(
897 in, kInputStride, out, kOutputStride, kInvalidFilter, 0,
898 kInvalidFilter, 0, Width(), Height()));
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700899
900 for (int y = 0; y < Height(); ++y)
901 for (int x = 0; x < Width(); ++x)
902 ASSERT_EQ(lookup(ref, y * kOutputStride + x),
903 lookup(out, y * kOutputStride + x))
904 << "mismatch at (" << x << "," << y << "), "
clang-format3a826f12016-08-11 17:46:05 -0700905 << "filters (" << filter_bank << "," << filter_x << ","
906 << filter_y << ")";
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700907 }
908 }
909 }
910 }
911 }
912}
913
Tero Rintaluomae326cec2013-08-22 11:29:19 +0300914/* This test exercises that enough rows and columns are filtered with every
915 possible initial fractional positions and scaling steps. */
916TEST_P(ConvolveTest, CheckScalingFiltering) {
clang-format3a826f12016-08-11 17:46:05 -0700917 uint8_t *const in = input();
918 uint8_t *const out = output();
Angie Chiangb1372892016-12-01 15:06:06 -0800919 const InterpKernel *const eighttap =
920 (const InterpKernel *)av1_get_interp_filter_kernel(EIGHTTAP_REGULAR);
Tero Rintaluomae326cec2013-08-22 11:29:19 +0300921
922 SetConstantInput(127);
923
924 for (int frac = 0; frac < 16; ++frac) {
925 for (int step = 1; step <= 32; ++step) {
926 /* Test the horizontal and vertical filters in combination. */
Scott LaVarnway4e6b5072015-08-05 10:47:06 -0700927 ASM_REGISTER_STATE_CHECK(UUT_->shv8_(in, kInputStride, out, kOutputStride,
clang-format3a826f12016-08-11 17:46:05 -0700928 eighttap[frac], step, eighttap[frac],
929 step, Width(), Height()));
Tero Rintaluomae326cec2013-08-22 11:29:19 +0300930
931 CheckGuardBlocks();
932
933 for (int y = 0; y < Height(); ++y) {
934 for (int x = 0; x < Width(); ++x) {
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700935 ASSERT_EQ(lookup(in, y * kInputStride + x),
936 lookup(out, y * kOutputStride + x))
clang-format3a826f12016-08-11 17:46:05 -0700937 << "x == " << x << ", y == " << y << ", frac == " << frac
938 << ", step == " << step;
Tero Rintaluomae326cec2013-08-22 11:29:19 +0300939 }
940 }
941 }
942 }
943}
944
John Koleszar5ca6a362013-01-25 09:47:09 -0800945using std::tr1::make_tuple;
946
Yaowu Xuf883b422016-08-30 14:01:10 -0700947#if CONFIG_AOM_HIGHBITDEPTH
clang-format3a826f12016-08-11 17:46:05 -0700948#define WRAP(func, bd) \
949 void wrap_##func##_##bd( \
950 const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, \
951 ptrdiff_t dst_stride, const int16_t *filter_x, int filter_x_stride, \
952 const int16_t *filter_y, int filter_y_stride, int w, int h) { \
Yaowu Xuf883b422016-08-30 14:01:10 -0700953 aom_highbd_##func(src, src_stride, dst, dst_stride, filter_x, \
clang-format3a826f12016-08-11 17:46:05 -0700954 filter_x_stride, filter_y, filter_y_stride, w, h, bd); \
955 }
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700956#if HAVE_SSE2 && ARCH_X86_64
Alex Converse0c00af12015-10-06 15:59:03 -0700957WRAP(convolve_copy_sse2, 8)
958WRAP(convolve_avg_sse2, 8)
959WRAP(convolve_copy_sse2, 10)
960WRAP(convolve_avg_sse2, 10)
961WRAP(convolve_copy_sse2, 12)
962WRAP(convolve_avg_sse2, 12)
Alex Converse7e779382015-10-09 11:42:05 -0700963WRAP(convolve8_horiz_sse2, 8)
964WRAP(convolve8_avg_horiz_sse2, 8)
965WRAP(convolve8_vert_sse2, 8)
966WRAP(convolve8_avg_vert_sse2, 8)
967WRAP(convolve8_sse2, 8)
968WRAP(convolve8_avg_sse2, 8)
969WRAP(convolve8_horiz_sse2, 10)
970WRAP(convolve8_avg_horiz_sse2, 10)
971WRAP(convolve8_vert_sse2, 10)
972WRAP(convolve8_avg_vert_sse2, 10)
973WRAP(convolve8_sse2, 10)
974WRAP(convolve8_avg_sse2, 10)
975WRAP(convolve8_horiz_sse2, 12)
976WRAP(convolve8_avg_horiz_sse2, 12)
977WRAP(convolve8_vert_sse2, 12)
978WRAP(convolve8_avg_vert_sse2, 12)
979WRAP(convolve8_sse2, 12)
980WRAP(convolve8_avg_sse2, 12)
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -0700981#endif // HAVE_SSE2 && ARCH_X86_64
982
Alex Converse7e779382015-10-09 11:42:05 -0700983WRAP(convolve_copy_c, 8)
984WRAP(convolve_avg_c, 8)
985WRAP(convolve8_horiz_c, 8)
986WRAP(convolve8_avg_horiz_c, 8)
987WRAP(convolve8_vert_c, 8)
988WRAP(convolve8_avg_vert_c, 8)
989WRAP(convolve8_c, 8)
990WRAP(convolve8_avg_c, 8)
991WRAP(convolve_copy_c, 10)
992WRAP(convolve_avg_c, 10)
993WRAP(convolve8_horiz_c, 10)
994WRAP(convolve8_avg_horiz_c, 10)
995WRAP(convolve8_vert_c, 10)
996WRAP(convolve8_avg_vert_c, 10)
997WRAP(convolve8_c, 10)
998WRAP(convolve8_avg_c, 10)
999WRAP(convolve_copy_c, 12)
1000WRAP(convolve_avg_c, 12)
1001WRAP(convolve8_horiz_c, 12)
1002WRAP(convolve8_avg_horiz_c, 12)
1003WRAP(convolve8_vert_c, 12)
1004WRAP(convolve8_avg_vert_c, 12)
1005WRAP(convolve8_c, 12)
1006WRAP(convolve8_avg_c, 12)
1007#undef WRAP
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001008
1009const ConvolveFunctions convolve8_c(
clang-format3a826f12016-08-11 17:46:05 -07001010 wrap_convolve_copy_c_8, wrap_convolve_avg_c_8, wrap_convolve8_horiz_c_8,
1011 wrap_convolve8_avg_horiz_c_8, wrap_convolve8_vert_c_8,
1012 wrap_convolve8_avg_vert_c_8, wrap_convolve8_c_8, wrap_convolve8_avg_c_8,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001013 wrap_convolve8_horiz_c_8, wrap_convolve8_avg_horiz_c_8,
clang-format3a826f12016-08-11 17:46:05 -07001014 wrap_convolve8_vert_c_8, wrap_convolve8_avg_vert_c_8, wrap_convolve8_c_8,
1015 wrap_convolve8_avg_c_8, 8);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001016const ConvolveFunctions convolve10_c(
clang-format3a826f12016-08-11 17:46:05 -07001017 wrap_convolve_copy_c_10, wrap_convolve_avg_c_10, wrap_convolve8_horiz_c_10,
1018 wrap_convolve8_avg_horiz_c_10, wrap_convolve8_vert_c_10,
1019 wrap_convolve8_avg_vert_c_10, wrap_convolve8_c_10, wrap_convolve8_avg_c_10,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001020 wrap_convolve8_horiz_c_10, wrap_convolve8_avg_horiz_c_10,
clang-format3a826f12016-08-11 17:46:05 -07001021 wrap_convolve8_vert_c_10, wrap_convolve8_avg_vert_c_10, wrap_convolve8_c_10,
1022 wrap_convolve8_avg_c_10, 10);
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001023const ConvolveFunctions convolve12_c(
clang-format3a826f12016-08-11 17:46:05 -07001024 wrap_convolve_copy_c_12, wrap_convolve_avg_c_12, wrap_convolve8_horiz_c_12,
1025 wrap_convolve8_avg_horiz_c_12, wrap_convolve8_vert_c_12,
1026 wrap_convolve8_avg_vert_c_12, wrap_convolve8_c_12, wrap_convolve8_avg_c_12,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001027 wrap_convolve8_horiz_c_12, wrap_convolve8_avg_horiz_c_12,
clang-format3a826f12016-08-11 17:46:05 -07001028 wrap_convolve8_vert_c_12, wrap_convolve8_avg_vert_c_12, wrap_convolve8_c_12,
1029 wrap_convolve8_avg_c_12, 12);
Alex Conversef03e2382016-04-26 18:09:40 -07001030const ConvolveParam kArrayConvolve_c[] = {
clang-format3a826f12016-08-11 17:46:05 -07001031 ALL_SIZES(convolve8_c), ALL_SIZES(convolve10_c), ALL_SIZES(convolve12_c)
Alex Conversef03e2382016-04-26 18:09:40 -07001032};
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001033
Deb Mukherjee10783d42014-09-02 16:34:09 -07001034#else
John Koleszar5ca6a362013-01-25 09:47:09 -08001035const ConvolveFunctions convolve8_c(
Yaowu Xuf883b422016-08-30 14:01:10 -07001036 aom_convolve_copy_c, aom_convolve_avg_c, aom_convolve8_horiz_c,
1037 aom_convolve8_avg_horiz_c, aom_convolve8_vert_c, aom_convolve8_avg_vert_c,
1038 aom_convolve8_c, aom_convolve8_avg_c, aom_scaled_horiz_c,
1039 aom_scaled_avg_horiz_c, aom_scaled_vert_c, aom_scaled_avg_vert_c,
1040 aom_scaled_2d_c, aom_scaled_avg_2d_c, 0);
Alex Conversef03e2382016-04-26 18:09:40 -07001041const ConvolveParam kArrayConvolve_c[] = { ALL_SIZES(convolve8_c) };
Deb Mukherjee10783d42014-09-02 16:34:09 -07001042#endif
clang-format3a826f12016-08-11 17:46:05 -07001043INSTANTIATE_TEST_CASE_P(C, ConvolveTest, ::testing::ValuesIn(kArrayConvolve_c));
John Koleszar29d47ac2013-02-07 17:00:37 -08001044
Deb Mukherjee10783d42014-09-02 16:34:09 -07001045#if HAVE_SSE2 && ARCH_X86_64
Yaowu Xuf883b422016-08-30 14:01:10 -07001046#if CONFIG_AOM_HIGHBITDEPTH
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001047const ConvolveFunctions convolve8_sse2(
Alex Converse0c00af12015-10-06 15:59:03 -07001048 wrap_convolve_copy_sse2_8, wrap_convolve_avg_sse2_8,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001049 wrap_convolve8_horiz_sse2_8, wrap_convolve8_avg_horiz_sse2_8,
1050 wrap_convolve8_vert_sse2_8, wrap_convolve8_avg_vert_sse2_8,
Scott LaVarnway4e6b5072015-08-05 10:47:06 -07001051 wrap_convolve8_sse2_8, wrap_convolve8_avg_sse2_8,
1052 wrap_convolve8_horiz_sse2_8, wrap_convolve8_avg_horiz_sse2_8,
1053 wrap_convolve8_vert_sse2_8, wrap_convolve8_avg_vert_sse2_8,
Deb Mukherjee0d3c3d32014-09-16 12:47:18 -07001054 wrap_convolve8_sse2_8, wrap_convolve8_avg_sse2_8, 8);
Deb Mukherjee27dce0f2014-11-07 10:19:46 -08001055const ConvolveFunctions convolve10_sse2(
Alex Converse0c00af12015-10-06 15:59:03 -07001056 wrap_convolve_copy_sse2_10, wrap_convolve_avg_sse2_10,
Deb Mukherjee27dce0f2014-11-07 10:19:46 -08001057 wrap_convolve8_horiz_sse2_10, wrap_convolve8_avg_horiz_sse2_10,
1058 wrap_convolve8_vert_sse2_10, wrap_convolve8_avg_vert_sse2_10,
Scott LaVarnway4e6b5072015-08-05 10:47:06 -07001059 wrap_convolve8_sse2_10, wrap_convolve8_avg_sse2_10,
1060 wrap_convolve8_horiz_sse2_10, wrap_convolve8_avg_horiz_sse2_10,
1061 wrap_convolve8_vert_sse2_10, wrap_convolve8_avg_vert_sse2_10,
Deb Mukherjee27dce0f2014-11-07 10:19:46 -08001062 wrap_convolve8_sse2_10, wrap_convolve8_avg_sse2_10, 10);
1063const ConvolveFunctions convolve12_sse2(
Alex Converse0c00af12015-10-06 15:59:03 -07001064 wrap_convolve_copy_sse2_12, wrap_convolve_avg_sse2_12,
Deb Mukherjee27dce0f2014-11-07 10:19:46 -08001065 wrap_convolve8_horiz_sse2_12, wrap_convolve8_avg_horiz_sse2_12,
1066 wrap_convolve8_vert_sse2_12, wrap_convolve8_avg_vert_sse2_12,
Scott LaVarnway4e6b5072015-08-05 10:47:06 -07001067 wrap_convolve8_sse2_12, wrap_convolve8_avg_sse2_12,
1068 wrap_convolve8_horiz_sse2_12, wrap_convolve8_avg_horiz_sse2_12,
1069 wrap_convolve8_vert_sse2_12, wrap_convolve8_avg_vert_sse2_12,
Deb Mukherjee27dce0f2014-11-07 10:19:46 -08001070 wrap_convolve8_sse2_12, wrap_convolve8_avg_sse2_12, 12);
clang-format3a826f12016-08-11 17:46:05 -07001071const ConvolveParam kArrayConvolve_sse2[] = { ALL_SIZES(convolve8_sse2),
1072 ALL_SIZES(convolve10_sse2),
1073 ALL_SIZES(convolve12_sse2) };
Deb Mukherjee10783d42014-09-02 16:34:09 -07001074#else
Yunqing Wang3fb728c2013-10-10 13:51:35 -07001075const ConvolveFunctions convolve8_sse2(
Yaowu Xuf883b422016-08-30 14:01:10 -07001076 aom_convolve_copy_sse2, aom_convolve_avg_sse2, aom_convolve8_horiz_sse2,
1077 aom_convolve8_avg_horiz_sse2, aom_convolve8_vert_sse2,
1078 aom_convolve8_avg_vert_sse2, aom_convolve8_sse2, aom_convolve8_avg_sse2,
1079 aom_scaled_horiz_c, aom_scaled_avg_horiz_c, aom_scaled_vert_c,
1080 aom_scaled_avg_vert_c, aom_scaled_2d_c, aom_scaled_avg_2d_c, 0);
Yunqing Wang3fb728c2013-10-10 13:51:35 -07001081
Alex Conversef03e2382016-04-26 18:09:40 -07001082const ConvolveParam kArrayConvolve_sse2[] = { ALL_SIZES(convolve8_sse2) };
Yaowu Xuf883b422016-08-30 14:01:10 -07001083#endif // CONFIG_AOM_HIGHBITDEPTH
Alex Conversef03e2382016-04-26 18:09:40 -07001084INSTANTIATE_TEST_CASE_P(SSE2, ConvolveTest,
1085 ::testing::ValuesIn(kArrayConvolve_sse2));
Deb Mukherjee10783d42014-09-02 16:34:09 -07001086#endif
Yunqing Wang3fb728c2013-10-10 13:51:35 -07001087
John Koleszar29d47ac2013-02-07 17:00:37 -08001088#if HAVE_SSSE3
1089const ConvolveFunctions convolve8_ssse3(
Yaowu Xuf883b422016-08-30 14:01:10 -07001090 aom_convolve_copy_c, aom_convolve_avg_c, aom_convolve8_horiz_ssse3,
1091 aom_convolve8_avg_horiz_ssse3, aom_convolve8_vert_ssse3,
1092 aom_convolve8_avg_vert_ssse3, aom_convolve8_ssse3, aom_convolve8_avg_ssse3,
1093 aom_scaled_horiz_c, aom_scaled_avg_horiz_c, aom_scaled_vert_c,
1094 aom_scaled_avg_vert_c, aom_scaled_2d_ssse3, aom_scaled_avg_2d_c, 0);
John Koleszar29d47ac2013-02-07 17:00:37 -08001095
Alex Conversef03e2382016-04-26 18:09:40 -07001096const ConvolveParam kArrayConvolve8_ssse3[] = { ALL_SIZES(convolve8_ssse3) };
1097INSTANTIATE_TEST_CASE_P(SSSE3, ConvolveTest,
1098 ::testing::ValuesIn(kArrayConvolve8_ssse3));
John Koleszar29d47ac2013-02-07 17:00:37 -08001099#endif
Johann158c80c2013-05-23 12:50:41 -07001100
Johann8645a532014-09-10 10:27:58 -07001101#if HAVE_AVX2 && HAVE_SSSE3
Yunqing Wang4f0943b2014-05-27 10:36:56 -07001102const ConvolveFunctions convolve8_avx2(
Yaowu Xuf883b422016-08-30 14:01:10 -07001103 aom_convolve_copy_c, aom_convolve_avg_c, aom_convolve8_horiz_avx2,
1104 aom_convolve8_avg_horiz_ssse3, aom_convolve8_vert_avx2,
1105 aom_convolve8_avg_vert_ssse3, aom_convolve8_avx2, aom_convolve8_avg_ssse3,
1106 aom_scaled_horiz_c, aom_scaled_avg_horiz_c, aom_scaled_vert_c,
1107 aom_scaled_avg_vert_c, aom_scaled_2d_c, aom_scaled_avg_2d_c, 0);
Yunqing Wang4f0943b2014-05-27 10:36:56 -07001108
Alex Conversef03e2382016-04-26 18:09:40 -07001109const ConvolveParam kArrayConvolve8_avx2[] = { ALL_SIZES(convolve8_avx2) };
1110INSTANTIATE_TEST_CASE_P(AVX2, ConvolveTest,
1111 ::testing::ValuesIn(kArrayConvolve8_avx2));
Johann8645a532014-09-10 10:27:58 -07001112#endif // HAVE_AVX2 && HAVE_SSSE3
Yunqing Wang4f0943b2014-05-27 10:36:56 -07001113
Geza Lore938b8df2016-03-04 15:55:48 +00001114// TODO(any): Make NEON versions support 128x128 128x64 64x128 block sizes
Yaowu Xuf883b422016-08-30 14:01:10 -07001115#if HAVE_NEON && !(CONFIG_AV1 && CONFIG_EXT_PARTITION)
Johannce239312014-05-07 11:01:31 -07001116#if HAVE_NEON_ASM
Johann158c80c2013-05-23 12:50:41 -07001117const ConvolveFunctions convolve8_neon(
Yaowu Xuf883b422016-08-30 14:01:10 -07001118 aom_convolve_copy_neon, aom_convolve_avg_neon, aom_convolve8_horiz_neon,
1119 aom_convolve8_avg_horiz_neon, aom_convolve8_vert_neon,
1120 aom_convolve8_avg_vert_neon, aom_convolve8_neon, aom_convolve8_avg_neon,
1121 aom_scaled_horiz_c, aom_scaled_avg_horiz_c, aom_scaled_vert_c,
1122 aom_scaled_avg_vert_c, aom_scaled_2d_c, aom_scaled_avg_2d_c, 0);
clang-format3a826f12016-08-11 17:46:05 -07001123#else // HAVE_NEON
Scott LaVarnway617382a2014-09-10 09:49:34 -07001124const ConvolveFunctions convolve8_neon(
Yaowu Xuf883b422016-08-30 14:01:10 -07001125 aom_convolve_copy_neon, aom_convolve_avg_neon, aom_convolve8_horiz_neon,
1126 aom_convolve8_avg_horiz_neon, aom_convolve8_vert_neon,
1127 aom_convolve8_avg_vert_neon, aom_convolve8_neon, aom_convolve8_avg_neon,
1128 aom_scaled_horiz_c, aom_scaled_avg_horiz_c, aom_scaled_vert_c,
1129 aom_scaled_avg_vert_c, aom_scaled_2d_c, aom_scaled_avg_2d_c, 0);
Scott LaVarnway617382a2014-09-10 09:49:34 -07001130#endif // HAVE_NEON_ASM
Johann158c80c2013-05-23 12:50:41 -07001131
Alex Conversef03e2382016-04-26 18:09:40 -07001132const ConvolveParam kArrayConvolve8_neon[] = { ALL_SIZES(convolve8_neon) };
1133INSTANTIATE_TEST_CASE_P(NEON, ConvolveTest,
1134 ::testing::ValuesIn(kArrayConvolve8_neon));
Scott LaVarnway617382a2014-09-10 09:49:34 -07001135#endif // HAVE_NEON
Parag Salasakar40edab52013-09-13 15:18:32 +05301136
Geza Lore938b8df2016-03-04 15:55:48 +00001137// TODO(any): Make DSPR2 versions support 128x128 128x64 64x128 block sizes
Yaowu Xuf883b422016-08-30 14:01:10 -07001138#if HAVE_DSPR2 && !(CONFIG_AV1 && CONFIG_EXT_PARTITION)
Parag Salasakar40edab52013-09-13 15:18:32 +05301139const ConvolveFunctions convolve8_dspr2(
Yaowu Xuf883b422016-08-30 14:01:10 -07001140 aom_convolve_copy_dspr2, aom_convolve_avg_dspr2, aom_convolve8_horiz_dspr2,
1141 aom_convolve8_avg_horiz_dspr2, aom_convolve8_vert_dspr2,
1142 aom_convolve8_avg_vert_dspr2, aom_convolve8_dspr2, aom_convolve8_avg_dspr2,
1143 aom_scaled_horiz_c, aom_scaled_avg_horiz_c, aom_scaled_vert_c,
1144 aom_scaled_avg_vert_c, aom_scaled_2d_c, aom_scaled_avg_2d_c, 0);
Parag Salasakar40edab52013-09-13 15:18:32 +05301145
Alex Conversef03e2382016-04-26 18:09:40 -07001146const ConvolveParam kArrayConvolve8_dspr2[] = { ALL_SIZES(convolve8_dspr2) };
1147INSTANTIATE_TEST_CASE_P(DSPR2, ConvolveTest,
1148 ::testing::ValuesIn(kArrayConvolve8_dspr2));
1149#endif // HAVE_DSPR2
Parag Salasakar27d083c2015-04-16 11:03:24 +05301150
Geza Lore938b8df2016-03-04 15:55:48 +00001151// TODO(any): Make MSA versions support 128x128 128x64 64x128 block sizes
Yaowu Xuf883b422016-08-30 14:01:10 -07001152#if HAVE_MSA && !(CONFIG_AV1 && CONFIG_EXT_PARTITION)
Parag Salasakar27d083c2015-04-16 11:03:24 +05301153const ConvolveFunctions convolve8_msa(
Yaowu Xuf883b422016-08-30 14:01:10 -07001154 aom_convolve_copy_msa, aom_convolve_avg_msa, aom_convolve8_horiz_msa,
1155 aom_convolve8_avg_horiz_msa, aom_convolve8_vert_msa,
1156 aom_convolve8_avg_vert_msa, aom_convolve8_msa, aom_convolve8_avg_msa,
1157 aom_scaled_horiz_c, aom_scaled_avg_horiz_c, aom_scaled_vert_c,
1158 aom_scaled_avg_vert_c, aom_scaled_2d_c, aom_scaled_avg_2d_c, 0);
Parag Salasakar27d083c2015-04-16 11:03:24 +05301159
Alex Conversef03e2382016-04-26 18:09:40 -07001160const ConvolveParam kArrayConvolve8_msa[] = { ALL_SIZES(convolve8_msa) };
1161INSTANTIATE_TEST_CASE_P(MSA, ConvolveTest,
1162 ::testing::ValuesIn(kArrayConvolve8_msa));
Parag Salasakar27d083c2015-04-16 11:03:24 +05301163#endif // HAVE_MSA
James Zern8fb48af2013-05-02 13:08:19 -07001164} // namespace