diff options
author | Dr.Smile <vabnick@gmail.com> | 2022-08-10 09:54:55 +0300 |
---|---|---|
committer | Dr.Smile <vabnick@gmail.com> | 2023-04-02 06:06:19 +0300 |
commit | 0f5175743587d3bfe072e9df5784abab4cee435a (patch) | |
tree | b03208d0d79da90541fe69f6532c326fadf97426 | |
parent | c9992e024d7a502c1b1499e0918be3b7a0834fed (diff) | |
download | libass-0f5175743587d3bfe072e9df5784abab4cee435a.tar.bz2 libass-0f5175743587d3bfe072e9df5784abab4cee435a.tar.xz |
checkasm: add test of blur bitmap functions
-rw-r--r-- | Makefile_util.am | 1 | ||||
-rw-r--r-- | checkasm/blur.c | 192 | ||||
-rw-r--r-- | checkasm/checkasm.c | 1 | ||||
-rw-r--r-- | checkasm/checkasm.h | 1 |
4 files changed, 195 insertions, 0 deletions
diff --git a/Makefile_util.am b/Makefile_util.am index 97dce66..43fe5e7 100644 --- a/Makefile_util.am +++ b/Makefile_util.am @@ -52,6 +52,7 @@ endif checkasm_checkasm_SOURCES = \ checkasm/blend_bitmaps.c \ checkasm/be_blur.c \ + checkasm/blur.c \ checkasm/checkasm.h checkasm/checkasm.c checkasm_checkasm_CPPFLAGS = -I$(top_srcdir)/libass diff --git a/checkasm/blur.c b/checkasm/blur.c new file mode 100644 index 0000000..279b53f --- /dev/null +++ b/checkasm/blur.c @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2021-2022 libass contributors + * + * This file is part of libass. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "checkasm.h" + +#define HEIGHT 13 +#define STRIDE 64 +#define MIN_WIDTH 1 + +static void check_stripe_unpack(Convert8to16Func func, const char *name, int align) +{ + ALIGN(uint8_t src[STRIDE * HEIGHT], 32); + ALIGN(int16_t dst_ref[STRIDE * HEIGHT], 32); + ALIGN(int16_t dst_new[STRIDE * HEIGHT], 32); + declare_func(void, + int16_t *dst, const uint8_t *src, ptrdiff_t src_stride, + size_t width, size_t height); + + if (check_func(func, name, align)) { + for (int w = MIN_WIDTH; w <= STRIDE; w++) { + for (int i = 0; i < sizeof(src); i++) + src[i] = rnd(); + + for (int i = 0; i < sizeof(dst_ref) / 2; i++) + dst_ref[i] = dst_new[i] = rnd(); + + int h = HEIGHT - (rnd() & 3); + call_ref(dst_ref, src, STRIDE, w, h); + call_new(dst_new, src, STRIDE, w, h); + + if (memcmp(dst_ref, dst_new, sizeof(dst_ref))) { + fail(); + break; + } + } + + bench_new(dst_new, src, STRIDE, STRIDE, HEIGHT); + } + + report(name, align); +} + +static void check_stripe_pack(Convert16to8Func func, const char *name, int align) +{ + ALIGN(int16_t src[STRIDE * HEIGHT], 32); + ALIGN(uint8_t dst_ref[STRIDE * HEIGHT], 32); + ALIGN(uint8_t dst_new[STRIDE * HEIGHT], 32); + declare_func(void, + uint8_t *dst, ptrdiff_t dst_stride, const int16_t *src, + size_t width, size_t height); + + if (check_func(func, name, align)) { + for (int w = MIN_WIDTH; w <= STRIDE; w++) { + for (int i = 0; i < sizeof(src) / 2; i++) + src[i] = rnd() % 0x4001; + + memset(dst_ref, 0, sizeof(dst_ref)); + memset(dst_new, 0, sizeof(dst_new)); + for (int y = 0; y < HEIGHT; y++) { + for (int x = 0; x < w; x++) + dst_ref[y * STRIDE + x] = dst_new[y * STRIDE + x] = rnd(); + } + + int h = HEIGHT - (rnd() & 3); + call_ref(dst_ref, STRIDE, src, w, h); + call_new(dst_new, STRIDE, src, w, h); + + if (memcmp(dst_ref, dst_new, sizeof(dst_ref))) { + fail(); + break; + } + } + + bench_new(dst_new, STRIDE, src, STRIDE, HEIGHT); + } + + report(name, align); +} + +static void check_fixed_filter(FilterFunc func, const char *name, int align) +{ + enum { PADDING = FFMAX(32 * HEIGHT, 4 * STRIDE) }; + + ALIGN(int16_t src[STRIDE * HEIGHT], 32); + ALIGN(int16_t dst_ref[2 * STRIDE * HEIGHT + PADDING], 32); + ALIGN(int16_t dst_new[2 * STRIDE * HEIGHT + PADDING], 32); + declare_func(void, + int16_t *dst, const int16_t *src, + size_t src_width, size_t src_height); + + if (check_func(func, name, align)) { + for (int w = MIN_WIDTH; w <= STRIDE; w++) { + for (int i = 0; i < sizeof(src) / 2; i++) + src[i] = rnd() % 0x4001; + + for (int i = 0; i < sizeof(dst_ref) / 2; i++) + dst_ref[i] = dst_new[i] = rnd(); + + int h = HEIGHT - (rnd() & 3); + call_ref(dst_ref, src, w, h); + call_new(dst_new, src, w, h); + + if (memcmp(dst_ref, dst_new, sizeof(dst_ref))) { + fail(); + break; + } + } + + bench_new(dst_new, src, STRIDE, HEIGHT); + } + + report(name, align); +} + +static void check_param_filter(ParamFilterFunc func, const char *name, int n, int align) +{ + enum { PADDING = FFMAX(32 * HEIGHT, 16 * STRIDE) }; + + ALIGN(int16_t src[STRIDE * HEIGHT], 32); + ALIGN(int16_t dst_ref[STRIDE * HEIGHT + PADDING], 32); + ALIGN(int16_t dst_new[STRIDE * HEIGHT + PADDING], 32); + int16_t param[8]; + declare_func(void, + int16_t *dst, const int16_t *src, + size_t src_width, size_t src_height, + const int16_t *param); + + if (check_func(func, name, n, align)) { + for (int w = MIN_WIDTH; w <= STRIDE; w++) { + for (int i = 0; i < sizeof(src) / 2; i++) + src[i] = rnd() % 0x4001; + + for (int i = 0; i < sizeof(dst_ref) / 2; i++) + dst_ref[i] = dst_new[i] = rnd(); + + int left = 0x8000; + for (int i = 0; i < n; i++) { + param[i] = rnd() % (left + 1); + left -= param[i]; + } + + int h = HEIGHT - (rnd() & 3); + call_ref(dst_ref, src, w, h, param); + call_new(dst_new, src, w, h, param); + + if (memcmp(dst_ref, dst_new, sizeof(dst_ref))) { + fail(); + break; + } + } + + bench_new(dst_new, src, STRIDE, HEIGHT, param); + } + + report(name, n, align); +} + +void checkasm_check_blur(unsigned cpu_flag) +{ + BitmapEngine engine[2] = { + ass_bitmap_engine_init(cpu_flag), + ass_bitmap_engine_init(cpu_flag | ASS_FLAG_WIDE_STRIPE) + }; + for (int i = 0; i < 2; i++) { + int align = 1 << engine[i].align_order; + check_stripe_unpack(engine[i].stripe_unpack, "stripe_unpack%d", align); + check_stripe_pack(engine[i].stripe_pack, "stripe_pack%d", align); + check_fixed_filter(engine[i].shrink_horz, "shrink_horz%d", align); + check_fixed_filter(engine[i].shrink_vert, "shrink_vert%d", align); + check_fixed_filter(engine[i].expand_horz, "expand_horz%d", align); + check_fixed_filter(engine[i].expand_vert, "expand_vert%d", align); + for (int n = 4; n <= 8; n++) { + check_param_filter(engine[i].blur_horz[n - 4], "blur%d_horz%d", n, align); + check_param_filter(engine[i].blur_vert[n - 4], "blur%d_vert%d", n, align); + } + } +} diff --git a/checkasm/checkasm.c b/checkasm/checkasm.c index 85398e0..148c68a 100644 --- a/checkasm/checkasm.c +++ b/checkasm/checkasm.c @@ -56,6 +56,7 @@ static const struct { } tests[] = { { "blend_bitmaps", checkasm_check_blend_bitmaps }, { "be_blur", checkasm_check_be_blur }, + { "blur", checkasm_check_blur }, { 0 } }; diff --git a/checkasm/checkasm.h b/checkasm/checkasm.h index 996fb53..c319a39 100644 --- a/checkasm/checkasm.h +++ b/checkasm/checkasm.h @@ -58,6 +58,7 @@ int xor128_rand(void); void checkasm_check_blend_bitmaps(unsigned cpu_flag); void checkasm_check_be_blur(unsigned cpu_flag); +void checkasm_check_blur(unsigned cpu_flag); void *checkasm_check_func(void *func, const char *name, ...); int checkasm_bench_func(void); |