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
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
26 * Images declared as "coherent" or "volatile" give certain guarantees
27 * regarding the visibility of memory writes to other shader invocations
28 * in the pipeline. This test checks the following assertion of the
30 * "When reading a variable declared as 'coherent', the values returned
31 * will reflect the results of previously completed writes performed by
32 * other shader invocations. When writing a variable declared as
33 * 'coherent', the values written will be reflected in subsequent
34 * coherent reads performed by other shader invocations."
37 * "When executing a shader whose inputs are generated from a previous
38 * programmable stage, the shader invocations from the previous stage
39 * are guaranteed to have executed far enough to generate final values
40 * for all next-stage inputs."
42 * In order to test this we bind two shader programs at different
43 * execution stages of the pipeline and check that the values written to
44 * an image from the first stage are visible when the same primitive is
45 * dispatched at the second stage. This is repeated for all combinations
46 * of dependent shader stages (what necessarily excludes the compute
47 * shader), for the "coherent" and "volatile" qualifiers (the latter is
48 * supposed to give stricter ordering guarantees), and for different
49 * execution sizes between 4x4 and 1024x1024 to account for
50 * implementations with varying levels of parallelism and with caches of
53 * Unless running in "quick" mode a series of control tests is
54 * executed repeating the same process without any memory qualifiers.
55 * This is useful to see if the cache is being hit since otherwise the
56 * main test is not meaningful. The control test always passes as it
57 * is expected to misrender.
62 /** Maximum image width. */
65 /** Maximum number of pixels. */
68 PIGLIT_GL_TEST_CONFIG_BEGIN
70 config
.supports_gl_core_version
= 32;
72 config
.window_width
= L
;
73 config
.window_height
= L
;
74 config
.window_visual
= PIGLIT_GL_VISUAL_DOUBLE
| PIGLIT_GL_VISUAL_RGBA
;
75 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
77 PIGLIT_GL_TEST_CONFIG_END
79 struct image_qualifier_info
{
83 /** Image qualifier keyword. */
84 const char *qualifier
;
86 /** Informative "control" test with no memory qualifiers whose
87 * result is ignored. */
91 const struct image_qualifier_info image_qualifiers
[] = {
92 { "control", "", true },
93 { "'coherent' qualifier", "coherent", false },
94 { "'volatile' qualifier", "volatile", false },
99 qualifier_hunk(const struct image_qualifier_info
*qual
)
103 (void)!asprintf(&s
, "#define IMAGE_Q %s\n", qual
->qualifier
);
108 init_image(const struct image_info img
)
110 static uint32_t pixels
[N
][4];
112 return init_pixels(img
, pixels
[0], 99, 99, 99, 99) &&
113 upload_image(img
, 0, pixels
[0]);
117 check(const struct grid_info grid
, const struct image_info img
)
119 static uint32_t pixels
[N
][4];
121 return download_result(grid
, pixels
[0]) &&
122 check_pixels(img
, pixels
[0], 33, 33, 33, 33);
126 run_test(const struct image_qualifier_info
*qual
,
127 const struct image_stage_info
*stage_w
,
128 const struct image_stage_info
*stage_r
,
131 const struct grid_info grid
= {
132 stage_w
->bit
| stage_r
->bit
,
133 get_image_format(GL_RGBA32UI
),
136 const struct image_info img
= image_info_for_grid(grid
);
137 GLuint prog
= generate_program(
140 * Write (11, 22, 33, 44) to some location on the
141 * image from the write stage.
144 concat(qualifier_hunk(qual
),
146 hunk("IMAGE_Q IMAGE_UNIFORM_T img;\n"
148 "GRID_T op(ivec2 idx, GRID_T x) {\n"
149 " imageStore(img, idx, DATA_T(11, 22, 33, 44));"
153 * The same location will read back the expected value
154 * if image access is coherent, as the shader inputs
155 * of the read stage are dependent on the outputs of
156 * the write stage and consequently they are
157 * guaranteed to be executed sequentially.
160 concat(qualifier_hunk(qual
),
162 hunk("IMAGE_Q IMAGE_UNIFORM_T img;\n"
164 "GRID_T op(ivec2 idx, GRID_T x) {\n"
165 " DATA_T v = imageLoad(img, idx);"
166 " if (v == DATA_T(11, 22, 33, 44))"
167 " return GRID_T(33, 33, 33, 33);"
169 " return GRID_T(77, 77, 77, 77);"
174 set_uniform_int(prog
, "img", 0) &&
175 draw_grid(grid
, prog
) &&
176 (check(grid
, img
) || qual
->control_test
);
178 glDeleteProgram(prog
);
183 piglit_init(int argc
, char **argv
)
185 const bool quick
= (argc
>= 2 && !strcmp(argv
[1], "--quick"));
186 const struct image_qualifier_info
*qual
;
187 const struct image_stage_info
*stage_w
;
188 const struct image_stage_info
*stage_r
;
189 enum piglit_result status
= PIGLIT_PASS
;
192 piglit_require_extension("GL_ARB_shader_image_load_store");
194 for (l
= 4; l
<= L
; l
*= (quick
? 8 : 2)) {
195 for (qual
= image_qualifiers
; qual
->name
; ++qual
) {
196 if (quick
&& qual
->control_test
)
200 * Loop for each pair of shader stages
201 * skipping the compute shader: "coherent"
202 * gives no useful guarantees in that case
203 * since its execution ordering is undefined
204 * with respect to the other shader stages.
206 for (stage_w
= image_stages();
207 stage_w
->stage
; ++stage_w
) {
208 for (stage_r
= stage_w
+ 1;
209 stage_r
->stage
; ++stage_r
) {
210 if (stage_w
->stage
== GL_COMPUTE_SHADER
||
211 stage_r
->stage
== GL_COMPUTE_SHADER
)
214 subtest(&status
, true,
215 run_test(qual
, stage_w
, stage_r
, l
),
216 "%s-%s shader/%s coherency test/%dx%d",
217 stage_w
->name
, stage_r
->name
,
224 piglit_report_result(status
);