ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / arb_shader_atomic_counters / semantics.c
blob7da3583994dbdfbc27cc11b482448e0262cc6d7e
1 /*
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
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.
24 /** @file semantics.c
26 * Tests that the atomic built-in functions have the expected effects
27 * on memory and return the expected results, with different binding
28 * points.
31 #include "common.h"
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
44 static bool
45 atomic_counters_expected_binding(GLuint prog,
46 GLuint binding)
48 GLint param;
50 glGetActiveAtomicCounterBufferiv(prog, 0,
51 GL_ATOMIC_COUNTER_BUFFER_BINDING,
52 &param);
53 if (binding != param)
54 printf ("Unexpected binding point found, %i expected, %i found\n",
55 binding, param);
57 return binding == param;
61 * @vs_source, @fs_source, @gs_source will be considered a template based on
62 * @stage.
64 static bool
65 test_shader(GLint max_bindings,
66 GLuint stage,
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)
74 GLuint prog;
75 bool ret = true;
76 GLuint buffer;
77 char *stage_source;
78 int i;
79 int asprintf_ret;
81 glGenBuffers(1, &buffer);
82 for (i = 0; i < max_bindings; i++) {
83 prog = glCreateProgram();
84 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, i, buffer);
86 switch (stage) {
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);
92 break;
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);
98 break;
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);
105 break;
106 default:
107 printf("Unsupported stage %i\n", stage);
108 return false;
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);
116 free(stage_source);
117 glDeleteProgram(prog);
119 if (!ret)
120 break;
123 glDeleteBuffers(1, &buffer);
125 return ret;
128 static bool
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"
134 "void main() {\n"
135 " fcolor = vcolor;\n"
136 "}\n";
137 const char *vs_template = "#version 140\n"
138 "#extension GL_ARB_shader_atomic_counters : enable\n"
139 "\n"
140 "layout(binding = %i, offset = 0) uniform atomic_uint x;\n"
141 "in vec4 piglit_vertex;\n"
142 "flat out ivec4 vcolor;\n"
143 "\n"
144 "void main() {\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"
150 "}\n";
151 const uint32_t start_buffer[] = { 0xffffffff };
152 const uint32_t expected_buffer[] = { 0x0 };
153 const uint32_t expected_color[] = { 0xfffffffe, 0xfffffffe,
154 0xffffffff, 0x0 };
156 return test_shader(max_bindings, GL_VERTEX_SHADER,
157 vs_template, fs_source, NULL,
158 start_buffer, expected_buffer, expected_color);
161 static bool
162 run_test_fragment(GLint max_bindings)
164 const char *fs_template = "#version 140\n"
165 "#extension GL_ARB_shader_atomic_counters : enable\n"
166 "\n"
167 "out ivec4 fcolor;\n"
168 "layout(binding = %i, offset = 0) uniform atomic_uint x;\n"
169 "\n"
170 "void main() {\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"
175 "}\n";
176 const char *vs_source = "#version 140\n"
177 "#extension GL_ARB_shader_atomic_counters : enable\n"
178 "\n"
179 "in vec4 piglit_vertex;\n"
180 "\n"
181 "void main() {\n"
182 " gl_Position = piglit_vertex;\n"
183 "}\n";
184 const uint32_t start_buffer[] = { 0xffffffff };
185 const uint32_t expected_buffer[] = { 0x0 };
186 const uint32_t expected_color[] = { 0xfffffffe, 0xfffffffe,
187 0xffffffff, 0x0 };
189 return test_shader(max_bindings, GL_FRAGMENT_SHADER,
190 vs_source, fs_template, NULL,
191 start_buffer, expected_buffer, expected_color);
194 static bool
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"
200 "void main() {\n"
201 " fcolor = gcolor;\n"
202 "}\n";
203 const char *gs_template = "#version 150\n"
204 "#extension GL_ARB_shader_atomic_counters : enable\n"
205 "\n"
206 "layout(points) in;\n"
207 "layout(points, max_vertices=1) out;\n"
208 "\n"
209 "flat out ivec4 gcolor;\n"
210 "\n"
211 "layout(binding = %i, offset = 0) uniform atomic_uint x;\n"
212 "\n"
213 "void main() {\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"
219 " EmitVertex();\n"
220 "}\n";
221 const char *vs_source = "#version 140\n"
222 "#extension GL_ARB_shader_atomic_counters : enable\n"
223 "\n"
224 "in vec4 piglit_vertex;\n"
225 "\n"
226 "void main() {\n"
227 " gl_Position = piglit_vertex;\n"
228 "}\n";
229 const uint32_t start_buffer[] = { 0xffffffff };
230 const uint32_t expected_buffer[] = { 0x0 };
231 const uint32_t expected_color[] = { 0xfffffffe, 0xfffffffe,
232 0xffffffff, 0x0 };
234 return test_shader(max_bindings, GL_GEOMETRY_SHADER,
235 vs_source, fs_source, gs_template,
236 start_buffer, expected_buffer, expected_color);
239 static bool
240 run_test_tess_control(void)
242 const char *fs_source = "#version 140\n"
243 "flat in ivec4 tecolor;\n"
244 "out ivec4 fg;\n"
245 "void main() {\n"
246 " fg = tecolor;\n"
247 "}\n";
248 const char *tes_source = "#version 150\n"
249 "#extension GL_ARB_tessellation_shader : enable\n"
250 "\n"
251 "layout(triangles, point_mode) in;\n"
252 "\n"
253 "patch in ivec4 tccolor;\n"
254 "flat out ivec4 tecolor;\n"
255 "\n"
256 "void main() {\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"
260 " \n"
261 " tecolor = tccolor;\n"
262 "}\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"
266 "\n"
267 "layout(vertices=3) out;\n"
268 "\n"
269 "patch out ivec4 tccolor;\n"
270 "\n"
271 "layout(binding = 0, offset = 0) uniform atomic_uint x;\n"
272 "\n"
273 "void main() {\n"
274 " if (gl_InvocationID == 0) {\n"
275 " gl_TessLevelInner[0] = 1;\n"
276 " \n"
277 " gl_TessLevelOuter[0] = 1;\n"
278 " gl_TessLevelOuter[1] = 1;\n"
279 " gl_TessLevelOuter[2] = 1;\n"
280 " \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"
285 " }\n"
286 " \n"
287 " gl_out[gl_InvocationID].gl_Position =\n"
288 " gl_in[gl_InvocationID].gl_Position;\n"
289 "}\n";
290 const char *vs_source = "#version 140\n"
291 "#extension GL_ARB_shader_atomic_counters : enable\n"
292 "\n"
293 "in vec4 piglit_vertex;\n"
294 "\n"
295 "void main() {\n"
296 " gl_Position = piglit_vertex;\n"
297 "}\n";
298 const uint32_t start_buffer[] = { 0xffffffff };
299 const uint32_t expected_buffer[] = { 0x0 };
300 const uint32_t expected_color[] = { 0xfffffffe, 0xfffffffe,
301 0xffffffff, 0x0 };
302 GLuint prog = glCreateProgram();
303 bool ret =
304 atomic_counters_compile(prog, GL_FRAGMENT_SHADER, fs_source) &&
305 atomic_counters_compile(prog, GL_TESS_EVALUATION_SHADER,
306 tes_source) &&
307 atomic_counters_compile(prog, GL_TESS_CONTROL_SHADER,
308 tcs_source) &&
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);
315 return ret;
318 static bool
319 run_test_tess_evaluation(void)
321 const char *fs_source = "#version 140\n"
322 "flat in ivec4 tecolor;\n"
323 "out ivec4 fg;\n"
324 "void main() {\n"
325 " fg = tecolor;\n"
326 "}\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"
330 "\n"
331 "layout(triangles, point_mode) in;\n"
332 "\n"
333 "layout(binding = 0, offset = 0) uniform atomic_uint x;\n"
334 "\n"
335 "flat out ivec4 tecolor;\n"
336 "\n"
337 "void main() {\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"
341 " \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"
347 " } else {\n"
348 " tecolor = ivec4(0);\n"
349 " }\n"
350 "}\n";
351 const char *tcs_source = "#version 150\n"
352 "#extension GL_ARB_tessellation_shader : enable\n"
353 "\n"
354 "layout(vertices=3) out;\n"
355 "\n"
356 "void main() {\n"
357 " if (gl_InvocationID == 0) {\n"
358 " gl_TessLevelInner[0] = 1;\n"
359 " \n"
360 " gl_TessLevelOuter[0] = 1;\n"
361 " gl_TessLevelOuter[1] = 1;\n"
362 " gl_TessLevelOuter[2] = 1;\n"
363 " }\n"
364 " \n"
365 " gl_out[gl_InvocationID].gl_Position =\n"
366 " gl_in[gl_InvocationID].gl_Position;\n"
367 "}\n";
368 const char *vs_source = "#version 140\n"
369 "#extension GL_ARB_shader_atomic_counters : enable\n"
370 "\n"
371 "in vec4 piglit_vertex;\n"
372 "\n"
373 "void main() {\n"
374 " gl_Position = piglit_vertex;\n"
375 "}\n";
376 const uint32_t start_buffer[] = { 0xffffffff };
377 const uint32_t expected_buffer[] = { 0x0 };
378 const uint32_t expected_color[] = { 0xfffffffe, 0xfffffffe,
379 0xffffffff, 0x0 };
380 GLuint prog = glCreateProgram();
381 bool ret =
382 atomic_counters_compile(prog, GL_FRAGMENT_SHADER, fs_source) &&
383 atomic_counters_compile(prog, GL_TESS_EVALUATION_SHADER,
384 tes_source) &&
385 atomic_counters_compile(prog, GL_TESS_CONTROL_SHADER,
386 tcs_source) &&
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);
393 return ret;
396 void
397 piglit_init(int argc, char **argv)
399 GLuint fb, rb, buffer;
400 enum piglit_result status = PIGLIT_PASS;
401 GLint max_bindings;
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 "
434 "semantics",
435 run_test_tess_control);
437 atomic_counters_subtest(&status, GL_TESS_EVALUATION_SHADER,
438 "Tessellation evaluation shader atomic built-in "
439 "semantics",
440 run_test_tess_evaluation);
442 piglit_report_result(status);
445 enum piglit_result
446 piglit_display(void)
448 /* UNREACHED */
449 return PIGLIT_FAIL;