framework/replay: disable AA accounting when comparing with no tolerance
[piglit.git] / tests / spec / arb_compute_variable_group_size / local-size.c
blob90a3477c389ee58df129df89e9adbe01a84bf389
1 /*
2 * Copyright (c) 2016 Samuel Pitoiset
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
21 * DEALINGS IN THE SOFTWARE.
24 /** \file
26 * Checks gl_LocalGroupSizeARB at various sizes up to the implementation
27 * maximums using atomic counters.
30 #include "piglit-util-gl.h"
32 PIGLIT_GL_TEST_CONFIG_BEGIN
34 config.supports_gl_compat_version = 33;
35 config.supports_gl_core_version = 33;
36 config.khr_no_error_support = PIGLIT_NO_ERRORS;
38 PIGLIT_GL_TEST_CONFIG_END
40 static GLuint atomics_bo = 0;
41 static GLint prog = 0;
43 static uint32_t global_x = 1, global_y = 1, global_z = 1;
44 static uint32_t local_x = 0, local_y = 0, local_z = 0;
45 static int32_t max_local_x = 0, max_local_y = 0, max_local_z = 0;
46 static int32_t max_variable_invocations = 0;
48 static uint32_t sizes[] = {
49 1, 2, 3, 4, 5, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65,
50 127, 128, 129, 255, 256, 257, 511, 512, 513, 1023, 1024
53 static const char *compute_shader_source =
54 "#version 330\n"
55 "#extension GL_ARB_compute_shader: enable\n"
56 "#extension GL_ARB_compute_variable_group_size: enable\n"
57 "#extension GL_ARB_shader_atomic_counters: require\n"
58 "\n"
59 "layout(binding = 0) uniform atomic_uint a;\n"
60 "layout(local_size_variable) in;\n"
61 "\n"
62 "void main()\n"
63 "{\n"
64 " if (gl_LocalGroupSizeARB.x == %du &&\n"
65 " gl_LocalGroupSizeARB.y == %du &&\n"
66 " gl_LocalGroupSizeARB.z == %du)\n"
67 " atomicCounterIncrement(a);\n"
68 "}\n";
70 static GLuint
71 generate_cs_prog(uint32_t x, uint32_t y, uint32_t z, char *src)
73 char *source = NULL;
75 (void)!asprintf(&source, src, x, y, z);
76 free(src);
78 GLuint prog = glCreateProgram();
80 GLuint shader =
81 piglit_compile_shader_text_nothrow(GL_COMPUTE_SHADER, source, true);
83 if (!shader) {
84 glDeleteProgram(prog);
85 return 0;
88 glAttachShader(prog, shader);
90 glLinkProgram(prog);
92 glDeleteShader(shader);
94 if (!piglit_link_check_status(prog)) {
95 glDeleteProgram(prog);
96 return 0;
99 return prog;
102 static enum piglit_result
103 check_result()
105 uint32_t expected = local_x * local_y * local_z;
106 bool pass = true;
107 uint32_t *p;
109 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomics_bo);
110 p = glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(uint32_t),
111 GL_MAP_READ_BIT);
112 if (!p) {
113 printf("Couldn't map atomic counter to verify expected value.\n");
114 return PIGLIT_FAIL;
117 if (p[0] != expected) {
118 printf("Atomic counter test failed for (%d, %d, %d)\n",
119 local_x, local_y, local_z);
120 printf(" Reference: %u\n", expected);
121 printf(" Observed: %u\n", p[0]);
122 pass = false;
125 glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
127 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
130 static enum piglit_result
131 run_test()
133 enum piglit_result result;
134 uint32_t atomics_init = 0;
136 if (local_x == 0 || local_y == 0 || local_z == 0)
137 return PIGLIT_FAIL;
139 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomics_bo);
140 glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(uint32_t), &atomics_init,
141 GL_STATIC_DRAW);
143 glUseProgram(prog);
145 glMemoryBarrier(GL_ALL_BARRIER_BITS);
146 glDispatchComputeGroupSizeARB(global_x, global_y, global_z,
147 local_x, local_y, local_z);
148 if (!piglit_check_gl_error(GL_NO_ERROR))
149 return PIGLIT_FAIL;
150 glMemoryBarrier(GL_ALL_BARRIER_BITS);
152 result = check_result();
153 if (result != PIGLIT_PASS)
154 piglit_report_result(result);
156 return result;
159 static void
160 clear_program()
162 if (prog != 0) {
163 local_x = 0;
164 local_y = 0;
165 local_z = 0;
166 glDeleteProgram(prog);
167 prog = 0;
171 static enum piglit_result
172 build_program_for_size(uint32_t x, uint32_t y, uint32_t z)
174 if (local_x == x && local_y == y &&
175 local_z == z && prog != 0) {
176 return PIGLIT_PASS;
179 clear_program();
181 prog = generate_cs_prog(x, y, z, strdup(compute_shader_source));
183 if (!prog)
184 return PIGLIT_FAIL;
186 local_x = x;
187 local_y = y;
188 local_z = z;
190 return PIGLIT_PASS;
193 enum piglit_result
194 set_local_size(uint32_t x, uint32_t y, uint32_t z)
196 enum piglit_result result = PIGLIT_PASS;
198 if (x == 0 || y == 0 || z == 0) {
199 clear_program();
200 return PIGLIT_FAIL;
203 result = build_program_for_size(x, y, z);
204 if (result != PIGLIT_PASS)
205 piglit_report_result(result);
207 return result;
210 static enum piglit_result
211 test_size(uint32_t x, uint32_t y, uint32_t z)
213 enum piglit_result result;
215 result = set_local_size(x, y, z);
216 if (result != PIGLIT_PASS)
217 piglit_report_result(result);
219 result = run_test();
220 if (result != PIGLIT_PASS)
221 piglit_report_result(result);
223 return result;
226 static enum piglit_result
227 test_all_sizes()
229 enum piglit_result result = PIGLIT_PASS;
230 uint32_t xi, yi, zi;
231 uint32_t x, y, z;
234 for (zi = 0; zi < ARRAY_SIZE(sizes); zi++) {
235 z = sizes[zi];
236 if (z > max_local_z)
237 break;
238 for (yi = 0; yi < ARRAY_SIZE(sizes); yi++) {
239 y = sizes[yi];
240 if (y > max_local_y ||
241 (y * z) > max_variable_invocations)
242 break;
243 for (xi = 0; xi < ARRAY_SIZE(sizes); xi++) {
244 x = sizes[xi];
245 if (x > max_local_x ||
246 (x * y * z) > max_variable_invocations)
247 break;
248 result = test_size(x, y, z);
249 if (result != PIGLIT_PASS)
250 return result;
255 return result;
258 enum piglit_result
259 piglit_display(void)
261 return PIGLIT_FAIL;
264 void
265 piglit_init(int argc, char **argv)
267 enum piglit_result result;
269 piglit_require_extension("GL_ARB_compute_variable_group_size");
270 piglit_require_extension("GL_ARB_shader_atomic_counters");
272 glGenBuffers(1, &atomics_bo);
273 if (!piglit_check_gl_error(GL_NO_ERROR))
274 piglit_report_result(PIGLIT_FAIL);
276 glGetIntegeri_v(GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB,
277 0, &max_local_x);
278 glGetIntegeri_v(GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB,
279 1, &max_local_y);
280 glGetIntegeri_v(GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB,
281 2, &max_local_z);
282 glGetIntegerv(GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB,
283 &max_variable_invocations);
285 result = test_all_sizes();
287 glDeleteBuffers(1, &atomics_bo);
289 piglit_report_result(result);