fix the spelling in whole piglit
[piglit.git] / tests / general / getactiveattrib.c
blob767265591b8f1061da3e1e2898d59ffc4cd0c6fc
1 /*
2 * Copyright © 2011 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 DEALINGS
21 * IN THE SOFTWARE.
24 /**
25 * \file getactiveattrib.c
26 * Verify that glGetActiveAttrib and GL_ACTIVE_ATTRIBUTES return the expected
27 * values for a variety of shaders.
29 * \author Ian Romanick
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 struct attribute {
43 /** Name of the attribute. */
44 const char *name;
46 /**
47 * This attribute must be active in the linked shader.
49 * Some attributes must be active and some may or may not be active
50 * (because a clever compiler could optimize them away. Attributes
51 * that must not be active should not be listed in
52 * \c test::attributes.
54 bool must_be_active;
56 /**
57 * Expected (array) size of the attribute.
59 * \note
60 * Attribute arrays aren't added until GLSL 1.50.
62 GLint size;
64 /** Expected GLSL type of the attribute. */
65 GLenum type;
68 struct test {
69 const char *code;
71 /**
72 * List of attributes to be checked
74 * \note
75 * The list is terminated by an attribute with a \c NULL \c name
76 * pointer.
78 struct attribute attributes[16];
81 static const struct test glsl110_tests[] = {
82 /* The first group of tests tries all the possible types for vertex
83 * shader inputs.
86 "attribute float vertex;\n"
87 "void main() { gl_Position = vec4(vertex); }",
89 { "vertex", true, 1, GL_FLOAT },
90 { NULL, }
94 "attribute vec2 vertex;\n"
95 "void main() { gl_Position = vertex.xyxy; }",
97 { "vertex", true, 1, GL_FLOAT_VEC2 },
98 { NULL, }
102 "attribute vec3 vertex;\n"
103 "void main() { gl_Position = vertex.xyzx; }",
105 { "vertex", true, 1, GL_FLOAT_VEC3 },
106 { NULL, }
110 "attribute vec4 vertex;\n"
111 "void main() { gl_Position = vertex; }",
113 { "vertex", true, 1, GL_FLOAT_VEC4 },
114 { NULL, }
118 "attribute mat2 vertex;\n"
119 "void main() { gl_Position = vertex[0].xyxy; }",
121 { "vertex", true, 1, GL_FLOAT_MAT2 },
122 { NULL, }
126 "attribute mat3 vertex;\n"
127 "void main() { gl_Position = vertex[0].xyzx; }",
129 { "vertex", true, 1, GL_FLOAT_MAT3 },
130 { NULL, }
134 "attribute mat4 vertex;\n"
135 "void main() { gl_Position = vertex[0]; }",
137 { "vertex", true, 1, GL_FLOAT_MAT4 },
138 { NULL, }
143 /* Try using each of the built-in attributes one at a time. Only the
144 * first two glMultiTexCoord attributes are checked because that's all
145 * an implementation is required to support.
148 "void main() { gl_Position = gl_Color; }",
150 { "gl_Color", true, 1, GL_FLOAT_VEC4 },
151 { NULL, }
155 "void main() { gl_Position = gl_SecondaryColor; }",
157 { "gl_SecondaryColor", true, 1, GL_FLOAT_VEC4 },
158 { NULL, }
162 "void main() { gl_Position = gl_Normal.xyzx; }",
164 { "gl_Normal", true, 1, GL_FLOAT_VEC3 },
165 { NULL, }
169 "void main() { gl_Position = gl_Vertex; }",
171 { "gl_Vertex", true, 1, GL_FLOAT_VEC4 },
172 { NULL, }
176 "void main() { gl_Position = gl_MultiTexCoord0; }",
178 { "gl_MultiTexCoord0", true, 1, GL_FLOAT_VEC4 },
179 { NULL, }
183 "void main() { gl_Position = gl_MultiTexCoord1; }",
185 { "gl_MultiTexCoord1", true, 1, GL_FLOAT_VEC4 },
186 { NULL, }
190 "void main() { gl_Position = vec4(gl_FogCoord); }",
192 { "gl_FogCoord", true, 1, GL_FLOAT },
193 { NULL, }
197 /* Try various cases of using / not using some user-defined attributes
198 * and some built-in attributes.
201 "attribute vec4 not_used;\n"
202 "void main() { gl_Position = gl_Vertex; }",
204 { "gl_Vertex", true, 1, GL_FLOAT_VEC4 },
205 { NULL, }
209 "attribute vec4 vertex;\n"
210 "void main() { gl_Position = vertex + gl_Vertex; }",
212 { "gl_Vertex", true, 1, GL_FLOAT_VEC4 },
213 { "vertex", true, 1, GL_FLOAT_VEC4 },
214 { NULL, }
218 "attribute vec4 vertex;\n"
219 "void main() {\n"
220 " gl_Position = vertex;\n"
221 " if (false) gl_Position = gl_Vertex;\n"
222 "}",
224 { "gl_Vertex", false, 1, GL_FLOAT_VEC4 },
225 { "vertex", true, 1, GL_FLOAT_VEC4 },
226 { NULL, }
230 "attribute vec4 vertex;\n"
231 "attribute vec2 alternate;\n"
232 "uniform bool use_alternate;\n"
233 "void main() {\n"
234 " gl_Position = vertex;\n"
235 " if (use_alternate) gl_Position = alternate.xyxy;\n"
236 "}",
238 { "vertex", true, 1, GL_FLOAT_VEC4 },
239 { "alternate", true, 1, GL_FLOAT_VEC2 },
240 { NULL, }
244 /* The built-in function ftransform should also mark gl_Vertex as used.
247 "void main() { gl_Position = ftransform(); }",
249 { "gl_Vertex", true, 1, GL_FLOAT_VEC4 },
250 { NULL, }
255 static const struct test glsl120_tests[] = {
256 /* Try all the possible types for vertex shader inputs. Note that
257 * this only checks the types that were added in GLSL 1.20.
259 * Since GLSL 1.20 doesn't add any new built-in attributes, there are
260 * no other tests added in the GLSL 1.20 group.
263 "#version 120\n"
264 "attribute mat2x3 vertex;\n"
265 "void main() { gl_Position = vertex[0].xxxx; }",
267 { "vertex", true, 1, GL_FLOAT_MAT2x3 },
268 { NULL, }
272 "#version 120\n"
273 "attribute mat2x4 vertex;\n"
274 "void main() { gl_Position = vertex[0].xxxx; }",
276 { "vertex", true, 1, GL_FLOAT_MAT2x4 },
277 { NULL, }
281 "#version 120\n"
282 "attribute mat3x2 vertex;\n"
283 "void main() { gl_Position = vertex[0].xxxx; }",
285 { "vertex", true, 1, GL_FLOAT_MAT3x2 },
286 { NULL, }
290 "#version 120\n"
291 "attribute mat3x4 vertex;\n"
292 "void main() { gl_Position = vertex[0].xxxx; }",
294 { "vertex", true, 1, GL_FLOAT_MAT3x4 },
295 { NULL, }
299 "#version 120\n"
300 "attribute mat4x2 vertex;\n"
301 "void main() { gl_Position = vertex[0].xxxx; }",
303 { "vertex", true, 1, GL_FLOAT_MAT4x2 },
304 { NULL, }
308 "#version 120\n"
309 "attribute mat4x3 vertex;\n"
310 "void main() { gl_Position = vertex[0].xxxx; }",
312 { "vertex", true, 1, GL_FLOAT_MAT4x3 },
313 { NULL, }
318 static const struct test glsl130_tests[] = {
319 /* Try all the possible types for vertex shader inputs. Note that
320 * this only checks the types that were added in GLSL 1.30.
322 * Since GLSL 1.30 doesn't add any new built-in attributes, there are
323 * no other tests added in the GLSL 1.30 group.
326 "#version 130\n"
327 "in int vertex;\n"
328 "void main() { gl_Position = vec4(vertex); }",
330 { "vertex", true, 1, GL_INT },
331 { NULL, }
335 "#version 130\n"
336 "in uint vertex;\n"
337 "void main() { gl_Position = vec4(vertex); }",
339 { "vertex", true, 1, GL_UNSIGNED_INT },
340 { NULL, }
344 "#version 130\n"
345 "in ivec2 vertex;\n"
346 "void main() { gl_Position = vec4(vertex.x); }",
348 { "vertex", true, 1, GL_INT_VEC2 },
349 { NULL, }
353 "#version 130\n"
354 "in uvec2 vertex;\n"
355 "void main() { gl_Position = vec4(vertex.x); }",
357 { "vertex", true, 1, GL_UNSIGNED_INT_VEC2 },
358 { NULL, }
362 "#version 130\n"
363 "in ivec3 vertex;\n"
364 "void main() { gl_Position = vec4(vertex.x); }",
366 { "vertex", true, 1, GL_INT_VEC3 },
367 { NULL, }
371 "#version 130\n"
372 "in uvec3 vertex;\n"
373 "void main() { gl_Position = vec4(vertex.x); }",
375 { "vertex", true, 1, GL_UNSIGNED_INT_VEC3 },
376 { NULL, }
380 "#version 130\n"
381 "in ivec4 vertex;\n"
382 "void main() { gl_Position = vec4(vertex.x); }",
384 { "vertex", true, 1, GL_INT_VEC4 },
385 { NULL, }
389 "#version 130\n"
390 "in uvec4 vertex;\n"
391 "void main() { gl_Position = vec4(vertex.x); }",
393 { "vertex", true, 1, GL_UNSIGNED_INT_VEC4 },
394 { NULL, }
399 enum piglit_result
400 piglit_display(void)
402 return PIGLIT_FAIL;
406 find_attrib(const struct attribute *attribs, const char *name)
408 unsigned i;
410 for (i = 0; attribs[i].name != NULL; i++) {
411 if (strcmp(attribs[i].name, name) == 0)
412 return (int) i;
415 return -1;
418 #define DUMP_SHADER(code) \
419 do { \
420 if (!shader_dumped) { \
421 fprintf(stderr, "\nFailing shader:\n%s\n\n", \
422 code); \
423 shader_dumped = true; \
425 } while (false)
427 bool
428 do_test(const struct test *tests, unsigned num_tests)
430 bool pass = true;
431 unsigned i;
433 for (i = 0; i < num_tests; i++) {
434 GLint vert =
435 piglit_compile_shader_text(GL_VERTEX_SHADER,
436 tests[i].code);
437 GLint prog = piglit_link_simple_program(vert, 0);
438 GLint num_attr;
439 unsigned visited_count[64];
440 unsigned j;
441 bool shader_dumped = false;
443 memset(visited_count, 0, sizeof(visited_count));
445 /* From page 93 (page 109 of the PDF) says:
447 * "An attribute variable (either conventional or generic)
448 * is considered active if it is determined by the
449 * compiler and linker that the attribute may be accessed
450 * when the shader is executed. Attribute variables that
451 * are declared in a vertex shader but never used will not
452 * count against the limit. In cases where the compiler
453 * and linker cannot make a conclusive determination, an
454 * attribute will be considered active."
456 * Compare the set of active attributes against the list of
457 * expected active attributes.
459 glGetProgramiv(prog, GL_ACTIVE_ATTRIBUTES, &num_attr);
461 for (j = 0; j < num_attr; j++) {
462 const struct attribute *attr;
463 char name_buf[256];
464 int attr_idx;
465 GLsizei name_len;
466 GLint size;
467 GLenum type;
469 glGetActiveAttrib(prog, j,
470 sizeof(name_buf),
471 &name_len,
472 &size,
473 &type,
474 name_buf);
475 attr_idx = find_attrib(tests[i].attributes, name_buf);
477 /* If the named attribute is not in the list for the
478 * test, then it must not be active.
480 if (attr_idx < 0) {
481 DUMP_SHADER(tests[i].code);
482 fprintf(stderr,
483 "Attribute `%s' should not be active "
484 "but is.\n", name_buf);
485 pass = false;
486 continue;
489 attr = &tests[i].attributes[attr_idx];
490 if (visited_count[attr_idx] != 0) {
491 DUMP_SHADER(tests[i].code);
492 fprintf(stderr,
493 "Attribute `%s' listed multiple times "
494 "in active list.\n", name_buf);
495 pass = false;
496 } else if (attr->size != size) {
497 DUMP_SHADER(tests[i].code);
498 fprintf(stderr,
499 "Attribute `%s' should have size %d, "
500 "but had size %d.\n",
501 name_buf, attr->size, size);
502 pass = false;
503 } else if (attr->type != type) {
504 DUMP_SHADER(tests[i].code);
505 fprintf(stderr,
506 "Attribute `%s' should have type "
507 "0x%04x, but had type 0x%04x.\n",
508 name_buf, attr->type, type);
509 pass = false;
512 visited_count[attr_idx]++;
515 for (j = 0; tests[i].attributes[j].name != NULL; j++) {
516 if (tests[i].attributes[j].must_be_active
517 && visited_count[j] == 0) {
518 DUMP_SHADER(tests[i].code);
519 fprintf(stderr,
520 "Attribute `%s' should have been "
521 "active but wasn't.\n",
522 tests[i].attributes[j].name);
523 pass = false;
528 return pass;
531 void usage_and_fail(const char *name)
533 fprintf(stderr, "Usage: %s [110|120|130]\n", name);
534 piglit_report_result(PIGLIT_FAIL);
537 void piglit_init(int argc, char **argv)
539 bool pass = true;
540 unsigned i;
542 if (argc == 1) {
543 usage_and_fail(argv[0]);
546 piglit_require_vertex_shader();
548 for (i = 1; i < argc; i++) {
549 if (strcmp("110", argv[i]) == 0) {
550 pass = do_test(glsl110_tests,
551 ARRAY_SIZE(glsl110_tests))
552 && pass;
553 } else if (strcmp("120", argv[i]) == 0) {
554 piglit_require_GLSL_version(120);
555 pass = do_test(glsl120_tests,
556 ARRAY_SIZE(glsl120_tests))
557 && pass;
558 } else if (strcmp("130", argv[i]) == 0) {
559 piglit_require_GLSL_version(130);
560 pass = do_test(glsl130_tests,
561 ARRAY_SIZE(glsl130_tests))
562 && pass;
563 } else {
564 usage_and_fail(argv[0]);
568 piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);