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
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
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
43 /** Name of the attribute. */
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.
57 * Expected (array) size of the attribute.
60 * Attribute arrays aren't added until GLSL 1.50.
64 /** Expected GLSL type of the attribute. */
72 * List of attributes to be checked
75 * The list is terminated by an attribute with a \c NULL \c name
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
86 "attribute float vertex;\n"
87 "void main() { gl_Position = vec4(vertex); }",
89 { "vertex", true, 1, GL_FLOAT
},
94 "attribute vec2 vertex;\n"
95 "void main() { gl_Position = vertex.xyxy; }",
97 { "vertex", true, 1, GL_FLOAT_VEC2
},
102 "attribute vec3 vertex;\n"
103 "void main() { gl_Position = vertex.xyzx; }",
105 { "vertex", true, 1, GL_FLOAT_VEC3
},
110 "attribute vec4 vertex;\n"
111 "void main() { gl_Position = vertex; }",
113 { "vertex", true, 1, GL_FLOAT_VEC4
},
118 "attribute mat2 vertex;\n"
119 "void main() { gl_Position = vertex[0].xyxy; }",
121 { "vertex", true, 1, GL_FLOAT_MAT2
},
126 "attribute mat3 vertex;\n"
127 "void main() { gl_Position = vertex[0].xyzx; }",
129 { "vertex", true, 1, GL_FLOAT_MAT3
},
134 "attribute mat4 vertex;\n"
135 "void main() { gl_Position = vertex[0]; }",
137 { "vertex", true, 1, GL_FLOAT_MAT4
},
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
},
155 "void main() { gl_Position = gl_SecondaryColor; }",
157 { "gl_SecondaryColor", true, 1, GL_FLOAT_VEC4
},
162 "void main() { gl_Position = gl_Normal.xyzx; }",
164 { "gl_Normal", true, 1, GL_FLOAT_VEC3
},
169 "void main() { gl_Position = gl_Vertex; }",
171 { "gl_Vertex", true, 1, GL_FLOAT_VEC4
},
176 "void main() { gl_Position = gl_MultiTexCoord0; }",
178 { "gl_MultiTexCoord0", true, 1, GL_FLOAT_VEC4
},
183 "void main() { gl_Position = gl_MultiTexCoord1; }",
185 { "gl_MultiTexCoord1", true, 1, GL_FLOAT_VEC4
},
190 "void main() { gl_Position = vec4(gl_FogCoord); }",
192 { "gl_FogCoord", true, 1, GL_FLOAT
},
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
},
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
},
218 "attribute vec4 vertex;\n"
220 " gl_Position = vertex;\n"
221 " if (false) gl_Position = gl_Vertex;\n"
224 { "gl_Vertex", false, 1, GL_FLOAT_VEC4
},
225 { "vertex", true, 1, GL_FLOAT_VEC4
},
230 "attribute vec4 vertex;\n"
231 "attribute vec2 alternate;\n"
232 "uniform bool use_alternate;\n"
234 " gl_Position = vertex;\n"
235 " if (use_alternate) gl_Position = alternate.xyxy;\n"
238 { "vertex", true, 1, GL_FLOAT_VEC4
},
239 { "alternate", true, 1, GL_FLOAT_VEC2
},
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
},
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.
264 "attribute mat2x3 vertex;\n"
265 "void main() { gl_Position = vertex[0].xxxx; }",
267 { "vertex", true, 1, GL_FLOAT_MAT2x3
},
273 "attribute mat2x4 vertex;\n"
274 "void main() { gl_Position = vertex[0].xxxx; }",
276 { "vertex", true, 1, GL_FLOAT_MAT2x4
},
282 "attribute mat3x2 vertex;\n"
283 "void main() { gl_Position = vertex[0].xxxx; }",
285 { "vertex", true, 1, GL_FLOAT_MAT3x2
},
291 "attribute mat3x4 vertex;\n"
292 "void main() { gl_Position = vertex[0].xxxx; }",
294 { "vertex", true, 1, GL_FLOAT_MAT3x4
},
300 "attribute mat4x2 vertex;\n"
301 "void main() { gl_Position = vertex[0].xxxx; }",
303 { "vertex", true, 1, GL_FLOAT_MAT4x2
},
309 "attribute mat4x3 vertex;\n"
310 "void main() { gl_Position = vertex[0].xxxx; }",
312 { "vertex", true, 1, GL_FLOAT_MAT4x3
},
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.
328 "void main() { gl_Position = vec4(vertex); }",
330 { "vertex", true, 1, GL_INT
},
337 "void main() { gl_Position = vec4(vertex); }",
339 { "vertex", true, 1, GL_UNSIGNED_INT
},
346 "void main() { gl_Position = vec4(vertex.x); }",
348 { "vertex", true, 1, GL_INT_VEC2
},
355 "void main() { gl_Position = vec4(vertex.x); }",
357 { "vertex", true, 1, GL_UNSIGNED_INT_VEC2
},
364 "void main() { gl_Position = vec4(vertex.x); }",
366 { "vertex", true, 1, GL_INT_VEC3
},
373 "void main() { gl_Position = vec4(vertex.x); }",
375 { "vertex", true, 1, GL_UNSIGNED_INT_VEC3
},
382 "void main() { gl_Position = vec4(vertex.x); }",
384 { "vertex", true, 1, GL_INT_VEC4
},
391 "void main() { gl_Position = vec4(vertex.x); }",
393 { "vertex", true, 1, GL_UNSIGNED_INT_VEC4
},
406 find_attrib(const struct attribute
*attribs
, const char *name
)
410 for (i
= 0; attribs
[i
].name
!= NULL
; i
++) {
411 if (strcmp(attribs
[i
].name
, name
) == 0)
418 #define DUMP_SHADER(code) \
420 if (!shader_dumped) { \
421 fprintf(stderr, "\nFailing shader:\n%s\n\n", \
423 shader_dumped = true; \
428 do_test(const struct test
*tests
, unsigned num_tests
)
433 for (i
= 0; i
< num_tests
; i
++) {
435 piglit_compile_shader_text(GL_VERTEX_SHADER
,
437 GLint prog
= piglit_link_simple_program(vert
, 0);
439 unsigned visited_count
[64];
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
;
469 glGetActiveAttrib(prog
, j
,
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.
481 DUMP_SHADER(tests
[i
].code
);
483 "Attribute `%s' should not be active "
484 "but is.\n", name_buf
);
489 attr
= &tests
[i
].attributes
[attr_idx
];
490 if (visited_count
[attr_idx
] != 0) {
491 DUMP_SHADER(tests
[i
].code
);
493 "Attribute `%s' listed multiple times "
494 "in active list.\n", name_buf
);
496 } else if (attr
->size
!= size
) {
497 DUMP_SHADER(tests
[i
].code
);
499 "Attribute `%s' should have size %d, "
500 "but had size %d.\n",
501 name_buf
, attr
->size
, size
);
503 } else if (attr
->type
!= type
) {
504 DUMP_SHADER(tests
[i
].code
);
506 "Attribute `%s' should have type "
507 "0x%04x, but had type 0x%04x.\n",
508 name_buf
, attr
->type
, type
);
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
);
520 "Attribute `%s' should have been "
521 "active but wasn't.\n",
522 tests
[i
].attributes
[j
].name
);
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
)
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
))
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
))
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
))
564 usage_and_fail(argv
[0]);
568 piglit_report_result(pass
? PIGLIT_PASS
: PIGLIT_FAIL
);