ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / arb_shader_image_load_store / shader-mem-barrier.c
blobb3301cdb79ef9cfbccbb1ce5054f6affcd8c7eb1
1 /*
2 * Copyright (C) 2014 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
24 /** @file shader-mem-barrier.c
26 * Test that the memoryBarrier() GLSL built-in effectively serializes
27 * memory transactions initiated after and before the call. This is
28 * done by having a number of threads write to separate locations in a
29 * loop serializing each pair of writes with memoryBarrier() while the
30 * remaining threads monitor the evolution of the same memory
31 * locations until an inconsistency is observed or the test runs to
32 * completion.
34 * The test is repeated for the "volatile" qualifier, for all
35 * execution stages and for different relative arrangements of
36 * producer and monitor threads to account for implementations with
37 * varying levels of parallelism and with caches of different sizes.
39 * Unless running in "quick" mode a series of control tests is
40 * executed which disables memory barriers in order to make sure that
41 * the test is meaningful. The control test always passes as it is
42 * expected to misrender.
45 #include "common.h"
47 /** Window width. */
48 #define W 256
50 /** Window height. */
51 #define H 64
53 /** Total number of pixels in the image. */
54 #define N (W * H)
56 /** Maximum modulus. */
57 #define K 128
59 PIGLIT_GL_TEST_CONFIG_BEGIN
61 config.supports_gl_core_version = 32;
63 config.window_width = W;
64 config.window_height = H;
65 config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
66 config.khr_no_error_support = PIGLIT_NO_ERRORS;
68 PIGLIT_GL_TEST_CONFIG_END
70 struct image_test_info {
71 /** Test name. */
72 const char *name;
74 /** Image qualifier keyword. */
75 const char *qualifier;
77 /** Memory barrier built-in call. */
78 const char *barrier;
80 /** Informative "control" test likely to fail whose result is
81 * ignored. */
82 bool control_test;
85 const struct image_test_info image_tests[] = {
86 { "control", "", "", true },
87 { "'coherent' qualifier", "coherent", "memoryBarrier()", false },
88 { "'volatile' qualifier", "volatile", "memoryBarrier()", false },
89 { 0 }
92 char *
93 test_hunk(const struct image_test_info *test, unsigned k)
95 char *s = NULL;
97 (void)!asprintf(&s, "#define IMAGE_Q %s\n"
98 "#define MEMORY_BARRIER() %s\n"
99 "#define K %d\n",
100 test->qualifier, test->barrier, k);
101 return s;
104 static bool
105 init_image(const struct image_info img)
107 uint32_t pixels[N] = { 0 };
109 return upload_image(img, 0, pixels);
112 static bool
113 check(const struct grid_info grid)
115 uint32_t pixels[N];
117 return download_result(grid, pixels) &&
118 check_pixels(image_info_for_grid(grid), pixels, 33, 0, 0, 0);
121 static bool
122 run_test(const struct image_test_info *test,
123 const struct image_stage_info *stage,
124 unsigned k)
126 const struct grid_info grid =
127 grid_info(stage->stage, GL_R32UI, W, H);
128 const struct image_info img = image_info_for_grid(grid);
129 GLuint prog = generate_program(
130 grid, stage->stage,
131 concat(test_hunk(test, k),
132 image_hunk(img, ""),
133 hunk("IMAGE_Q IMAGE_UNIFORM_T img;\n"
134 "\n"
135 "GRID_T op(ivec2 idx, GRID_T arg) {\n"
136 " /*\n"
137 " * Shader invocations are classified into producers\n"
138 " * (check==false) and consumers (check==true), each\n"
139 " * producer being paired with a consumer K threads to\n"
140 " * the right.\n"
141 " */\n"
142 " bool check = ((idx.x / K) % 2 == 1);\n"
143 " int x = (idx.x % K) + (idx.x / (2 * K)) * (2 * K);\n"
144 " int i, n = 1000;\n"
145 "\n"
146 " for (i = 0; i < n; ++i) {\n"
147 " uint u, v;\n"
148 "\n"
149 " if (check) {\n"
150 " /*\n"
151 " * Consumer: Monitor the evolution of a pair of\n"
152 " * image locations until the test runs to\n"
153 " * completion or an inconsistency is observed.\n"
154 " */\n"
155 " v = imageLoad(img, ivec2(x, idx.y)).x;\n"
156 " MEMORY_BARRIER();\n"
157 " u = imageLoad(img, ivec2(x + K, idx.y)).x;\n"
158 "\n"
159 " if (u < v)\n"
160 " /* Fail. */\n"
161 " return GRID_T(v << 16 | u, 0, 0, 1);\n"
162 " } else {\n"
163 " /*\n"
164 " * Producer: Update the same pair of image locations\n"
165 " * sequentially with increasing values ordering the\n"
166 " * stores with a barrier.\n"
167 " */\n"
168 " imageStore(img, ivec2(x + K, idx.y), DATA_T(i));\n"
169 " MEMORY_BARRIER();\n"
170 " imageStore(img, ivec2(x, idx.y), DATA_T(i));\n"
171 " }\n"
172 " }\n"
173 "\n"
174 " /* Success. */\n"
175 " return GRID_T(33, 0, 0, 1);\n"
176 "}\n"), NULL));
177 bool ret = prog &&
178 init_fb(grid) &&
179 init_image(img) &&
180 set_uniform_int(prog, "img", 0) &&
181 draw_grid(grid, prog) &&
182 (check(grid) || test->control_test);
184 glDeleteProgram(prog);
185 return ret;
188 void
189 piglit_init(int argc, char **argv)
191 const bool quick = (argc >= 2 && !strcmp(argv[1], "--quick"));
192 const struct image_test_info *test;
193 const struct image_stage_info *stage;
194 enum piglit_result status = PIGLIT_PASS;
195 unsigned k;
197 piglit_require_extension("GL_ARB_shader_image_load_store");
199 for (k = 1; k <= K; k *= (quick ? 4 : 2)) {
200 for (test = image_tests; test->name; ++test) {
201 if (quick && test->control_test)
202 continue;
204 for (stage = image_stages(); stage->name; ++stage) {
205 subtest(&status, true,
206 run_test(test, stage, k),
207 "%s shader/%s memory barrier test"
208 "/modulus=%d",
209 stage->name, test->name, k);
214 piglit_report_result(status);
217 enum piglit_result
218 piglit_display(void)
220 return PIGLIT_FAIL;