ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / arb_query_buffer_object / coherency.c
blob3f59fbe46cab63ccac3623b045c1aa3c1e3482c5
1 /*
2 * Copyright (c) 2017 Advanced Micro Devices, Inc.
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 /**
25 * \file qbo-coherency.c
26 * Test coherency of ARB_query_buffer_object results with pre-shader pipeline
27 * stages:
28 * 1. Indirect draw
29 * Write the qbo result to the 'first' member of the indirect draw
30 * structure, and write the gl_VertexID to a transform feedback buffer.
31 * 2. Index buffer fetch
32 * Write the qbo result to the index buffer, and write the gl_VertexID to
33 * a transform feedback buffer.
34 * 3. Indirect draw count
35 * Write the qbo result to the 'drawcount' value for an
36 * GL_ARB_indirect_parameters multi-draw, and increment an atomic counter
37 * in the vertex shader.
38 * 4. Indirect dispatch
39 * Write the qbo result to the number of groups, and count the groups using
40 * an atomic counter.
43 #include "common.h"
45 PIGLIT_GL_TEST_CONFIG_BEGIN
46 config.supports_gl_compat_version = 32;
47 config.supports_gl_core_version = 32;
48 config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE |
49 PIGLIT_GL_VISUAL_DEPTH;
50 PIGLIT_GL_TEST_CONFIG_END
52 #define BUFFER_OFFSET(i) ((void *)((char *)NULL + i))
54 #define DRAW_COUNT_CLAMP_MAX 50
56 static GLuint prog_compute;
57 static GLuint prog_xfb;
58 static GLuint prog_vs_atomic;
59 static GLuint empty_vao;
60 static GLuint indirect_draw_count_data_bo;
62 static const char *arg_consumer_mode;
63 static const char *arg_query_type;
65 struct consumer_mode {
66 const char *name;
67 unsigned (*run)(unsigned query);
68 const char *extensions[2];
69 bool amplify;
70 bool clamped;
71 unsigned clamp_max;
74 static unsigned
75 indirect_draw(unsigned query)
77 static const GLuint indirect_data[] = {
78 1, /* count */
79 1, /* instanceCount */
80 999, /* first */
81 0, /* baseInstance */
83 unsigned indirect_bo;
84 unsigned xfb_bo;
86 glGenBuffers(1, &indirect_bo);
87 glBindBuffer(GL_QUERY_BUFFER, indirect_bo);
88 glBufferData(GL_QUERY_BUFFER, sizeof(indirect_data), indirect_data, GL_STATIC_DRAW);
89 glGetQueryObjectuivARB(query, GL_QUERY_RESULT, BUFFER_OFFSET(2 * sizeof(GLuint)));
91 glUseProgram(prog_xfb);
92 glBindVertexArray(empty_vao);
94 glGenBuffers(1, &xfb_bo);
95 glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_bo, 0, sizeof(GLuint));
96 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(GLuint), NULL, GL_STREAM_READ);
98 glEnable(GL_RASTERIZER_DISCARD);
99 glBeginTransformFeedback(GL_POINTS);
101 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, indirect_bo);
102 glDrawArraysIndirect(GL_POINTS, BUFFER_OFFSET(0));
104 glEndTransformFeedback();
105 glDisable(GL_RASTERIZER_DISCARD);
107 unsigned result;
108 glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(result), &result);
110 glDeleteBuffers(1, &indirect_bo);
111 glDeleteBuffers(1, &xfb_bo);
112 piglit_check_gl_error(GL_NO_ERROR);
114 return result;
117 static unsigned
118 index_buffer(unsigned query)
120 static const GLuint index_data[] = {
121 999,
123 unsigned index_bo;
124 unsigned xfb_bo;
126 glGenBuffers(1, &index_bo);
127 glBindBuffer(GL_QUERY_BUFFER, index_bo);
128 glBufferData(GL_QUERY_BUFFER, sizeof(index_data), index_data, GL_STATIC_DRAW);
129 glGetQueryObjectuivARB(query, GL_QUERY_RESULT, BUFFER_OFFSET(0));
131 glUseProgram(prog_xfb);
132 glBindVertexArray(empty_vao);
134 glGenBuffers(1, &xfb_bo);
135 glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_bo, 0, sizeof(GLuint));
136 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(GLuint), NULL, GL_STREAM_READ);
138 glEnable(GL_RASTERIZER_DISCARD);
139 glBeginTransformFeedback(GL_POINTS);
141 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_bo);
142 glDrawElements(GL_POINTS, 1, GL_UNSIGNED_INT, BUFFER_OFFSET(0));
144 glEndTransformFeedback();
145 glDisable(GL_RASTERIZER_DISCARD);
147 unsigned result;
148 glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(result), &result);
150 glDeleteBuffers(1, &index_bo);
151 glDeleteBuffers(1, &xfb_bo);
152 piglit_check_gl_error(GL_NO_ERROR);
154 return result;
157 static unsigned
158 indirect_draw_count(unsigned query)
160 static const unsigned zero = 0;
161 static const unsigned count_default = 999;
162 unsigned indirect_count_bo;
163 unsigned atomic_bo;
165 glGenBuffers(1, &indirect_count_bo);
166 glBindBuffer(GL_QUERY_BUFFER, indirect_count_bo);
167 glBufferData(GL_QUERY_BUFFER, sizeof(count_default), &count_default, GL_STATIC_DRAW);
168 glGetQueryObjectuivARB(query, GL_QUERY_RESULT, BUFFER_OFFSET(0));
170 glUseProgram(prog_vs_atomic);
171 glBindVertexArray(empty_vao);
173 glGenBuffers(1, &atomic_bo);
174 glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, atomic_bo, 0, 4);
175 glBufferData(GL_ATOMIC_COUNTER_BUFFER, 4, &zero, GL_STATIC_DRAW);
177 glEnable(GL_RASTERIZER_DISCARD);
179 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, indirect_draw_count_data_bo);
180 glBindBuffer(GL_PARAMETER_BUFFER_ARB, indirect_count_bo);
181 glMultiDrawArraysIndirectCountARB(GL_POINTS, BUFFER_OFFSET(0), 0,
182 DRAW_COUNT_CLAMP_MAX, 0);
184 glDisable(GL_RASTERIZER_DISCARD);
186 unsigned result;
187 glGetBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(result), &result);
189 glDeleteBuffers(1, &indirect_count_bo);
190 glDeleteBuffers(1, &atomic_bo);
191 piglit_check_gl_error(GL_NO_ERROR);
193 return result;
196 static unsigned
197 indirect_dispatch(unsigned query)
199 static const GLuint indirect_data[] = {
200 999, /* num_groups_x */
201 1, /* num_groups_y */
202 1, /* num_groups_z */
204 static const unsigned zero = 0;
205 unsigned indirect_bo;
206 unsigned atomic_bo;
208 glGenBuffers(1, &indirect_bo);
209 glBindBuffer(GL_QUERY_BUFFER, indirect_bo);
210 glBufferData(GL_QUERY_BUFFER, sizeof(indirect_data), indirect_data, GL_STATIC_DRAW);
211 glGetQueryObjectuivARB(query, GL_QUERY_RESULT, BUFFER_OFFSET(0));
213 glUseProgram(prog_compute);
215 glGenBuffers(1, &atomic_bo);
216 glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, atomic_bo, 0, 4);
217 glBufferData(GL_ATOMIC_COUNTER_BUFFER, 4, &zero, GL_STATIC_DRAW);
219 glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, indirect_bo);
220 glDispatchComputeIndirect(0);
222 unsigned result;
223 glGetBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(result), &result);
225 glDeleteBuffers(1, &indirect_bo);
226 glDeleteBuffers(1, &atomic_bo);
227 piglit_check_gl_error(GL_NO_ERROR);
229 return result;
232 static const struct consumer_mode consumer_modes[] = {
233 { "indirect-draw", &indirect_draw,
234 { "GL_ARB_draw_indirect", NULL } },
235 { "index-buffer", &index_buffer, { NULL, } },
236 { "indirect-draw-count", &indirect_draw_count,
237 { "GL_ARB_indirect_parameters", "GL_ARB_shader_atomic_counters" },
238 .clamped = true, .clamp_max = DRAW_COUNT_CLAMP_MAX },
239 { "indirect-dispatch", &indirect_dispatch,
240 { "GL_ARB_compute_shader", NULL },
241 .amplify = true },
244 static enum piglit_result
245 run_subtest(const struct consumer_mode *cm, const struct query_type_desc *qdesc)
247 GLuint query;
248 bool exact;
249 unsigned expected, result;
251 get_query_values(qdesc, &exact, &expected);
253 glGenQueries(1, &query);
255 run_query(query, qdesc);
256 result = cm->run(query);
258 glDeleteQueries(1, &query);
260 piglit_check_gl_error(GL_NO_ERROR);
262 if (cm->clamped)
263 expected = MIN2(expected, cm->clamp_max);
265 if (result != expected && (exact || result < expected)) {
266 fprintf(stderr, "Result: %u\nExpected: %u\n", result, expected);
267 return PIGLIT_FAIL;
270 return PIGLIT_PASS;
273 enum piglit_result
274 piglit_display(void)
276 enum piglit_result result = PIGLIT_PASS;
277 int vertex_counters;
278 unsigned qnum_count = num_query_types();
280 for (unsigned cnum = 0; cnum < ARRAY_SIZE(consumer_modes); cnum++) {
281 const struct consumer_mode *cm = &consumer_modes[cnum];
282 bool supported = true;
284 if (arg_consumer_mode && strcmp(arg_consumer_mode, cm->name))
285 continue;
287 for (unsigned i = 0; i < ARRAY_SIZE(cm->extensions); ++i) {
288 if (cm->extensions[i] &&
289 !piglit_is_extension_supported(cm->extensions[i])) {
290 supported = false;
291 break;
295 if (!strcmp(cm->name, "indirect-draw-count")) {
296 glGetIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTERS, &vertex_counters);
298 if(vertex_counters < 1)
299 supported = false;
302 for (unsigned qnum = 0; qnum < qnum_count; qnum++) {
303 enum piglit_result subtest_result = PIGLIT_SKIP;
304 const struct query_type_desc *qdesc = &query_types[qnum];
306 if (arg_query_type &&
307 strcmp(arg_query_type, piglit_get_gl_enum_name(qdesc->type)))
308 continue;
310 supported = supported && is_query_supported(qdesc);
312 if (cm->amplify) {
313 if (qdesc->type == GL_TIMESTAMP ||
314 qdesc->type == GL_TIME_ELAPSED)
315 continue;
318 if (supported) {
319 subtest_result = run_subtest(cm, qdesc);
320 if (subtest_result != PIGLIT_PASS)
321 result = subtest_result;
324 piglit_report_subtest_result(
325 subtest_result, "%s-%s",
326 cm->name,
327 piglit_get_gl_enum_name(qdesc->type));
331 return result;
334 static void
335 prepare_prog_xfb()
337 static const char *tf_out = "tf_out";
339 prog_xfb = piglit_build_simple_program_unlinked(
340 "#version 130\n"
341 "\n"
342 "out int tf_out;\n"
343 "\n"
344 "void main() {\n"
345 " tf_out = gl_VertexID;\n"
346 " gl_Position = vec4(0);\n"
347 "}\n",
348 NULL);
349 glTransformFeedbackVaryings(prog_xfb, 1, &tf_out, GL_INTERLEAVED_ATTRIBS);
350 glLinkProgram(prog_xfb);
351 if (!piglit_link_check_status(prog_xfb))
352 piglit_report_result(PIGLIT_FAIL);
353 piglit_check_gl_error(GL_NO_ERROR);
356 static void
357 prepare_indirect_draw_count()
359 prog_vs_atomic = piglit_build_simple_program(
360 "#version 150\n"
361 "#extension GL_ARB_shader_atomic_counters: require\n"
362 "\n"
363 "layout(binding = 0, offset = 0) uniform atomic_uint counter;\n"
364 "\n"
365 "void main() {\n"
366 " atomicCounterIncrement(counter);\n"
367 " gl_Position = vec4(0);\n"
368 "}\n",
369 NULL);
371 static const GLuint indirect_draw_template[] = {
372 1, /* count */
373 1, /* instanceCount */
374 0, /* first */
375 0, /* baseInstance */
378 char *indirect_draw_count_data = malloc(DRAW_COUNT_CLAMP_MAX * sizeof(indirect_draw_template));
379 char *dst = indirect_draw_count_data;
380 for (unsigned i = 0; i < DRAW_COUNT_CLAMP_MAX; ++i) {
381 memcpy(dst, indirect_draw_template, sizeof(indirect_draw_template));
382 dst += sizeof(indirect_draw_template);
385 glGenBuffers(1, &indirect_draw_count_data_bo);
386 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, indirect_draw_count_data_bo);
387 glBufferData(GL_DRAW_INDIRECT_BUFFER,
388 DRAW_COUNT_CLAMP_MAX * sizeof(indirect_draw_template),
389 indirect_draw_count_data, GL_STATIC_DRAW);
391 free(indirect_draw_count_data);
393 piglit_check_gl_error(GL_NO_ERROR);
396 static void
397 prepare_prog_compute()
399 GLuint shader = piglit_compile_shader_text(GL_COMPUTE_SHADER,
400 "#version 150\n"
401 "#extension GL_ARB_compute_shader: require\n"
402 "#extension GL_ARB_shader_atomic_counters: require\n"
403 "\n"
404 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
405 "\n"
406 "layout(binding = 0, offset = 0) uniform atomic_uint counter;\n"
407 "\n"
408 "void main() {\n"
409 " atomicCounterIncrement(counter);\n"
410 "}\n");
412 prog_compute = glCreateProgram();
413 glAttachShader(prog_compute, shader);
414 glLinkProgram(prog_compute);
415 glDeleteShader(shader);
417 if (!piglit_link_check_status(prog_compute))
418 piglit_report_result(PIGLIT_FAIL);
419 piglit_check_gl_error(GL_NO_ERROR);
422 void
423 piglit_init(int argc, char **argv)
425 piglit_require_extension("GL_ARB_query_buffer_object");
427 if (argc > 1) {
428 if (argc != 3) {
429 fprintf(stderr, "usage: %s <consumer> <query_type>\n", argv[0]);
430 exit(1);
433 arg_consumer_mode = argv[1];
434 arg_query_type = argv[2];
437 query_common_init();
439 prepare_prog_xfb();
441 if (piglit_is_extension_supported("GL_ARB_compute_shader"))
442 prepare_prog_compute();
444 if (piglit_is_extension_supported("GL_ARB_indirect_parameters") &&
445 piglit_is_extension_supported("GL_ARB_shader_atomic_counters"))
446 prepare_indirect_draw_count();
448 glGenVertexArrays(1, &empty_vao);