• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The libgav1 Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/dsp/convolve.h"
16 
17 #include <algorithm>
18 #include <cassert>
19 #include <cstddef>
20 #include <cstdint>
21 #include <cstdio>
22 #include <cstring>
23 #include <ostream>
24 #include <string>
25 #include <tuple>
26 
27 #include "absl/strings/match.h"
28 #include "absl/strings/str_format.h"
29 #include "absl/strings/string_view.h"
30 #include "absl/time/clock.h"
31 #include "absl/time/time.h"
32 #include "gtest/gtest.h"
33 #include "src/dsp/constants.h"
34 #include "src/dsp/dsp.h"
35 #include "src/utils/common.h"
36 #include "src/utils/compiler_attributes.h"
37 #include "src/utils/constants.h"
38 #include "src/utils/cpu.h"
39 #include "src/utils/memory.h"
40 #include "tests/block_utils.h"
41 #include "tests/third_party/libvpx/acm_random.h"
42 #include "tests/third_party/libvpx/md5_helper.h"
43 #include "tests/utils.h"
44 
45 namespace libgav1 {
46 namespace dsp {
47 namespace {
48 
49 // The convolve function will access at most (block_height + 7) rows/columns
50 // from the beginning.
51 constexpr int kMaxBlockWidth = kMaxSuperBlockSizeInPixels + kSubPixelTaps;
52 constexpr int kMaxBlockHeight = kMaxSuperBlockSizeInPixels + kSubPixelTaps;
53 
54 // Test all the filters in |kSubPixelFilters|. There are 6 different filters but
55 // filters [4] and [5] are only reached through GetFilterIndex().
56 constexpr int kMinimumViableRuns = 4 * 16;
57 
58 struct ConvolveTestParam {
59   enum BlockSize {
60     kBlockSize2x2,
61     kBlockSize2x4,
62     kBlockSize4x2,
63     kBlockSize4x4,
64     kBlockSize4x8,
65     kBlockSize8x2,
66     kBlockSize8x4,
67     kBlockSize8x8,
68     kBlockSize8x16,
69     kBlockSize16x8,
70     kBlockSize16x16,
71     kBlockSize16x32,
72     kBlockSize32x16,
73     kBlockSize32x32,
74     kBlockSize32x64,
75     kBlockSize64x32,
76     kBlockSize64x64,
77     kBlockSize64x128,
78     kBlockSize128x64,
79     kBlockSize128x128,
80     kNumBlockSizes
81   };
82 
83   static constexpr int kBlockWidth[kNumBlockSizes] = {
84       2, 2, 4, 4, 4, 8, 8, 8, 8, 16, 16, 16, 32, 32, 32, 64, 64, 64, 128, 128};
85   static constexpr int kBlockHeight[kNumBlockSizes] = {
86       2, 4, 2, 4, 8, 2, 4, 8, 16, 8, 16, 32, 16, 32, 64, 32, 64, 128, 64, 128};
87 
ConvolveTestParamlibgav1::dsp::__anonc8f7b3170111::ConvolveTestParam88   explicit ConvolveTestParam(BlockSize block_size)
89       : block_size(block_size),
90         width(kBlockWidth[block_size]),
91         height(kBlockHeight[block_size]) {}
92 
93   BlockSize block_size;
94   int width;
95   int height;
96 };
97 
98 #if !LIBGAV1_CXX17
99 constexpr int ConvolveTestParam::kBlockWidth[kNumBlockSizes];   // static.
100 constexpr int ConvolveTestParam::kBlockHeight[kNumBlockSizes];  // static.
101 #endif
102 
GetConvolveDigest8bpp(int id)103 const char* GetConvolveDigest8bpp(int id) {
104   // Entries containing 'XXXXX...' are skipped. See the test for details.
105   static const char* const kDigest[ConvolveTestParam::kNumBlockSizes * 16] = {
106       "ae5977a4ceffbac0cde72a04a43a9d57", "6cf5f791fe0d8dcd3526be3c6b814035",
107       "d905dfcad930aded7718587c05b48aaf", "6baf153feff04cc5b7e87c0bb60a905d",
108       "871ed5a69ca31e6444faa720895949bf", "c9cf1deba08dac5972b3b0a43eff8f98",
109       "68e2f90eaa0ab5da7e6f5776993f7eea", "f1f8282fb33c30eb68c0c315b7a4bc01",
110       "9412064b0eebf8123f23d74147d04dff", "cc08936effe309ab9a4fa1bf7e28e24e",
111       "36cbef36fa21b98df03536c918bf752a", "9d0da6321cf5311ea0bdd41271763030",
112       "55a10165ee8a660d7dddacf7de558cdd", "ac7fc9f9ea7213743fae5a023faaaf08",
113       "077e1b7b355c7ab3ca40230ee8efd8ea", "7a3e8de2a1caae206cf3e51a86dfd15a",
114       "1ddf9020f18fa7883355cf8c0881186a", "2377dd167ef2707978bed6f10ffd4e76",
115       "f918e0e4422967c6a7e47298135c7ae9", "b2264e129636368b5496760b39e64b7a",
116       "1168251e6261e2ff1fa69a93226dbd76", "4821befdf63f8c6da6440afeb57f320f",
117       "c30fc44d83821141e84cc4793e127301", "a8293b933d9f2e5d7f922ea40111d643",
118       "354a54861a94e8b027afd9931e61f997", "b384e9e3d81f9f4f9024028fbe451d8b",
119       "eeeb8589c1b31cbb565154736ca939ec", "f49dab626ddd977ed171f79295c24935",
120       "78d2f27e0d4708cb16856d7d40dc16fb", "9d2393ea156a1c2083f5b4207793064b",
121       "a9c62745b95c66fa497a524886af57e2", "2c614ec4463386ec075a0f1dbb587933",
122       "7a8856480d752153370240b066b90f6a", "beaef1dbffadc701fccb7c18a03e3a41",
123       "72b1e700c949d06eaf62d664dafdb5b6", "684f5c3a25a080edaf79add6e9137a8e",
124       "3be970f49e4288988818b087201d54da", "d2b9dba2968894a414756bb510ac389a",
125       "9a3215eb97aedbbddd76c7440837d040", "4e317feac6da46addf0e8b9d8d54304b",
126       "d2f5ca2b7958c332a3fb771f66da01f0", "7aec92c3b65e456b64ae285c12b03b0d",
127       "f72a99ad63f6a88c23724e898b705d21", "07a1f07f114c4a38ba08d2f44e1e1132",
128       "26b9de95edb45b31ac5aa19825831c7a", "4e4677a0623d44237eb8d6a622cdc526",
129       "c1b836a6ce023663b90db0e320389414", "5befcf222152ebc8d779fcc10b95320a",
130       "62adf407fc27d8682ced4dd7b55af14e", "35be0786a072bf2f1286989261bf6580",
131       "90562fc42dc5d879ae74c4909c1dec30", "a1427352f9e413975a0949e2b300c657",
132       "bcbc418bc2beb243e463851cd95335a9", "cb8fedcbecee3947358dc61f95e56530",
133       "0d0154a7d573685285a83a4cf201ac57", "b14bd8068f108905682b83cc15778065",
134       "c96c867d998473197dde9b587be14e3a", "f596c63c7b14cada0174e17124c83942",
135       "eb2822ad8204ed4ecbf0f30fcb210498", "538ce869ffd23b6963e61badfab7712b",
136       "6bbcc075f8b768a02cdc9149f150326d", "4ae70d9db2ec36885394db7d59bdd4f7",
137       "5fee162fe52c11c823db4d5ede370654", "9365186c59ef66d9def40f437022ad93",
138       "0f95fb0276c9c7910937fbdf75f2811d", "356d4003477283e157c8d2b5a79d913c",
139       "b355dab2dbb6f5869018563eece22862", "cf6ff8c43d8059cea6090a23ab66a0ef",
140       "a336f8b7bcf188840ca65c0d0e66518a", "de953f03895923359c6a719e6a537b89",
141       "8463ade9347ed602663e2cec5c4c3fe6", "392de11ffcd5c2ecf3db3480ee135340",
142       "bddd31e3e852712e6244b616622af83d", "30a36245c40d978fc8976b442a8600c3",
143       "93aa662b988b8502e5ea95659eafde59", "70440ba9ee7f9d16d297dbb49e54a56e",
144       "1eb2be4c05b50e427e29c72fa566bff5", "52c0980bae63e8459e82eee7d8af2334",
145       "75e57104d6058cd2bce1d3d8142d273d", "b4c735269ade44419169adbd852d5ddc",
146       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
147       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "a7305087fae23de53d21a6909009ff69",
148       "8dcce009395264379c1a51239f4bb22c", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
149       "8dcce009395264379c1a51239f4bb22c", "d90a69e7bae8aa46ed0e1e5f911d7a07",
150       "6ab4dc87be03be1dcc5d956ca819d938", "6ab4dc87be03be1dcc5d956ca819d938",
151       "8f2afdb2f03cd04ffacd421b958caaa0", "710ccecc103033088d898a2b924551fb",
152       "710ccecc103033088d898a2b924551fb", "a4093e3e5902dd659407ce6471635a4e",
153       "375d7f5358d7a088a498b8b3aaecc0d5", "375d7f5358d7a088a498b8b3aaecc0d5",
154       "08867ea5cc38c705ec52af821bc4736a", "2afb540e8063f58d1b03896486c5e89b",
155       "2afb540e8063f58d1b03896486c5e89b", "6ce47b11d2e60c5d183c84ce9f2e46cc",
156       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
157       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "a5a1ac658d7ce4a846a32b9fcfaa3475",
158       "2370f4e4a83edf91b7f504bbe4b00e90", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
159       "ae5464066a049622a7a264cdf9394b55", "45368b6db3d1fee739a64b0bc823ea9c",
160       "8dff0f28192d9f8c0bf7fb5405719dd8", "632738ef3ff3021cff45045c41978849",
161       "f7ec43384037e8d6c618e0df826ec029", "a6bc648197781a2dc99c487e66464320",
162       "1112ebd509007154c72c5a485b220b62", "9714c4ce636b6fb0ad05cba246d48c76",
163       "2c93dde8884f09fb5bb5ad6d95cde86d", "a49e6160b5d1b56bc2046963101cd606",
164       "7f084953976111e9f65b57876e7552b1", "0846ec82555b66197c5c45b08240fbcc",
165       "ca7471c126ccd22189e874f0a6e41960", "0802b6318fbd0969a33de8fdfcd07f10",
166       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
167       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "3b1ceebf0579fcbbfd6136938c595b91",
168       "ecafabcad1045f15d31ce2f3b13132f2", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
169       "5f211eba020e256a5781b203c5aa1d2e", "3b04497634364dd2cd3f2482b5d4b32f",
170       "a8ac7b5dc65ffb758b0643508a0e744e", "561ed8be43c221a561f8885a0d74c7ef",
171       "8159619fc234598c8c75154d80021fd4", "8f43645dce92cf7594aa4822aa53b17d",
172       "b6ccddb7dfa4eddc87b4eff08b5a3195", "b4e605327b28db573d88844a1a09db8d",
173       "15b00a15d1cc6cc96ca85d00b167e4dd", "7bf911888c11a9fefd604b8b9c82e9a1",
174       "bfb69b4d7d4aed73cfa75a0f55b66440", "034d1d62581bd0d840c4cf1e28227931",
175       "8cba849640e9e2859d509bc81ca94acd", "bc79acf2a0fe419194cdb4529bc7dcc8",
176       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
177       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "3bfad931bce82335219e0e29c15f2b21",
178       "68a701313d2247d2b32636ebc1f2a008", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
179       "05afe1f40d37a45a97a5e0aadd5066fb", "9e1f0e0bddb58d15d0925eeaede9b84c",
180       "03313cdaa593a1a7b4869010dcc7b241", "88a50d2b4107ee5b5074b2520183f8ac",
181       "ac50ea9f7306da95a5092709442989cf", "739b17591437edffd36799237b962658",
182       "b8a7eb7dd9c216e240517edfc6489397", "75b755f199dbf4a0e5ebbb86c2bd871d",
183       "31b0017ba1110e3d70b020901bc15564", "0a1aa8f5ecfd11ddba080af0051c576a",
184       "536181ee90de883cc383787aec089221", "29f82b0f3e4113944bd28aacd9b8489a",
185       "ee3e76371240d1f1ff811cea6a7d4f63", "17a20dbbf09feae557d40aa5818fbe76",
186       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
187       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "6baf153feff04cc5b7e87c0bb60a905d",
188       "871ed5a69ca31e6444faa720895949bf", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
189       "68e2f90eaa0ab5da7e6f5776993f7eea", "f1f8282fb33c30eb68c0c315b7a4bc01",
190       "9412064b0eebf8123f23d74147d04dff", "cc08936effe309ab9a4fa1bf7e28e24e",
191       "36cbef36fa21b98df03536c918bf752a", "9d0da6321cf5311ea0bdd41271763030",
192       "55a10165ee8a660d7dddacf7de558cdd", "ac7fc9f9ea7213743fae5a023faaaf08",
193       "077e1b7b355c7ab3ca40230ee8efd8ea", "7a3e8de2a1caae206cf3e51a86dfd15a",
194       "1ddf9020f18fa7883355cf8c0881186a", "2377dd167ef2707978bed6f10ffd4e76",
195       "f918e0e4422967c6a7e47298135c7ae9", "b2264e129636368b5496760b39e64b7a",
196       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
197       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "4cfad2c437084a93ea76913e21c2dd89",
198       "d372f0c17bce98855d6d59fbee814c3d", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
199       "d99ffd2579eb781c30bc0df7b76ad61e", "4e139e57cbb049a0f4ef816adc48d026",
200       "be53b2507048e7ff50226d15c0b28865", "b73f3c1a10405de89d1f9e812ff73b5a",
201       "c7d51b1f2df49ab83962257e8a5934e5", "159e443d79cc59b11ca4a80aa7aa09be",
202       "6ef14b14882e1465b0482b0e0b16d8ce", "22a8d287b425c870f40c64a50f91ce54",
203       "f1d96db5a2e0a2160df38bd96d28d19b", "637d1e5221422dfe9a6dbcfd7f62ebdd",
204       "f275af4f1f350ffaaf650310cb5dddec", "f81c4d6b001a14584528880fa6988a87",
205       "a5a2f9c2e7759d8a3dec1bc4b56be587", "2317c57ab69a36eb3bf278cf8a8795a3",
206       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
207       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "1a0bdfc96a3b9fd904e658f238ab1076",
208       "56d16e54afe205e97527902770e71c71", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
209       "1f7b5b8282ff3cf4d8e8c52d80ef5b4d", "79e9e260a2028c5fe320005c272064b9",
210       "2418ebcdf85551b9ae6e3725f04aae6d", "98bdf907ebacacb734c9eef1ee727c6e",
211       "4dd5672d53c8f359e8f80badaa843dfc", "a1bef519bbf07138e2eec5a91694de46",
212       "df1cb51fe1a937cd7834e973dc5cb814", "317fe65abf81ef3ea07976ef8667baeb",
213       "2da29da97806ae0ee300c5e69c35a4aa", "555475f5d1685638169ab904447e4f13",
214       "b3e3a6234e8045e6182cf90a09f767b2", "849dfeca59074525dea59681a7f88ab4",
215       "39a68af80be11e1682b6f3c4ede33530", "b22d765af176d87e7d3048b4b89b86ad",
216       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
217       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "b8a710baa6a9fc784909671d450ecd99",
218       "f9e6a56382d8d12da676d6631bb6ef75", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
219       "3bf8e11e18527b16f0d7c0361d74a52d", "b9ff54c6f1e3b41fc7fc0f3fa0e75cf2",
220       "06ef1504f31af5f173d3317866ca57cb", "635e8ee11cf04d73598549234ad732a0",
221       "fab693410d59ee88aa2895527efc31ac", "3041eb26c23a63a587fbec623919e2d2",
222       "c61d99d5daf575664fb7ad64976f4b03", "822f6c4eb5db760468d822b21f48d94d",
223       "3f6fcb9fae3666e085b9e29002a802fc", "d9b9fecd195736a6049c528d4cb886b5",
224       "fed17fc391e6c3db4aa14ea1d6596c87", "d0d3482d981989e117cbb32fc4550267",
225       "39561688bf6680054edbfae6035316ce", "087c5992ca6f829e1ba4ba5332d67947",
226   };
227   assert(id >= 0);
228   assert(id < sizeof(kDigest) / sizeof(kDigest[0]));
229   return kDigest[id];
230 }
231 
GetConvolveScaleDigest8bpp(int id)232 const char* GetConvolveScaleDigest8bpp(int id) {
233   // Entries containing 'XXXXX...' are skipped. See the test for details.
234   static const char* const kDigest[ConvolveTestParam::kNumBlockSizes * 2] = {
235       "0291a23f2ac4c40b5d8e957e63769904", "1d48447857472d6455af10d5526f6827",
236       "409b2278d6d372248f1891ca0dd12760", "9e416606a3f82fe5bb3f7182e4f42c2d",
237       "e126563f859ddd5c5ffde6f641168fad", "9bad4f1b7e1865f814b6fd5620816ebd",
238       "50e5e5a57185477cb2af83490c33b47c", "3d2fb301c61d7fbd0e21ac263f7ac552",
239       "5920032c6432c80c6e5e61b684018d13", "07ada64d24339488cdce492e6e0c6b0d",
240       "aaf1589aff6d062a87c627ab9ba20e3e", "91adf91bb24d2c4ea3f882bdf7396e33",
241       "1d17a932a68bb1f199f709e7725fe44b", "07716c63afda034cb386511ea25a63b5",
242       "cca17ef3324c41d189e674a059ef1255", "37d17e70619823a606c0b5f74bf2e33b",
243       "ba8ed5474c187c8e8d7f82a6a29ee860", "27663f037973ebe82ec10252a4d91299",
244       "24c27e187e8d5a2bbfa0fef9046d3eb0", "9854fdc91a48e3bd4639edcc940e5c09",
245       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
246       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "a71907c60a9f1f81972a2859ae54a805",
247       "817bc3bf0c77abc4186eac39f2320184", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
248       "4e7182a8b226982e2678abcf5f83325d", "50cef7c6e57544135f102226bb95bed9",
249       "225e054dbcfff05b1c8b0792c731449e", "16eb63f03839159f3af0e08be857170f",
250       "c8e5d111a2e3f4487330a8bd893cb894", "4fd99eaf9c160442aab35b9bdc5d275b",
251       "8b0f61bfb30747d4c9215618ac42557c", "1df78022da202cefb9a8100b114152d9",
252       "378466e1eda63dbc03565b78af8e723f", "28ea721411fbf5fc805035be9a384140",
253       "4fed5d4163a3bfcc6726a42f20410b0a", "55abfca0c820771bd926e4b94f66a499",
254       "6c8b8ef0a78859c768e629e1decc0019", "d0ead286b5ba3841d24dd114efbfef0a",
255   };
256   assert(id >= 0);
257   assert(id < sizeof(kDigest) / sizeof(kDigest[0]));
258   return kDigest[id];
259 }
260 
261 #if LIBGAV1_MAX_BITDEPTH >= 10
GetConvolveDigest10bpp(int id)262 const char* GetConvolveDigest10bpp(int id) {
263   // Entries containing 'XXXXX...' are skipped. See the test for details.
264   static const char* const kDigest[ConvolveTestParam::kNumBlockSizes * 16] = {
265       "b1b6903d60501c7bc11e5285beb26a52", "a7855ed75772d7fa815978a202bbcd9f",
266       "bde291a4e8087c085fe8b3632f4d7351", "238980eebc9e63ae3eea2771c7a70f12",
267       "0eac13431bd7d8a573318408a72246d5", "d05a237ed7a9ca877256b71555b1b8e4",
268       "73438155feb62595e3e406921102d748", "5871e0e88a776840d619670fbf107858",
269       "1c6376ce55c9ee9e35d432edb1ffb3b7", "d675e0195c9feca956e637f3f1959f40",
270       "b5681673903ade13d69e295f82fdd009", "3c43020105ae93a301404b4cd6238654",
271       "dd2c5880a94ed3758bfea0b0e8c78286", "4ebb1a7b25a39d8b9868ec8a1243103f",
272       "d34ec07845cd8523651e5f5112984a14", "2ce55308d873f4cd244f16da2b06e06e",
273       "a4bb5d5ff4b25f391265b5231049a09a", "c9106e0c820b03bcdde3aa94efc11a3e",
274       "7ec2eae9e118506da8b33440b399511a", "78de867c8ee947ed6d29055747f26949",
275       "a693b4bd0334a3b98d45e67d3985bb63", "156de3172d9acf3c7f251cd7a18ad461",
276       "e545b8a3ff958f8363c7968cbae96732", "7842b2047356c1417d9d88219707f1a1",
277       "1a487c658d684314d91bb6d961a94672", "94b3e5bcd6b849b66a4571ec3d23f9be",
278       "0635a296be01b7e641de98ee27c33cd2", "82dc120bf8c2043bc5eee81007309ebf",
279       "58c826cad3c14cdf26a649265758c58b", "f166254037c0dfb140f54cd7b08bddfe",
280       "74ab206f14ac5f62653cd3dd71a7916d", "5621caef7cc1d6522903290ccc5c2cb8",
281       "78ec6cf42cce4b1feb65e076c78ca241", "42188e2dbb4e02cd353552ea147ad03f",
282       "f9813870fc27941a7c00a0443d7c2fe7", "20b14a6b5af7aa356963bcaaf23d230d",
283       "9c9c41435697f75fa118b6d6464ee7cb", "38816245ed832ba313fefafcbed1e5c8",
284       "5d34137cc8ddba75347b0fa1d0a91791", "465dcb046a0449b9dfb3e0b297aa3863",
285       "3e787534dff83c22b3033750e448865a", "4c91f676a054d582bcae1ca9adb87a31",
286       "eab5894046a99ad0a1a12c91b0f37bd7", "765b4cfbfc1a4988878c412d53bcb597",
287       "bc63b29ec78c1efec5543885a45bb822", "91d6bdbc62d4bb80c9b371d9704e3c9e",
288       "cecd57396a0033456408f3f3554c6912", "5b37f94ef136c1eb9a6181c19491459c",
289       "716ba3a25b454e44b46caa42622c128c", "9076f58c4ab20f2f06d701a6b53b1c4f",
290       "d3212ab3922f147c3cf126c3b1aa17f6", "b55fea77f0e14a8bf8b6562b766fe91f",
291       "59b578268ff26a1e21c5b4273f73f852", "16761e7c8ba2645718153bed83ae78f6",
292       "a9e9805769fe1baf5c7933793ccca0d8", "553a2c24939dff18ec5833c77f556cfb",
293       "5c1ec75a160c444fa90abf106fa1140e", "2266840f11ac4c066d941ec473b1a54f",
294       "9e194755b2a37b615a517d5f8746dfbb", "bbf86f8174334f0b8d869fd8d58bf92d",
295       "fd1da8d197cb385f7917cd296d67afb9", "a984202c527b757337c605443f376915",
296       "c347f4a58fd784c5e88c1a23e4ff15d2", "29cbaadbff9adf4a3d49bd9900a9dd0b",
297       "c5997b802a6ba1cf5ba1057ddc5baa7e", "4f750f6375524311d260306deb233861",
298       "59f33727e5beeb783a057770bec7b4cd", "0654d72f22306b28d9ae42515845240c",
299       "6c9d7d9e6ef81d76e775a85c53abe209", "a35f435ccc67717a49251a07e62ae204",
300       "c5325015cb0b7c42839ac4aa21803fa0", "f81f31f1585c0f70438c09e829416f20",
301       "ab10b22fb8dd8199040745565b28595d", "0d928d6111f86c60ccefc6c6604d5659",
302       "4ed1a6200912995d4f571bdb7822aa83", "92e31a45513582f386dc9c22a57bbbbd",
303       "6dbf310a9c8d85f76306d6a35545f8af", "80fce29dc82d5857c1ed5ef2aea16835",
304       "14f2c5b9d2cd621c178a39f1ec0c38eb", "da54cfb4530841bda29966cfa05f4879",
305       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
306       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "7e3fa9c03bc3dfbdeb67f24c5d9a49cd",
307       "f3454ca93cbb0c8c09b0695d90a0df3d", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
308       "f3454ca93cbb0c8c09b0695d90a0df3d", "1a77d2af4d2b6cf8737cfbcacacdc4e4",
309       "89bec831efea2f88129dedcad06bb3fa", "89bec831efea2f88129dedcad06bb3fa",
310       "dead0fe4030085c22e92d16bb110de9d", "306a2f5dfd675df4ed9af44fd5cac8c0",
311       "306a2f5dfd675df4ed9af44fd5cac8c0", "9d01c946a12f5ef9d9cebd9816e06014",
312       "768f63912e43148c13688d7f23281531", "768f63912e43148c13688d7f23281531",
313       "2e7927158e7b8e40e7269fc909fb584b", "123028e18c2bfb334e34adb5a4f67de4",
314       "123028e18c2bfb334e34adb5a4f67de4", "2c979c2bddef79a760e72a802f83cc76",
315       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
316       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "da1a6ff2be03ec8acde4cb1cd519a6f0",
317       "a4ca37cb869a0dbd1c4a2dcc449a8f31", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
318       "1b5d1d4c7be8d5ec00a42a49eecf918f", "98b77e88b0784baaea64c98c8707fe46",
319       "8148788044522edc3c497e1017efe2ce", "acf60abeda98bbea161139b915317423",
320       "262c96b1f2c4f85c86c0e9c77fedff1e", "f35a3d13516440f9168076d9b07c9e98",
321       "13782526fc2726100cb3cf375b3150ed", "13c07441b47b0c1ed80f015ac302d220",
322       "02880fde51ac991ad18d8986f4e5145c", "aa25073115bad49432953254e7dce0bc",
323       "69e3361b7199e10e75685b90fb0df623", "2f8ab35f6e7030e82ca922a68b29af4a",
324       "452f91b01833c57db4e909575a029ff6", "1fabf0655bedb671e4d7287fec8119ba",
325       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
326       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "d54206c34785cc3d8a06c2ceac46378c",
327       "85a11892ed884e3e74968435f6b16e64", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
328       "16434230d24b9522ae2680e8c37e1b95", "963dea92f3efbb99137d1de9c56728d3",
329       "b72fb6a9a073c2fe65013af1842dc9b0", "86fa0c299737eb499cbcdce94abe2d33",
330       "6b80af04470b83673d98f46925e678a5", "65baca6167fe5249f7a839ce5b2fd591",
331       "e47ded6c0eec1d5baadd02aff172f2b1", "c0950e609f278efb7050d319a9756bb3",
332       "9051290279237f9fb1389989b142d2dd", "34cdc1be291c95981c98812c5c343a15",
333       "5b64a6911cb7c3d60bb8f961ed9782a2", "7133de9d03a4b07716a12226b5e493e8",
334       "3594eff52d5ed875bd9655ddbf106fae", "90d7e13aa2f9a064493ff2b3b5b12109",
335       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
336       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "b1f26ee13df2e14a757416ba8a682278",
337       "996b6c166f9ed25bd07ea6acdf7597ff", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
338       "34895d4c69a6c3303693e6f431bcd5d8", "c9497b00cb1bc3363dd126ffdddadc8e",
339       "1e461869bb2ee9b6069c5e52cf817291", "8d7f1d7ea6a0dcc922ad5d2e77bc74dd",
340       "138855d9bf0ccd0c62ac14c7bff4fd37", "64035142864914d05a48ef8e013631d0",
341       "205904fa3c644433b46e01c11dd2fe40", "291425aaf8206b20e88db8ebf3cf7e7f",
342       "cb6238b8eb6b72980958e6fcceb2f2eb", "626321a6dfac542d0fc70321fac13ff3",
343       "1c6fda7501e0f8bdad972f7857cd9354", "4fd485dadcb570e5a0a5addaf9ba84da",
344       "d3f140aea9e8eabf4e1e5190e0148288", "e4938219593bbed5ae638a93f2f4a580",
345       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
346       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "238980eebc9e63ae3eea2771c7a70f12",
347       "0eac13431bd7d8a573318408a72246d5", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
348       "73438155feb62595e3e406921102d748", "5871e0e88a776840d619670fbf107858",
349       "1c6376ce55c9ee9e35d432edb1ffb3b7", "d675e0195c9feca956e637f3f1959f40",
350       "b5681673903ade13d69e295f82fdd009", "3c43020105ae93a301404b4cd6238654",
351       "dd2c5880a94ed3758bfea0b0e8c78286", "4ebb1a7b25a39d8b9868ec8a1243103f",
352       "d34ec07845cd8523651e5f5112984a14", "2ce55308d873f4cd244f16da2b06e06e",
353       "a4bb5d5ff4b25f391265b5231049a09a", "c9106e0c820b03bcdde3aa94efc11a3e",
354       "7ec2eae9e118506da8b33440b399511a", "78de867c8ee947ed6d29055747f26949",
355       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
356       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "e552466a4e7ff187251b8914b084d404",
357       "981b7c44b6f7b7ac2acf0cc4096e6bf4", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
358       "a4c75372af36162831cb872e24e1088c", "497271227a70a72f9ad25b415d41563f",
359       "c48bd7e11ec44ba7b2bc8b6a04592439", "0960a9af91250e9faa1eaac32227bf6f",
360       "746c2e0f96ae2246d534d67102be068c", "d6f6db079da9b8909a153c07cc9d0e63",
361       "7c8928a0d769f4264d195f39cb68a772", "db645c96fc8be04015e0eb538afec9ae",
362       "946af3a8f5362def5f4e27cb0fd4e754", "7ad78dfe7bbedf696dd58d9ad01bcfba",
363       "f0fd9c09d454e4ce918faa97e9ac10be", "af6ae5c0eb28417bd251184baf2eaba7",
364       "866f8df540dd3b58ab1339314d139cbd", "72803589b453a29501540aeddc23e6f4",
365       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
366       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "aba5d5ef5e96fe418e65d20e506ea834",
367       "d70bf16e2a31e90b7b3cdeaef1494cf9", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
368       "6df80bb7f264f4f285d09a4d61533fae", "c8831118d1004a7cca015a4fca140018",
369       "b7f82c140369067c105c7967c75b6f9e", "130f47aae365aabfec4360fa5b5ff554",
370       "92483ed631de21b685ffe6ccadbbec8f", "cbb6ab31547df6b91cfb48630fdffb48",
371       "1eea5e8a24d6aa11778eb3e5e5e9c9f2", "9e193b6b28ce798c44c744efde19eee9",
372       "885c384d90aaa34acd8303958033c252", "8110ed10e7234851dff3c7e4a51108a2",
373       "6fb9383302eb7e7a13387464d2634e03", "864d51fcc737bc73a3f588b67515039a",
374       "2ecb7890f00234bcb28c1d969f489012", "c4793d431dbf2d88826bb440bf027512",
375       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
376       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "972aeba65e8a6d20dd0f95279be2aa75",
377       "34165457282e2af2e9b3f5840e4dec5d", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
378       "b8c5582b9bbb789c45471f93be83b41f", "257bf5467db570974d7cf2356bacf116",
379       "5255dded79f56b0078543b5a1814a668", "ef745100f5f34c8ff841b2b0b57eb33f",
380       "edae8ed67286ca6a31573a541b3deb6f", "01adcd8bf15fbf70df47fbf3a953aa14",
381       "ba539808a8501609ce052a1562a62b25", "ac8e6391200cec2abdebb00744a2ba82",
382       "54b17120f7d71ddb4d70590ecd231cc1", "f6e36446a97611a4db4425df926974b2",
383       "a82f4080699300b659bbe1b5c4463147", "ecedb178f7cad3dc1b921eca67f9efb6",
384       "0609ca0ff3ca90069e8b48829b4b0891", "839e86c681e97359f7819c766000dd1c",
385   };
386   assert(id >= 0);
387   assert(id < sizeof(kDigest) / sizeof(kDigest[0]));
388   return kDigest[id];
389 }
390 
GetConvolveScaleDigest10bpp(int id)391 const char* GetConvolveScaleDigest10bpp(int id) {
392   // Entries containing 'XXXXX...' are skipped. See the test for details.
393   static const char* const kDigest[ConvolveTestParam::kNumBlockSizes * 2] = {
394       "27e21eb31687f9fbd0a66865fa8d7c8a", "9bff726c8e1d0998451a3b9cf2b3d8c8",
395       "661d74cfef36f12ed8d9b4c3ccb7fe0d", "5fc365fd1fcc9599dd97a885ba0c2eec",
396       "acdba2c82a6268e3c0ae8fc32be1b41f", "a5db60bbeaf56ab030ed21c42d553cf3",
397       "1228bb633f9fd63fdb998b775ca79e98", "07812c97f9f43a2a8ae07329dc488699",
398       "903525fb782119c4dfaf61b98a310c9f", "f38b51cef38b929e317861ccbc73ecd8",
399       "b78b05138e1d5fbf089144c42ce03058", "f2e227664cbf2d821b242a34fcbc9835",
400       "cb992dac70591e7d3663588ae13b9adc", "f2292d33657d939fa85ea5bacdfe39a3",
401       "7049dc742d6d8ad6f5d4309968ff281c", "e4beebde1ac335a4d92e4af94653a2ce",
402       "cc77875f98f54b9b26b5f7d9fcbc828d", "fb623f7b9e1ffcf2ae361599728a5589",
403       "c33847e47a7eda214734084640818df9", "ab3e1aec3d720c0c89c46a8d5b161b44",
404       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
405       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "efe4de861dcf0f7458b6208cae7e3584",
406       "814751c55fa84f0fed94ff15fc30fc24", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
407       "31a63fe47297102937acbe7a328588b7", "b804a0a24633243f7da48d7a5f51c0bf",
408       "cb492672b005fc378cccc8c03003cd4a", "1d18732bcf2ea487e84579489cc59a22",
409       "457c4b3ec38a8d6c210584ade1a9fae2", "a3afdd468e6a5238a3dbd2cc21c11c9e",
410       "6ff8a16f21d6e8a9741dacf0734ae563", "3ffa29ef7e54e51f6849c9a3d3c79d03",
411       "af89899b083cf269ac1bd988aeb15b15", "3365d8411c11081fb228436238b9a671",
412       "3ba56d30f5f81d7098f356635a58b9af", "b3013776900c6520bd30f868e8c963b6",
413       "81febaa7342692483040f500ba2e5e2b", "4a51ff1d9a4a68687d590b41aa7835a3",
414   };
415   assert(id >= 0);
416   assert(id < sizeof(kDigest) / sizeof(kDigest[0]));
417   return kDigest[id];
418 }
419 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
420 
421 #if LIBGAV1_MAX_BITDEPTH == 12
GetConvolveDigest12bpp(int id)422 const char* GetConvolveDigest12bpp(int id) {
423   // Entries containing 'XXXXX...' are skipped. See the test for details.
424   static const char* const kDigest[ConvolveTestParam::kNumBlockSizes * 16] = {
425       "e25031afae184cc4d186cde7e3d51e33", "6fb55dec2506dae6c229469cdf2e7d83",
426       "9df34d27f5bd040d1ed1455b151cd1ff", "7f6829458f00edb88f78851dd1a08739",
427       "a8bbe9b6b9eaf6f681d91c981b994949", "21f74980b36cb246426f4bc3fe7c08c3",
428       "403c2ccced3b5b141a4c7559c0cd841b", "1c3c4c6cd8a3e79cd95d6038531b47e5",
429       "f18d6950d36619086ac0055bab528cb1", "37d9c5babddf24fe8cb061297297b769",
430       "c111000d4021381f3d18ea0e24a1b5f5", "4e1e4f0a592ff028e35f8187627d6e68",
431       "0ca9ad4614d32da05746f8712a46d861", "8a122ab194e2fdb7089b29be50af8c86",
432       "3c21326e22a80982d1b0ffc09be4beae", "f6c8d1fe2c1fb19604c49c6a49bd26a8",
433       "d3eda9d7aa80e4ea1f18bf565b143e57", "fe21bd1cb8e90466dc727f2223ea7aed",
434       "01efe3df83c715325aaddd4d4ce130ad", "ecaa751360121d3746b72932415fb998",
435       "291e67095399651dc5c8a033390f255f", "66b26828e434faf37ddc57d3e0abb6db",
436       "e9cd69e9ba70864e3d0b175ac0a177d6", "64e4db895a843cb05384f5997b1ba978",
437       "f305161c82de999d2c93eac65f609cfe", "4762b2bd27983ad916ec0a930c0eca6b",
438       "1631495ffae43a927267ebd476015ef1", "b0f22de7b10057e07af71f9bce4615ce",
439       "6fa29dc4be1a46d246a41d66a3d35cb4", "734601c2185bdf30ba9ded8b07003a05",
440       "524e4553d92c69e7e4ed934f7b806c6b", "3709c8950bc5fcc4a2b3ec68fc78bf7e",
441       "69c274d9f8e0fd6790495e9695251f1f", "ee30cc1232c27494ef53edd383568f25",
442       "e525dbeb0b4341952a92270dcfc51730", "b3685c9e783d3402497bbd49d28c7dd7",
443       "d1c9f02dc818e6b974794dfb7749aac8", "bdb9e4961f9aa8c25568d3394e968518",
444       "f5f74555adcad85f3ebd3cb85dc7b770", "737e2a0be806dbd701014f2078be7898",
445       "20a18294e3a9422193aa0a219fd80ede", "7106648ecb9ae24a54d1dbabf2a9e318",
446       "20f39cbd6b5ed87a6ae4f818932325c0", "a99666e3157e32a07c87b01e52091a76",
447       "123e4d533d478c3089c975323c85396b", "d2a8021f7683a0cdf2658418fa90a6fc",
448       "1437e192a3349db8702d5b90eb88dbc1", "fe097fc4aeed7cda0b0f405124efb19d",
449       "1988227c51fa589db1307fd890bb5972", "537e25a6c30b240dc1e3bddd1c3a0a03",
450       "aebe5cffaae448db5a08987a3375a428", "7127ae9bdc63df4459590dc02ca95403",
451       "7ad281903a210f2b1f39f7c40c8df272", "d4b97ba21f7b400ba9f9cd8bb1a576df",
452       "0884a824203aaf72c78f73fdaf2b23a2", "63d60388605c92daee55d517de622a9e",
453       "171ec49a779de1efa69510eefbd09bba", "541cf051579c5a10b9debd3bfdcb7f32",
454       "91c14451ad93ed88e96b5d639ce408de", "3b0313ec0e043d19744bf88c90e875a1",
455       "6adcb3cee91fe3a83b36deb11c5ad6dd", "c6d4bfad24616a88222681992a99d782",
456       "515dc0f2a41730d5c434e4f3c81b02c3", "1c69abdee3b9608a6094034badc2bec0",
457       "1785a0f321d7dd90aa8846961737a767", "dd12c5b8c341f2423d0d5db4f285d199",
458       "5741fb69aae1ca8a0fbe4f1478df88ef", "a4390ceb4e4e9f5cf6a47a9b11a97015",
459       "6778eb25df902092b440c3402e7f0f80", "5ad9d6b36f8898bb55e901c1c0c523da",
460       "73969b6c03bb5a7345a8b968b542668e", "f48192947e66d70f116193a4186d0186",
461       "53f60d0e89d7d994ec6d6131fb7e75ae", "c75f6f8813839ae3cf192baa29039265",
462       "9ff0852ebbad56663250f86ac3a3bf9b", "668938580a770ea7ace8bbf7d349e89f",
463       "5b06bb0a15ac465a250d9b209f05289f", "a2128f5c8692fed7e7c1c7af22ce9f72",
464       "f80f1d7a58869ec794258c0f7df14620", "ed1e03a35924c92ed2fc9808dc3f06f3",
465       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
466       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "35ef89c35d2e8e46feb856c554c21c9f",
467       "b98ce33a1bf4fab840b7ef261b30dbc4", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
468       "b98ce33a1bf4fab840b7ef261b30dbc4", "42263fb359c4fdf1c7cdb4980b3e97f2",
469       "1e7071b7db3144188bdcf5d199fe5355", "1e7071b7db3144188bdcf5d199fe5355",
470       "30d367304a87bd25f0ad2ff8e4b5eb41", "4abe6dbb3198219015838dbedf07297a",
471       "4abe6dbb3198219015838dbedf07297a", "acec349a95b5bba98bb830372fa15e73",
472       "a73ad8661256ce2fdf5110425eb260b2", "a73ad8661256ce2fdf5110425eb260b2",
473       "8ff2f049d3f972867f14775188fe589b", "87f5f9a07aea75c325e6d7ff6c96c7c2",
474       "87f5f9a07aea75c325e6d7ff6c96c7c2", "325fcde7d415d7aa4929a3ea013fb9cc",
475       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
476       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "05aa29814d5ce35389dbcf20368850da",
477       "fbb89f907a040e70953e3364dbe1feda", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
478       "44ac511baf45032078cc0b45e41dba79", "efb98974adc58d88e122293436bb9184",
479       "7eee18c1a16bcb4e7ef7b27f68ba884f", "b0904c9b118dd9a1f9f034c0ff82d1c1",
480       "54436deb5183dd9669dd4f5feadb3850", "4db1c310b7d9a8bd3e2b5d20fa820e3b",
481       "c40abc6b2d67527f48a287cd7e157428", "48ec3fcf509805f484c8e0948c3469be",
482       "cb7d4a76fa7de52ed2fe889785327b38", "f57983346815fa41e969c195c1c03774",
483       "7dba59b0de2c877666ded6bdaefdcc30", "4837f8ba2f67f17f28a38c5e2a434c73",
484       "09e06fe9dc7ef7818f2a96895235afd4", "002976970ec62b360f956b9c091782d4",
485       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
486       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "78673b1084367e97b8dd83990adc5219",
487       "06b5d4a30b9efb6c1d95ef7957f49e76", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
488       "ce460146922cd53970b510d460aa4062", "6fd051938b8efcec9ece042f1edc177a",
489       "f5ff0dcfe3c1a56e3856549d8ded416b", "b69bc2cfc17c6b4313264db96831f0d1",
490       "38a5e65bd71934becfb376eb3b9bc513", "32c1163aa4ca6b6c69d950aba7b06d48",
491       "0c22a6c014c6347983de4ca863f3b53f", "a80c5ee9eb2dfb9a0d56e92eb3f85d91",
492       "a9719722a150a81175427bc161b95d7a", "8237befd456131a488cc5b8b63f4aca5",
493       "51616abcd0beea53a78ffce106b974fc", "6c47b22270f01d27b404da07e1be1202",
494       "356268298d3887edaabd0169a912c94e", "d2b00216e106cb8c5450e2eff1f8481a",
495       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
496       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "c2de3a582c79aee811076211c497d2bc",
497       "d1b6d9c73da41def26dd4f85fbd1bde8", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
498       "d8374eb7825081b89f74b05c66bccd63", "d5f7d68c10b5eaf0fba6f93ee26266e6",
499       "94d19cb65f29db65e6656b588f431ade", "5126e95f0249024a6f6d426714bd5b20",
500       "d7d3654b9c2dabe13239875984770acd", "6491afd5d651aab80aa179b579b74341",
501       "037a5de0de89983808f8e8f6dc39110f", "5980073b7685c5c9b2ec027e06be2cbc",
502       "0abb9d035aca426b62ca0f3fab063bab", "fe002a902bb4ec24dfe3ea0fe381a472",
503       "1ac15726df1aa2cd8855162a91893379", "0758c3ac16467605d73c725a697c3dc1",
504       "97d894d85f6ccfa4ff81e0e8fdf03da1", "c3c7b362f063a18244ea542a42d2873c",
505       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
506       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "7f6829458f00edb88f78851dd1a08739",
507       "a8bbe9b6b9eaf6f681d91c981b994949", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
508       "403c2ccced3b5b141a4c7559c0cd841b", "1c3c4c6cd8a3e79cd95d6038531b47e5",
509       "f18d6950d36619086ac0055bab528cb1", "37d9c5babddf24fe8cb061297297b769",
510       "c111000d4021381f3d18ea0e24a1b5f5", "4e1e4f0a592ff028e35f8187627d6e68",
511       "0ca9ad4614d32da05746f8712a46d861", "8a122ab194e2fdb7089b29be50af8c86",
512       "3c21326e22a80982d1b0ffc09be4beae", "f6c8d1fe2c1fb19604c49c6a49bd26a8",
513       "d3eda9d7aa80e4ea1f18bf565b143e57", "fe21bd1cb8e90466dc727f2223ea7aed",
514       "01efe3df83c715325aaddd4d4ce130ad", "ecaa751360121d3746b72932415fb998",
515       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
516       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "67b2ea94cc4d0b32db3ae3c29eee4d46",
517       "bcfec99ad75988fa1efc1733204f17f2", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
518       "79c222c5796e50119f1921e7bc534a25", "ae3f7c189458f044e9c52399d37a55e2",
519       "fd6dde45bd2937331428de9ef4f8e869", "b384d065423f3d271b85781d76a73218",
520       "466ea0680c06f59e8b3bb293608731fb", "360541ba94f42d115fe687a97a457ffb",
521       "e5a0794d37af40c40a4d2c6d3f7d2aa2", "4eed285651a75614bd60adebbe2e185c",
522       "bbdbf93942282d7b9c4f07591a1764a6", "1288a9ec3e6f79213b6745e6e7568c44",
523       "4ff1310bfd656d69ed5c108a91a9b01a", "3380806b5f67eb3ebce42f8e7c05b256",
524       "09c4bdf0f30aca6812fb55a5ac06b1bd", "722c86ba6bf21f40742ee33b4edc17c4",
525       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
526       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "f5303c96d1630f9840eaaba058cd818b",
527       "c20cd45782b2f52c05e4189912047570", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
528       "d6360f96fe15a3ee1e903b0a53dcaaeb", "4b18995cdf2f5d18410d3a732c5932b1",
529       "6f62bf7395c3dfccc1565ba8424f20e8", "c9987ed30491cd28bbc711dd57228247",
530       "8e277ec837cbecf529ae2eb0578fddc1", "c0c132386f23c5f0fba055a12fb79547",
531       "6b5617ab78dd0916690dfa358298b7b3", "394abedca37f60d1a5148a4c975305ed",
532       "bb88881e0e4cf2d88c2d2b38b5833f20", "bef10806be8d58ea8e97870a813b075e",
533       "b4b017d1f792bea69d3b773db7c80c7c", "0660bc63041213a8a4d74724a3bc4291",
534       "5050c8c5388a561691fd414b00c041df", "9ed40c68de6a8008a902d7224f8b620f",
535       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
536       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "ec10ce4a674424478a401847f744251d",
537       "bdd897eafc8ef2651a7bba5e523a6ac2", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
538       "2745de4a6b29abb85ee513e22ad362c3", "8aaad384b7cd349b4b968e657ec15523",
539       "fb6c0723432bcd2246d51a90f5fb5826", "f8104ed5921ebd48c6eed16150ffe028",
540       "85c2e236b3e32bf731601237cf0594cd", "8bd6eefff9640766cdf64ab082cb1485",
541       "78b5cd9dde6c6a5900f3040c57172091", "aaa980506bd7bb1d75924a8025698d1a",
542       "90050a411d501f7166f6741832b0c342", "d6ec88b2c38e32511f3359e1d5f9d85b",
543       "96506b8b39274c8fe687ea39761997f1", "3322ea83995c2762fb60db993b401658",
544       "151b6e4ce60392639982fca5a73ac3d3", "d52a1038e135bef233674a843f8c7cb6",
545   };
546   assert(id >= 0);
547   assert(id < sizeof(kDigest) / sizeof(kDigest[0]));
548   return kDigest[id];
549 }
550 
GetConvolveScaleDigest12bpp(int id)551 const char* GetConvolveScaleDigest12bpp(int id) {
552   // Entries containing 'XXXXX...' are skipped. See the test for details.
553   static const char* const kDigest[ConvolveTestParam::kNumBlockSizes * 2] = {
554       "aea59b7a638f27acad2b90fd2b8c9fee", "be87ba981a0af25611a7d5f0970be9b3",
555       "7c81f1486cd607376d776bf2c6e81dec", "f683ba2a9b353bea35f26c1ed730f3c5",
556       "11e2d70daff1726093cb4fcae33ce0d6", "567575eac0dea2f379019b2d4bafe444",
557       "216479ed580d6e0d7c1d523015394814", "dcabbe5f5709a4b6634d77cc514e863a",
558       "4e888207fe917faeea2b44383ac16caf", "d617c5608fae3b01c507c7e88040fee3",
559       "eeac5d9b3dc005e76f13dfc7483eae48", "8ff0a82811f77303c4516bb8c761336f",
560       "95a7c315aaa208097b6ab006f1d07654", "da63527ee80e6772435cff8321a29a95",
561       "404457f72e7113d1f3797a39319fd3fe", "43cbccfe2663ec11c157319acfe629a5",
562       "1dc5b8dee4542f3d7fcf6b0fa325dfde", "16d4506674f2fcedfcd1e006eb097141",
563       "4fcf329ddb405cd6bbb0a6fb87e29eb3", "de77a781957653ea1750f79995605cdc",
564       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
565       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "436f6fdc008d94a94bc6f516f98f402f",
566       "b436bd9036f08ba7e50cfc536911dbbd", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
567       "720a01018856bd83f4d89a9024b14728", "b7e01a3f161007712ce342f59b2c51f2",
568       "922420ebe5dec4f19c259ebdf8a3259a", "979aaba579556207a7bbcc939123c1b2",
569       "89a30898cbaa4d64f9072173e8365864", "0586ff961f2e4228f4e38299fb25ae07",
570       "adb27a03f8b1b50fe2a52b5ca8d4fc28", "4f91cd92aab2e09f4b123251a8d2f219",
571       "620fba0fff163d96a1cd663d1af4a4c5", "bf7a0fa65b1a90ba34c834558fa2c86e",
572       "c21f7d7d16d047a27b871a7bf8476e2d", "a94b17c81f3ce2b47081bd8dd762a2e5",
573       "9078d20f59bc24862af3856acb8c0357", "ee510ce6b3d22de9e4bd7920a26fd69a",
574   };
575   assert(id >= 0);
576   assert(id < sizeof(kDigest) / sizeof(kDigest[0]));
577   return kDigest[id];
578 }
579 #endif  // LIBGAV1_MAX_BITDEPTH == 12
580 
581 struct ConvolveTypeParam {
ConvolveTypeParamlibgav1::dsp::__anonc8f7b3170111::ConvolveTypeParam582   ConvolveTypeParam(bool is_intra_block_copy, bool is_compound,
583                     bool has_vertical_filter, bool has_horizontal_filter)
584       : is_intra_block_copy(is_intra_block_copy),
585         is_compound(is_compound),
586         has_vertical_filter(has_vertical_filter),
587         has_horizontal_filter(has_horizontal_filter) {}
588   bool is_intra_block_copy;
589   bool is_compound;
590   bool has_vertical_filter;
591   bool has_horizontal_filter;
592 };
593 
operator <<(std::ostream & os,const ConvolveTestParam & param)594 std::ostream& operator<<(std::ostream& os, const ConvolveTestParam& param) {
595   return os << "BlockSize" << param.width << "x" << param.height;
596 }
597 
operator <<(std::ostream & os,const ConvolveTypeParam & param)598 std::ostream& operator<<(std::ostream& os, const ConvolveTypeParam& param) {
599   return os << "is_intra_block_copy: " << param.is_intra_block_copy
600             << ", is_compound: " << param.is_compound
601             << ", has_(vertical/horizontal)_filter: "
602             << param.has_vertical_filter << "/" << param.has_horizontal_filter;
603 }
604 
605 //------------------------------------------------------------------------------
606 template <int bitdepth, typename Pixel>
607 class ConvolveTest : public testing::TestWithParam<
608                          std::tuple<ConvolveTypeParam, ConvolveTestParam>> {
609  public:
610   static_assert(bitdepth >= kBitdepth8 && bitdepth <= LIBGAV1_MAX_BITDEPTH, "");
611   ConvolveTest() = default;
612   ~ConvolveTest() override = default;
613 
SetUp()614   void SetUp() override {
615     ConvolveInit_C();
616 
617     const Dsp* const dsp = GetDspTable(bitdepth);
618     ASSERT_NE(dsp, nullptr);
619     GetConvolveFunc(dsp, &base_convolve_func_);
620 
621     const testing::TestInfo* const test_info =
622         testing::UnitTest::GetInstance()->current_test_info();
623     const absl::string_view test_case = test_info->test_suite_name();
624     if (absl::StartsWith(test_case, "C/")) {
625       base_convolve_func_ = nullptr;
626     } else if (absl::StartsWith(test_case, "SSE41/")) {
627       if ((GetCpuInfo() & kSSE4_1) != 0) {
628         ConvolveInit_SSE4_1();
629       }
630     } else if (absl::StartsWith(test_case, "AVX2/")) {
631       if ((GetCpuInfo() & kAVX2) != 0) {
632         ConvolveInit_AVX2();
633       }
634     } else if (absl::StartsWith(test_case, "NEON/")) {
635       ConvolveInit_NEON();
636 #if LIBGAV1_MAX_BITDEPTH >= 10
637       ConvolveInit10bpp_NEON();
638 #endif
639     } else {
640       FAIL() << "Unrecognized architecture prefix in test case name: "
641              << test_case;
642     }
643 
644     GetConvolveFunc(dsp, &cur_convolve_func_);
645 
646     // Skip functions that have not been specialized for this particular
647     // architecture.
648     if (cur_convolve_func_ == base_convolve_func_) {
649       cur_convolve_func_ = nullptr;
650     }
651   }
652 
653  protected:
GetDigestId() const654   int GetDigestId() const {
655     int id = param_.block_size;
656     id += param_.kNumBlockSizes *
657           static_cast<int>(type_param_.has_horizontal_filter);
658     id += 2 * param_.kNumBlockSizes *
659           static_cast<int>(type_param_.has_vertical_filter);
660     id += 4 * param_.kNumBlockSizes * static_cast<int>(type_param_.is_compound);
661     id += 8 * param_.kNumBlockSizes *
662           static_cast<int>(type_param_.is_intra_block_copy);
663     return id;
664   }
665 
666   void GetConvolveFunc(const Dsp* dsp, ConvolveFunc* func);
667   void SetInputData(bool use_fixed_values, int value);
668   void Check(bool use_fixed_values, const Pixel* src, const Pixel* dest,
669              libvpx_test::MD5* md5_digest);
670   void Check16Bit(bool use_fixed_values, const uint16_t* src,
671                   const uint16_t* dest, libvpx_test::MD5* md5_digest);
672   // |num_runs| covers the categories of filters (6) and the number of filters
673   // under each category (16).
674   void Test(bool use_fixed_values, int value,
675             int num_runs = kMinimumViableRuns);
676 
677   const ConvolveTypeParam type_param_ = std::get<0>(GetParam());
678   const ConvolveTestParam param_ = std::get<1>(GetParam());
679 
680  private:
681   ConvolveFunc base_convolve_func_;
682   ConvolveFunc cur_convolve_func_;
683   // Convolve filters are 7-tap, which need 3 pixels
684   // (kRestorationHorizontalBorder) padding.
685   Pixel source_[kMaxBlockHeight * kMaxBlockWidth] = {};
686   uint16_t source_16bit_[kMaxBlockHeight * kMaxBlockWidth] = {};
687   uint16_t dest_16bit_[kMaxBlockHeight * kMaxBlockWidth] = {};
688   Pixel dest_clipped_[kMaxBlockHeight * kMaxBlockWidth] = {};
689 
690   const int source_stride_ = kMaxBlockWidth;
691   const int source_height_ = kMaxBlockHeight;
692 };
693 
694 template <int bitdepth, typename Pixel>
GetConvolveFunc(const Dsp * const dsp,ConvolveFunc * func)695 void ConvolveTest<bitdepth, Pixel>::GetConvolveFunc(const Dsp* const dsp,
696                                                     ConvolveFunc* func) {
697   *func =
698       dsp->convolve[type_param_.is_intra_block_copy][type_param_.is_compound]
699                    [type_param_.has_vertical_filter]
700                    [type_param_.has_horizontal_filter];
701 }
702 
703 template <int bitdepth, typename Pixel>
SetInputData(bool use_fixed_values,int value)704 void ConvolveTest<bitdepth, Pixel>::SetInputData(bool use_fixed_values,
705                                                  int value) {
706   if (use_fixed_values) {
707     std::fill(source_, source_ + source_height_ * source_stride_, value);
708   } else {
709     const int offset =
710         kConvolveBorderLeftTop * source_stride_ + kConvolveBorderLeftTop;
711     const int mask = (1 << bitdepth) - 1;
712     libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed());
713     const int height = param_.height;
714     const int width = param_.width;
715     for (int y = 0; y < height; ++y) {
716       for (int x = 0; x < width; ++x) {
717         source_[y * source_stride_ + x + offset] = rnd.Rand16() & mask;
718       }
719     }
720     // Copy border pixels to the left and right borders.
721     for (int y = 0; y < height; ++y) {
722       Memset(&source_[(y + kConvolveBorderLeftTop) * source_stride_],
723              source_[y * source_stride_ + offset], kConvolveBorderLeftTop);
724       Memset(&source_[y * source_stride_ + offset + width],
725              source_[y * source_stride_ + offset + width - 1],
726              kConvolveBorderLeftTop);
727     }
728     // Copy border pixels to the top and bottom borders.
729     for (int y = 0; y < kConvolveBorderLeftTop; ++y) {
730       memcpy(&source_[y * source_stride_],
731              &source_[kConvolveBorderLeftTop * source_stride_],
732              source_stride_ * sizeof(Pixel));
733       memcpy(&source_[(y + kConvolveBorderLeftTop + height) * source_stride_],
734              &source_[(kConvolveBorderLeftTop + height - 1) * source_stride_],
735              source_stride_ * sizeof(Pixel));
736     }
737   }
738 }
739 
740 template <int bitdepth, typename Pixel>
Check(bool use_fixed_values,const Pixel * src,const Pixel * dest,libvpx_test::MD5 * md5_digest)741 void ConvolveTest<bitdepth, Pixel>::Check(bool use_fixed_values,
742                                           const Pixel* src, const Pixel* dest,
743                                           libvpx_test::MD5* md5_digest) {
744   if (use_fixed_values) {
745     // For fixed values, input and output are identical.
746     const bool success =
747         test_utils::CompareBlocks(src, dest, param_.width, param_.height,
748                                   kMaxBlockWidth, kMaxBlockWidth, false, false);
749     EXPECT_TRUE(success);
750   } else {
751     // For random input, compare md5.
752     const int offset =
753         kConvolveBorderLeftTop * kMaxBlockWidth + kConvolveBorderLeftTop;
754     const size_t size = sizeof(dest_clipped_) - offset * sizeof(Pixel);
755     md5_digest->Add(reinterpret_cast<const uint8_t*>(dest), size);
756   }
757 }
758 
759 template <int bitdepth, typename Pixel>
Check16Bit(bool use_fixed_values,const uint16_t * src,const uint16_t * dest,libvpx_test::MD5 * md5_digest)760 void ConvolveTest<bitdepth, Pixel>::Check16Bit(bool use_fixed_values,
761                                                const uint16_t* src,
762                                                const uint16_t* dest,
763                                                libvpx_test::MD5* md5_digest) {
764   if (use_fixed_values) {
765     // For fixed values, input and output are identical.
766     const bool success =
767         test_utils::CompareBlocks(src, dest, param_.width, param_.height,
768                                   kMaxBlockWidth, kMaxBlockWidth, false);
769     EXPECT_TRUE(success);
770   } else {
771     // For random input, compare md5.
772     const int offset =
773         kConvolveBorderLeftTop * kMaxBlockWidth + kConvolveBorderLeftTop;
774     const size_t size = sizeof(dest_16bit_) - offset * sizeof(uint16_t);
775     md5_digest->Add(reinterpret_cast<const uint8_t*>(dest), size);
776   }
777 }
778 
779 template <int bitdepth, typename Pixel>
Test(bool use_fixed_values,int value,int num_runs)780 void ConvolveTest<bitdepth, Pixel>::Test(
781     bool use_fixed_values, int value, int num_runs /*= kMinimumViableRuns*/) {
782   // There's no meaning testing fixed input in compound convolve.
783   if (type_param_.is_compound && use_fixed_values) return;
784 
785   // There should not be any function set for this combination.
786   if (type_param_.is_intra_block_copy && type_param_.is_compound) {
787     ASSERT_EQ(cur_convolve_func_, nullptr);
788     return;
789   }
790 
791   // Compound and intra block copy functions are only used for blocks 4x4 or
792   // greater.
793   if (type_param_.is_compound || type_param_.is_intra_block_copy) {
794     if (param_.width < 4 || param_.height < 4) {
795       GTEST_SKIP();
796     }
797   }
798 
799   // Skip unspecialized functions.
800   if (cur_convolve_func_ == nullptr) {
801     GTEST_SKIP();
802   }
803 
804   SetInputData(use_fixed_values, value);
805   int subpixel_x = 0;
806   int subpixel_y = 0;
807   int vertical_index = 0;
808   int horizontal_index = 0;
809   const int offset =
810       kConvolveBorderLeftTop * kMaxBlockWidth + kConvolveBorderLeftTop;
811   const Pixel* const src = source_ + offset;
812   const ptrdiff_t src_stride = source_stride_ * sizeof(Pixel);
813   const ptrdiff_t src_stride_16 = source_stride_;
814   const ptrdiff_t dst_stride = kMaxBlockWidth * sizeof(Pixel);
815   // Pack Compound output since we control the predictor buffer.
816   const ptrdiff_t dst_stride_compound = param_.width;
817 
818   // Output is always 16 bits regardless of |bitdepth|.
819   uint16_t* dst_16 = dest_16bit_ + offset;
820   // Output depends on |bitdepth|.
821   Pixel* dst_pixel = dest_clipped_ + offset;
822 
823   // Collect the first |kMinimumViableRuns| into one md5 buffer.
824   libvpx_test::MD5 md5_digest;
825 
826   absl::Duration elapsed_time;
827   for (int i = 0; i < num_runs; ++i) {
828     // Test every filter.
829     // Because of masking |subpixel_{x,y}| values roll over every 16 iterations.
830     subpixel_x += 1 << 6;
831     subpixel_y += 1 << 6;
832 
833     const int horizontal_filter_id = (subpixel_x >> 6) & 0xF;
834     const int vertical_filter_id = (subpixel_y >> 6) & 0xF;
835 
836     // |filter_id| == 0 (copy) must be handled by the appropriate 1D or copy
837     // function.
838     if (horizontal_filter_id == 0 || vertical_filter_id == 0) {
839       continue;
840     }
841 
842     // For focused speed testing these can be set to the desired filter. Want
843     // only 8 tap filters? Set |{vertical,horizontal}_index| to 2.
844     vertical_index += static_cast<int>(i % 16 == 0);
845     vertical_index %= 4;
846     horizontal_index += static_cast<int>(i % 16 == 0);
847     horizontal_index %= 4;
848 
849     if (type_param_.is_compound) {
850       // Output type is uint16_t.
851       const absl::Time start = absl::Now();
852       cur_convolve_func_(src, src_stride, horizontal_index, vertical_index,
853                          horizontal_filter_id, vertical_filter_id, param_.width,
854                          param_.height, dst_16, dst_stride_compound);
855       elapsed_time += absl::Now() - start;
856     } else {
857       // Output type is Pixel.
858       const absl::Time start = absl::Now();
859       cur_convolve_func_(src, src_stride, horizontal_index, vertical_index,
860                          horizontal_filter_id, vertical_filter_id, param_.width,
861                          param_.height, dst_pixel, dst_stride);
862       elapsed_time += absl::Now() - start;
863     }
864 
865     // Only check the output for the first set. After that it's just repeated
866     // runs for speed timing.
867     if (i >= kMinimumViableRuns) continue;
868 
869     if (type_param_.is_compound) {
870       // Need to copy source to a uint16_t buffer for comparison.
871       Pixel* src_ptr = source_;
872       uint16_t* src_ptr_16 = source_16bit_;
873       for (int y = 0; y < kMaxBlockHeight; ++y) {
874         for (int x = 0; x < kMaxBlockWidth; ++x) {
875           src_ptr_16[x] = src_ptr[x];
876         }
877         src_ptr += src_stride_16;
878         src_ptr_16 += src_stride_16;
879       }
880 
881       Check16Bit(use_fixed_values, source_16bit_ + offset, dst_16, &md5_digest);
882     } else {
883       Check(use_fixed_values, src, dst_pixel, &md5_digest);
884     }
885   }
886 
887   if (!use_fixed_values) {
888     // md5 sums are only calculated for random input.
889     const char* ref_digest = nullptr;
890     switch (bitdepth) {
891       case 8:
892         ref_digest = GetConvolveDigest8bpp(GetDigestId());
893         break;
894 #if LIBGAV1_MAX_BITDEPTH >= 10
895       case 10:
896         ref_digest = GetConvolveDigest10bpp(GetDigestId());
897         break;
898 #endif
899 #if LIBGAV1_MAX_BITDEPTH == 12
900       case 12:
901         ref_digest = GetConvolveDigest12bpp(GetDigestId());
902         break;
903 #endif
904     }
905     ASSERT_NE(ref_digest, nullptr);
906 
907     const char* direction;
908     if (type_param_.has_vertical_filter && type_param_.has_horizontal_filter) {
909       direction = "2D";
910     } else if (type_param_.has_vertical_filter) {
911       direction = "Vertical";
912     } else if (type_param_.has_horizontal_filter) {
913       direction = "Horizontal";
914     } else {
915       direction = "Copy";
916     }
917     const auto elapsed_time_us =
918         static_cast<int>(absl::ToInt64Microseconds(elapsed_time));
919     printf("Mode Convolve%s%s%s[%25s]: %5d us MD5: %s\n",
920            type_param_.is_compound ? "Compound" : "",
921            type_param_.is_intra_block_copy ? "IntraBlockCopy" : "", direction,
922            absl::StrFormat("%dx%d", param_.width, param_.height).c_str(),
923            elapsed_time_us, md5_digest.Get());
924     EXPECT_STREQ(ref_digest, md5_digest.Get());
925   }
926 }
927 
ApplyFilterToSignedInput(const int min_input,const int max_input,const int8_t filter[kSubPixelTaps],int * min_output,int * max_output)928 void ApplyFilterToSignedInput(const int min_input, const int max_input,
929                               const int8_t filter[kSubPixelTaps],
930                               int* min_output, int* max_output) {
931   int min = 0, max = 0;
932   for (int i = 0; i < kSubPixelTaps; ++i) {
933     const int tap = filter[i];
934     if (tap > 0) {
935       max += max_input * tap;
936       min += min_input * tap;
937     } else {
938       min += max_input * tap;
939       max += min_input * tap;
940     }
941   }
942   *min_output = min;
943   *max_output = max;
944 }
945 
ApplyFilterToUnsignedInput(const int max_input,const int8_t filter[kSubPixelTaps],int * min_output,int * max_output)946 void ApplyFilterToUnsignedInput(const int max_input,
947                                 const int8_t filter[kSubPixelTaps],
948                                 int* min_output, int* max_output) {
949   ApplyFilterToSignedInput(0, max_input, filter, min_output, max_output);
950 }
951 
952 // Validate the maximum ranges for different parts of the Convolve process.
953 template <int bitdepth>
ShowRange()954 void ShowRange() {
955   // Subtract one from the shift bits because the filter is pre-shifted by 1.
956   constexpr int horizontal_bits = (bitdepth == kBitdepth12)
957                                       ? kInterRoundBitsHorizontal12bpp - 1
958                                       : kInterRoundBitsHorizontal - 1;
959   constexpr int vertical_bits = (bitdepth == kBitdepth12)
960                                     ? kInterRoundBitsVertical12bpp - 1
961                                     : kInterRoundBitsVertical - 1;
962   constexpr int compound_vertical_bits = kInterRoundBitsCompoundVertical - 1;
963 
964   constexpr int compound_offset = (bitdepth == 8) ? 0 : kCompoundOffset;
965 
966   constexpr int max_input = (1 << bitdepth) - 1;
967 
968   const int8_t* worst_convolve_filter = kHalfSubPixelFilters[2][8];
969 
970   // First pass.
971   printf("Bitdepth: %2d Input range:            [%8d, %8d]\n", bitdepth, 0,
972          max_input);
973 
974   int min, max;
975   ApplyFilterToUnsignedInput(max_input, worst_convolve_filter, &min, &max);
976 
977   if (bitdepth == 8) {
978     // 8bpp can use int16_t for sums.
979     assert(min > INT16_MIN);
980     assert(max < INT16_MAX);
981   } else {
982     // 10bpp and 12bpp require int32_t.
983     assert(min > INT32_MIN);
984     assert(max > INT16_MAX && max < INT32_MAX);
985   }
986 
987   printf("  Horizontal upscaled range:         [%8d, %8d]\n", min, max);
988 
989   const int first_pass_min = RightShiftWithRounding(min, horizontal_bits);
990   const int first_pass_max = RightShiftWithRounding(max, horizontal_bits);
991 
992   // All bitdepths can use int16_t for first pass output.
993   assert(first_pass_min > INT16_MIN);
994   assert(first_pass_max < INT16_MAX);
995 
996   printf("  Horizontal downscaled range:       [%8d, %8d]\n", first_pass_min,
997          first_pass_max);
998 
999   // Second pass.
1000   ApplyFilterToSignedInput(first_pass_min, first_pass_max,
1001                            worst_convolve_filter, &min, &max);
1002 
1003   // All bitdepths require int32_t for second pass sums.
1004   assert(min < INT16_MIN && min > INT32_MIN);
1005   assert(max > INT16_MAX && max < INT32_MAX);
1006 
1007   printf("  Vertical upscaled range:           [%8d, %8d]\n", min, max);
1008 
1009   // Second pass non-compound output is clipped to Pixel values.
1010   const int second_pass_min =
1011       Clip3(RightShiftWithRounding(min, vertical_bits), 0, max_input);
1012   const int second_pass_max =
1013       Clip3(RightShiftWithRounding(max, vertical_bits), 0, max_input);
1014   printf("  Pixel output range:                [%8d, %8d]\n", second_pass_min,
1015          second_pass_max);
1016 
1017   // Output is Pixel so matches Pixel values.
1018   assert(second_pass_min == 0);
1019   assert(second_pass_max == max_input);
1020 
1021   const int compound_second_pass_min =
1022       RightShiftWithRounding(min, compound_vertical_bits) + compound_offset;
1023   const int compound_second_pass_max =
1024       RightShiftWithRounding(max, compound_vertical_bits) + compound_offset;
1025 
1026   printf("  Compound output range:             [%8d, %8d]\n",
1027          compound_second_pass_min, compound_second_pass_max);
1028 
1029   if (bitdepth == 8) {
1030     // 8bpp output is int16_t without an offset.
1031     assert(compound_second_pass_min > INT16_MIN);
1032     assert(compound_second_pass_max < INT16_MAX);
1033   } else {
1034     // 10bpp and 12bpp use the offset to fit inside uint16_t.
1035     assert(compound_second_pass_min > 0);
1036     assert(compound_second_pass_max < UINT16_MAX);
1037   }
1038 
1039   printf("\n");
1040 }
1041 
TEST(ConvolveTest,ShowRange)1042 TEST(ConvolveTest, ShowRange) {
1043   ShowRange<kBitdepth8>();
1044   ShowRange<kBitdepth10>();
1045   ShowRange<kBitdepth12>();
1046 }
1047 
1048 using ConvolveTest8bpp = ConvolveTest<8, uint8_t>;
1049 
TEST_P(ConvolveTest8bpp,FixedValues)1050 TEST_P(ConvolveTest8bpp, FixedValues) {
1051   Test(true, 0);
1052   Test(true, 1);
1053   Test(true, 128);
1054   Test(true, 255);
1055 }
1056 
TEST_P(ConvolveTest8bpp,RandomValues)1057 TEST_P(ConvolveTest8bpp, RandomValues) { Test(false, 0); }
1058 
TEST_P(ConvolveTest8bpp,DISABLED_Speed)1059 TEST_P(ConvolveTest8bpp, DISABLED_Speed) {
1060   const int num_runs = static_cast<int>(1.0e7 / (param_.width * param_.height));
1061   Test(false, 0, num_runs);
1062 }
1063 
1064 //------------------------------------------------------------------------------
1065 template <int bitdepth, typename Pixel>
1066 class ConvolveScaleTest
1067     : public testing::TestWithParam<
1068           std::tuple<bool /*is_compound*/, ConvolveTestParam>> {
1069  public:
1070   static_assert(bitdepth >= kBitdepth8 && bitdepth <= LIBGAV1_MAX_BITDEPTH, "");
1071   ConvolveScaleTest() = default;
1072   ~ConvolveScaleTest() override = default;
1073 
SetUp()1074   void SetUp() override {
1075     ConvolveInit_C();
1076 
1077     const Dsp* const dsp = GetDspTable(bitdepth);
1078     ASSERT_NE(dsp, nullptr);
1079     base_convolve_scale_func_ = dsp->convolve_scale[is_compound_];
1080 
1081     const testing::TestInfo* const test_info =
1082         testing::UnitTest::GetInstance()->current_test_info();
1083     const absl::string_view test_case = test_info->test_suite_name();
1084     if (absl::StartsWith(test_case, "C/")) {
1085       base_convolve_scale_func_ = nullptr;
1086     } else if (absl::StartsWith(test_case, "SSE41/")) {
1087       if ((GetCpuInfo() & kSSE4_1) != 0) {
1088         ConvolveInit_SSE4_1();
1089       }
1090     } else if (absl::StartsWith(test_case, "AVX2/")) {
1091       if ((GetCpuInfo() & kAVX2) != 0) {
1092         ConvolveInit_AVX2();
1093       }
1094     } else if (absl::StartsWith(test_case, "NEON/")) {
1095       ConvolveInit_NEON();
1096 #if LIBGAV1_MAX_BITDEPTH >= 10
1097       ConvolveInit10bpp_NEON();
1098 #endif
1099     } else {
1100       FAIL() << "Unrecognized architecture prefix in test case name: "
1101              << test_case;
1102     }
1103 
1104     cur_convolve_scale_func_ = dsp->convolve_scale[is_compound_];
1105 
1106     // Skip functions that have not been specialized for this particular
1107     // architecture.
1108     if (cur_convolve_scale_func_ == base_convolve_scale_func_) {
1109       cur_convolve_scale_func_ = nullptr;
1110     }
1111   }
1112 
1113  protected:
GetDigestId() const1114   int GetDigestId() const {
1115     return param_.block_size +
1116            param_.kNumBlockSizes * static_cast<int>(is_compound_);
1117   }
1118 
1119   void SetInputData(bool use_fixed_values, int value);
1120   void Check(bool use_fixed_values, const Pixel* src, const Pixel* dest,
1121              libvpx_test::MD5* md5_digest);
1122   void Check16Bit(bool use_fixed_values, const uint16_t* src,
1123                   const uint16_t* dest, libvpx_test::MD5* md5_digest);
1124   // |num_runs| covers the categories of filters (6) and the number of filters
1125   // under each category (16).
1126   void Test(bool use_fixed_values, int value,
1127             int num_runs = kMinimumViableRuns);
1128 
1129   const bool is_compound_ = std::get<0>(GetParam());
1130   const ConvolveTestParam param_ = std::get<1>(GetParam());
1131 
1132  private:
1133   ConvolveScaleFunc base_convolve_scale_func_;
1134   ConvolveScaleFunc cur_convolve_scale_func_;
1135   // Convolve filters are 7-tap, which need 3 pixels
1136   // (kRestorationHorizontalBorder) padding.
1137   // The source can be at most 2 times of max width/height.
1138   Pixel source_[kMaxBlockHeight * kMaxBlockWidth * 4] = {};
1139   uint16_t source_16bit_[kMaxBlockHeight * kMaxBlockWidth * 4] = {};
1140   uint16_t dest_16bit_[kMaxBlockHeight * kMaxBlockWidth] = {};
1141   Pixel dest_clipped_[kMaxBlockHeight * kMaxBlockWidth] = {};
1142 
1143   const int source_stride_ = kMaxBlockWidth * 2;
1144   const int source_height_ = kMaxBlockHeight * 2;
1145 };
1146 
1147 template <int bitdepth, typename Pixel>
SetInputData(bool use_fixed_values,int value)1148 void ConvolveScaleTest<bitdepth, Pixel>::SetInputData(bool use_fixed_values,
1149                                                       int value) {
1150   if (use_fixed_values) {
1151     std::fill(source_, source_ + source_height_ * source_stride_, value);
1152   } else {
1153     const int offset =
1154         kConvolveBorderLeftTop * source_stride_ + kConvolveBorderLeftTop;
1155     const int mask = (1 << bitdepth) - 1;
1156     libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed());
1157     const int height = param_.height * 2;
1158     const int width = param_.width * 2;
1159     for (int y = 0; y < height; ++y) {
1160       for (int x = 0; x < width; ++x) {
1161         source_[y * source_stride_ + x + offset] = rnd.Rand16() & mask;
1162       }
1163     }
1164     // Copy border pixels to the left and right borders.
1165     for (int y = 0; y < height; ++y) {
1166       Memset(&source_[(y + kConvolveBorderLeftTop) * source_stride_],
1167              source_[y * source_stride_ + offset], kConvolveBorderLeftTop);
1168       Memset(&source_[y * source_stride_ + offset + width],
1169              source_[y * source_stride_ + offset + width - 1],
1170              kConvolveBorderLeftTop);
1171     }
1172     // Copy border pixels to the top and bottom borders.
1173     for (int y = 0; y < kConvolveBorderLeftTop; ++y) {
1174       memcpy(&source_[y * source_stride_],
1175              &source_[kConvolveBorderLeftTop * source_stride_],
1176              source_stride_ * sizeof(Pixel));
1177       memcpy(&source_[(y + kConvolveBorderLeftTop + height) * source_stride_],
1178              &source_[(kConvolveBorderLeftTop + height - 1) * source_stride_],
1179              source_stride_ * sizeof(Pixel));
1180     }
1181   }
1182 }
1183 
1184 template <int bitdepth, typename Pixel>
Check(bool use_fixed_values,const Pixel * src,const Pixel * dest,libvpx_test::MD5 * md5_digest)1185 void ConvolveScaleTest<bitdepth, Pixel>::Check(bool use_fixed_values,
1186                                                const Pixel* src,
1187                                                const Pixel* dest,
1188                                                libvpx_test::MD5* md5_digest) {
1189   if (use_fixed_values) {
1190     // For fixed values, input and output are identical.
1191     const bool success =
1192         test_utils::CompareBlocks(src, dest, param_.width, param_.height,
1193                                   kMaxBlockWidth, kMaxBlockWidth, false, false);
1194     EXPECT_TRUE(success);
1195   } else {
1196     // For random input, compare md5.
1197     const int offset =
1198         kConvolveBorderLeftTop * kMaxBlockWidth + kConvolveBorderLeftTop;
1199     const size_t size = sizeof(dest_clipped_) - offset * sizeof(Pixel);
1200     md5_digest->Add(reinterpret_cast<const uint8_t*>(dest), size);
1201   }
1202 }
1203 
1204 template <int bitdepth, typename Pixel>
Check16Bit(bool use_fixed_values,const uint16_t * src,const uint16_t * dest,libvpx_test::MD5 * md5_digest)1205 void ConvolveScaleTest<bitdepth, Pixel>::Check16Bit(
1206     bool use_fixed_values, const uint16_t* src, const uint16_t* dest,
1207     libvpx_test::MD5* md5_digest) {
1208   if (use_fixed_values) {
1209     // For fixed values, input and output are identical.
1210     const bool success =
1211         test_utils::CompareBlocks(src, dest, param_.width, param_.height,
1212                                   kMaxBlockWidth, kMaxBlockWidth, false);
1213     EXPECT_TRUE(success);
1214   } else {
1215     // For random input, compare md5.
1216     const int offset =
1217         kConvolveBorderLeftTop * kMaxBlockWidth + kConvolveBorderLeftTop;
1218     const size_t size = sizeof(dest_16bit_) - offset * sizeof(uint16_t);
1219     md5_digest->Add(reinterpret_cast<const uint8_t*>(dest), size);
1220   }
1221 }
1222 
1223 template <int bitdepth, typename Pixel>
Test(bool use_fixed_values,int value,int num_runs)1224 void ConvolveScaleTest<bitdepth, Pixel>::Test(
1225     bool use_fixed_values, int value, int num_runs /*= kMinimumViableRuns*/) {
1226   // There's no meaning testing fixed input in compound convolve.
1227   if (is_compound_ && use_fixed_values) return;
1228 
1229   // The compound function is only used for blocks 4x4 or greater.
1230   if (is_compound_) {
1231     if (param_.width < 4 || param_.height < 4) {
1232       GTEST_SKIP();
1233     }
1234   }
1235 
1236   // Skip unspecialized functions.
1237   if (cur_convolve_scale_func_ == nullptr) {
1238     GTEST_SKIP();
1239   }
1240 
1241   SetInputData(use_fixed_values, value);
1242   libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed() +
1243                              GetDigestId());
1244   // [1,2048] for |step_[xy]|. This covers a scaling range of 1/1024 to 2x.
1245   const int step_x = (rnd.Rand16() & ((1 << 11) - 1)) + 1;
1246   const int step_y = (rnd.Rand16() & ((1 << 11) - 1)) + 1;
1247   int subpixel_x = 0;
1248   int subpixel_y = 0;
1249   int vertical_index = 0;
1250   int horizontal_index = 0;
1251   const int offset =
1252       kConvolveBorderLeftTop * kMaxBlockWidth + kConvolveBorderLeftTop;
1253   const int offset_scale =
1254       kConvolveBorderLeftTop * source_stride_ + kConvolveBorderLeftTop;
1255   const Pixel* const src_scale = source_ + offset_scale;
1256   const ptrdiff_t src_stride = source_stride_ * sizeof(Pixel);
1257   const ptrdiff_t dst_stride = kMaxBlockWidth * sizeof(Pixel);
1258   // Pack Compound output since we control the predictor buffer.
1259   const ptrdiff_t dst_stride_compound = param_.width;
1260 
1261   // Output is always 16 bits regardless of |bitdepth|.
1262   uint16_t* dst_16 = dest_16bit_ + offset;
1263   // Output depends on |bitdepth|.
1264   Pixel* dst_pixel = dest_clipped_ + offset;
1265 
1266   // Collect the first |kMinimumViableRuns| into one md5 buffer.
1267   libvpx_test::MD5 md5_digest;
1268 
1269   absl::Duration elapsed_time;
1270   for (int i = 0; i < num_runs; ++i) {
1271     // Test every filter.
1272     // Because of masking |subpixel_{x,y}| values roll over every 16 iterations.
1273     subpixel_x += 1 << 6;
1274     subpixel_y += 1 << 6;
1275 
1276     const int horizontal_filter_id = (subpixel_x >> 6) & 0xF;
1277     const int vertical_filter_id = (subpixel_y >> 6) & 0xF;
1278 
1279     // |filter_id| == 0 (copy) must be handled by the appropriate 1D or copy
1280     // function.
1281     if (horizontal_filter_id == 0 || vertical_filter_id == 0) {
1282       continue;
1283     }
1284 
1285     // For focused speed testing these can be set to the desired filter. Want
1286     // only 8 tap filters? Set |{vertical,horizontal}_index| to 2.
1287     vertical_index += static_cast<int>(i % 16 == 0);
1288     vertical_index %= 4;
1289     horizontal_index += static_cast<int>(i % 16 == 0);
1290     horizontal_index %= 4;
1291 
1292     // Output type is uint16_t.
1293     const absl::Time start = absl::Now();
1294     if (is_compound_) {
1295       cur_convolve_scale_func_(
1296           source_, src_stride, horizontal_index, vertical_index, 0, 0, step_x,
1297           step_y, param_.width, param_.height, dst_16, dst_stride_compound);
1298     } else {
1299       cur_convolve_scale_func_(
1300           source_, src_stride, horizontal_index, vertical_index, 0, 0, step_x,
1301           step_y, param_.width, param_.height, dst_pixel, dst_stride);
1302     }
1303     elapsed_time += absl::Now() - start;
1304 
1305     // Only check the output for the first set. After that it's just repeated
1306     // runs for speed timing.
1307     if (i >= kMinimumViableRuns) continue;
1308 
1309     // Convolve function does not clip the output. The clipping is applied
1310     // later, but libaom clips the output. So we apply clipping to match
1311     // libaom in tests.
1312     if (is_compound_) {
1313       const int single_round_offset = (1 << bitdepth) + (1 << (bitdepth - 1));
1314       Pixel* dest_row = dest_clipped_;
1315       for (int y = 0; y < kMaxBlockHeight; ++y) {
1316         for (int x = 0; x < kMaxBlockWidth; ++x) {
1317           dest_row[x] = static_cast<Pixel>(Clip3(
1318               dest_16bit_[y * dst_stride_compound + x] - single_round_offset, 0,
1319               (1 << bitdepth) - 1));
1320         }
1321         dest_row += kMaxBlockWidth;
1322       }
1323     }
1324 
1325     if (is_compound_) {
1326       Check16Bit(use_fixed_values, source_16bit_ + offset_scale, dst_16,
1327                  &md5_digest);
1328     } else {
1329       Check(use_fixed_values, src_scale, dst_pixel, &md5_digest);
1330     }
1331   }
1332 
1333   if (!use_fixed_values) {
1334     // md5 sums are only calculated for random input.
1335     const char* ref_digest = nullptr;
1336     switch (bitdepth) {
1337       case 8:
1338         ref_digest = GetConvolveScaleDigest8bpp(GetDigestId());
1339         break;
1340 #if LIBGAV1_MAX_BITDEPTH >= 10
1341       case 10:
1342         ref_digest = GetConvolveScaleDigest10bpp(GetDigestId());
1343         break;
1344 #endif
1345 #if LIBGAV1_MAX_BITDEPTH == 12
1346       case 12:
1347         ref_digest = GetConvolveScaleDigest12bpp(GetDigestId());
1348         break;
1349 #endif
1350     }
1351     ASSERT_NE(ref_digest, nullptr);
1352 
1353     const auto elapsed_time_us =
1354         static_cast<int>(absl::ToInt64Microseconds(elapsed_time));
1355     printf("Mode Convolve%sScale2D[%25s]: %5d us MD5: %s\n",
1356            is_compound_ ? "Compound" : "",
1357            absl::StrFormat("%dx%d", param_.width, param_.height).c_str(),
1358            elapsed_time_us, md5_digest.Get());
1359     EXPECT_STREQ(ref_digest, md5_digest.Get());
1360   }
1361 }
1362 
1363 using ConvolveScaleTest8bpp = ConvolveScaleTest<8, uint8_t>;
1364 
TEST_P(ConvolveScaleTest8bpp,FixedValues)1365 TEST_P(ConvolveScaleTest8bpp, FixedValues) {
1366   Test(true, 0);
1367   Test(true, 1);
1368   Test(true, 128);
1369   Test(true, 255);
1370 }
1371 
TEST_P(ConvolveScaleTest8bpp,RandomValues)1372 TEST_P(ConvolveScaleTest8bpp, RandomValues) { Test(false, 0); }
1373 
TEST_P(ConvolveScaleTest8bpp,DISABLED_Speed)1374 TEST_P(ConvolveScaleTest8bpp, DISABLED_Speed) {
1375   const int num_runs = static_cast<int>(1.0e7 / (param_.width * param_.height));
1376   Test(false, 0, num_runs);
1377 }
1378 
1379 //------------------------------------------------------------------------------
1380 const ConvolveTestParam kConvolveParam[] = {
1381     ConvolveTestParam(ConvolveTestParam::kBlockSize2x2),
1382     ConvolveTestParam(ConvolveTestParam::kBlockSize2x4),
1383     ConvolveTestParam(ConvolveTestParam::kBlockSize4x2),
1384     ConvolveTestParam(ConvolveTestParam::kBlockSize4x4),
1385     ConvolveTestParam(ConvolveTestParam::kBlockSize4x8),
1386     ConvolveTestParam(ConvolveTestParam::kBlockSize8x2),
1387     ConvolveTestParam(ConvolveTestParam::kBlockSize8x4),
1388     ConvolveTestParam(ConvolveTestParam::kBlockSize8x8),
1389     ConvolveTestParam(ConvolveTestParam::kBlockSize8x16),
1390     ConvolveTestParam(ConvolveTestParam::kBlockSize16x8),
1391     ConvolveTestParam(ConvolveTestParam::kBlockSize16x16),
1392     ConvolveTestParam(ConvolveTestParam::kBlockSize16x32),
1393     ConvolveTestParam(ConvolveTestParam::kBlockSize32x16),
1394     ConvolveTestParam(ConvolveTestParam::kBlockSize32x32),
1395     ConvolveTestParam(ConvolveTestParam::kBlockSize32x64),
1396     ConvolveTestParam(ConvolveTestParam::kBlockSize64x32),
1397     ConvolveTestParam(ConvolveTestParam::kBlockSize64x64),
1398     ConvolveTestParam(ConvolveTestParam::kBlockSize64x128),
1399     ConvolveTestParam(ConvolveTestParam::kBlockSize128x64),
1400     ConvolveTestParam(ConvolveTestParam::kBlockSize128x128),
1401 };
1402 
1403 const ConvolveTypeParam kConvolveTypeParam[] = {
1404     ConvolveTypeParam(false, false, false, false),
1405     ConvolveTypeParam(false, false, false, true),
1406     ConvolveTypeParam(false, false, true, false),
1407     ConvolveTypeParam(false, false, true, true),
1408     ConvolveTypeParam(false, true, false, false),
1409     ConvolveTypeParam(false, true, false, true),
1410     ConvolveTypeParam(false, true, true, false),
1411     ConvolveTypeParam(false, true, true, true),
1412     ConvolveTypeParam(true, false, false, false),
1413     ConvolveTypeParam(true, false, false, true),
1414     ConvolveTypeParam(true, false, true, false),
1415     ConvolveTypeParam(true, false, true, true),
1416     // This is left to ensure no function exists for |intra_block_copy| when
1417     // |is_compound| is true; all combinations aren't necessary.
1418     ConvolveTypeParam(true, true, false, false),
1419 };
1420 
1421 INSTANTIATE_TEST_SUITE_P(C, ConvolveTest8bpp,
1422                          testing::Combine(testing::ValuesIn(kConvolveTypeParam),
1423                                           testing::ValuesIn(kConvolveParam)));
1424 INSTANTIATE_TEST_SUITE_P(C, ConvolveScaleTest8bpp,
1425                          testing::Combine(testing::Bool(),
1426                                           testing::ValuesIn(kConvolveParam)));
1427 
1428 #if LIBGAV1_ENABLE_NEON
1429 INSTANTIATE_TEST_SUITE_P(NEON, ConvolveTest8bpp,
1430                          testing::Combine(testing::ValuesIn(kConvolveTypeParam),
1431                                           testing::ValuesIn(kConvolveParam)));
1432 INSTANTIATE_TEST_SUITE_P(NEON, ConvolveScaleTest8bpp,
1433                          testing::Combine(testing::Bool(),
1434                                           testing::ValuesIn(kConvolveParam)));
1435 #endif  // LIBGAV1_ENABLE_NEON
1436 
1437 #if LIBGAV1_ENABLE_SSE4_1
1438 INSTANTIATE_TEST_SUITE_P(SSE41, ConvolveTest8bpp,
1439                          testing::Combine(testing::ValuesIn(kConvolveTypeParam),
1440                                           testing::ValuesIn(kConvolveParam)));
1441 INSTANTIATE_TEST_SUITE_P(SSE41, ConvolveScaleTest8bpp,
1442                          testing::Combine(testing::Bool(),
1443                                           testing::ValuesIn(kConvolveParam)));
1444 #endif  // LIBGAV1_ENABLE_SSE4_1
1445 
1446 #if LIBGAV1_ENABLE_AVX2
1447 INSTANTIATE_TEST_SUITE_P(AVX2, ConvolveTest8bpp,
1448                          testing::Combine(testing::ValuesIn(kConvolveTypeParam),
1449                                           testing::ValuesIn(kConvolveParam)));
1450 INSTANTIATE_TEST_SUITE_P(AVX2, ConvolveScaleTest8bpp,
1451                          testing::Combine(testing::Bool(),
1452                                           testing::ValuesIn(kConvolveParam)));
1453 #endif  // LIBGAV1_ENABLE_AVX2
1454 
1455 #if LIBGAV1_MAX_BITDEPTH >= 10
1456 using ConvolveTest10bpp = ConvolveTest<10, uint16_t>;
1457 
TEST_P(ConvolveTest10bpp,FixedValues)1458 TEST_P(ConvolveTest10bpp, FixedValues) {
1459   Test(true, 0);
1460   Test(true, 1);
1461   Test(true, 128);
1462   Test(true, (1 << 10) - 1);
1463 }
1464 
TEST_P(ConvolveTest10bpp,RandomValues)1465 TEST_P(ConvolveTest10bpp, RandomValues) { Test(false, 0); }
1466 
TEST_P(ConvolveTest10bpp,DISABLED_Speed)1467 TEST_P(ConvolveTest10bpp, DISABLED_Speed) {
1468   const int num_runs = static_cast<int>(1.0e7 / (param_.width * param_.height));
1469   Test(false, 0, num_runs);
1470 }
1471 
1472 using ConvolveScaleTest10bpp = ConvolveScaleTest<10, uint16_t>;
1473 
TEST_P(ConvolveScaleTest10bpp,FixedValues)1474 TEST_P(ConvolveScaleTest10bpp, FixedValues) {
1475   Test(true, 0);
1476   Test(true, 1);
1477   Test(true, 128);
1478   Test(true, (1 << 10) - 1);
1479 }
1480 
TEST_P(ConvolveScaleTest10bpp,RandomValues)1481 TEST_P(ConvolveScaleTest10bpp, RandomValues) { Test(false, 0); }
1482 
TEST_P(ConvolveScaleTest10bpp,DISABLED_Speed)1483 TEST_P(ConvolveScaleTest10bpp, DISABLED_Speed) {
1484   const int num_runs = static_cast<int>(1.0e7 / (param_.width * param_.height));
1485   Test(false, 0, num_runs);
1486 }
1487 
1488 INSTANTIATE_TEST_SUITE_P(C, ConvolveTest10bpp,
1489                          testing::Combine(testing::ValuesIn(kConvolveTypeParam),
1490                                           testing::ValuesIn(kConvolveParam)));
1491 INSTANTIATE_TEST_SUITE_P(C, ConvolveScaleTest10bpp,
1492                          testing::Combine(testing::Bool(),
1493                                           testing::ValuesIn(kConvolveParam)));
1494 
1495 #if LIBGAV1_ENABLE_NEON
1496 INSTANTIATE_TEST_SUITE_P(NEON, ConvolveTest10bpp,
1497                          testing::Combine(testing::ValuesIn(kConvolveTypeParam),
1498                                           testing::ValuesIn(kConvolveParam)));
1499 INSTANTIATE_TEST_SUITE_P(NEON, ConvolveScaleTest10bpp,
1500                          testing::Combine(testing::Bool(),
1501                                           testing::ValuesIn(kConvolveParam)));
1502 #endif  // LIBGAV1_ENABLE_NEON
1503 
1504 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
1505 
1506 #if LIBGAV1_MAX_BITDEPTH == 12
1507 using ConvolveTest12bpp = ConvolveTest<12, uint16_t>;
1508 
TEST_P(ConvolveTest12bpp,FixedValues)1509 TEST_P(ConvolveTest12bpp, FixedValues) {
1510   Test(true, 0);
1511   Test(true, 1);
1512   Test(true, 128);
1513   Test(true, (1 << 12) - 1);
1514 }
1515 
TEST_P(ConvolveTest12bpp,RandomValues)1516 TEST_P(ConvolveTest12bpp, RandomValues) { Test(false, 0); }
1517 
TEST_P(ConvolveTest12bpp,DISABLED_Speed)1518 TEST_P(ConvolveTest12bpp, DISABLED_Speed) {
1519   const int num_runs = static_cast<int>(1.0e7 / (param_.width * param_.height));
1520   Test(false, 0, num_runs);
1521 }
1522 
1523 using ConvolveScaleTest12bpp = ConvolveScaleTest<12, uint16_t>;
1524 
TEST_P(ConvolveScaleTest12bpp,FixedValues)1525 TEST_P(ConvolveScaleTest12bpp, FixedValues) {
1526   Test(true, 0);
1527   Test(true, 1);
1528   Test(true, 128);
1529   Test(true, (1 << 12) - 1);
1530 }
1531 
TEST_P(ConvolveScaleTest12bpp,RandomValues)1532 TEST_P(ConvolveScaleTest12bpp, RandomValues) { Test(false, 0); }
1533 
TEST_P(ConvolveScaleTest12bpp,DISABLED_Speed)1534 TEST_P(ConvolveScaleTest12bpp, DISABLED_Speed) {
1535   const int num_runs = static_cast<int>(1.0e7 / (param_.width * param_.height));
1536   Test(false, 0, num_runs);
1537 }
1538 
1539 INSTANTIATE_TEST_SUITE_P(C, ConvolveTest12bpp,
1540                          testing::Combine(testing::ValuesIn(kConvolveTypeParam),
1541                                           testing::ValuesIn(kConvolveParam)));
1542 INSTANTIATE_TEST_SUITE_P(C, ConvolveScaleTest12bpp,
1543                          testing::Combine(testing::Bool(),
1544                                           testing::ValuesIn(kConvolveParam)));
1545 #endif  // LIBGAV1_MAX_BITDEPTH == 12
1546 
1547 }  // namespace
1548 }  // namespace dsp
1549 }  // namespace libgav1
1550