From: Søren Sandmann Pedersen <s...@redhat.com> This test runs the new floating point combiners on random input with divide-by-zero exceptions turned on.
With the floating point combiners the only thing we guarantee is that divide-by-zero exceptions are not generated, so change enable_fp_exceptions() to only enable those, and rename accordingly. --- demos/radial-test.c | 2 +- pixman/pixman-private.h | 6 ++ pixman/pixman-utils.c | 9 +++ test/Makefile.sources | 1 + test/combiner-test.c | 151 ++++++++++++++++++++++++++++++++++++++++++++ test/gradient-crash-test.c | 2 +- test/pdf-op-test.c | 2 +- test/stress-test.c | 2 +- test/utils.c | 14 +---- test/utils.h | 2 +- 10 files changed, 174 insertions(+), 17 deletions(-) create mode 100644 test/combiner-test.c diff --git a/demos/radial-test.c b/demos/radial-test.c index 35e90d7..e64f357 100644 --- a/demos/radial-test.c +++ b/demos/radial-test.c @@ -133,7 +133,7 @@ main (int argc, char **argv) pixman_image_t *src_img, *dest_img; int i, j; - enable_fp_exceptions (); + enable_divbyzero_exceptions (); dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 949d384..c82316f 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -764,6 +764,12 @@ get_implementation (void) return global_implementation; } +/* This function is exported for the sake of the test suite and not part + * of the ABI. + */ +PIXMAN_EXPORT pixman_implementation_t * +_pixman_internal_only_get_implementation (void); + /* Memory allocation helpers */ void * pixman_malloc_ab (unsigned int n, unsigned int b); diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c index 5633f8f..e4a9730 100644 --- a/pixman/pixman-utils.c +++ b/pixman/pixman-utils.c @@ -262,6 +262,15 @@ pixman_region32_copy_from_region16 (pixman_region32_t *dst, return retval; } +/* This function is exported for the sake of the test suite and not part + * of the ABI. + */ +PIXMAN_EXPORT pixman_implementation_t * +_pixman_internal_only_get_implementation (void) +{ + return get_implementation (); +} + #ifdef DEBUG void diff --git a/test/Makefile.sources b/test/Makefile.sources index 0f34411..0778971 100644 --- a/test/Makefile.sources +++ b/test/Makefile.sources @@ -4,6 +4,7 @@ TESTPROGRAMS = \ pdf-op-test \ region-test \ region-translate-test \ + combiner-test \ fetch-test \ rotate-test \ oob-test \ diff --git a/test/combiner-test.c b/test/combiner-test.c new file mode 100644 index 0000000..c438ae6 --- /dev/null +++ b/test/combiner-test.c @@ -0,0 +1,151 @@ +#include <stdio.h> +#include <stdlib.h> +#include "utils.h" +#include <sys/types.h> +#include "pixman-private.h" + +static const pixman_op_t op_list[] = +{ + PIXMAN_OP_SRC, + PIXMAN_OP_OVER, + PIXMAN_OP_ADD, + PIXMAN_OP_CLEAR, + PIXMAN_OP_SRC, + PIXMAN_OP_DST, + PIXMAN_OP_OVER, + PIXMAN_OP_OVER_REVERSE, + PIXMAN_OP_IN, + PIXMAN_OP_IN_REVERSE, + PIXMAN_OP_OUT, + PIXMAN_OP_OUT_REVERSE, + PIXMAN_OP_ATOP, + PIXMAN_OP_ATOP_REVERSE, + PIXMAN_OP_XOR, + PIXMAN_OP_ADD, + PIXMAN_OP_SATURATE, + PIXMAN_OP_DISJOINT_CLEAR, + PIXMAN_OP_DISJOINT_SRC, + PIXMAN_OP_DISJOINT_DST, + PIXMAN_OP_DISJOINT_OVER, + PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_OP_DISJOINT_IN, + PIXMAN_OP_DISJOINT_IN_REVERSE, + PIXMAN_OP_DISJOINT_OUT, + PIXMAN_OP_DISJOINT_OUT_REVERSE, + PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_OP_DISJOINT_XOR, + PIXMAN_OP_CONJOINT_CLEAR, + PIXMAN_OP_CONJOINT_SRC, + PIXMAN_OP_CONJOINT_DST, + PIXMAN_OP_CONJOINT_OVER, + PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_OP_CONJOINT_IN, + PIXMAN_OP_CONJOINT_IN_REVERSE, + PIXMAN_OP_CONJOINT_OUT, + PIXMAN_OP_CONJOINT_OUT_REVERSE, + PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_OP_CONJOINT_XOR, + PIXMAN_OP_MULTIPLY, + PIXMAN_OP_SCREEN, + PIXMAN_OP_OVERLAY, + PIXMAN_OP_DARKEN, + PIXMAN_OP_LIGHTEN, + PIXMAN_OP_COLOR_DODGE, + PIXMAN_OP_COLOR_BURN, + PIXMAN_OP_HARD_LIGHT, + PIXMAN_OP_DIFFERENCE, + PIXMAN_OP_EXCLUSION, + PIXMAN_OP_SOFT_LIGHT, + PIXMAN_OP_HSL_HUE, + PIXMAN_OP_HSL_SATURATION, + PIXMAN_OP_HSL_COLOR, + PIXMAN_OP_HSL_LUMINOSITY, +}; + +static float +rand_float (void) +{ + uint32_t u = lcg_rand_u32(); + + return *(float *)&u; +} + +static void +random_floats (argb_t *argb, int width) +{ + int i; + + for (i = 0; i < width; ++i) + { + argb_t *p = argb + i; + + p->a = rand_float(); + p->r = rand_float(); + p->g = rand_float(); + p->b = rand_float(); + } +} + +#define WIDTH 512 + +static pixman_combine_float_func_t +lookup_combiner (pixman_implementation_t *imp, pixman_op_t op, + pixman_bool_t component_alpha) +{ + pixman_combine_float_func_t f; + + do + { + if (component_alpha) + f = imp->combine_float_ca[op]; + else + f = imp->combine_float[op]; + + imp = imp->fallback; + } + while (!f); + + return f; +} + +int +main () +{ + pixman_implementation_t *impl; + argb_t *src_bytes = malloc (WIDTH * sizeof (argb_t)); + argb_t *mask_bytes = malloc (WIDTH * sizeof (argb_t)); + argb_t *dest_bytes = malloc (WIDTH * sizeof (argb_t)); + int i; + + enable_divbyzero_exceptions(); + + impl = _pixman_internal_only_get_implementation(); + + lcg_srand (0); + + for (i = 0; i < ARRAY_LENGTH (op_list); ++i) + { + pixman_op_t op = op_list[i]; + pixman_combine_float_func_t combiner; + int ca; + + for (ca = 0; ca < 2; ++ca) + { + combiner = lookup_combiner (impl, op, ca); + + random_floats (src_bytes, WIDTH); + random_floats (mask_bytes, WIDTH); + random_floats (dest_bytes, WIDTH); + + combiner (impl, op, + (float *)dest_bytes, + (float *)mask_bytes, + (float *)src_bytes, + WIDTH); + } + } + + return 0; +} diff --git a/test/gradient-crash-test.c b/test/gradient-crash-test.c index 73e5bbc..962d1cb 100644 --- a/test/gradient-crash-test.c +++ b/test/gradient-crash-test.c @@ -85,7 +85,7 @@ main (int argc, char **argv) pixman_fixed_t r_inner; pixman_fixed_t r_outer; - enable_fp_exceptions(); + enable_divbyzero_exceptions(); for (i = 0; i < WIDTH * HEIGHT; ++i) dest[i] = 0x4f00004f; /* pale blue */ diff --git a/test/pdf-op-test.c b/test/pdf-op-test.c index 99cb7df..dcb3a60 100644 --- a/test/pdf-op-test.c +++ b/test/pdf-op-test.c @@ -36,7 +36,7 @@ main () { int o, s, m, d; - enable_fp_exceptions(); + enable_divbyzero_exceptions(); for (o = 0; o < ARRAY_LENGTH (pdf_ops); ++o) { diff --git a/test/stress-test.c b/test/stress-test.c index edcfe09..059250d 100644 --- a/test/stress-test.c +++ b/test/stress-test.c @@ -850,7 +850,7 @@ main (int argc, char **argv) pixman_disable_out_of_bounds_workaround (); - enable_fp_exceptions(); + enable_divbyzero_exceptions(); if (getenv ("VERBOSE") != NULL) verbose = TRUE; diff --git a/test/utils.c b/test/utils.c index c922ae5..716bb75 100644 --- a/test/utils.c +++ b/test/utils.c @@ -723,21 +723,11 @@ fail_after (int seconds, const char *msg) } void -enable_fp_exceptions (void) +enable_divbyzero_exceptions (void) { #ifdef HAVE_FENV_H #ifdef HAVE_FEENABLEEXCEPT - /* Note: we don't enable the FE_INEXACT trap because - * that happens quite commonly. It is possible that - * over- and underflow should similarly be considered - * okay, but for now the test suite passes with them - * enabled, and it's useful to know if they start - * occuring. - */ - feenableexcept (FE_DIVBYZERO | - FE_INVALID | - FE_OVERFLOW | - FE_UNDERFLOW); + feenableexcept (FE_DIVBYZERO); #endif #endif } diff --git a/test/utils.h b/test/utils.h index faf427f..f7ea34c 100644 --- a/test/utils.h +++ b/test/utils.h @@ -110,7 +110,7 @@ void fail_after (int seconds, const char *msg); /* If possible, enable traps for floating point exceptions */ -void enable_fp_exceptions(void); +void enable_divbyzero_exceptions(void); /* Converts a8r8g8b8 pixels to pixels that * - are not premultiplied, -- 1.7.4 _______________________________________________ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman