[Piglit] [PATCH] tests/image_load_store/atomic: use piglit subtest framework

Dylan Baker dylan at pnwbakers.com
Wed Nov 21 17:25:16 UTC 2018


Quoting Rafael Antognolli (2018-11-20 17:01:11)
> Awesome, thanks for doing this.
> 
> Reviewed-by: Rafael Antognolli <rafael.antognolli at intel.com>
> 
> Also, it fixes the issue I had, but apparently it's not the only test
> with that problem. Another test with the same issue:
> 
> spec at arb_shader_image_size@builtin
> 
> I would guess there are other tests in the same situation, it just
> happens that I didn't have a GPU hang with them, and so they didn't
> incorrectly report pass when they actually hung.
> 
> Thanks anyway.
> Rafael

Yeah, basically all tests using subtests (except for a very small number that
have been fixed already) have this problem. I just haven't gotten around to
fixing them all yet.

> 
> On Mon, Nov 19, 2018 at 03:12:27PM -0800, Dylan Baker wrote:
> > cc: Rafael Antognolli <rafael.antognolli at intel.com>
> > ---
> >  .../arb_shader_image_load_store/atomicity.c   | 403 +++++++++++-------
> >  1 file changed, 239 insertions(+), 164 deletions(-)
> > 
> > diff --git a/tests/spec/arb_shader_image_load_store/atomicity.c b/tests/spec/arb_shader_image_load_store/atomicity.c
> > index f53dddaa2..88d15d65d 100644
> > --- a/tests/spec/arb_shader_image_load_store/atomicity.c
> > +++ b/tests/spec/arb_shader_image_load_store/atomicity.c
> > @@ -1,5 +1,6 @@
> >  /*
> >   * Copyright (C) 2014 Intel Corporation
> > + * Copyright © 2018 Intel Corporation
> >   *
> >   * Permission is hereby granted, free of charge, to any person obtaining a
> >   * copy of this software and associated documentation files (the "Software"),
> > @@ -58,16 +59,7 @@
> >  /** Total number of pixels in the window and image. */
> >  #define N (W * H)
> >  
> > -PIGLIT_GL_TEST_CONFIG_BEGIN
> > -
> > -config.supports_gl_core_version = 32;
> > -
> > -config.window_width = W;
> > -config.window_height = H;
> > -config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
> > -config.khr_no_error_support = PIGLIT_NO_ERRORS;
> > -
> > -PIGLIT_GL_TEST_CONFIG_END
> > +static struct piglit_gl_test_config *piglit_config;
> >  
> >  static bool
> >  init_image(const struct image_info img, uint32_t v)
> > @@ -112,56 +104,28 @@ check_image_const(const struct image_info img, unsigned n, uint32_t v)
> >                               pixels, v, 0, 0, 0);
> >  }
> >  
> > -/**
> > - * Test skeleton: Init image to \a init_value, run the provided shader
> > - * \a op, check that the first \a check_sz pixels of the image equal
> > - * \a check_value and optionally check that the resulting fragment
> > - * values on the framebuffer are unique.
> > - */
> > -static bool
> > -run_test(uint32_t init_value, unsigned check_sz, uint32_t check_value,
> > -         bool check_unique, const char *op)
> > -{
> > -        const struct grid_info grid =
> > -                grid_info(GL_FRAGMENT_SHADER, GL_R32UI, W, H);
> > -        const struct image_info img =
> > -                image_info(GL_TEXTURE_1D, GL_R32UI, W, H);
> > -        GLuint prog = generate_program(
> > -                grid, GL_FRAGMENT_SHADER,
> > -                concat(image_hunk(img, ""),
> > -                       hunk("volatile IMAGE_UNIFORM_T img;\n"),
> > -                       hunk(op), NULL));
> > -        bool ret = prog &&
> > -                init_fb(grid) &&
> > -                init_image(img, init_value) &&
> > -                set_uniform_int(prog, "img", 0) &&
> > -                draw_grid(grid, prog) &&
> > -                check_image_const(img, check_sz, check_value) &&
> > -                (!check_unique || check_fb_unique(grid));
> > -
> > -        glDeleteProgram(prog);
> > -        return ret;
> > -}
> > -
> > -void
> > -piglit_init(int argc, char **argv)
> > +struct testcase
> >  {
> > -        enum piglit_result status = PIGLIT_PASS;
> > -
> > -        piglit_require_extension("GL_ARB_shader_image_load_store");
> > -
> > +     uint32_t init_value;
> > +     unsigned check_sz;
> > +     uint32_t check_value;
> > +     bool check_unique;
> > +     const char * op;
> > +};
> > +
> > +static struct testcase testdata[] = {
> >          /*
> >           * If imageAtomicAdd() is atomic the return values obtained
> >           * from each call are guaranteed to be unique.
> >           */
> > -        subtest(&status, true,
> > -                run_test(0, 1, N, true,
> > -                         "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > -                         "       return GRID_T("
> > -                         "          imageAtomicAdd(img, IMAGE_ADDR(ivec2(0)), 1u),"
> > -                         "          0, 0, 1);\n"
> > -                         "}\n"),
> > -                "imageAtomicAdd");
> > +     {
> > +             0, 1, N, true,
> > +             "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > +             "       return GRID_T("
> > +             "          imageAtomicAdd(img, IMAGE_ADDR(ivec2(0)), 1u),"
> > +             "          0, 0, 1);\n"
> > +             "}\n",
> > +     },
> >  
> >          /*
> >           * Call imageAtomicMin() on a fixed location from within a
> > @@ -175,20 +139,20 @@ piglit_init(int argc, char **argv)
> >           * repeat.  In the end we obtain a unique counter value for
> >           * each fragment if the read-modify-write operation is atomic.
> >           */
> > -        subtest(&status, true,
> > -                run_test(0xffffffff, 1, 0xffffffff - N, true,
> > -                        "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > -                        "       uint old, v = 0xffffffffu;"
> > -                        "\n"
> > -                        "       do {\n"
> > -                        "               old = v;\n"
> > -                        "               v = imageAtomicMin(img, IMAGE_ADDR(ivec2(0)),"
> > -                        "                                  v - 1u);\n"
> > -                        "       } while (v != old);\n"
> > -                        "\n"
> > -                        "       return GRID_T(v, 0, 0, 1);\n"
> > -                        "}\n"),
> > -                "imageAtomicMin");
> > +     {
> > +                0xffffffff, 1, 0xffffffff - N, true,
> > +                "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > +                "       uint old, v = 0xffffffffu;"
> > +                "\n"
> > +                "       do {\n"
> > +                "               old = v;\n"
> > +                "               v = imageAtomicMin(img, IMAGE_ADDR(ivec2(0)),"
> > +                "                                  v - 1u);\n"
> > +                "       } while (v != old);\n"
> > +                "\n"
> > +                "       return GRID_T(v, 0, 0, 1);\n"
> > +                "}\n",
> > +     },
> >  
> >          /*
> >           * Use imageAtomicMax() on a fixed location to increment a
> > @@ -196,94 +160,93 @@ piglit_init(int argc, char **argv)
> >           * atomicity of the built-in guarantees that the obtained
> >           * values will be unique for each fragment.
> >           */
> > -        subtest(&status, true,
> > -                run_test(0, 1, N, true,
> > -                        "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > -                        "       uint old, v = 0u;"
> > -                        "\n"
> > -                        "       do {\n"
> > -                        "               old = v;\n"
> > -                        "               v = imageAtomicMax(img, IMAGE_ADDR(ivec2(0)),"
> > -                        "                                  v + 1u);\n"
> > -                        "       } while (v != old);\n"
> > -                        "\n"
> > -                        "       return GRID_T(v, 0, 0, 1);\n"
> > -                        "}\n"),
> > -                "imageAtomicMax");
> > +     {
> > +                0, 1, N, true,
> > +                "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > +                "       uint old, v = 0u;"
> > +                "\n"
> > +                "       do {\n"
> > +                "               old = v;\n"
> > +                "               v = imageAtomicMax(img, IMAGE_ADDR(ivec2(0)),"
> > +                "                                  v + 1u);\n"
> > +                "       } while (v != old);\n"
> > +                "\n"
> > +                "       return GRID_T(v, 0, 0, 1);\n"
> > +                "}\n",
> > +     },
> >  
> >          /*
> >           * Use imageAtomicAnd() to flip individual bits of a bitmap
> >           * atomically.  The atomicity of the built-in guarantees that
> >           * all bits will be clear on termination.
> >           */
> > -        subtest(&status, true,
> > -                run_test(0xffffffff, N / 32, 0, false,
> > -                        "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > -                        "       int i = IMAGE_ADDR(idx);\n"
> > -                        "       uint m = ~(1u << (i % 32));\n"
> > -                        "\n"
> > -                        "       imageAtomicAnd(img, i / 32, m);\n"
> > -                        "\n"
> > -                        "       return GRID_T(0, 0, 0, 1);\n"
> > -                        "}\n"),
> > -                "imageAtomicAnd");
> > +     {
> > +                0xffffffff, N / 32, 0, false,
> > +                "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > +                "       int i = IMAGE_ADDR(idx);\n"
> > +                "       uint m = ~(1u << (i % 32));\n"
> > +                "\n"
> > +                "       imageAtomicAnd(img, i / 32, m);\n"
> > +                "\n"
> > +                "       return GRID_T(0, 0, 0, 1);\n"
> > +                "}\n",
> > +     },
> >  
> >          /*
> >           * Use imageAtomicOr() to flip individual bits of a bitmap
> >           * atomically.  The atomicity of the built-in guarantees that
> >           * all bits will be set on termination.
> >           */
> > -        subtest(&status, true,
> > -                run_test(0, N / 32, 0xffffffff, false,
> > -                        "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > -                        "       int i = IMAGE_ADDR(idx);\n"
> > -                        "       uint m = (1u << (i % 32));\n"
> > -                        "\n"
> > -                        "       imageAtomicOr(img, i / 32, m);\n"
> > -                        "\n"
> > -                        "       return GRID_T(0, 0, 0, 1);\n"
> > -                        "}\n"),
> > -                "imageAtomicOr");
> > +     {
> > +                0, N / 32, 0xffffffff, false,
> > +                "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > +                "       int i = IMAGE_ADDR(idx);\n"
> > +                "       uint m = (1u << (i % 32));\n"
> > +                "\n"
> > +                "       imageAtomicOr(img, i / 32, m);\n"
> > +                "\n"
> > +                "       return GRID_T(0, 0, 0, 1);\n"
> > +                "}\n",
> > +     },
> >  
> >          /*
> >           * Use imageAtomicXor() to flip individual bits of a bitmap
> >           * atomically.  The atomicity of the built-in guarantees that
> >           * all bits will have been inverted on termination.
> >           */
> > -        subtest(&status, true,
> > -                run_test(0x55555555, N / 32, 0xaaaaaaaa, false,
> > -                        "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > -                        "       int i = IMAGE_ADDR(idx);\n"
> > -                        "       uint m = (1u << (i % 32));\n"
> > -                        "\n"
> > -                        "       imageAtomicXor(img, i / 32, m);\n"
> > -                        "\n"
> > -                        "       return GRID_T(0, 0, 0, 1);\n"
> > -                        "}\n"),
> > -                "imageAtomicXor");
> > +     {
> > +                0x55555555, N / 32, 0xaaaaaaaa, false,
> > +                "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > +                "       int i = IMAGE_ADDR(idx);\n"
> > +                "       uint m = (1u << (i % 32));\n"
> > +                "\n"
> > +                "       imageAtomicXor(img, i / 32, m);\n"
> > +                "\n"
> > +                "       return GRID_T(0, 0, 0, 1);\n"
> > +                "}\n",
> > +     },
> >  
> >          /*
> >           * Use imageAtomicExchange() to flip individual bits of a
> >           * bitmap atomically.  The atomicity of the built-in
> >           * guarantees that all bits will be set on termination.
> >           */
> > -        subtest(&status, true,
> > -                run_test(0, N / 32, 0xffffffff, false,
> > -                        "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > -                        "       int i = IMAGE_ADDR(idx);\n"
> > -                        "       uint m = (1u << (i % 32));\n"
> > -                        "       uint old = 0u;\n"
> > -                        "\n"
> > -                        "       do {\n"
> > -                        "               m |= old;\n"
> > -                        "               old = imageAtomicExchange("
> > -                        "                       img, i / 32, m);\n"
> > -                        "       } while ((old & ~m) != 0u);\n"
> > -                        "\n"
> > -                        "       return GRID_T(0, 0, 0, 1);\n"
> > -                        "}\n"),
> > -                "imageAtomicExchange");
> > -
> > +     {
> > +                0, N / 32, 0xffffffff, false,
> > +                "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > +                "       int i = IMAGE_ADDR(idx);\n"
> > +                "       uint m = (1u << (i % 32));\n"
> > +                "       uint old = 0u;\n"
> > +                "\n"
> > +                "       do {\n"
> > +                "               m |= old;\n"
> > +                "               old = imageAtomicExchange("
> > +                "                       img, i / 32, m);\n"
> > +                "       } while ((old & ~m) != 0u);\n"
> > +                "\n"
> > +                "       return GRID_T(0, 0, 0, 1);\n"
> > +                "}\n",
> > +     },
> >  #if 0
> >          /*
> >           * Use imageAtomicExchange() on a fixed location to increment
> > @@ -318,21 +281,22 @@ piglit_init(int argc, char **argv)
> >           * hang.  It seems to work fine on nVidia though, it would be
> >           * interesting to see if it works on other platforms.
> >           */
> > -        subtest(&status, true,
> > -                run_test(0, 1, N, true,
> > -                        "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > -                        "       uint p = 0xffffffffu, v = 0xffffffffu;\n"
> > -                        "\n"
> > -                        "       do {\n"
> > -                        "               if (p != 0xffffffffu)\n"
> > -                        "                       v = p++;\n"
> > -                        "               p = imageAtomicExchange("
> > -                        "                  img, IMAGE_ADDR(ivec2(0)), p);\n"
> > -                        "       } while (v == 0xffffffffu);\n"
> > -                        "\n"
> > -                        "       return GRID_T(v, 0, 0, 1);\n"
> > -                        "}\n"),
> > -                "imageAtomicExchange (locking)");
> > +     {
> > +                0, 1, N, true,
> > +                "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > +                "       uint p = 0xffffffffu, v = 0xffffffffu;\n"
> > +                "\n"
> > +                "       do {\n"
> > +                "               if (p != 0xffffffffu)\n"
> > +                "                       v = p++;\n"
> > +                "               p = imageAtomicExchange("
> > +                "                  img, IMAGE_ADDR(ivec2(0)), p);\n"
> > +                "       } while (v == 0xffffffffu);\n"
> > +                "\n"
> > +                "       return GRID_T(v, 0, 0, 1);\n"
> > +                "}\n",
> > +                "imageAtomicExchange (locking)",
> > +     },
> >  #endif
> >  
> >          /*
> > @@ -342,22 +306,133 @@ piglit_init(int argc, char **argv)
> >           * argument.  The atomicity of the built-in guarantees that
> >           * the obtained values will be unique for each fragment.
> >           */
> > -        subtest(&status, true,
> > -                run_test(0, 1, N, true,
> > -                        "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > -                        "       uint old, v = 0u;"
> > -                        "\n"
> > -                        "       do {\n"
> > -                        "               old = v;\n"
> > -                        "               v = imageAtomicCompSwap("
> > -                        "                  img, IMAGE_ADDR(ivec2(0)), v, v + 1u);\n"
> > -                        "       } while (v != old);\n"
> > -                        "\n"
> > -                        "       return GRID_T(v, 0, 0, 1);\n"
> > -                        "}\n"),
> > -                "imageAtomicCompSwap");
> > -
> > -        piglit_report_result(status);
> > +     {
> > +                0, 1, N, true,
> > +                "GRID_T op(ivec2 idx, GRID_T x) {\n"
> > +                "       uint old, v = 0u;"
> > +                "\n"
> > +                "       do {\n"
> > +                "               old = v;\n"
> > +                "               v = imageAtomicCompSwap("
> > +                "                  img, IMAGE_ADDR(ivec2(0)), v, v + 1u);\n"
> > +                "       } while (v != old);\n"
> > +                "\n"
> > +                "       return GRID_T(v, 0, 0, 1);\n"
> > +                "}\n",
> > +     },
> > +};
> > +
> > +/**
> > + * Test skeleton: Init image to \a init_value, run the provided shader
> > + * \a op, check that the first \a check_sz pixels of the image equal
> > + * \a check_value and optionally check that the resulting fragment
> > + * values on the framebuffer are unique.
> > + */
> > +static enum piglit_result
> > +run_test(void * data)
> > +{
> > +     const struct testcase * test = (const struct testcase *)data;
> > +
> > +        const struct grid_info grid =
> > +                grid_info(GL_FRAGMENT_SHADER, GL_R32UI, W, H);
> > +        const struct image_info img =
> > +                image_info(GL_TEXTURE_1D, GL_R32UI, W, H);
> > +        GLuint prog = generate_program(
> > +                grid, GL_FRAGMENT_SHADER,
> > +                concat(image_hunk(img, ""),
> > +                       hunk("volatile IMAGE_UNIFORM_T img;\n"),
> > +                       hunk(test->op), NULL));
> > +        bool ret = prog &&
> > +                init_fb(grid) &&
> > +                init_image(img, test->init_value) &&
> > +                set_uniform_int(prog, "img", 0) &&
> > +                draw_grid(grid, prog) &&
> > +                check_image_const(img, test->check_sz, test->check_value) &&
> > +                (!test->check_unique || check_fb_unique(grid));
> > +
> > +        glDeleteProgram(prog);
> > +        return ret ? PIGLIT_PASS : PIGLIT_FAIL;
> > +}
> > +
> > +static struct piglit_subtest tests[] = {
> > +     {
> > +             "imageAtomicAdd",
> > +             "add",
> > +             run_test,
> > +             (void *)&testdata[0],
> > +     },
> > +     {
> > +             "imageAtomicMin",
> > +             "min",
> > +             run_test,
> > +             (void *)&testdata[1],
> > +     },
> > +     {
> > +                "imageAtomicMax",
> > +             "max",
> > +             run_test,
> > +             (void *)&testdata[2],
> > +     },
> > +     {
> > +                "imageAtomicAnd",
> > +             "and",
> > +             run_test,
> > +             (void *)&testdata[3],
> > +     },
> > +     {
> > +                "imageAtomicOr",
> > +             "or",
> > +             run_test,
> > +             (void *)&testdata[4],
> > +     },
> > +     {
> > +                "imageAtomicXor",
> > +             "xor",
> > +             run_test,
> > +             (void *)&testdata[5],
> > +     },
> > +     {
> > +                "imageAtomicExchange",
> > +             "exchange",
> > +             run_test,
> > +             (void *)&testdata[6],
> > +     },
> > +     {
> > +                "imageAtomicCompSwap",
> > +             "comp_swap",
> > +             run_test,
> > +             (void *)&testdata[7],
> > +     },
> > +     {0},
> > +};
> > +
> > +PIGLIT_GL_TEST_CONFIG_BEGIN
> > +
> > +piglit_config = &config;
> > +config.subtests = tests;
> > +config.supports_gl_core_version = 32;
> > +
> > +config.window_width = W;
> > +config.window_height = H;
> > +config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
> > +config.khr_no_error_support = PIGLIT_NO_ERRORS;
> > +
> > +PIGLIT_GL_TEST_CONFIG_END
> > +
> > +void
> > +piglit_init(int argc, char **argv)
> > +{
> > +        piglit_require_extension("GL_ARB_shader_image_load_store");
> > +
> > +        enum piglit_result result = PIGLIT_PASS;
> > +
> > +     result = piglit_run_selected_subtests(
> > +             tests,
> > +             piglit_config->selected_subtests,
> > +             piglit_config->num_selected_subtests,
> > +             result);
> > +
> > +     piglit_report_result(result);
> >  }
> >  
> >  enum piglit_result
> > -- 
> > 2.19.1
> > 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: signature
URL: <https://lists.freedesktop.org/archives/piglit/attachments/20181121/8d43765a/attachment-0001.sig>


More information about the Piglit mailing list