1 /* Tests to validate fixes to various bugs in src/mesa/shader/shader_api.c
3 * Written by Bruce Merry
15 static void assert_test(const char *file
, int line
, int cond
, const char *msg
)
18 fprintf(stderr
, "%s:%d assertion \"%s\" failed\n", file
, line
, msg
);
22 #define assert(x) assert_test(__FILE__, __LINE__, (x), #x)
24 static void assert_no_error_test(const char *file
, int line
)
29 if (err
!= GL_NO_ERROR
)
30 fprintf(stderr
, "%s:%d received error %s\n",
31 file
, line
, gluErrorString(err
));
34 #define assert_no_error() assert_no_error_test(__FILE__, __LINE__)
36 static void assert_error_test(const char *file
, int line
, GLenum expect
)
42 fprintf(stderr
, "%s:%d expected %s but received %s\n",
43 file
, line
, gluErrorString(expect
), gluErrorString(err
));
44 while (glGetError()); /* consume any following errors */
47 #define assert_error(err) assert_error_test(__FILE__, __LINE__, (err))
49 static void check_status(GLuint id
, GLenum pname
, void (APIENTRY
*query
)(GLuint
, GLenum
, GLint
*))
53 query(id
, pname
, &status
);
58 fprintf(stderr
, "Compilation/link failure:\n");
59 glGetInfoLogARB(id
, sizeof(info
), NULL
, info
);
60 fprintf(stderr
, "%s\n", info
);
65 static void check_compile_status(GLuint id
)
67 check_status(id
, GL_COMPILE_STATUS
, glGetShaderiv
);
70 static void check_link_status(GLuint id
)
72 check_status(id
, GL_LINK_STATUS
, glGetProgramiv
);
75 static GLuint
make_shader(GLenum type
, const char *src
)
80 id
= glCreateShader(type
);
81 glShaderSource(id
, 1, &src
, NULL
);
83 check_compile_status(id
);
88 static GLuint
make_program(const char *vs_src
, const char *fs_src
)
93 id
= glCreateProgram();
95 vs
= make_shader(GL_VERTEX_SHADER
, vs_src
);
96 glAttachShader(id
, vs
);
100 fs
= make_shader(GL_FRAGMENT_SHADER
, fs_src
);
101 glAttachShader(id
, fs
);
105 check_link_status(id
);
112 static void test_uniform_size_type1(const char *glslType
, GLenum glType
, const char *el
)
120 printf(" Running subtest %s\n", glslType
);
122 sprintf(buffer
, "#version 120\nuniform %s m[60];\nvoid main() { gl_Position[0] = m[59]%s; }\n",
125 program
= make_program(buffer
, NULL
);
126 glGetProgramiv(program
, GL_ACTIVE_UNIFORMS
, &active
);
128 for (i
= 0; i
< active
; i
++) {
131 glGetActiveUniform(program
, i
, sizeof(buffer
), NULL
, &size
, &type
, buffer
);
133 if (strncmp(buffer
, "m", 1) == 0)
136 assert(i
< active
); /* Otherwise the compiler optimised it out */
137 assert(type
== glType
);
141 static void test_uniform_size_type(void)
143 test_uniform_size_type1("float", GL_FLOAT
, "");
144 test_uniform_size_type1("vec2", GL_FLOAT_VEC2
, "[0]");
145 test_uniform_size_type1("vec3", GL_FLOAT_VEC3
, "[0]");
146 test_uniform_size_type1("vec4", GL_FLOAT_VEC4
, "[0]");
148 test_uniform_size_type1("bool", GL_BOOL
, " ? 1.0 : 0.0");
149 test_uniform_size_type1("bvec2", GL_BOOL_VEC2
, "[0] ? 1.0 : 0.0");
150 test_uniform_size_type1("bvec3", GL_BOOL_VEC3
, "[0] ? 1.0 : 0.0");
151 test_uniform_size_type1("bvec4", GL_BOOL_VEC4
, "[0] ? 1.0 : 0.0");
153 test_uniform_size_type1("int", GL_INT
, "");
154 test_uniform_size_type1("ivec2", GL_INT_VEC2
, "[0]");
155 test_uniform_size_type1("ivec3", GL_INT_VEC3
, "[0]");
156 test_uniform_size_type1("ivec4", GL_INT_VEC4
, "[0]");
158 test_uniform_size_type1("mat2", GL_FLOAT_MAT2
, "[0][0]");
159 test_uniform_size_type1("mat3", GL_FLOAT_MAT3
, "[0][0]");
160 test_uniform_size_type1("mat4", GL_FLOAT_MAT4
, "[0][0]");
161 test_uniform_size_type1("mat2x3", GL_FLOAT_MAT2x3
, "[0][0]");
162 test_uniform_size_type1("mat2x4", GL_FLOAT_MAT2x4
, "[0][0]");
163 test_uniform_size_type1("mat3x2", GL_FLOAT_MAT3x2
, "[0][0]");
164 test_uniform_size_type1("mat3x4", GL_FLOAT_MAT3x4
, "[0][0]");
165 test_uniform_size_type1("mat4x2", GL_FLOAT_MAT4x2
, "[0][0]");
166 test_uniform_size_type1("mat4x3", GL_FLOAT_MAT4x3
, "[0][0]");
169 static void test_attrib_size_type1(const char *glslType
, GLenum glType
, const char *el
)
177 printf(" Running subtest %s\n", glslType
);
179 sprintf(buffer
, "#version 120\nattribute %s m;\nvoid main() { gl_Position[0] = m%s; }\n",
182 program
= make_program(buffer
, NULL
);
183 glGetProgramiv(program
, GL_ACTIVE_ATTRIBUTES
, &active
);
185 for (i
= 0; i
< active
; i
++) {
188 glGetActiveAttrib(program
, i
, sizeof(buffer
), NULL
, &size
, &type
, buffer
);
190 if (strncmp(buffer
, "m", 1) == 0)
193 assert(i
< active
); /* Otherwise the compiler optimised it out */
194 assert(type
== glType
);
198 static void test_attrib_size_type(void)
200 test_attrib_size_type1("float", GL_FLOAT
, "");
201 test_attrib_size_type1("vec2", GL_FLOAT_VEC2
, "[0]");
202 test_attrib_size_type1("vec3", GL_FLOAT_VEC3
, "[0]");
203 test_attrib_size_type1("vec4", GL_FLOAT_VEC4
, "[0]");
205 test_attrib_size_type1("mat2", GL_FLOAT_MAT2
, "[0][0]");
206 test_attrib_size_type1("mat3", GL_FLOAT_MAT3
, "[0][0]");
207 test_attrib_size_type1("mat4", GL_FLOAT_MAT4
, "[0][0]");
208 test_attrib_size_type1("mat2x3", GL_FLOAT_MAT2x3
, "[0][0]");
209 test_attrib_size_type1("mat2x4", GL_FLOAT_MAT2x4
, "[0][0]");
210 test_attrib_size_type1("mat3x2", GL_FLOAT_MAT3x2
, "[0][0]");
211 test_attrib_size_type1("mat3x4", GL_FLOAT_MAT3x4
, "[0][0]");
212 test_attrib_size_type1("mat4x2", GL_FLOAT_MAT4x2
, "[0][0]");
213 test_attrib_size_type1("mat4x3", GL_FLOAT_MAT4x3
, "[0][0]");
216 static void test_uniform_array_overflow(void)
222 program
= make_program("#version 120\nuniform vec2 x[10];\nvoid main() { gl_Position.xy = x[9]; }\n", NULL
);
223 location
= glGetUniformLocation(program
, "x");
225 glUniform2fv(location
, 64, data
);
229 static void test_uniform_scalar_count(void)
235 program
= make_program("#version 110\nuniform vec2 x;\nvoid main() { gl_Position.xy = x; }\n", NULL
);
236 location
= glGetUniformLocation(program
, "x");
238 glUniform2fv(location
, 64, data
);
239 assert_error(GL_INVALID_OPERATION
);
242 static void test_uniform_query_matrix(void)
249 program
= make_program("#version 110\nuniform mat3 m[2];\nvoid main() { gl_Position.xyz = m[1][2]; }\n", NULL
);
250 location
= glGetUniformLocation(program
, "m");
251 for (i
= 0; i
< 9; i
++)
253 for (i
= 9; i
< 18; i
++)
255 glUniformMatrix3fv(location
, 1, GL_TRUE
, data
);
257 for (i
= 0; i
< 18; i
++)
259 glGetUniformfv(program
, location
, data
);
260 for (c
= 0; c
< 3; c
++)
261 for (r
= 0; r
< 3; r
++)
262 assert(data
[c
* 3 + r
] == r
* 3 + c
);
263 for (i
= 9; i
< 18; i
++)
264 assert(data
[i
] == 123.0);
267 static void test_uniform_neg_location(void)
272 program
= make_program("#version 110\nvoid main() { gl_Position = vec4(1.0, 1.0, 1.0, 1.0); }\n", NULL
);
276 glUniform1i(-200, 1);
277 assert_error(GL_INVALID_OPERATION
);
278 glUniformMatrix2fv(-1, 1, GL_FALSE
, data
);
280 glUniformMatrix2fv(-200, 1, GL_FALSE
, data
);
281 assert_error(GL_INVALID_OPERATION
);
284 static void test_uniform_bool_conversion(void)
288 GLint value
[16]; /* in case glGetUniformiv goes nuts on the stack */
291 program
= make_program("uniform bool b;\nvoid main() { gl_Position.x = b ? 1.5 : 0.5; }\n", NULL
);
292 location
= glGetUniformLocation(program
, "b");
293 assert(location
!= -1);
295 glUniform1i(location
, 5);
297 glGetUniformiv(program
, location
, &value
[0]);
299 assert(value
[0] == 1);
302 static void test_uniform_multiple_samplers(void)
306 GLint values
[2] = {0, 1};
309 program
= make_program(NULL
, "uniform sampler2D s[2];\nvoid main() { gl_FragColor = texture2D(s[1], vec2(0.0, 0.0)); }\n");
310 location
= glGetUniformLocation(program
, "s[0]");
311 assert(location
!= -1);
313 glUniform1iv(location
, 2, values
);
317 static void run_test(const char *name
, void (*callback
)(void))
319 printf("Running %s\n", name
);
324 #define RUN_TEST(name) run_test(#name, (name))
326 int main(int argc
, char **argv
)
330 glutInit(&argc
, argv
);
331 glutCreateWindow("Mesa bug demo");
334 version
= (const char *) glGetString(GL_VERSION
);
335 if (version
[0] == '1') {
336 printf("Sorry, this test requires OpenGL 2.x GLSL support\n");
340 RUN_TEST(test_uniform_size_type
);
341 RUN_TEST(test_attrib_size_type
);
342 RUN_TEST(test_uniform_array_overflow
);
343 RUN_TEST(test_uniform_scalar_count
);
344 RUN_TEST(test_uniform_query_matrix
);
345 RUN_TEST(test_uniform_neg_location
);
346 RUN_TEST(test_uniform_bool_conversion
);
347 /* Leave this one at the end, since it crashes Mesa's shader compiler */
348 RUN_TEST(test_uniform_multiple_samplers
);