cl: Don't use device_infos if num_device_infos == 0
[piglit.git] / tests / general / depth-clear-precision-check.c
blobc2fc3573c985bd8ee0d599b0c9aa2772e33007f3
1 /*
2 * Copyright (C) 2019, 2020, 2021, 2022 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.
25 /** @file depth-clear-precision-check.c
27 * Tests that glClearDepth store on gpu exactly the transferred values
28 * with different depth's values and with different depth formats.
31 #include "piglit-util-gl.h"
33 const struct piglit_subtest subtests[];
34 enum piglit_result test(void *data);
35 static struct piglit_gl_test_config *piglit_config;
37 #define ftoh(x) (piglit_float_from_half(piglit_half_from_float(x)))
39 PIGLIT_GL_TEST_CONFIG_BEGIN
41 piglit_config = &config;
42 config.subtests = subtests;
43 config.supports_gl_compat_version = 10;
44 config.window_width = 20;
45 config.window_height = 20;
46 config.window_visual = PIGLIT_GL_VISUAL_DOUBLE;
47 config.khr_no_error_support = PIGLIT_NO_ERRORS;
49 PIGLIT_GL_TEST_CONFIG_END
51 const struct piglit_subtest subtests[] = {
53 "depth16",
54 "depth16",
55 test,
56 (void *)GL_DEPTH_COMPONENT16
59 "depth24",
60 "depth24",
61 test,
62 (void *)GL_DEPTH_COMPONENT24
65 "depth32",
66 "depth32",
67 test,
68 (void *)GL_DEPTH_COMPONENT32
71 "depth24_stencil8",
72 "depth24_stencil8",
73 test,
74 (void *)GL_DEPTH24_STENCIL8
77 "depth32f",
78 "depth32f",
79 test,
80 (void *)GL_DEPTH_COMPONENT32F
83 "depth32f_stencil8",
84 "depth32f_stencil8",
85 test,
86 (void *)GL_DEPTH32F_STENCIL8
88 {0}};
90 static GLuint prog;
92 static const char *vs_source =
93 "#version 110 \n"
94 "void main() \n"
95 "{ \n"
96 " gl_Position = gl_Vertex;\n"
97 "} \n";
99 static const char *fs_source =
100 "#version 110 \n"
101 "uniform float depth;\n"
102 "void main() \n"
103 "{ \n"
104 " gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0);\n"
105 " gl_FragDepth = depth;\n"
106 "} \n";
109 * number of iteration must be below than all possible,
110 * because for big format (like 32bit) if testing every value,
111 * time of test approaches infinity. iteration_pow controls
112 * sampling rate, we test 2^iteration_pow number of values,
113 * independent of format and evenly chosen in all possible values
114 * for this format
116 static const uint32_t iteration_pow = 8;
118 uint32_t
119 depth_num_of_bits(uint32_t depth)
121 switch (depth) {
122 case GL_DEPTH_COMPONENT16: return 16;
123 case GL_DEPTH_COMPONENT24: return 24;
124 case GL_DEPTH_COMPONENT32: return 32;
125 case GL_DEPTH24_STENCIL8: return 24;
126 case GL_DEPTH_COMPONENT32F: return 32;
127 case GL_DEPTH32F_STENCIL8: return 32;
128 default: return 8;
132 bool
133 check_color(float depth)
135 int depth_location;
136 static const GLfloat green[] = {0.0, 1.0, 0.0, 1.0};
138 glClearDepth(depth);
139 glClearColor(1.0, 0.0, 0.0, 1.0);
140 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
142 depth_location = glGetUniformLocation(prog, "depth");
143 glUniform1f(depth_location, depth);
145 piglit_draw_rect(-1, -1, 2, 2);
147 return piglit_probe_pixel_rgb(0, 0, green);
150 enum piglit_result
151 test(void *data)
153 GLuint fb;
154 GLuint db, cb;
155 GLenum depth_format = (long unsigned)data;
157 GLenum status;
159 if (depth_format == GL_DEPTH24_STENCIL8)
160 if (!piglit_is_extension_supported(
161 "GL_EXT_packed_depth_stencil"))
162 return PIGLIT_SKIP;
164 if (depth_format == GL_DEPTH_COMPONENT32F ||
165 depth_format == GL_DEPTH32F_STENCIL8)
166 if (!piglit_is_extension_supported(
167 "GL_ARB_depth_buffer_float"))
168 return PIGLIT_SKIP;
170 glUseProgram(prog);
172 /* Create the FBO. */
173 glGenRenderbuffers(1, &db);
174 glBindRenderbuffer(GL_RENDERBUFFER, db);
176 glRenderbufferStorage(GL_RENDERBUFFER, depth_format,
177 piglit_width, piglit_height);
179 glGenRenderbuffers(1, &cb);
180 glBindRenderbuffer(GL_RENDERBUFFER, cb);
182 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8,
183 piglit_width, piglit_height);
185 glBindRenderbuffer(GL_RENDERBUFFER, 0);
187 glGenFramebuffers(1, &fb);
188 glBindFramebuffer(GL_FRAMEBUFFER, fb);
190 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
191 GL_RENDERBUFFER, db);
193 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
194 GL_RENDERBUFFER, cb);
196 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
198 if (status == GL_FRAMEBUFFER_UNSUPPORTED)
199 return PIGLIT_SKIP;
201 if (status != GL_FRAMEBUFFER_COMPLETE) {
202 printf("FBO incomplete status %s\n",
203 piglit_get_gl_enum_name(status));
204 return PIGLIT_FAIL;
207 bool pass = true;
209 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
210 glEnable(GL_DEPTH_TEST);
211 glDepthFunc(GL_EQUAL);
213 uint32_t numOfBits = depth_num_of_bits(depth_format);
214 uint32_t maxStoreableValue = (1l << numOfBits) - 1;
215 uint32_t step = 1 << (numOfBits - iteration_pow);
217 for (uint64_t depth = 0; depth < maxStoreableValue; depth += step) {
218 float fdepth = depth / (float)maxStoreableValue;
220 assert(maxStoreableValue * fdepth == depth);
222 if (numOfBits < 32)
223 fdepth = ftoh(depth / (float)maxStoreableValue);
225 pass = check_color(fdepth);
227 if (!pass) {
228 printf("Testing format: %s.\n"
229 "Mismatch between value set with "
230 "glClearDepth and set in shader. "
231 "Depth: %f\n",
232 piglit_get_gl_enum_name(depth_format),
233 fdepth);
234 break;
238 /* Cleanup. */
239 glDeleteRenderbuffers(1, &cb);
240 glDeleteRenderbuffers(1, &db);
241 glDeleteFramebuffers(1, &fb);
243 if (!piglit_check_gl_error(GL_NO_ERROR))
244 pass = false;
246 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
249 enum piglit_result
250 piglit_display(void)
252 enum piglit_result pass = PIGLIT_SKIP;
253 GLuint fs, vs;
255 vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source);
256 fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source);
257 prog = piglit_link_simple_program(vs, fs);
259 pass = piglit_run_selected_subtests(piglit_config->subtests,
260 piglit_config->selected_subtests,
261 piglit_config->num_selected_subtests,
262 pass);
264 glDeleteProgram(prog);
265 glDeleteShader(fs);
266 glDeleteShader(vs);
268 return pass;
271 void piglit_init(int argc, char **argv)
273 piglit_require_extension("GL_ARB_framebuffer_object");