2 * Copyright © 2013 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
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
26 * Tests that the atomic built-in functions have the expected effects
27 * on memory and return the expected results, with different binding
33 PIGLIT_GL_TEST_CONFIG_BEGIN
35 config
.supports_gl_core_version
= 31;
37 config
.window_width
= 1;
38 config
.window_height
= 1;
39 config
.window_visual
= PIGLIT_GL_VISUAL_DOUBLE
| PIGLIT_GL_VISUAL_RGBA
;
40 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
42 PIGLIT_GL_TEST_CONFIG_END
45 atomic_counters_expected_binding(GLuint prog
,
50 glGetActiveAtomicCounterBufferiv(prog
, 0,
51 GL_ATOMIC_COUNTER_BUFFER_BINDING
,
54 printf ("Unexpected binding point found, %i expected, %i found\n",
57 return binding
== param
;
61 * @vs_source, @fs_source, @gs_source will be considered a template based on
65 test_shader(GLint max_bindings
,
67 const char *vs_source
,
68 const char *fs_source
,
69 const char *gs_source
,
70 const uint32_t *start_buffer
,
71 const uint32_t *expected_buffer
,
72 const uint32_t *expected_color
)
81 glGenBuffers(1, &buffer
);
82 for (i
= 0; i
< max_bindings
; i
++) {
83 prog
= glCreateProgram();
84 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER
, i
, buffer
);
87 case GL_VERTEX_SHADER
:
88 asprintf_ret
= asprintf(&stage_source
, vs_source
, i
);
89 assert(asprintf_ret
> 0);
90 ret
= atomic_counters_compile(prog
, GL_FRAGMENT_SHADER
, fs_source
) &&
91 atomic_counters_compile(prog
, GL_VERTEX_SHADER
, stage_source
);
93 case GL_FRAGMENT_SHADER
:
94 asprintf_ret
= asprintf(&stage_source
, fs_source
, i
);
95 assert(asprintf_ret
> 0);
96 ret
= atomic_counters_compile(prog
, GL_FRAGMENT_SHADER
, stage_source
) &&
97 atomic_counters_compile(prog
, GL_VERTEX_SHADER
, vs_source
);
99 case GL_GEOMETRY_SHADER
:
100 asprintf_ret
= asprintf(&stage_source
, gs_source
, i
);
101 assert(asprintf_ret
> 0);
102 ret
= atomic_counters_compile(prog
, GL_FRAGMENT_SHADER
, fs_source
) &&
103 atomic_counters_compile(prog
, GL_VERTEX_SHADER
, vs_source
) &&
104 atomic_counters_compile(prog
, GL_GEOMETRY_SHADER
, stage_source
);
107 printf("Unsupported stage %i\n", stage
);
111 ret
= ret
&& atomic_counters_draw_point(prog
, 1, start_buffer
) &&
112 piglit_probe_rect_rgba_uint(0, 0, 1, 1, expected_color
) &&
113 atomic_counters_probe_buffer(0, 1, expected_buffer
) &&
114 atomic_counters_expected_binding(prog
, i
);
117 glDeleteProgram(prog
);
123 glDeleteBuffers(1, &buffer
);
129 run_test_vertex(GLint max_bindings
)
131 const char *fs_source
= "#version 140\n"
132 "flat in ivec4 vcolor;\n"
133 "out ivec4 fcolor;\n"
135 " fcolor = vcolor;\n"
137 const char *vs_template
= "#version 140\n"
138 "#extension GL_ARB_shader_atomic_counters : enable\n"
140 "layout(binding = %i, offset = 0) uniform atomic_uint x;\n"
141 "in vec4 piglit_vertex;\n"
142 "flat out ivec4 vcolor;\n"
145 " vcolor.x = int(atomicCounterDecrement(x));\n"
146 " vcolor.y = int(atomicCounterIncrement(x));\n"
147 " vcolor.z = int(atomicCounterIncrement(x));\n"
148 " vcolor.w = int(atomicCounter(x));\n"
149 " gl_Position = piglit_vertex;\n"
151 const uint32_t start_buffer
[] = { 0xffffffff };
152 const uint32_t expected_buffer
[] = { 0x0 };
153 const uint32_t expected_color
[] = { 0xfffffffe, 0xfffffffe,
156 return test_shader(max_bindings
, GL_VERTEX_SHADER
,
157 vs_template
, fs_source
, NULL
,
158 start_buffer
, expected_buffer
, expected_color
);
162 run_test_fragment(GLint max_bindings
)
164 const char *fs_template
= "#version 140\n"
165 "#extension GL_ARB_shader_atomic_counters : enable\n"
167 "out ivec4 fcolor;\n"
168 "layout(binding = %i, offset = 0) uniform atomic_uint x;\n"
171 " fcolor.x = int(atomicCounterDecrement(x));\n"
172 " fcolor.y = int(atomicCounterIncrement(x));\n"
173 " fcolor.z = int(atomicCounterIncrement(x));\n"
174 " fcolor.w = int(atomicCounter(x));\n"
176 const char *vs_source
= "#version 140\n"
177 "#extension GL_ARB_shader_atomic_counters : enable\n"
179 "in vec4 piglit_vertex;\n"
182 " gl_Position = piglit_vertex;\n"
184 const uint32_t start_buffer
[] = { 0xffffffff };
185 const uint32_t expected_buffer
[] = { 0x0 };
186 const uint32_t expected_color
[] = { 0xfffffffe, 0xfffffffe,
189 return test_shader(max_bindings
, GL_FRAGMENT_SHADER
,
190 vs_source
, fs_template
, NULL
,
191 start_buffer
, expected_buffer
, expected_color
);
195 run_test_geometry(GLint max_bindings
)
197 const char *fs_source
= "#version 140\n"
198 "flat in ivec4 gcolor;\n"
199 "out ivec4 fcolor;\n"
201 " fcolor = gcolor;\n"
203 const char *gs_template
= "#version 150\n"
204 "#extension GL_ARB_shader_atomic_counters : enable\n"
206 "layout(points) in;\n"
207 "layout(points, max_vertices=1) out;\n"
209 "flat out ivec4 gcolor;\n"
211 "layout(binding = %i, offset = 0) uniform atomic_uint x;\n"
214 " gl_Position = gl_in[0].gl_Position;\n"
215 " gcolor.x = int(atomicCounterDecrement(x));\n"
216 " gcolor.y = int(atomicCounterIncrement(x));\n"
217 " gcolor.z = int(atomicCounterIncrement(x));\n"
218 " gcolor.w = int(atomicCounter(x));\n"
221 const char *vs_source
= "#version 140\n"
222 "#extension GL_ARB_shader_atomic_counters : enable\n"
224 "in vec4 piglit_vertex;\n"
227 " gl_Position = piglit_vertex;\n"
229 const uint32_t start_buffer
[] = { 0xffffffff };
230 const uint32_t expected_buffer
[] = { 0x0 };
231 const uint32_t expected_color
[] = { 0xfffffffe, 0xfffffffe,
234 return test_shader(max_bindings
, GL_GEOMETRY_SHADER
,
235 vs_source
, fs_source
, gs_template
,
236 start_buffer
, expected_buffer
, expected_color
);
240 run_test_tess_control(void)
242 const char *fs_source
= "#version 140\n"
243 "flat in ivec4 tecolor;\n"
248 const char *tes_source
= "#version 150\n"
249 "#extension GL_ARB_tessellation_shader : enable\n"
251 "layout(triangles, point_mode) in;\n"
253 "patch in ivec4 tccolor;\n"
254 "flat out ivec4 tecolor;\n"
257 " gl_Position = gl_in[0].gl_Position * gl_TessCoord.x +\n"
258 " gl_in[1].gl_Position * gl_TessCoord.y +\n"
259 " gl_in[2].gl_Position * gl_TessCoord.z;\n"
261 " tecolor = tccolor;\n"
263 const char *tcs_source
= "#version 150\n"
264 "#extension GL_ARB_tessellation_shader : enable\n"
265 "#extension GL_ARB_shader_atomic_counters : enable\n"
267 "layout(vertices=3) out;\n"
269 "patch out ivec4 tccolor;\n"
271 "layout(binding = 0, offset = 0) uniform atomic_uint x;\n"
274 " if (gl_InvocationID == 0) {\n"
275 " gl_TessLevelInner[0] = 1;\n"
277 " gl_TessLevelOuter[0] = 1;\n"
278 " gl_TessLevelOuter[1] = 1;\n"
279 " gl_TessLevelOuter[2] = 1;\n"
281 " tccolor.x = int(atomicCounterDecrement(x));\n"
282 " tccolor.y = int(atomicCounterIncrement(x));\n"
283 " tccolor.z = int(atomicCounterIncrement(x));\n"
284 " tccolor.w = int(atomicCounter(x));\n"
287 " gl_out[gl_InvocationID].gl_Position =\n"
288 " gl_in[gl_InvocationID].gl_Position;\n"
290 const char *vs_source
= "#version 140\n"
291 "#extension GL_ARB_shader_atomic_counters : enable\n"
293 "in vec4 piglit_vertex;\n"
296 " gl_Position = piglit_vertex;\n"
298 const uint32_t start_buffer
[] = { 0xffffffff };
299 const uint32_t expected_buffer
[] = { 0x0 };
300 const uint32_t expected_color
[] = { 0xfffffffe, 0xfffffffe,
302 GLuint prog
= glCreateProgram();
304 atomic_counters_compile(prog
, GL_FRAGMENT_SHADER
, fs_source
) &&
305 atomic_counters_compile(prog
, GL_TESS_EVALUATION_SHADER
,
307 atomic_counters_compile(prog
, GL_TESS_CONTROL_SHADER
,
309 atomic_counters_compile(prog
, GL_VERTEX_SHADER
, vs_source
) &&
310 atomic_counters_draw_patch(prog
, 1, start_buffer
) &&
311 piglit_probe_rect_rgba_uint(0, 0, 1, 1, expected_color
) &&
312 atomic_counters_probe_buffer(0, 1, expected_buffer
);
314 glDeleteProgram(prog
);
319 run_test_tess_evaluation(void)
321 const char *fs_source
= "#version 140\n"
322 "flat in ivec4 tecolor;\n"
327 const char *tes_source
= "#version 150\n"
328 "#extension GL_ARB_shader_atomic_counters : enable\n"
329 "#extension GL_ARB_tessellation_shader : enable\n"
331 "layout(triangles, point_mode) in;\n"
333 "layout(binding = 0, offset = 0) uniform atomic_uint x;\n"
335 "flat out ivec4 tecolor;\n"
338 " gl_Position = gl_in[0].gl_Position * gl_TessCoord.x +\n"
339 " gl_in[1].gl_Position * gl_TessCoord.y +\n"
340 " gl_in[2].gl_Position * gl_TessCoord.z;\n"
342 " if (gl_TessCoord.y == 0.0 && gl_TessCoord.x == 1.0) {\n"
343 " tecolor.x = int(atomicCounterDecrement(x));\n"
344 " tecolor.y = int(atomicCounterIncrement(x));\n"
345 " tecolor.z = int(atomicCounterIncrement(x));\n"
346 " tecolor.w = int(atomicCounter(x));\n"
348 " tecolor = ivec4(0);\n"
351 const char *tcs_source
= "#version 150\n"
352 "#extension GL_ARB_tessellation_shader : enable\n"
354 "layout(vertices=3) out;\n"
357 " if (gl_InvocationID == 0) {\n"
358 " gl_TessLevelInner[0] = 1;\n"
360 " gl_TessLevelOuter[0] = 1;\n"
361 " gl_TessLevelOuter[1] = 1;\n"
362 " gl_TessLevelOuter[2] = 1;\n"
365 " gl_out[gl_InvocationID].gl_Position =\n"
366 " gl_in[gl_InvocationID].gl_Position;\n"
368 const char *vs_source
= "#version 140\n"
369 "#extension GL_ARB_shader_atomic_counters : enable\n"
371 "in vec4 piglit_vertex;\n"
374 " gl_Position = piglit_vertex;\n"
376 const uint32_t start_buffer
[] = { 0xffffffff };
377 const uint32_t expected_buffer
[] = { 0x0 };
378 const uint32_t expected_color
[] = { 0xfffffffe, 0xfffffffe,
380 GLuint prog
= glCreateProgram();
382 atomic_counters_compile(prog
, GL_FRAGMENT_SHADER
, fs_source
) &&
383 atomic_counters_compile(prog
, GL_TESS_EVALUATION_SHADER
,
385 atomic_counters_compile(prog
, GL_TESS_CONTROL_SHADER
,
387 atomic_counters_compile(prog
, GL_VERTEX_SHADER
, vs_source
) &&
388 atomic_counters_draw_patch(prog
, 1, start_buffer
) &&
389 piglit_probe_rect_rgba_uint(0, 0, 1, 1, expected_color
) &&
390 atomic_counters_probe_buffer(0, 1, expected_buffer
);
392 glDeleteProgram(prog
);
397 piglit_init(int argc
, char **argv
)
399 GLuint fb
, rb
, buffer
;
400 enum piglit_result status
= PIGLIT_PASS
;
403 piglit_require_extension("GL_ARB_shader_atomic_counters");
405 glGenFramebuffers(1, &fb
);
406 glGenRenderbuffers(1, &rb
);
408 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, fb
);
409 glBindFramebuffer(GL_READ_FRAMEBUFFER
, fb
);
410 glBindRenderbuffer(GL_RENDERBUFFER
, rb
);
412 glRenderbufferStorage(GL_RENDERBUFFER
, GL_RGBA32UI
, 1, 1);
413 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
414 GL_RENDERBUFFER
, rb
);
416 glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS
, &max_bindings
);
418 atomic_counters_subtest(&status
, GL_FRAGMENT_SHADER
,
419 "Fragment shader atomic built-in semantics",
420 run_test_fragment
, max_bindings
);
422 atomic_counters_subtest(&status
, GL_VERTEX_SHADER
,
423 "Vertex shader atomic built-in semantics",
424 run_test_vertex
, max_bindings
);
426 atomic_counters_subtest(&status
, GL_GEOMETRY_SHADER
,
427 "Geometry shader atomic built-in semantics",
428 run_test_geometry
, max_bindings
);
430 glGenBuffers(1, &buffer
);
431 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER
, 0, buffer
);
432 atomic_counters_subtest(&status
, GL_TESS_CONTROL_SHADER
,
433 "Tessellation control shader atomic built-in "
435 run_test_tess_control
);
437 atomic_counters_subtest(&status
, GL_TESS_EVALUATION_SHADER
,
438 "Tessellation evaluation shader atomic built-in "
440 run_test_tess_evaluation
);
442 piglit_report_result(status
);