cl: Don't use device_infos if num_device_infos == 0
[piglit.git] / tests / shaders / glsl-uniform-out-of-bounds-2.c
bloba1dff4f67a600d89ef162d3153462a633d077df5
1 /*
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
19 /**
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
42 enum piglit_result
43 piglit_display(void)
45 /* unreached */
46 return PIGLIT_FAIL;
49 void
50 piglit_init(int argc, char **argv)
52 GLint prog;
53 GLint vs, fs;
54 int i, k;
55 bool pass = true;
56 GLint num_active_uniform;
57 GLint min = -1, max = -1;
58 GLint bogus[99];
59 int num_bogus = 0;
61 piglit_require_gl_version(20);
63 vs = piglit_compile_shader_text(GL_VERTEX_SHADER,
64 "attribute vec4 p;\n"
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);
74 glUseProgram(prog);
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) {
80 GLchar name[99];
81 GLint num_active_elements;
82 GLenum type;
83 char *bracket;
85 glGetActiveUniform(prog, k, ARRAY_SIZE(name), NULL,
86 &num_active_elements,
87 &type, name);
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
91 * it optional.
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);
98 pass = false;
100 *bracket = '\0';
103 if (!((name[0] == 'v' || name[0] == 'm') && name[1] == 0))
104 continue;
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;
111 GLchar element[112];
112 GLint loc;
113 sprintf(element, "%s[%d]", name, i);
114 loc = glGetUniformLocation(prog, element);
116 /* does glGetUniformLocation agree with
117 * glGetActiveUniform?
119 if (loc == -1) {
120 if (is_active) {
121 printf("FAIL: no location for "
122 "active %s\n", element);
123 pass = false;
125 } else {
126 if (!is_active) {
127 printf("FAIL: got location for "
128 "inactive %s\n", element);
129 pass = false;
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)
137 min = loc;
138 if (max == -1 || loc > max)
139 max = loc;
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
150 * lower 16
152 bogus[num_bogus++] = max + (1<<16) + i - 3;
155 /* test writing and reading bogus locations */
156 for (i = 0; i < num_bogus; ++i) {
157 GLfloat v[16];
158 if (bogus[i] == -1)
159 continue;
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");
164 pass = false;
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");
169 pass = false;
171 glGetUniformfv(prog, bogus[i], v);
172 if (!piglit_check_gl_error(GL_INVALID_OPERATION)) {
173 printf("FAIL: read from bogus location\n");
174 pass = false;
178 piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);