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
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.
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
=
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"
59 "layout(binding = 0) uniform atomic_uint a;\n"
60 "layout(local_size_variable) in;\n"
64 " if (gl_LocalGroupSizeARB.x == %du &&\n"
65 " gl_LocalGroupSizeARB.y == %du &&\n"
66 " gl_LocalGroupSizeARB.z == %du)\n"
67 " atomicCounterIncrement(a);\n"
71 generate_cs_prog(uint32_t x
, uint32_t y
, uint32_t z
, char *src
)
75 (void)!asprintf(&source
, src
, x
, y
, z
);
78 GLuint prog
= glCreateProgram();
81 piglit_compile_shader_text_nothrow(GL_COMPUTE_SHADER
, source
, true);
84 glDeleteProgram(prog
);
88 glAttachShader(prog
, shader
);
92 glDeleteShader(shader
);
94 if (!piglit_link_check_status(prog
)) {
95 glDeleteProgram(prog
);
102 static enum piglit_result
105 uint32_t expected
= local_x
* local_y
* local_z
;
109 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER
, 0, atomics_bo
);
110 p
= glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER
, 0, sizeof(uint32_t),
113 printf("Couldn't map atomic counter to verify expected value.\n");
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]);
125 glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER
);
127 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;
130 static enum piglit_result
133 enum piglit_result result
;
134 uint32_t atomics_init
= 0;
136 if (local_x
== 0 || local_y
== 0 || local_z
== 0)
139 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER
, 0, atomics_bo
);
140 glBufferData(GL_ATOMIC_COUNTER_BUFFER
, sizeof(uint32_t), &atomics_init
,
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
))
150 glMemoryBarrier(GL_ALL_BARRIER_BITS
);
152 result
= check_result();
153 if (result
!= PIGLIT_PASS
)
154 piglit_report_result(result
);
166 glDeleteProgram(prog
);
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) {
181 prog
= generate_cs_prog(x
, y
, z
, strdup(compute_shader_source
));
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) {
203 result
= build_program_for_size(x
, y
, z
);
204 if (result
!= PIGLIT_PASS
)
205 piglit_report_result(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
);
220 if (result
!= PIGLIT_PASS
)
221 piglit_report_result(result
);
226 static enum piglit_result
229 enum piglit_result result
= PIGLIT_PASS
;
234 for (zi
= 0; zi
< ARRAY_SIZE(sizes
); zi
++) {
238 for (yi
= 0; yi
< ARRAY_SIZE(sizes
); yi
++) {
240 if (y
> max_local_y
||
241 (y
* z
) > max_variable_invocations
)
243 for (xi
= 0; xi
< ARRAY_SIZE(sizes
); xi
++) {
245 if (x
> max_local_x
||
246 (x
* y
* z
) > max_variable_invocations
)
248 result
= test_size(x
, y
, z
);
249 if (result
!= PIGLIT_PASS
)
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
,
278 glGetIntegeri_v(GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB
,
280 glGetIntegeri_v(GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB
,
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
);