ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / arb_query_buffer_object / qbo.c
blob3ba11ee26862c8b98d929e6b598e7e8f590e10c1
1 /*
2 * Copyright © 2015 Glenn Kennard
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.
23 * Author: Glenn Kennard <glenn.kennard@gmail.com>
26 /**
27 * \file qbo.c
28 * Tests ARB_query_buffer_object
29 * - synchronous wait for result
30 * - asynchrounous result, default value is left intact if result unavailable
31 * - asynchrounous result, retrieve result to client memory before & after
34 #include "common.h"
36 PIGLIT_GL_TEST_CONFIG_BEGIN
37 config.supports_gl_compat_version = 32;
38 config.supports_gl_core_version = 32;
39 config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE |
40 PIGLIT_GL_VISUAL_DEPTH;
42 PIGLIT_GL_TEST_CONFIG_END
44 #define BUFFER_OFFSET(i) ((void *)((char *)NULL + i))
46 static const float green[] = {0, 1, 0, 1};
48 static unsigned query;
49 static unsigned qbo;
51 static int qbo_prog;
52 static int sync_mode_loc;
53 static int expect_exact_loc;
54 static int is_64bit_loc;
55 static int expected_loc;
56 static int expected_hi_loc;
58 enum sync_mode {
59 QBO_SYNC,
60 QBO_SYNC_CPU_READ_AFTER_CACHE_TEST,
61 QBO_ASYNC,
62 QBO_ASYNC_CPU_READ_BEFORE,
63 QBO_ASYNC_CPU_READ_AFTER,
64 NUM_QBO_SYNC_MODES,
67 static const char * const sync_mode_names[] = {
68 "SYNC",
69 "SYNC_CPU_READ_AFTER_CACHE_TEST",
70 "ASYNC",
71 "ASYNC_CPU_READ_BEFORE",
72 "ASYNC_CPU_READ_AFTER",
75 static const struct query_type_desc *query_desc;
76 static enum sync_mode sync_mode;
77 static GLenum result_type;
79 static enum piglit_result
80 cpu_gather_query(bool exact, uint32_t expected, uint64_t *cpu_result)
82 *cpu_result = 0;
84 glBindBuffer(GL_QUERY_BUFFER, 0);
86 if (result_type == GL_INT)
87 glGetQueryObjectiv(query, GL_QUERY_RESULT, (GLint*)cpu_result);
88 else if (result_type == GL_UNSIGNED_INT)
89 glGetQueryObjectuiv(query, GL_QUERY_RESULT, (GLuint*)cpu_result);
90 else
91 glGetQueryObjectui64v(query, GL_QUERY_RESULT, cpu_result);
93 glBindBuffer(GL_QUERY_BUFFER, qbo);
95 return (exact ? *cpu_result == expected : *cpu_result >= expected)
96 ? PIGLIT_PASS : PIGLIT_FAIL;
99 enum piglit_result
100 run_subtest(void)
102 bool exact;
103 uint32_t expected;
104 uint64_t cpu_result;
105 bool have_cpu_result = false;
106 uint32_t default_value[4] = { 0xccccccccu, 0xccccccccu, 0xccccccccu, 0xccccccccu };
107 bool is_sync =
108 sync_mode == QBO_SYNC ||
109 sync_mode == QBO_SYNC_CPU_READ_AFTER_CACHE_TEST;
111 get_query_values(query_desc, &exact, &expected);
113 glGenQueries(1, &query);
114 run_query(query, query_desc);
116 /* Load default value into buffer */
117 glBindBuffer(GL_QUERY_BUFFER, qbo);
118 glBufferData(GL_QUERY_BUFFER, 16, default_value, GL_DYNAMIC_COPY);
120 if (sync_mode == QBO_ASYNC_CPU_READ_BEFORE) {
121 if (cpu_gather_query(exact, expected, &cpu_result))
122 return PIGLIT_FAIL;
123 have_cpu_result = true;
126 glBindBuffer(GL_QUERY_BUFFER, qbo);
127 if (is_sync) {
128 /* Special mode to test against a possible cache invalidation
129 * in case the wait-for-result is handled at a different place
130 * in the memory hierarchy than actually reading and
131 * summarizing the result.
133 if (sync_mode == QBO_SYNC_CPU_READ_AFTER_CACHE_TEST)
134 glGetQueryObjectivARB(query, GL_QUERY_RESULT_NO_WAIT, BUFFER_OFFSET(0));
136 if (result_type == GL_INT)
137 glGetQueryObjectivARB(query, GL_QUERY_RESULT, BUFFER_OFFSET(0));
138 else if (result_type == GL_UNSIGNED_INT)
139 glGetQueryObjectuivARB(query, GL_QUERY_RESULT, BUFFER_OFFSET(0));
140 else
141 glGetQueryObjectui64v(query, GL_QUERY_RESULT, BUFFER_OFFSET(0));
142 } else {
143 if (result_type == GL_INT) {
144 glGetQueryObjectivARB(query, GL_QUERY_RESULT_AVAILABLE, BUFFER_OFFSET(8));
145 glGetQueryObjectivARB(query, GL_QUERY_RESULT_NO_WAIT, BUFFER_OFFSET(0));
146 } else if (result_type == GL_UNSIGNED_INT) {
147 glGetQueryObjectuivARB(query, GL_QUERY_RESULT_AVAILABLE, BUFFER_OFFSET(8));
148 glGetQueryObjectuivARB(query, GL_QUERY_RESULT_NO_WAIT, BUFFER_OFFSET(0));
149 } else {
150 glGetQueryObjectui64v(query, GL_QUERY_RESULT_AVAILABLE, BUFFER_OFFSET(8));
151 glGetQueryObjectui64v(query, GL_QUERY_RESULT_NO_WAIT, BUFFER_OFFSET(0));
155 if (sync_mode == QBO_SYNC_CPU_READ_AFTER_CACHE_TEST ||
156 sync_mode == QBO_ASYNC_CPU_READ_AFTER) {
157 if (cpu_gather_query(exact, expected, &cpu_result))
158 return PIGLIT_FAIL;
159 have_cpu_result = true;
162 /* Make it available to shader as uniform buffer 0 */
163 glBindBufferBase(GL_UNIFORM_BUFFER, 0, qbo);
165 glUseProgram(qbo_prog);
167 /* Setup program uniforms */
168 glUniform1ui(sync_mode_loc, is_sync ? GL_TRUE : GL_FALSE);
169 glUniform1ui(expect_exact_loc, have_cpu_result || exact);
170 glUniform1ui(is_64bit_loc, result_type == GL_UNSIGNED_INT64_ARB);
171 glUniform1ui(expected_loc, have_cpu_result ? cpu_result : expected);
172 glUniform1ui(expected_hi_loc, have_cpu_result ? (cpu_result >> 32) : 0);
174 glDisable(GL_DEPTH_TEST);
175 /* Draw green if query successful */
176 piglit_draw_rect(-1, -1, 2, 2);
178 glDeleteQueries(1, &query);
180 if (!piglit_probe_rect_rgba(0, 0, piglit_width, piglit_height, green)) {
181 unsigned *ptr = glMapBuffer(GL_QUERY_BUFFER, GL_READ_ONLY);
183 printf("Expected: %u\n", expected);
184 if (have_cpu_result)
185 printf("CPU result: %lu\n", cpu_result);
186 printf("QBO: %u %u %u %u\n", ptr[0], ptr[1], ptr[2], ptr[3]);
187 glUnmapBuffer(GL_QUERY_BUFFER);
189 return PIGLIT_FAIL;
192 return PIGLIT_PASS;
195 enum piglit_result
196 piglit_display(void)
198 static const GLenum result_types[] = {
199 GL_INT,
200 GL_UNSIGNED_INT,
201 GL_UNSIGNED_INT64_ARB
203 enum piglit_result r = PIGLIT_PASS;
205 for (unsigned qnum = 0; qnum < num_query_types(); qnum++) {
206 query_desc = &query_types[qnum];
208 bool supported = is_query_supported(query_desc);
210 for (sync_mode = QBO_SYNC;
211 sync_mode < NUM_QBO_SYNC_MODES;
212 sync_mode++) {
213 for (unsigned ridx = 0; ridx < ARRAY_SIZE(result_types); ++ridx) {
214 enum piglit_result subtest_result = PIGLIT_SKIP;
216 result_type = result_types[ridx];
218 if (supported) {
219 subtest_result = run_subtest();
220 if (subtest_result != PIGLIT_PASS)
221 r = subtest_result;
224 piglit_report_subtest_result(subtest_result, "query-%s-%s-%s",
225 piglit_get_gl_enum_name(query_desc->type),
226 sync_mode_names[sync_mode],
227 piglit_get_gl_enum_name(result_type));
232 return r;
235 void
236 piglit_init(int argc, char **argv)
238 char *vsCode;
239 char *qboFsCode;
241 piglit_require_extension("GL_ARB_query_buffer_object");
242 piglit_require_extension("GL_ARB_uniform_buffer_object");
244 query_common_init();
246 glGenBuffers(1, &qbo);
247 glBindBuffer(GL_QUERY_BUFFER, qbo);
248 glBufferData(GL_QUERY_BUFFER, 4, NULL, GL_DYNAMIC_COPY);
250 vsCode =
251 "#version 150\n"
252 "in vec4 pos_in;\n"
253 "void main() {\n"
254 " gl_Position = pos_in;\n"
255 "}\n";
256 qboFsCode =
257 "#version 150\n"
258 "#extension GL_ARB_uniform_buffer_object : require\n"
259 "uniform query {\n"
260 " uint result;\n"
261 " uint result_hi;\n"
262 " uint available;\n"
263 " uint available_hi;\n"
264 "};\n"
265 "uniform bool sync_mode;\n"
266 "uniform bool expect_exact;\n"
267 "uniform bool is_64bit;\n"
268 "uniform uint expected;\n"
269 "uniform uint expected_hi;\n"
270 "out vec4 color;\n"
271 "void main() {\n"
272 " uint INIT = uint(0xcccccccc);\n"
273 " bool ready = sync_mode || available != 0u;\n"
274 " if (!is_64bit && (result_hi != INIT || available_hi != INIT)) {\n"
275 " color = vec4(1.0, 0.0, 0.25, 1.0);\n"
276 " } else if ((sync_mode && (available != INIT ||\n"
277 " available_hi != INIT)) ||\n"
278 " (!sync_mode && ((available != 0u && available != 1u) ||\n"
279 " (is_64bit && available_hi != 0u) ||\n"
280 " (!is_64bit && available_hi != INIT)))) {\n"
281 " color = vec4(1.0, 0.0, 0.5, 1.0);\n"
282 " } else {\n"
283 " bool result_ok = false;\n"
284 " if (result == expected &&\n"
285 " (!is_64bit || result_hi == expected_hi))\n"
286 " result_ok = true;\n"
287 " if (!expect_exact &&\n"
288 " ((!is_64bit && result >= expected) ||\n"
289 " (is_64bit && ((result_hi == expected_hi && result >= expected) ||\n"
290 " (result_hi > expected_hi)))))\n"
291 " result_ok = true;\n"
292 " if (!ready && result == INIT && result_hi == INIT)\n"
293 " result_ok = true;\n"
294 " if (result_ok) {\n"
295 " color = vec4(0.0, 1.0, 0.0, 1.0);\n"
296 " } else if (ready) {\n"
297 " color = vec4(1.0, 0.0, 0.0, 1.0);\n"
298 " } else {\n"
299 " color = vec4(1.0, 0.5, 0.0, 1.0);\n"
300 " }\n"
301 " }\n"
302 "}\n";
304 qbo_prog = piglit_build_simple_program(vsCode, qboFsCode);
305 sync_mode_loc = glGetUniformLocation(qbo_prog, "sync_mode");
306 expect_exact_loc = glGetUniformLocation(qbo_prog, "expect_exact");
307 is_64bit_loc = glGetUniformLocation(qbo_prog, "is_64bit");
308 expected_loc = glGetUniformLocation(qbo_prog, "expected");
309 expected_hi_loc = glGetUniformLocation(qbo_prog, "expected_hi");