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
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.
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.
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
73 piglit_init(int argc
, char **argv
)
78 "#extension GL_ARB_uniform_buffer_object : enable\n"
79 "uniform a { float u1; };\n"
80 "uniform b { float u2; };\n"
82 " gl_FragColor = vec4(u1 + u2);\n"
85 int binding
, max_bindings
;
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
);
95 for (i
= 0; i
< blocks
; i
++) {
96 glGetActiveUniformBlockiv(prog
, i
, GL_UNIFORM_BLOCK_BINDING
,
101 "Linked program should have binding[%d] = %d, "
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
,
116 if (binding
!= blocks
- i
) {
118 "Updated binding[%d] to %d, but got %d\n",
119 i
, blocks
- i
, binding
);
126 for (i
= 0; i
< blocks
; i
++) {
127 glGetActiveUniformBlockiv(prog
, i
, GL_UNIFORM_BLOCK_BINDING
,
132 "Relinked program should have binding[%d] = %d, "
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)