ARB_ubo/referenced-by-shader: pass if shader compiler moves UBOs between shaders
[piglit.git] / tests / spec / arb_uniform_buffer_object / uniformblockbinding.c
blob8ae47d1817a360f7cf3a69e71f1eaeaf4f9a020f
1 /*
2 * Copyright © 2012 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
21 * DEALINGS IN THE SOFTWARE.
24 /** @file uniformblockbinding.c
26 * From the GL_ARB_uniform_buffer_object spec:
28 * "Each of a program's active uniform blocks has a corresponding
29 * uniform buffer object binding point. This binding point can be
30 * assigned by calling:
32 * void UniformBlockBinding(uint program,
33 * uint uniformBlockIndex,
34 * uint uniformBlockBinding);
36 * <program> is a name of a program object for which the command
37 * LinkProgram has been issued in the past.
39 * <uniformBlockIndex> must be an active uniform block index of
40 * the program <program>. Otherwise, INVALID_VALUE is generated.
42 * <uniformBlockBinding> must be less than MAX_UNIFORM_BUFFER_BINDINGS.
43 * Otherwise, INVALID_VALUE is generated.
45 * ...
47 * When a program object is linked or re-linked, the uniform
48 * buffer object binding point assigned to each of its active
49 * uniform blocks is reset to zero.
51 * ...
53 * The error INVALID_VALUE is generated by GetActiveUniformsiv,
54 * GetActiveUniformName, GetActiveUniformBlockiv,
55 * GetActiveUniformBlockName, and UniformBlockBinding if
56 * <program> is not a value generated by GL."
59 #include "piglit-util-gl.h"
61 PIGLIT_GL_TEST_CONFIG_BEGIN
63 config.supports_gl_compat_version = 10;
65 config.window_width = 10;
66 config.window_height = 10;
67 config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
68 config.khr_no_error_support = PIGLIT_NO_ERRORS;
70 PIGLIT_GL_TEST_CONFIG_END
72 void
73 piglit_init(int argc, char **argv)
75 int i;
76 GLuint prog;
77 const char *source =
78 "#extension GL_ARB_uniform_buffer_object : enable\n"
79 "uniform a { float u1; };\n"
80 "uniform b { float u2; };\n"
81 "void main() {\n"
82 " gl_FragColor = vec4(u1 + u2);\n"
83 "}\n";
84 int blocks;
85 int binding, max_bindings;
86 bool pass = true;
88 piglit_require_extension("GL_ARB_uniform_buffer_object");
90 prog = piglit_build_simple_program(NULL, source);
92 glGetProgramiv(prog, GL_ACTIVE_UNIFORM_BLOCKS, &blocks);
93 assert(blocks == 2);
95 for (i = 0; i < blocks; i++) {
96 glGetActiveUniformBlockiv(prog, i, GL_UNIFORM_BLOCK_BINDING,
97 &binding);
99 if (binding != 0) {
100 fprintf(stderr,
101 "Linked program should have binding[%d] = %d, "
102 "saw %d\n",
103 i, 0, binding);
104 pass = false;
108 for (i = 0; i < blocks; i++) {
109 glUniformBlockBinding(prog, i, blocks - i);
112 for (i = 0; i < blocks; i++) {
113 glGetActiveUniformBlockiv(prog, i, GL_UNIFORM_BLOCK_BINDING,
114 &binding);
116 if (binding != blocks - i) {
117 fprintf(stderr,
118 "Updated binding[%d] to %d, but got %d\n",
119 i, blocks - i, binding);
120 pass = false;
124 glLinkProgram(prog);
126 for (i = 0; i < blocks; i++) {
127 glGetActiveUniformBlockiv(prog, i, GL_UNIFORM_BLOCK_BINDING,
128 &binding);
130 if (binding != 0) {
131 fprintf(stderr,
132 "Relinked program should have binding[%d] = %d, "
133 "saw %d\n",
134 i, 0, binding);
135 pass = false;
139 if (!piglit_khr_no_error) {
140 glUniformBlockBinding(prog, blocks, 0);
141 pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
143 glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_bindings);
144 glUniformBlockBinding(prog, 0, max_bindings);
145 pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
147 glUniformBlockBinding(0xd0d0, 0, 0);
148 pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
151 glDeleteProgram(prog);
153 piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
156 enum piglit_result piglit_display(void)
158 /* UNREACHED */
159 return PIGLIT_FAIL;