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 * 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
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.
56 /** Total number of pixels in the window and image. */
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
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
);
82 const struct image_info img
= image_info(GL_TEXTURE_2D
, GL_R32F
, W
, H
);
85 glReadPixels(0, 0, W
, H
, GL_DEPTH_COMPONENT
, GL_FLOAT
, pixels
);
86 if (!piglit_check_gl_error(GL_NO_ERROR
))
89 if (!check_pixels(img
, pixels
, z
, 0, 0, 0)) {
90 printf(" Source: depth buffer\n");
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
))
105 if (!check_pixels(img
, pixels
, r
, g
, b
, a
)) {
106 printf(" Source: image\n");
114 check_query(GLuint q
, int expect
)
118 glGetQueryObjectiv(q
, GL_QUERY_RESULT
, &value
);
119 if (value
!= expect
) {
120 printf("Query result\n Expected: %d\n Observed: %d\n",
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.
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
),
144 hunk("IMAGE_UNIFORM_T img;\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"
152 bool ret
= prog
&& init_fb(grid
) &&
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
) &&
163 glDeleteProgram(prog
);
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.
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"
184 " gl_FragDepth = 1.0;\n"
185 " return GRID_T(0, 1, 0, 1);\n"
187 bool ret
= prog
&& init_fb(grid
);
190 glEnable(GL_DEPTH_TEST
);
191 glDepthFunc(depth_func
);
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
);
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
217 subtest(&status
, true,
218 run_test_image("layout(early_fragment_tests) in;\n",
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
227 subtest(&status
, true,
228 run_test_image("layout(early_fragment_tests) in;\n",
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,
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
248 subtest(&status
, true,
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",
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",
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
278 subtest(&status
, true,
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,
290 "occlusion query test/late-z fail");
292 piglit_report_result(status
);