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 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,
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.
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
78 piglit_init(int argc
, char **argv
)
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"
88 " gl_FragColor = vec4(a + bb + c + dddd);\n"
92 const char *names
[4] = {"a", "bb", "c", "dddd"};
93 bool found
[4] = {false, false, false, false};
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;
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) {
119 "return strlen %d, longer than the buffer size\n",
123 } else if (name
[written_strlen
] != 0) {
124 fprintf(stderr
, "return name[%d] was %d, expected 0\n",
125 written_strlen
, name
[written_strlen
]);
128 } else if (strlen(name
) != written_strlen
) {
129 fprintf(stderr
, "return strlen was %d, but \"%s\" "
130 "has strlen %d\n", written_strlen
, name
,
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
]) {
140 "Uniform name \"%s\" "
141 "returned twice.\n", name
);
144 found
[name_index
] = true;
148 if (name_index
== ARRAY_SIZE(names
)) {
150 "uniform \"%s\" is not a known name\n", name
);
155 if (namelen
!= written_strlen
+ 1) {
157 "uniform \"%s\" had "
158 "GL_UNIFORM_NAME_LENGTH %d, expected %d\n",
159 name
, namelen
, written_strlen
+ 1);
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
],
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
)
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
)
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
)
199 glDeleteProgram(prog
);
201 piglit_report_result(pass
? PIGLIT_PASS
: PIGLIT_FAIL
);
204 enum piglit_result
piglit_display(void)