summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr.Smile <vabnick@gmail.com>2022-08-10 09:54:55 +0300
committerDr.Smile <vabnick@gmail.com>2023-04-02 06:06:19 +0300
commit0f5175743587d3bfe072e9df5784abab4cee435a (patch)
treeb03208d0d79da90541fe69f6532c326fadf97426
parentc9992e024d7a502c1b1499e0918be3b7a0834fed (diff)
downloadlibass-0f5175743587d3bfe072e9df5784abab4cee435a.tar.bz2
libass-0f5175743587d3bfe072e9df5784abab4cee435a.tar.xz
checkasm: add test of blur bitmap functions
-rw-r--r--Makefile_util.am1
-rw-r--r--checkasm/blur.c192
-rw-r--r--checkasm/checkasm.c1
-rw-r--r--checkasm/checkasm.h1
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);