2 * Copyright 2012 Google Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20 * \file glsl-uniform-out-of-bounds-2.c
22 * glGetUniformLocation should return:
23 * -1 for inactive array elements (as reported by glGetActiveUniform)
24 * not -1 for active array elements (as reported by glGetActiveUniform)
25 * -1 for non-existent array elements (indices outside the array)
27 * Write and read some invalid locations and check for GL_INVALID_OPERATION.
29 * \author Frank Henigman <fjhenigman@google.com>
32 #include "piglit-util-gl.h"
34 PIGLIT_GL_TEST_CONFIG_BEGIN
36 config
.supports_gl_compat_version
= 10;
38 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
| PIGLIT_GL_VISUAL_DOUBLE
;
40 PIGLIT_GL_TEST_CONFIG_END
50 piglit_init(int argc
, char **argv
)
56 GLint num_active_uniform
;
57 GLint min
= -1, max
= -1;
61 piglit_require_gl_version(20);
63 vs
= piglit_compile_shader_text(GL_VERTEX_SHADER
,
65 "void main() { gl_Position = p; }\n"
67 fs
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
,
68 "uniform vec4 v[4];\n"
69 "uniform mat4 m[4];\n"
70 "void main() { gl_FragColor = v[1] + m[1][1]; }\n"
73 prog
= piglit_link_simple_program(vs
, fs
);
75 glGetProgramiv(prog
, GL_ACTIVE_UNIFORMS
, &num_active_uniform
);
76 printf("active uniforms %d\n", num_active_uniform
);
78 /* for each array in shader */
79 for (k
= 0; k
< num_active_uniform
; ++k
) {
81 GLint num_active_elements
;
85 glGetActiveUniform(prog
, k
, ARRAY_SIZE(name
), NULL
,
89 /* OpenGL 4.2 and OpenGL ES 3.0 require that the name returned
90 * for an array have "[0]" on the end. Earlier versions make
93 bracket
= strchr(name
, '[');
94 if (bracket
!= NULL
) {
95 if (strncmp(bracket
, "[0]", 3) != 0) {
96 printf("FAIL: invalid uniform array element "
97 "returned: %s\n", name
);
103 if (!((name
[0] == 'v' || name
[0] == 'm') && name
[1] == 0))
105 printf("array '%s' active elements %d\n",
106 name
, num_active_elements
);
108 /* for each index in array, plus some before and after */
109 for (i
= -2; i
< 6; ++i
) {
110 bool is_active
= 0 <= i
&& i
< num_active_elements
;
113 sprintf(element
, "%s[%d]", name
, i
);
114 loc
= glGetUniformLocation(prog
, element
);
116 /* does glGetUniformLocation agree with
117 * glGetActiveUniform?
121 printf("FAIL: no location for "
122 "active %s\n", element
);
127 printf("FAIL: got location for "
128 "inactive %s\n", element
);
132 /* keep track of location min/max so
133 * we can pick some locations to test
134 * that we know aren't available.
136 if (min
== -1 || loc
< min
)
138 if (max
== -1 || loc
> max
)
144 // make up some bogus locations
145 for (i
= 1; i
< 6; ++i
) {
146 bogus
[num_bogus
++] = min
- i
;
147 bogus
[num_bogus
++] = max
+ i
;
148 /* mesa encodes the uniform variable in the upper 16
149 * bits of a location and puts the array index in the
152 bogus
[num_bogus
++] = max
+ (1<<16) + i
- 3;
155 /* test writing and reading bogus locations */
156 for (i
= 0; i
< num_bogus
; ++i
) {
160 printf("trying bogus location %d\n", bogus
[i
]);
161 glUniform4fv(bogus
[i
], 1, v
);
162 if (!piglit_check_gl_error(GL_INVALID_OPERATION
)) {
163 printf("FAIL: wrote vector to bogus location\n");
166 glUniformMatrix4fv(bogus
[i
], 1, GL_FALSE
, v
);
167 if (!piglit_check_gl_error(GL_INVALID_OPERATION
)) {
168 printf("FAIL: wrote matrix to bogus location\n");
171 glGetUniformfv(prog
, bogus
[i
], v
);
172 if (!piglit_check_gl_error(GL_INVALID_OPERATION
)) {
173 printf("FAIL: read from bogus location\n");
178 piglit_report_result(pass
? PIGLIT_PASS
: PIGLIT_FAIL
);