cmake: move defaults into the per-platform section
[piglit.git] / tests / general / clearbuffer-depth-cs-probe.c
blobd45b0202059be8f19b572de8b502cd7904515c16
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
12 * Software.
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
20 * IN THE SOFTWARE.
23 /**
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
41 struct framebuffer
43 GLuint fbo;
44 GLuint depth;
47 static struct
49 GLuint program;
50 GLuint counter;
51 } cs_probe;
53 static void
54 cs_probe_init(float expected_depth);
56 static bool
57 cs_probe_check(GLuint texture);
59 static void
60 cs_probe_free();
62 static struct framebuffer
63 generate_fbo();
65 void piglit_init(int argc, char **argv)
68 unsigned i;
69 bool pass = true;
70 static const float expected_depth[3] = {
71 0.16f,
72 0.77f,
73 0.35f
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++) {
82 GLenum err;
83 struct framebuffer fb = generate_fbo();
85 cs_probe_init(expected_depth[i + 1]);
87 glClearBufferfv(GL_DEPTH, 0, &expected_depth[i]);
88 err = glGetError();
89 if (err != GL_NO_ERROR) {
90 fprintf(stderr,
91 "First call to glClearBufferfv erroneously "
92 "generated a GL error (%s, 0x%04x)\n",
93 piglit_get_gl_error_name(err), err);
94 pass = false;
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]);
104 err = glGetError();
105 if (err != GL_NO_ERROR) {
106 fprintf(stderr,
107 "First call to glClearBufferfv erroneously "
108 "generated a GL error (%s, 0x%04x)\n",
109 piglit_get_gl_error_name(err), err);
110 pass = false;
113 pass = cs_probe_check(fb.depth) && pass;
115 cs_probe_free();
117 glDeleteFramebuffers(1, &fb.fbo);
118 glDeleteTextures(1, &fb.depth);
120 piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
123 static struct framebuffer
124 generate_fbo()
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);
151 glFinish();
153 if (!piglit_check_gl_error(GL_NO_ERROR))
154 piglit_report_result(PIGLIT_FAIL);
156 return fb;
160 static bool
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,
181 sizeof(unsigned),
182 GL_MAP_READ_BIT);
183 glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
184 return differences == 0u;
187 static char*
188 generate_shader_src(float expected_depth)
190 static const char *cs_probe_source =
191 "#version 150\n"
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"
198 "void main() {\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"
202 "}\n";
204 char *shader_src;
205 unsigned size;
207 size = strlen(cs_probe_source) + 32;
208 shader_src = malloc(size);
209 snprintf(shader_src, size, cs_probe_source, expected_depth);
210 return shader_src;
213 static void
214 cs_probe_init(float expected_depth)
216 GLuint cs;
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);
226 glDeleteShader(cs);
227 free(source);
230 static void
231 cs_probe_free()
233 glDeleteProgram(cs_probe.program);
234 glDeleteBuffers(1, &cs_probe.counter);
237 enum piglit_result
238 piglit_display(void)
240 return PIGLIT_FAIL;