glsl: test loop unroll with uint overflow
[piglit.git] / tests / spec / arb_uniform_buffer_object / getactiveuniformblockname.c
blob4f9852823d3432d64e59dbb5ff277ac62e2e2eab
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 getactiveuniformblockname.c
26 * From the GL_ARB_uniform_buffer_object spec:
28 * "An active uniform block's name string can be queried from its
29 * uniform block index by calling
31 * void GetActiveUniformBlockName(uint program,
32 * uint uniformBlockIndex,
33 * sizei bufSize,
34 * sizei* length,
35 * char* uniformBlockName);
37 * The string name of the uniform block identified by
38 * <uniformBlockIndex> is returned into <uniformBlockName>. The
39 * name is null-terminated. The actual number of characters
40 * written into <uniformBlockName>, excluding the null
41 * terminator, is returned in <length>. If <length> is NULL, no
42 * length is returned.
44 * <bufSize> contains the maximum number of characters (including
45 * the null terminator) that will be written back to
46 * <uniformBlockName>.
48 * If an error occurs, nothing will be written to
49 * <uniformBlockName> or <length>.
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.
58 * The error INVALID_VALUE is generated by GetActiveUniformName
59 * and GetActiveUniformBlockName if <bufSize> is less than zero.
61 * The error INVALID_VALUE is generated by
62 * GetActiveUniformBlockiv, GetActiveUniformBlockName, and
63 * UniformBlockBinding if <uniformBlockIndex> is greater than or
64 * equal to ACTIVE_UNIFORM_BLOCKS."
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 int i;
81 GLuint prog;
82 const char *source =
83 "#extension GL_ARB_uniform_buffer_object : enable\n"
84 "uniform a { float u1; };\n"
85 "uniform bbb { float u2; };\n"
86 "uniform cc { float u3; };\n"
87 "void main() {\n"
88 " gl_FragColor = vec4(u1 + u2 + u3);\n"
89 "}\n";
90 int blocks;
91 bool pass = true;
92 const char *names[3] = {"a", "bbb", "cc"};
93 bool found[3] = {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_UNIFORM_BLOCKS, &blocks);
102 assert(blocks == 3);
104 for (i = 0; i < blocks; 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 glGetActiveUniformBlockiv(prog, i, GL_UNIFORM_BLOCK_NAME_LENGTH,
112 &namelen);
114 memset(name, 0xd0, sizeof(name));
115 glGetActiveUniformBlockName(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 block \"%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 "block \"%s\" is not a known block name\n", name);
151 pass = false;
152 continue;
155 if (namelen != written_strlen + 1) {
156 fprintf(stderr,
157 "block \"%s\" had "
158 "GL_UNIFORM_BLOCK_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 glGetActiveUniformBlockName(prog, i, written_strlen,
170 NULL, name);
171 if (name[written_strlen] != fill_char) {
172 fprintf(stderr, "glGetActiveUniformName overflowed: "
173 "name[%d] = 0x%02x instead of 0x%02x\n",
174 written_strlen, name[written_strlen],
175 fill_char);
176 pass = false;
180 if (!piglit_khr_no_error) {
181 no_write = fill_char;
182 glGetActiveUniformBlockName(0xd0d0, 0, 1, NULL, &no_write);
183 pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
184 if (no_write != fill_char)
185 pass = false;
187 no_write = fill_char;
188 glGetActiveUniformBlockName(prog, 0, -1, NULL, &no_write);
189 pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
190 if (no_write != fill_char)
191 pass = false;
193 no_write = fill_char;
194 glGetActiveUniformBlockName(prog, blocks, 1, NULL, &no_write);
195 pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
196 if (no_write != fill_char)
197 pass = false;
200 glDeleteProgram(prog);
202 piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
205 enum piglit_result piglit_display(void)
207 /* UNREACHED */
208 return PIGLIT_FAIL;