glsl: test loop unroll with uint overflow
[piglit.git] / tests / spec / arb_shader_image_load_store / early-z.c
blobc55d81a87909577af4f58324e5223bfc6c404045
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 early-z.c
26 * Test the interaction between early per-fragment tests, image access
27 * and occlusion queries. According to the spec:
29 * "When early per-fragment operations are enabled, the depth bounds
30 * test, stencil test, depth buffer test, and occlusion query sample
31 * counting operations are performed prior to fragment shader
32 * execution, and the stencil buffer, depth buffer, and occlusion
33 * query sample counts will be updated accordingly."
35 * "If a fragment is discarded during any of these operations, it will
36 * not be processed by any subsequent stage, including fragment
37 * shader execution."
39 * This checks several consequences of the quoted text, including that
40 * the fragment shader is guaranteed not to be executed if the depth
41 * test fails, that the depth value computed by the fragment shader is
42 * ignored, and that fragments discarded during fragment shader
43 * execution are counted by occlusion queries. We also check that
44 * when using normal (late) fragment tests image stores have an effect
45 * regardless of the depth test results.
48 #include "common.h"
50 /** Window width. */
51 #define W 16
53 /** Window height. */
54 #define H 96
56 /** Total number of pixels in the window and image. */
57 #define N (W * H)
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 static bool
71 init_image(const struct image_info img)
73 uint32_t pixels[4 * N];
75 return init_pixels(img, pixels, 1, 0, 0, 1) &&
76 upload_image(img, 0, pixels);
79 static bool
80 check_zb(double z)
82 const struct image_info img = image_info(GL_TEXTURE_2D, GL_R32F, W, H);
83 uint32_t pixels[N];
85 glReadPixels(0, 0, W, H, GL_DEPTH_COMPONENT, GL_FLOAT, pixels);
86 if (!piglit_check_gl_error(GL_NO_ERROR))
87 return false;
89 if (!check_pixels(img, pixels, z, 0, 0, 0)) {
90 printf(" Source: depth buffer\n");
91 return false;
94 return true;
97 static bool
98 check_img(const struct image_info img, double r, double g, double b, double a)
100 uint32_t pixels[4 * N];
102 if (!download_image(img, 0, pixels))
103 return false;
105 if (!check_pixels(img, pixels, r, g, b, a)) {
106 printf(" Source: image\n");
107 return false;
110 return true;
113 static bool
114 check_query(GLuint q, int expect)
116 int value;
118 glGetQueryObjectiv(q, GL_QUERY_RESULT, &value);
119 if (value != expect) {
120 printf("Query result\n Expected: %d\n Observed: %d\n",
121 expect, value);
122 return false;
125 return piglit_check_gl_error(GL_NO_ERROR);
129 * Write to an image from the fragment shader using early or late
130 * depth tests according to \a input_layout and check the results.
132 static bool
133 run_test_image(const char *input_layout, GLenum depth_func,
134 double expect_r, double expect_g, double expect_b,
135 double expect_a, double expect_z)
137 const struct grid_info grid =
138 grid_info(GL_FRAGMENT_SHADER, GL_RGBA32F, W, H);
139 const struct image_info img = image_info_for_grid(grid);
140 GLuint prog = generate_program(
141 grid, GL_FRAGMENT_SHADER,
142 concat(hunk(input_layout),
143 image_hunk(img, ""),
144 hunk("IMAGE_UNIFORM_T img;\n"
145 "\n"
146 "GRID_T op(ivec2 idx, GRID_T x) {\n"
147 " imageStore(img, IMAGE_ADDR(idx),"
148 " GRID_T(0, 1, 0, 1));\n"
149 " gl_FragDepth = 1.0;\n"
150 " return GRID_T(0, 1, 0, 1);\n"
151 "}\n"), NULL));
152 bool ret = prog && init_fb(grid) &&
153 init_image(img) &&
154 set_uniform_int(prog, "img", 0);
156 glEnable(GL_DEPTH_TEST);
157 glDepthFunc(depth_func);
159 ret &= draw_grid(grid, prog) &&
160 check_img(img, expect_r, expect_g, expect_b, expect_a) &&
161 check_zb(expect_z);
163 glDeleteProgram(prog);
164 return ret;
168 * Draw a grid of conditionally discarded fragments with early or late
169 * depth tests according to \a input_layout and check the resulting
170 * occlusion query sample count.
172 static bool
173 run_test_query(const char *input_layout, GLenum depth_func,
174 unsigned expect_samples_passed)
176 const struct grid_info grid =
177 grid_info(GL_FRAGMENT_SHADER, GL_RGBA32F, W, H);
178 GLuint prog = generate_program(
179 grid, GL_FRAGMENT_SHADER,
180 concat(hunk(input_layout),
181 hunk("GRID_T op(ivec2 idx, GRID_T x) {\n"
182 " if ((idx.x & 1) == 0)\n"
183 " discard;\n"
184 " gl_FragDepth = 1.0;\n"
185 " return GRID_T(0, 1, 0, 1);\n"
186 "}\n"), NULL));
187 bool ret = prog && init_fb(grid);
188 GLenum q;
190 glEnable(GL_DEPTH_TEST);
191 glDepthFunc(depth_func);
192 glGenQueries(1, &q);
194 glBeginQuery(GL_SAMPLES_PASSED, q);
195 ret &= draw_grid(grid, prog);
196 glEndQuery(GL_SAMPLES_PASSED);
198 ret &= check_query(q, expect_samples_passed);
200 glDeleteQueries(1, &q);
201 glDeleteProgram(prog);
202 return ret;
205 void
206 piglit_init(int argc, char **argv)
208 enum piglit_result status = PIGLIT_PASS;
210 piglit_require_extension("GL_ARB_shader_image_load_store");
213 * Image stores should be executed, but the computed depth
214 * value should have no effect if the early depth test
215 * passes.
217 subtest(&status, true,
218 run_test_image("layout(early_fragment_tests) in;\n",
219 GL_LEQUAL,
220 0.0, 1.0, 0.0, 1.0, 0.5),
221 "image access test/early-z pass");
224 * Image stores should have no effect if the early depth test
225 * fails.
227 subtest(&status, true,
228 run_test_image("layout(early_fragment_tests) in;\n",
229 GL_GREATER,
230 1.0, 0.0, 0.0, 1.0, 0.5),
231 "image access test/early-z fail");
234 * Image stores should be executed and the computed depth
235 * value should be recorded if the late depth test passes.
237 subtest(&status, true,
238 run_test_image("",
239 GL_GREATER,
240 0.0, 1.0, 0.0, 1.0, 1.0),
241 "image access test/late-z pass");
244 * Image stores should be executed, but the computed depth
245 * value should have no effect if the late depth test
246 * fails.
248 subtest(&status, true,
249 run_test_image("",
250 GL_LEQUAL,
251 0.0, 1.0, 0.0, 1.0, 0.5),
252 "image access test/late-z fail");
255 * All fragments should be recorded in the occlusion query
256 * with a passing early depth test even if some are discarded
257 * further down the pipeline.
259 subtest(&status, true,
260 run_test_query("layout(early_fragment_tests) in;\n",
261 GL_LEQUAL, N),
262 "occlusion query test/early-z pass");
265 * No fragments should be recorded in the occlusion query with
266 * a failing early depth test.
268 subtest(&status, true,
269 run_test_query("layout(early_fragment_tests) in;\n",
270 GL_GREATER, 0),
271 "occlusion query test/early-z fail");
274 * Only the fragments that don't call discard should be
275 * recorded in the sample count with a passing late depth
276 * test.
278 subtest(&status, true,
279 run_test_query("",
280 GL_GREATER, N / 2),
281 "occlusion query test/late-z pass");
284 * No fragments should be recorded in the sample count with a
285 * failing late depth test.
287 subtest(&status, true,
288 run_test_query("",
289 GL_LEQUAL, 0),
290 "occlusion query test/late-z fail");
292 piglit_report_result(status);
295 enum piglit_result
296 piglit_display(void)
298 return PIGLIT_FAIL;