1 /* Tests to validate fixes to various bugs in src/mesa/shader/shader_api.c
3 * Written by Bruce Merry
11 static void assert_test(const char *file
, int line
, int cond
, const char *msg
)
14 fprintf(stderr
, "%s:%d assertion \"%s\" failed\n", file
, line
, msg
);
18 #define assert(x) assert_test(__FILE__, __LINE__, (x), #x)
20 static void assert_no_error_test(const char *file
, int line
)
25 if (err
!= GL_NO_ERROR
)
26 fprintf(stderr
, "%s:%d received error %s\n",
27 file
, line
, gluErrorString(err
));
30 #define assert_no_error() assert_no_error_test(__FILE__, __LINE__)
32 static void assert_error_test(const char *file
, int line
, GLenum expect
)
38 fprintf(stderr
, "%s:%d expected %s but received %s\n",
39 file
, line
, gluErrorString(expect
), gluErrorString(err
));
40 while (glGetError()); /* consume any following errors */
43 #define assert_error(err) assert_error_test(__FILE__, __LINE__, (err))
45 static void check_status(GLuint id
, GLenum pname
, void (*query
)(GLuint
, GLenum
, GLint
*))
49 query(id
, pname
, &status
);
54 fprintf(stderr
, "Compilation/link failure:\n");
55 glGetInfoLogARB(id
, sizeof(info
), NULL
, info
);
56 fprintf(stderr
, "%s\n", info
);
61 static void check_compile_status(GLuint id
)
63 check_status(id
, GL_COMPILE_STATUS
, glGetShaderiv
);
66 static void check_link_status(GLuint id
)
68 check_status(id
, GL_LINK_STATUS
, glGetProgramiv
);
71 static GLuint
make_shader(GLenum type
, const char *src
)
76 id
= glCreateShader(type
);
77 glShaderSource(id
, 1, &src
, NULL
);
79 check_compile_status(id
);
84 static GLuint
make_program(const char *vs_src
, const char *fs_src
)
89 id
= glCreateProgram();
91 vs
= make_shader(GL_VERTEX_SHADER
, vs_src
);
92 glAttachShader(id
, vs
);
96 fs
= make_shader(GL_FRAGMENT_SHADER
, fs_src
);
97 glAttachShader(id
, fs
);
101 check_link_status(id
);
108 static void test_uniform_size_type1(const char *glslType
, GLenum glType
, const char *el
)
116 printf(" Running subtest %s\n", glslType
);
118 sprintf(buffer
, "#version 120\nuniform %s m[60];\nvoid main() { gl_Position[0] = m[59]%s; }\n",
121 program
= make_program(buffer
, NULL
);
122 glGetProgramiv(program
, GL_ACTIVE_UNIFORMS
, &active
);
124 for (i
= 0; i
< active
; i
++) {
127 glGetActiveUniform(program
, i
, sizeof(buffer
), NULL
, &size
, &type
, buffer
);
129 if (strncmp(buffer
, "m", 1) == 0)
132 assert(i
< active
); /* Otherwise the compiler optimised it out */
133 assert(type
== glType
);
137 static void test_uniform_size_type(void)
139 test_uniform_size_type1("float", GL_FLOAT
, "");
140 test_uniform_size_type1("vec2", GL_FLOAT_VEC2
, "[0]");
141 test_uniform_size_type1("vec3", GL_FLOAT_VEC3
, "[0]");
142 test_uniform_size_type1("vec4", GL_FLOAT_VEC4
, "[0]");
144 test_uniform_size_type1("bool", GL_BOOL
, " ? 1.0 : 0.0");
145 test_uniform_size_type1("bvec2", GL_BOOL_VEC2
, "[0] ? 1.0 : 0.0");
146 test_uniform_size_type1("bvec3", GL_BOOL_VEC3
, "[0] ? 1.0 : 0.0");
147 test_uniform_size_type1("bvec4", GL_BOOL_VEC4
, "[0] ? 1.0 : 0.0");
149 test_uniform_size_type1("int", GL_INT
, "");
150 test_uniform_size_type1("ivec2", GL_INT_VEC2
, "[0]");
151 test_uniform_size_type1("ivec3", GL_INT_VEC3
, "[0]");
152 test_uniform_size_type1("ivec4", GL_INT_VEC4
, "[0]");
154 test_uniform_size_type1("mat2", GL_FLOAT_MAT2
, "[0][0]");
155 test_uniform_size_type1("mat3", GL_FLOAT_MAT3
, "[0][0]");
156 test_uniform_size_type1("mat4", GL_FLOAT_MAT4
, "[0][0]");
157 test_uniform_size_type1("mat2x3", GL_FLOAT_MAT2x3
, "[0][0]");
158 test_uniform_size_type1("mat2x4", GL_FLOAT_MAT2x4
, "[0][0]");
159 test_uniform_size_type1("mat3x2", GL_FLOAT_MAT3x2
, "[0][0]");
160 test_uniform_size_type1("mat3x4", GL_FLOAT_MAT3x4
, "[0][0]");
161 test_uniform_size_type1("mat4x2", GL_FLOAT_MAT4x2
, "[0][0]");
162 test_uniform_size_type1("mat4x3", GL_FLOAT_MAT4x3
, "[0][0]");
165 static void test_attrib_size_type1(const char *glslType
, GLenum glType
, const char *el
)
173 printf(" Running subtest %s\n", glslType
);
175 sprintf(buffer
, "#version 120\nattribute %s m;\nvoid main() { gl_Position[0] = m%s; }\n",
178 program
= make_program(buffer
, NULL
);
179 glGetProgramiv(program
, GL_ACTIVE_ATTRIBUTES
, &active
);
181 for (i
= 0; i
< active
; i
++) {
184 glGetActiveAttrib(program
, i
, sizeof(buffer
), NULL
, &size
, &type
, buffer
);
186 if (strncmp(buffer
, "m", 1) == 0)
189 assert(i
< active
); /* Otherwise the compiler optimised it out */
190 assert(type
== glType
);
194 static void test_attrib_size_type(void)
196 test_attrib_size_type1("float", GL_FLOAT
, "");
197 test_attrib_size_type1("vec2", GL_FLOAT_VEC2
, "[0]");
198 test_attrib_size_type1("vec3", GL_FLOAT_VEC3
, "[0]");
199 test_attrib_size_type1("vec4", GL_FLOAT_VEC4
, "[0]");
201 test_attrib_size_type1("mat2", GL_FLOAT_MAT2
, "[0][0]");
202 test_attrib_size_type1("mat3", GL_FLOAT_MAT3
, "[0][0]");
203 test_attrib_size_type1("mat4", GL_FLOAT_MAT4
, "[0][0]");
204 test_attrib_size_type1("mat2x3", GL_FLOAT_MAT2x3
, "[0][0]");
205 test_attrib_size_type1("mat2x4", GL_FLOAT_MAT2x4
, "[0][0]");
206 test_attrib_size_type1("mat3x2", GL_FLOAT_MAT3x2
, "[0][0]");
207 test_attrib_size_type1("mat3x4", GL_FLOAT_MAT3x4
, "[0][0]");
208 test_attrib_size_type1("mat4x2", GL_FLOAT_MAT4x2
, "[0][0]");
209 test_attrib_size_type1("mat4x3", GL_FLOAT_MAT4x3
, "[0][0]");
212 static void test_uniform_array_overflow(void)
218 program
= make_program("#version 120\nuniform vec2 x[10];\nvoid main() { gl_Position.xy = x[9]; }\n", NULL
);
219 location
= glGetUniformLocation(program
, "x");
221 glUniform2fv(location
, 64, data
);
225 static void test_uniform_scalar_count(void)
231 program
= make_program("#version 110\nuniform vec2 x;\nvoid main() { gl_Position.xy = x; }\n", NULL
);
232 location
= glGetUniformLocation(program
, "x");
234 glUniform2fv(location
, 64, data
);
235 assert_error(GL_INVALID_OPERATION
);
238 static void test_uniform_query_matrix(void)
245 program
= make_program("#version 110\nuniform mat3 m[2];\nvoid main() { gl_Position.xyz = m[1][2]; }\n", NULL
);
246 location
= glGetUniformLocation(program
, "m");
247 for (i
= 0; i
< 9; i
++)
249 for (i
= 9; i
< 18; i
++)
251 glUniformMatrix3fv(location
, 1, GL_TRUE
, data
);
253 for (i
= 0; i
< 18; i
++)
255 glGetUniformfv(program
, location
, data
);
256 for (c
= 0; c
< 3; c
++)
257 for (r
= 0; r
< 3; r
++)
258 assert(data
[c
* 3 + r
] == r
* 3 + c
);
259 for (i
= 9; i
< 18; i
++)
260 assert(data
[i
] == 123.0);
263 static void test_uniform_neg_location(void)
268 program
= make_program("#version 110\nvoid main() { gl_Position = vec4(1.0, 1.0, 1.0, 1.0); }\n", NULL
);
272 glUniform1i(-200, 1);
273 assert_error(GL_INVALID_OPERATION
);
274 glUniformMatrix2fv(-1, 1, GL_FALSE
, data
);
276 glUniformMatrix2fv(-200, 1, GL_FALSE
, data
);
277 assert_error(GL_INVALID_OPERATION
);
280 static void test_uniform_bool_conversion(void)
284 GLint value
[16]; /* in case glGetUniformiv goes nuts on the stack */
287 program
= make_program("uniform bool b;\nvoid main() { gl_Position.x = b ? 1.5 : 0.5; }\n", NULL
);
288 location
= glGetUniformLocation(program
, "b");
289 assert(location
!= -1);
291 glUniform1i(location
, 5);
293 glGetUniformiv(program
, location
, &value
[0]);
295 assert(value
[0] == 1);
298 static void test_uniform_multiple_samplers(void)
302 GLint values
[2] = {0, 1};
305 program
= make_program(NULL
, "uniform sampler2D s[2];\nvoid main() { gl_FragColor = texture2D(s[1], vec2(0.0, 0.0)); }\n");
306 location
= glGetUniformLocation(program
, "s[0]");
307 assert(location
!= -1);
309 glUniform1iv(location
, 2, values
);
313 static void run_test(const char *name
, void (*callback
)(void))
315 printf("Running %s\n", name
);
320 #define RUN_TEST(name) run_test(#name, (name))
322 int main(int argc
, char **argv
)
326 glutInit(&argc
, argv
);
327 glutCreateWindow("Mesa bug demo");
330 version
= (const char *) glGetString(GL_VERSION
);
331 if (version
[0] == '1') {
332 printf("Sorry, this test requires OpenGL 2.x GLSL support\n");
336 RUN_TEST(test_uniform_size_type
);
337 RUN_TEST(test_attrib_size_type
);
338 RUN_TEST(test_uniform_array_overflow
);
339 RUN_TEST(test_uniform_scalar_count
);
340 RUN_TEST(test_uniform_query_matrix
);
341 RUN_TEST(test_uniform_neg_location
);
342 RUN_TEST(test_uniform_bool_conversion
);
343 /* Leave this one at the end, since it crashes Mesa's shader compiler */
344 RUN_TEST(test_uniform_multiple_samplers
);