1 // Unit tests for ResampleEffect.
4 #include <gtest/gtest.h>
9 #include "effect_chain.h"
10 #include "flat_input.h"
12 #include "image_format.h"
14 #include "resample_effect.h"
15 #include "test_util.h"
25 return sin(M_PI * x) / (M_PI * x);
28 float lanczos(float x, float a)
33 return sinc(x) * sinc(x / a);
39 class ResampleEffectTest : public testing::TestWithParam<string> {
41 ResampleEffectTest() : disabler(GetParam() == "fragment") {}
42 bool should_skip() { return disabler.should_skip(); }
45 DisableComputeShadersTemporarily disabler;
48 TEST_P(ResampleEffectTest, IdentityTransformDoesNothing) {
51 float data[size * size] = {
57 float out_data[size * size];
59 EffectChainTester tester(data, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
60 Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
61 ASSERT_TRUE(resample_effect->set_int("width", 4));
62 ASSERT_TRUE(resample_effect->set_int("height", 4));
63 tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
65 expect_equal(data, out_data, size, size);
68 TEST_P(ResampleEffectTest, UpscaleByTwoGetsCorrectPixelCenters) {
71 float data[size * size] = {
72 0.0, 0.0, 0.0, 0.0, 0.0,
73 0.0, 0.0, 0.0, 0.0, 0.0,
74 0.0, 0.0, 1.0, 0.0, 0.0,
75 0.0, 0.0, 0.0, 0.0, 0.0,
76 0.0, 0.0, 0.0, 0.0, 0.0,
78 float expected_data[size * size * 4], out_data[size * size * 4];
80 for (int y = 0; y < size * 2; ++y) {
81 for (int x = 0; x < size * 2; ++x) {
82 float weight = lanczos((x - size + 0.5f) * 0.5f, 3.0f);
83 weight *= lanczos((y - size + 0.5f) * 0.5f, 3.0f);
84 expected_data[y * (size * 2) + x] = weight;
88 EffectChainTester tester(nullptr, size * 2, size * 2, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
91 format.color_space = COLORSPACE_sRGB;
92 format.gamma_curve = GAMMA_LINEAR;
94 FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, size, size);
95 input->set_pixel_data(data);
96 tester.get_chain()->add_input(input);
98 Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
99 ASSERT_TRUE(resample_effect->set_int("width", size * 2));
100 ASSERT_TRUE(resample_effect->set_int("height", size * 2));
101 tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
103 expect_equal(expected_data, out_data, size * 2, size * 2);
106 TEST_P(ResampleEffectTest, DownscaleByTwoGetsCorrectPixelCenters) {
109 // This isn't a perfect dot, since the Lanczos filter has a slight
110 // sharpening effect; the most important thing is that we have kept
111 // the texel center right (everything is nicely symmetric).
112 // The approximate magnitudes have been checked against ImageMagick.
113 float expected_data[size * size] = {
114 0.0045, -0.0067, -0.0599, -0.0067, 0.0045,
115 -0.0067, 0.0100, 0.0892, 0.0100, -0.0067,
116 -0.0599, 0.0890, 0.7925, 0.0892, -0.0599,
117 -0.0067, 0.0100, 0.0890, 0.0100, -0.0067,
118 0.0045, -0.0067, -0.0599, -0.0067, 0.0045,
120 float data[size * size * 4], out_data[size * size];
122 for (int y = 0; y < size * 2; ++y) {
123 for (int x = 0; x < size * 2; ++x) {
124 float weight = lanczos((x - size + 0.5f) * 0.5f, 3.0f);
125 weight *= lanczos((y - size + 0.5f) * 0.5f, 3.0f);
126 data[y * (size * 2) + x] = weight;
130 EffectChainTester tester(nullptr, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
133 format.color_space = COLORSPACE_sRGB;
134 format.gamma_curve = GAMMA_LINEAR;
136 FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, size * 2, size * 2);
137 input->set_pixel_data(data);
138 tester.get_chain()->add_input(input);
140 Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
141 ASSERT_TRUE(resample_effect->set_int("width", size));
142 ASSERT_TRUE(resample_effect->set_int("height", size));
143 tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
145 expect_equal(expected_data, out_data, size, size);
148 TEST_P(ResampleEffectTest, UpscaleByThreeGetsCorrectPixelCenters) {
151 float data[size * size] = {
152 0.0, 0.0, 0.0, 0.0, 0.0,
153 0.0, 0.0, 0.0, 0.0, 0.0,
154 0.0, 0.0, 1.0, 0.0, 0.0,
155 0.0, 0.0, 0.0, 0.0, 0.0,
156 0.0, 0.0, 0.0, 0.0, 0.0,
158 float out_data[size * size * 9];
160 EffectChainTester tester(nullptr, size * 3, size * 3, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
163 format.color_space = COLORSPACE_sRGB;
164 format.gamma_curve = GAMMA_LINEAR;
166 FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, size, size);
167 input->set_pixel_data(data);
168 tester.get_chain()->add_input(input);
170 Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
171 ASSERT_TRUE(resample_effect->set_int("width", size * 3));
172 ASSERT_TRUE(resample_effect->set_int("height", size * 3));
173 tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
175 // We only bother checking that the middle pixel is still correct,
176 // and that symmetry holds. Note that the middle weight in practice
177 // becomes something like 0.99999 due to the normalization
178 // (some supposedly zero weights become 1e-6 or so), and then after
179 // squaring, the error compounds. Ironically, less texture precision
180 // here will give a more accurate result, since the weight can get
181 // rounded towards 1.0.
182 EXPECT_NEAR(1.0, out_data[7 * (size * 3) + 7], 1e-3);
183 for (unsigned y = 0; y < size * 3; ++y) {
184 for (unsigned x = 0; x < size * 3; ++x) {
185 EXPECT_NEAR(out_data[y * (size * 3) + x], out_data[(size * 3 - y - 1) * (size * 3) + x], 1e-6);
186 EXPECT_NEAR(out_data[y * (size * 3) + x], out_data[y * (size * 3) + (size * 3 - x - 1)], 1e-6);
191 TEST_P(ResampleEffectTest, HeavyResampleGetsSumRight) {
192 // Do only one resample pass, more specifically the last one, which goes to
193 // our fp32 output. This allows us to analyze the precision without intermediate
195 const int swidth = 1, sheight = 1280;
196 const int dwidth = 1, dheight = 64;
198 float data[swidth * sheight], out_data[dwidth * dheight], expected_data[dwidth * dheight];
199 for (int y = 0; y < sheight; ++y) {
200 for (int x = 0; x < swidth; ++x) {
201 data[y * swidth + x] = 1.0f;
204 for (int y = 0; y < dheight; ++y) {
205 for (int x = 0; x < dwidth; ++x) {
206 expected_data[y * dwidth + x] = 1.0f;
210 EffectChainTester tester(nullptr, dwidth, dheight, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR, GL_RGBA32F);
213 format.color_space = COLORSPACE_sRGB;
214 format.gamma_curve = GAMMA_LINEAR;
216 FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, swidth, sheight);
217 input->set_pixel_data(data);
219 tester.get_chain()->add_input(input);
220 Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
221 ASSERT_TRUE(resample_effect->set_int("width", dwidth));
222 ASSERT_TRUE(resample_effect->set_int("height", dheight));
223 tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
225 // Require that we are within 10-bit accuracy. Note that this limit is for
226 // one pass only, but the limit is tight enough that it should be good enough
227 // for 10-bit accuracy even after two passes.
228 expect_equal(expected_data, out_data, dwidth, dheight, 0.12 / 1023.0);
231 TEST_P(ResampleEffectTest, ReadWholePixelFromLeft) {
234 float data[size * size] = {
235 0.0, 0.0, 0.0, 0.0, 0.0,
236 0.0, 0.0, 0.0, 0.0, 0.0,
237 0.0, 0.0, 1.0, 0.0, 0.0,
238 0.0, 0.0, 0.0, 0.0, 0.0,
239 0.0, 0.0, 0.0, 0.0, 0.0,
241 float expected_data[size * size] = {
242 0.0, 0.0, 0.0, 0.0, 0.0,
243 0.0, 0.0, 0.0, 0.0, 0.0,
244 0.0, 1.0, 0.0, 0.0, 0.0,
245 0.0, 0.0, 0.0, 0.0, 0.0,
246 0.0, 0.0, 0.0, 0.0, 0.0,
248 float out_data[size * size];
250 EffectChainTester tester(data, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
251 Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
252 ASSERT_TRUE(resample_effect->set_int("width", size));
253 ASSERT_TRUE(resample_effect->set_int("height", size));
254 ASSERT_TRUE(resample_effect->set_float("left", 1.0f));
255 tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
257 expect_equal(expected_data, out_data, size, size);
260 TEST_P(ResampleEffectTest, ReadQuarterPixelFromLeft) {
263 float data[size * size] = {
264 0.0, 0.0, 0.0, 0.0, 0.0,
265 0.0, 0.0, 0.0, 0.0, 0.0,
266 0.0, 0.0, 1.0, 0.0, 0.0,
267 0.0, 0.0, 0.0, 0.0, 0.0,
268 0.0, 0.0, 0.0, 0.0, 0.0,
271 float expected_data[size * size] = {
272 0.0, 0.0, 0.0, 0.0, 0.0,
273 0.0, 0.0, 0.0, 0.0, 0.0,
275 // sin(x*pi)/(x*pi) * sin(x*pi/3)/(x*pi/3) for
276 // x = -1.75, -0.75, 0.25, 1.25, 2.25.
277 // Note that the weight is mostly on the left side.
278 -0.06779, 0.27019, 0.89007, -0.13287, 0.03002,
280 0.0, 0.0, 0.0, 0.0, 0.0,
281 0.0, 0.0, 0.0, 0.0, 0.0,
283 float out_data[size * size];
285 EffectChainTester tester(data, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
286 Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
287 ASSERT_TRUE(resample_effect->set_int("width", size));
288 ASSERT_TRUE(resample_effect->set_int("height", size));
289 ASSERT_TRUE(resample_effect->set_float("left", 0.25f));
290 tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
292 expect_equal(expected_data, out_data, size, size);
295 TEST_P(ResampleEffectTest, ReadQuarterPixelFromTop) {
297 const int height = 5;
299 float data[width * height] = {
307 // See ReadQuarterPixelFromLeft for explanation of the data.
308 float expected_data[width * height] = {
315 float out_data[width * height];
317 EffectChainTester tester(data, width, height, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
318 Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
319 ASSERT_TRUE(resample_effect->set_int("width", width));
320 ASSERT_TRUE(resample_effect->set_int("height", height));
321 ASSERT_TRUE(resample_effect->set_float("top", 0.25f));
322 tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
324 expect_equal(expected_data, out_data, width, height);
327 TEST_P(ResampleEffectTest, ReadHalfPixelFromLeftAndScale) {
328 const int src_width = 4;
329 const int dst_width = 8;
331 float data[src_width * 1] = {
334 float expected_data[dst_width * 1] = {
335 // Empirical; the real test is that we are the same for 0.499 and 0.501.
336 1.1553, 1.7158, 2.2500, 2.7461, 3.2812, 3.8418, 4.0703, 4.0508
338 float out_data[dst_width * 1];
340 EffectChainTester tester(nullptr, dst_width, 1, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
343 format.color_space = COLORSPACE_sRGB;
344 format.gamma_curve = GAMMA_LINEAR;
346 FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, src_width, 1);
347 input->set_pixel_data(data);
348 tester.get_chain()->add_input(input);
350 Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
351 ASSERT_TRUE(resample_effect->set_int("width", dst_width));
352 ASSERT_TRUE(resample_effect->set_int("height", 1));
354 // Check that we are (almost) the same no matter the rounding.
355 ASSERT_TRUE(resample_effect->set_float("left", 0.499f));
356 tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
357 expect_equal(expected_data, out_data, dst_width, 1, 1.5f / 255.0f, 0.4f / 255.0f);
359 ASSERT_TRUE(resample_effect->set_float("left", 0.501f));
360 tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
361 expect_equal(expected_data, out_data, dst_width, 1, 1.5f / 255.0f, 0.4f / 255.0f);
364 TEST_P(ResampleEffectTest, Zoom) {
366 const int height = 3;
368 float data[width * height] = {
369 0.0, 0.0, 0.0, 0.0, 0.0,
370 0.2, 0.4, 0.6, 0.4, 0.2,
371 0.0, 0.0, 0.0, 0.0, 0.0,
373 float expected_data[width * height] = {
374 0.0, 0.0, 0.0, 0.0, 0.0,
375 0.4, 0.5396, 0.6, 0.5396, 0.4,
376 0.0, 0.0, 0.0, 0.0, 0.0,
378 float out_data[width * height];
380 EffectChainTester tester(data, width, height, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
381 Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
382 ASSERT_TRUE(resample_effect->set_int("width", width));
383 ASSERT_TRUE(resample_effect->set_int("height", height));
384 ASSERT_TRUE(resample_effect->set_float("zoom_x", 2.0f));
385 tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
387 expect_equal(expected_data, out_data, width, height);
390 TEST_P(ResampleEffectTest, VerticalZoomFromTop) {
392 const int height = 5;
394 float data[width * height] = {
395 0.2, 0.4, 0.6, 0.4, 0.2,
396 0.0, 0.0, 0.0, 0.0, 0.0,
397 0.0, 0.0, 0.0, 0.0, 0.0,
398 0.0, 0.0, 0.0, 0.0, 0.0,
399 0.0, 0.0, 0.0, 0.0, 0.0,
402 // Largely empirical data; the main point is that the top line
403 // is unchanged, since that's our zooming point.
404 float expected_data[width * height] = {
405 0.2000, 0.4000, 0.6000, 0.4000, 0.2000,
406 0.1389, 0.2778, 0.4167, 0.2778, 0.1389,
407 0.0600, 0.1199, 0.1798, 0.1199, 0.0600,
408 0.0000, 0.0000, 0.0000, 0.0000, 0.0000,
409 -0.0229, -0.0459, -0.0688, -0.0459, -0.0229,
411 float out_data[width * height];
413 EffectChainTester tester(data, width, height, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
414 Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
415 ASSERT_TRUE(resample_effect->set_int("width", width));
416 ASSERT_TRUE(resample_effect->set_int("height", height));
417 ASSERT_TRUE(resample_effect->set_float("zoom_y", 3.0f));
418 ASSERT_TRUE(resample_effect->set_float("zoom_center_y", 0.5f / height));
419 tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
421 expect_equal(expected_data, out_data, width, height);
424 TEST_P(ResampleEffectTest, Precision) {
425 const int size = 1920; // Difficult non-power-of-two size.
426 const int offset = 5;
428 // Deliberately put the data of interest very close to the right,
429 // where texture coordinates are farther from 0 and thus less precise.
430 float data[size * 2] = {0};
431 data[size - offset] = 1.0f;
432 float expected_data[size * 2] = {0};
433 for (int x = 0; x < size * 2; ++x) {
434 expected_data[x] = lanczos((x - (size - 2 * offset + 1) + 0.5f) * 0.5f, 3.0f);
436 float out_data[size * 2];
438 EffectChainTester tester(data, size * 2, 1, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
439 Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
440 ASSERT_TRUE(resample_effect->set_int("width", size * 2));
441 ASSERT_TRUE(resample_effect->set_int("height", 1));
442 ASSERT_TRUE(resample_effect->set_float("zoom_x", 2.0f));
443 tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
445 expect_equal(expected_data, out_data, size, 1);
448 INSTANTIATE_TEST_CASE_P(ResampleEffectTest,
450 testing::Values("fragment", "compute"));
452 #ifdef HAVE_BENCHMARK
453 template<> inline uint8_t from_fp32<uint8_t>(float x) { return lrintf(x * 255.0f); }
456 void BM_ResampleEffect(benchmark::State &state, GammaCurve gamma_curve, GLenum output_format, const std::string &shader_type)
458 DisableComputeShadersTemporarily disabler(shader_type == "fragment");
459 if (disabler.should_skip(&state)) return;
461 unsigned in_width = state.range(0), in_height = state.range(1);
462 unsigned out_width = state.range(2), out_height = state.range(3);
464 unique_ptr<T[]> data(new T[in_width * in_height * 4]);
465 unique_ptr<T[]> out_data(new T[out_width * out_height * 4]);
467 for (unsigned i = 0; i < in_width * in_height * 4; ++i) {
468 data[i] = from_fp32<T>(rand() / (RAND_MAX + 1.0));
471 EffectChainTester tester(nullptr, out_width, out_height, FORMAT_BGRA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, gamma_curve, output_format);
472 tester.add_input(data.get(), FORMAT_BGRA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, gamma_curve, in_width, in_height);
473 Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
475 ASSERT_TRUE(resample_effect->set_int("width", out_width));
476 ASSERT_TRUE(resample_effect->set_int("height", out_height));
478 tester.benchmark(state, out_data.get(), GL_BGRA, COLORSPACE_sRGB, gamma_curve, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED);
481 void BM_ResampleEffectHalf(benchmark::State &state, GammaCurve gamma_curve, const std::string &shader_type)
483 BM_ResampleEffect<fp16_int_t>(state, gamma_curve, GL_RGBA16F, shader_type);
486 void BM_ResampleEffectInt8(benchmark::State &state, GammaCurve gamma_curve, const std::string &shader_type)
488 BM_ResampleEffect<uint8_t>(state, gamma_curve, GL_RGBA8, shader_type);
491 BENCHMARK_CAPTURE(BM_ResampleEffectInt8, Int8Upscale, GAMMA_REC_709, "fragment")->Args({640, 360, 1280, 720})->Args({320, 180, 1280, 720})->Args({321, 181, 1280, 720})->UseRealTime()->Unit(benchmark::kMicrosecond);
492 BENCHMARK_CAPTURE(BM_ResampleEffectHalf, Float16Upscale, GAMMA_LINEAR, "fragment")->Args({640, 360, 1280, 720})->Args({320, 180, 1280, 720})->Args({321, 181, 1280, 720})->UseRealTime()->Unit(benchmark::kMicrosecond);
493 BENCHMARK_CAPTURE(BM_ResampleEffectInt8, Int8Downscale, GAMMA_REC_709, "fragment")->Args({1280, 720, 640, 360})->Args({1280, 720, 320, 180})->Args({1280, 720, 321, 181})->UseRealTime()->Unit(benchmark::kMicrosecond);
494 BENCHMARK_CAPTURE(BM_ResampleEffectHalf, Float16Downscale, GAMMA_LINEAR, "fragment")->Args({1280, 720, 640, 360})->Args({1280, 720, 320, 180})->Args({1280, 720, 321, 181})->UseRealTime()->Unit(benchmark::kMicrosecond);
495 BENCHMARK_CAPTURE(BM_ResampleEffectInt8, Int8UpscaleCompute, GAMMA_REC_709, "compute")->Args({640, 360, 1280, 720})->Args({320, 180, 1280, 720})->Args({321, 181, 1280, 720})->UseRealTime()->Unit(benchmark::kMicrosecond);
496 BENCHMARK_CAPTURE(BM_ResampleEffectHalf, Float16UpscaleCompute, GAMMA_LINEAR, "compute")->Args({640, 360, 1280, 720})->Args({320, 180, 1280, 720})->Args({321, 181, 1280, 720})->UseRealTime()->Unit(benchmark::kMicrosecond);
497 BENCHMARK_CAPTURE(BM_ResampleEffectInt8, Int8DownscaleCompute, GAMMA_REC_709, "compute")->Args({1280, 720, 640, 360})->Args({1280, 720, 320, 180})->Args({1280, 720, 321, 181})->UseRealTime()->Unit(benchmark::kMicrosecond);
498 BENCHMARK_CAPTURE(BM_ResampleEffectHalf, Float16DownscaleCompute, GAMMA_LINEAR, "compute")->Args({1280, 720, 640, 360})->Args({1280, 720, 320, 180})->Args({1280, 720, 321, 181})->UseRealTime()->Unit(benchmark::kMicrosecond);
500 void BM_ComputeBilinearScalingWeights(benchmark::State &state)
502 constexpr unsigned src_size = 1280;
503 constexpr unsigned dst_size = 35;
504 int old_precision = movit_texel_subpixel_precision;
505 movit_texel_subpixel_precision = 64; // To get consistent results across GPUs; this is a CPU test.
507 // One iteration warmup to make sure the Lanczos table is computed.
508 calculate_bilinear_scaling_weights(src_size, dst_size, 0.999f, 0.0f, BilinearFormatConstraints::ALLOW_FP16_AND_FP32);
510 for (auto _ : state) {
511 ScalingWeights weights = calculate_bilinear_scaling_weights(src_size, dst_size, 0.999f, 0.0f, BilinearFormatConstraints::ALLOW_FP16_AND_FP32);
514 movit_texel_subpixel_precision = old_precision;
516 BENCHMARK(BM_ComputeBilinearScalingWeights)->Unit(benchmark::kMicrosecond);
518 void BM_ComputeBilinearScalingWeightsNoFP16(benchmark::State &state)
520 constexpr unsigned src_size = 1280;
521 constexpr unsigned dst_size = 35;
522 int old_precision = movit_texel_subpixel_precision;
523 movit_texel_subpixel_precision = 64; // To get consistent results across GPUs; this is a CPU test.
525 // One iteration warmup to make sure the Lanczos table is computed.
526 calculate_bilinear_scaling_weights(src_size, dst_size, 0.999f, 0.0f, BilinearFormatConstraints::ALLOW_FP32_ONLY);
528 for (auto _ : state) {
529 ScalingWeights weights = calculate_bilinear_scaling_weights(src_size, dst_size, 0.999f, 0.0f, BilinearFormatConstraints::ALLOW_FP32_ONLY);
532 movit_texel_subpixel_precision = old_precision;
534 BENCHMARK(BM_ComputeBilinearScalingWeightsNoFP16)->Unit(benchmark::kMicrosecond);
536 void BM_ComputeRawScalingWeights(benchmark::State &state)
538 constexpr unsigned src_size = 1280;
539 constexpr unsigned dst_size = 35;
541 // One iteration warmup to make sure the Lanczos table is computed.
542 calculate_raw_scaling_weights(src_size, dst_size, 0.999f, 0.0f);
544 for (auto _ : state) {
545 ScalingWeights weights = calculate_raw_scaling_weights(src_size, dst_size, 0.999f, 0.0f);
548 BENCHMARK(BM_ComputeRawScalingWeights)->Unit(benchmark::kMicrosecond);