fbo-mrt-alphatest: Actually require MRTs to be available.
[piglit.git] / tests / spec / arb_shader_image_load_store / coherency.c
bloba3ef5fe1ac578f694c8e0598bf979a83110e853e
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 coherency.c
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
29 * spec:
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."
36 * Together with:
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
51 * different sizes.
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.
60 #include "common.h"
62 /** Maximum image width. */
63 #define L 1024
65 /** Maximum number of pixels. */
66 #define N (L * L)
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 {
80 /** Test name. */
81 const char *name;
83 /** Image qualifier keyword. */
84 const char *qualifier;
86 /** Informative "control" test with no memory qualifiers whose
87 * result is ignored. */
88 bool control_test;
91 const struct image_qualifier_info image_qualifiers[] = {
92 { "control", "", true },
93 { "'coherent' qualifier", "coherent", false },
94 { "'volatile' qualifier", "volatile", false },
95 { 0 }
98 char *
99 qualifier_hunk(const struct image_qualifier_info *qual)
101 char *s = NULL;
103 (void)!asprintf(&s, "#define IMAGE_Q %s\n", qual->qualifier);
104 return s;
107 static bool
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]);
116 static bool
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);
125 static bool
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,
129 unsigned l)
131 const struct grid_info grid = {
132 stage_w->bit | stage_r->bit,
133 get_image_format(GL_RGBA32UI),
134 { l, l, 1, 1 }
136 const struct image_info img = image_info_for_grid(grid);
137 GLuint prog = generate_program(
138 grid,
140 * Write (11, 22, 33, 44) to some location on the
141 * image from the write stage.
143 stage_w->stage,
144 concat(qualifier_hunk(qual),
145 image_hunk(img, ""),
146 hunk("IMAGE_Q IMAGE_UNIFORM_T img;\n"
147 "\n"
148 "GRID_T op(ivec2 idx, GRID_T x) {\n"
149 " imageStore(img, idx, DATA_T(11, 22, 33, 44));"
150 " return x;"
151 "}\n"), NULL),
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.
159 stage_r->stage,
160 concat(qualifier_hunk(qual),
161 image_hunk(img, ""),
162 hunk("IMAGE_Q IMAGE_UNIFORM_T img;\n"
163 "\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);"
168 " else"
169 " return GRID_T(77, 77, 77, 77);"
170 "}\n"), NULL));
171 bool ret = prog &&
172 init_fb(grid) &&
173 init_image(img) &&
174 set_uniform_int(prog, "img", 0) &&
175 draw_grid(grid, prog) &&
176 (check(grid, img) || qual->control_test);
178 glDeleteProgram(prog);
179 return ret;
182 void
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;
190 unsigned l;
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)
197 continue;
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)
212 continue;
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,
218 qual->name, l, l);
224 piglit_report_result(status);
227 enum piglit_result
228 piglit_display(void)
230 return PIGLIT_FAIL;