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

Dylan Baker dylan at pnwbakers.com
Mon Nov 19 23:12:27 UTC 2018


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



More information about the Piglit mailing list