ARB_ubo/referenced-by-shader: pass if shader compiler moves UBOs between shaders
[piglit.git] / tests / spec / arb_uniform_buffer_object / getactiveuniformname.c
bloba83f61a998a9dd44f603b554fbb40645008621a9
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 getactiveuniformname.c
26 * From the GL_ARB_uniform_buffer_object spec:
28 * "The name of an active uniform may be queried from the
29 * corresponding uniform index by calling
31 * void GetActiveUniformName(uint program,
32 * uint uniformIndex,
33 * sizei bufSize,
34 * sizei* length,
35 * char* uniformName);
38 * The name of the uniform identified by <uniformIndex> is
39 * returned as a null-terminated string in <uniformName>. The
40 * actual number of characters written into <uniformName>,
41 * excluding the null terminator, is returned in <length>. If
42 * <length> is NULL, no length is returned. The maximum number of
43 * characters that may be written into <uniformName>, including
44 * the null terminator, is specified by <bufSize>. The returned
45 * uniform name can be the name of built-in uniform state as
46 * well. The complete list of built-in uniform state is described
47 * in section 7.5 of the OpenGL Shading Language
48 * specification. The length of the longest uniform name in
49 * <program> is given by the value of ACTIVE_UNIFORM_MAX_LENGTH,
50 * which can be queried with GetProgramiv.
52 * ...
55 * The error INVALID_VALUE is generated by GetActiveUniformsiv,
56 * GetActiveUniformName, GetActiveUniformBlockiv,
57 * GetActiveUniformBlockName, and UniformBlockBinding if
58 * <program> is not a value generated by GL.
60 * The error INVALID_VALUE is generated by GetActiveUniformName and
61 * GetActiveUniformBlockName if <bufSize> is less than zero.
63 * The error INVALID_VALUE is generated by GetActiveUniformName if
64 * <uniformIndex> is greater than or equal to ACTIVE_UNIFORMS.
67 #include "piglit-util-gl.h"
69 PIGLIT_GL_TEST_CONFIG_BEGIN
71 config.supports_gl_compat_version = 10;
72 config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
73 config.khr_no_error_support = PIGLIT_NO_ERRORS;
75 PIGLIT_GL_TEST_CONFIG_END
77 void
78 piglit_init(int argc, char **argv)
80 unsigned int i;
81 GLuint prog;
82 const char *source =
83 "#extension GL_ARB_uniform_buffer_object : enable\n"
84 "uniform ubo1 { float a; };\n"
85 "uniform ubo2 { float bb; float c; };\n"
86 "uniform float dddd;\n"
87 "void main() {\n"
88 " gl_FragColor = vec4(a + bb + c + dddd);\n"
89 "}\n";
90 int uniforms;
91 bool pass = true;
92 const char *names[4] = {"a", "bb", "c", "dddd"};
93 bool found[4] = {false, false, false, false};
94 char no_write;
95 char fill_char = 0xd0;
97 piglit_require_extension("GL_ARB_uniform_buffer_object");
99 prog = piglit_build_simple_program(NULL, source);
101 glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &uniforms);
102 assert(uniforms == 4);
104 for (i = 0; i < uniforms; i++) {
105 GLint written_strlen = 0;
106 GLint namelen = 9999;
107 char name[1000];
108 int name_index;
110 /* This is the size including null terminator. */
111 glGetActiveUniformsiv(prog, 1, &i,
112 GL_UNIFORM_NAME_LENGTH, &namelen);
114 memset(name, 0xd0, sizeof(name));
115 glGetActiveUniformName(prog, i, sizeof(name),
116 &written_strlen, name);
117 if (written_strlen >= sizeof(name) - 1) {
118 fprintf(stderr,
119 "return strlen %d, longer than the buffer size\n",
120 written_strlen);
121 pass = false;
122 continue;
123 } else if (name[written_strlen] != 0) {
124 fprintf(stderr, "return name[%d] was %d, expected 0\n",
125 written_strlen, name[written_strlen]);
126 pass = false;
127 continue;
128 } else if (strlen(name) != written_strlen) {
129 fprintf(stderr, "return strlen was %d, but \"%s\" "
130 "has strlen %d\n", written_strlen, name,
131 (int)strlen(name));
132 pass = false;
133 continue;
136 for (name_index = 0; name_index < ARRAY_SIZE(names); name_index++) {
137 if (strcmp(names[name_index], name) == 0) {
138 if (found[name_index]) {
139 fprintf(stderr,
140 "Uniform name \"%s\" "
141 "returned twice.\n", name);
142 pass = false;
144 found[name_index] = true;
145 break;
148 if (name_index == ARRAY_SIZE(names)) {
149 fprintf(stderr,
150 "uniform \"%s\" is not a known name\n", name);
151 pass = false;
152 continue;
155 if (namelen != written_strlen + 1) {
156 fprintf(stderr,
157 "uniform \"%s\" had "
158 "GL_UNIFORM_NAME_LENGTH %d, expected %d\n",
159 name, namelen, written_strlen + 1);
160 pass = false;
161 continue;
164 /* Test for overflow by writing to a bufSize equal to
165 * strlen and checking if a null terminator or
166 * something landed past that.
168 memset(name, fill_char, sizeof(name));
169 glGetActiveUniformName(prog, i, written_strlen, NULL, name);
170 if (name[written_strlen] != fill_char) {
171 fprintf(stderr, "glGetActiveUniformName overflowed: "
172 "name[%d] = 0x%02x instead of 0x%02x\n",
173 written_strlen, name[written_strlen],
174 fill_char);
175 pass = false;
179 if (!piglit_khr_no_error) {
180 no_write = fill_char;
181 glGetActiveUniformName(0xd0d0, 0, 1, NULL, &no_write);
182 pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
183 if (no_write != fill_char)
184 pass = false;
186 no_write = fill_char;
187 glGetActiveUniformName(prog, 0, -1, NULL, &no_write);
188 pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
189 if (no_write != fill_char)
190 pass = false;
192 no_write = fill_char;
193 glGetActiveUniformName(prog, uniforms, 1, NULL, &no_write);
194 pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
195 if (no_write != fill_char)
196 pass = false;
199 glDeleteProgram(prog);
201 piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
204 enum piglit_result piglit_display(void)
206 /* UNREACHED */
207 return PIGLIT_FAIL;