1 /* Copyright © 2020 Intel Corporation
3 * Permission is hereby granted, free of charge, to any person obtaining a
4 * copy of this software and associated documentation files (the "Software"),
5 * to deal in the Software without restriction, including without limitation
6 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 * and/or sell copies of the Software, and to permit persons to whom the
8 * Software is furnished to do so, subject to the following conditions:
10 * The above copyright notice and this permission notice (including the next
11 * paragraph) shall be included in all copies or substantial portions of the
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 * \file clearbuffer-depth-cs-probe.c
26 * Verify clearing depth buffer with \c glClearBufferfv and
27 * check its result by using compute shader
29 * \author Andrii Simiklit
31 #include "piglit-util-gl.h"
33 PIGLIT_GL_TEST_CONFIG_BEGIN
35 config
.supports_gl_compat_version
= 33;
36 config
.supports_gl_core_version
= 33;
37 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
39 PIGLIT_GL_TEST_CONFIG_END
54 cs_probe_init(float expected_depth
);
57 cs_probe_check(GLuint texture
);
62 static struct framebuffer
65 void piglit_init(int argc
, char **argv
)
70 static const float expected_depth
[3] = {
76 piglit_require_extension("GL_ARB_compute_shader");
77 piglit_require_extension("GL_ARB_shader_atomic_counters");
78 piglit_require_extension("GL_ARB_explicit_uniform_location");
80 for (i
= 0; i
< (ARRAY_SIZE(expected_depth
) - 1); i
++) {
83 struct framebuffer fb
= generate_fbo();
85 cs_probe_init(expected_depth
[i
+ 1]);
87 glClearBufferfv(GL_DEPTH
, 0, &expected_depth
[i
]);
89 if (err
!= GL_NO_ERROR
) {
91 "First call to glClearBufferfv erroneously "
92 "generated a GL error (%s, 0x%04x)\n",
93 piglit_get_gl_error_name(err
), err
);
98 * After first clear the shader has to detect differences
99 * because shader expects other depth value
101 pass
= !cs_probe_check(fb
.depth
) && pass
;
103 glClearBufferfv(GL_DEPTH
, 0, &expected_depth
[i
+ 1]);
105 if (err
!= GL_NO_ERROR
) {
107 "First call to glClearBufferfv erroneously "
108 "generated a GL error (%s, 0x%04x)\n",
109 piglit_get_gl_error_name(err
), err
);
113 pass
= cs_probe_check(fb
.depth
) && pass
;
117 glDeleteFramebuffers(1, &fb
.fbo
);
118 glDeleteTextures(1, &fb
.depth
);
120 piglit_report_result(pass
? PIGLIT_PASS
: PIGLIT_FAIL
);
123 static struct framebuffer
126 static const float default_depth
= 0.2;
127 struct framebuffer fb
;
129 glGenFramebuffers(1, &fb
.fbo
);
130 glBindFramebuffer(GL_FRAMEBUFFER
, fb
.fbo
);
132 glGenTextures(1, &fb
.depth
);
134 glBindTexture(GL_TEXTURE_2D
, fb
.depth
);
135 glTexStorage2D(GL_TEXTURE_2D
, 1, GL_DEPTH_COMPONENT24
, piglit_width
, piglit_height
);
136 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAX_LEVEL
, 0);
137 glFramebufferTexture2D(GL_FRAMEBUFFER
, GL_DEPTH_ATTACHMENT
, GL_TEXTURE_2D
, fb
.depth
, 0);
139 /* If GL_ARB_ES2_compatibility is not supported, the GL
140 * expects the draw buffer and read buffer be disabled if
141 * there is no color buffer (to read or draw).
143 glDrawBuffer(GL_NONE
);
144 glReadBuffer(GL_NONE
);
146 if (!piglit_check_gl_error(GL_NO_ERROR
))
147 piglit_report_result(PIGLIT_FAIL
);
149 glClearDepth(default_depth
);
150 glClear(GL_DEPTH_BUFFER_BIT
);
153 if (!piglit_check_gl_error(GL_NO_ERROR
))
154 piglit_report_result(PIGLIT_FAIL
);
161 cs_probe_check(GLuint texture
)
163 static const unsigned initial_count
= 0;
164 unsigned differences
= 0u;
166 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER
, 0, cs_probe
.counter
);
167 glBufferData(GL_ATOMIC_COUNTER_BUFFER
,
168 sizeof(unsigned), &initial_count
, GL_DYNAMIC_DRAW
);
170 glActiveTexture(GL_TEXTURE0
);
171 glBindTexture(GL_TEXTURE_2D
, texture
);
173 glUseProgram(cs_probe
.program
);
174 glUniform1i(glGetUniformLocation(cs_probe
.program
, "source"), 0);
176 glDispatchCompute(piglit_width
, piglit_height
, 1);
178 glMemoryBarrier(GL_ALL_BARRIER_BITS
);
179 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER
, 0, cs_probe
.counter
);
180 differences
= *(unsigned*)glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER
, 0,
183 glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER
);
184 return differences
== 0u;
188 generate_shader_src(float expected_depth
)
190 static const char *cs_probe_source
=
192 "#extension GL_ARB_compute_shader: require\n"
193 "#extension GL_ARB_shader_atomic_counters: require\n"
194 "#extension GL_ARB_explicit_uniform_location: require\n"
195 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
196 "layout(binding = 0) uniform atomic_uint differences;\n"
197 "uniform sampler2D source;\n"
199 " ivec2 coord = ivec2(gl_GlobalInvocationID.xy);\n"
200 " if (abs(texelFetch(source, coord, 0).r - %f) > 0.001f)\n"
201 " atomicCounterIncrement(differences);\n"
207 size
= strlen(cs_probe_source
) + 32;
208 shader_src
= malloc(size
);
209 snprintf(shader_src
, size
, cs_probe_source
, expected_depth
);
214 cs_probe_init(float expected_depth
)
217 char *source
= generate_shader_src(expected_depth
);
219 cs
= piglit_compile_shader_text(GL_COMPUTE_SHADER
, source
);
220 cs_probe
.program
= glCreateProgram();
221 glAttachShader(cs_probe
.program
, cs
);
222 glLinkProgram(cs_probe
.program
);
224 glGenBuffers(1, &cs_probe
.counter
);
233 glDeleteProgram(cs_probe
.program
);
234 glDeleteBuffers(1, &cs_probe
.counter
);