1 /*
2 * Copyright © 2016 Intel Corporation
3 *
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:
10 *
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.
14 *
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.
22 */
23
24 /**
25 * \file getactiveattrib.c
26 * Verify that glGetActiveAttrib and GL_ACTIVE_ATTRIBUTES return the expected
27 * values for the new tokens defined at ARB_vertex_attrib_64bit specification.
28 *
29 * This is based on tests/general/getactiveattrib.c
30 */
31
32 #include "piglit-util-gl.h"
33
34 PIGLIT_GL_TEST_CONFIG_BEGIN
35 config.supports_gl_compat_version = 32;
36 config.supports_gl_core_version = 32;
37
38 config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
39 config.khr_no_error_support = PIGLIT_NO_ERRORS;
40 PIGLIT_GL_TEST_CONFIG_END
41
42 struct attribute {
43 /** Name of the attribute. */
44 const char *name;
45
46 /** Expected GLSL type of the attribute. */
47 GLenum type;
48 };
49
50 struct test {
51 const char *code;
52
53 /**
54 * List of attributes to be checked
55 *
56 * \note
57 * The list is terminated by an attribute with a \c NULL \c name
58 * pointer.
59 */
60 struct attribute attributes[16];
61 };
62
63 static const struct test vertex_attrib_64bit_tests[] = {
64 /* Try all the possible types for vertex shader inputs added
65 * at the spec. They could be added as 13 attributes on the
66 * same vertex shader, but we would need to get them all
67 * active. It is easier to read this way.
68 */
69 {
70 "#version 150\n"
71 "#extension GL_ARB_vertex_attrib_64bit: require\n"
72 "#extension GL_ARB_gpu_shader_fp64: require\n"
73 "in double _double;\n"
74 "void main() { gl_Position = vec4(float(_double)); }\n",
75 {
76 { "_double", GL_DOUBLE },
77 { NULL, }
78 }
79 },
80 {
81 "#version 150\n"
82 "#extension GL_ARB_vertex_attrib_64bit: require\n"
83 "#extension GL_ARB_gpu_shader_fp64: require\n"
84 "in dvec2 _dvec2;\n"
85 "void main() { gl_Position = vec4(float(_dvec2.x)); }\n",
86 {
87 { "_dvec2", GL_DOUBLE_VEC2 },
88 { NULL, }
89 }
90 },
91 {
92 "#version 150\n"
93 "#extension GL_ARB_vertex_attrib_64bit: require\n"
94 "#extension GL_ARB_gpu_shader_fp64: require\n"
95 "in dvec3 _dvec3;\n"
96 "void main() { gl_Position = vec4(float(_dvec3.x)); }\n",
97 {
98 { "_dvec3", GL_DOUBLE_VEC3 },
99 { NULL, }
100 }
101 },
102 {
103 "#version 150\n"
104 "#extension GL_ARB_vertex_attrib_64bit: require\n"
105 "#extension GL_ARB_gpu_shader_fp64: require\n"
106 "in dvec4 _dvec4;\n"
107 "void main() { gl_Position = vec4(float(_dvec4.x)); }\n",
108 {
109 { "_dvec4", GL_DOUBLE_VEC4 },
110 { NULL, }
111 }
112 },
113 {
114 "#version 150\n"
115 "#extension GL_ARB_vertex_attrib_64bit: require\n"
116 "#extension GL_ARB_gpu_shader_fp64: require\n"
117 "in dmat2 _dmat2;\n"
118 "void main() { gl_Position = vec4(float(_dmat2[0][0])); }\n",
119 {
120 { "_dmat2", GL_DOUBLE_MAT2 },
121 { NULL, }
122 }
123 },
124 {
125 "#version 150\n"
126 "#extension GL_ARB_vertex_attrib_64bit: require\n"
127 "#extension GL_ARB_gpu_shader_fp64: require\n"
128 "in dmat3 _dmat3;\n"
129 "void main() { gl_Position = vec4(float(_dmat3[0][0])); }\n",
130 {
131 { "_dmat3", GL_DOUBLE_MAT3 },
132 { NULL, }
133 }
134 },
135 {
136 "#version 150\n"
137 "#extension GL_ARB_vertex_attrib_64bit: require\n"
138 "#extension GL_ARB_gpu_shader_fp64: require\n"
139 "in dmat4 _dmat4;\n"
140 "void main() { gl_Position = vec4(float(_dmat4[0][0])); }\n",
141 {
142 { "_dmat4", GL_DOUBLE_MAT4 },
143 { NULL, }
144 }
145 },
146 {
147 "#version 150\n"
148 "#extension GL_ARB_vertex_attrib_64bit: require\n"
149 "#extension GL_ARB_gpu_shader_fp64: require\n"
150 "in dmat2x3 _dmat2x3;\n"
151 "void main() { gl_Position = vec4(float(_dmat2x3[0][0])); }\n",
152 {
153 { "_dmat2x3", GL_DOUBLE_MAT2x3 },
154 { NULL, }
155 }
156 },
157 {
158 "#version 150\n"
159 "#extension GL_ARB_vertex_attrib_64bit: require\n"
160 "#extension GL_ARB_gpu_shader_fp64: require\n"
161 "in dmat2x4 _dmat2x4;\n"
162 "void main() { gl_Position = vec4(float(_dmat2x4[0][0])); }\n",
163 {
164 { "_dmat2x4", GL_DOUBLE_MAT2x4 },
165 { NULL, }
166 }
167 },
168 {
169 "#version 150\n"
170 "#extension GL_ARB_vertex_attrib_64bit: require\n"
171 "#extension GL_ARB_gpu_shader_fp64: require\n"
172 "in dmat3x2 _dmat3x2;\n"
173 "void main() { gl_Position = vec4(float(_dmat3x2[0][0])); }\n",
174 {
175 { "_dmat3x2", GL_DOUBLE_MAT3x2 },
176 { NULL, }
177 }
178 },
179 {
180 "#version 150\n"
181 "#extension GL_ARB_vertex_attrib_64bit: require\n"
182 "#extension GL_ARB_gpu_shader_fp64: require\n"
183 "in dmat3x4 _dmat3x4;\n"
184 "void main() { gl_Position = vec4(float(_dmat3x4[0][0])); }\n",
185 {
186 { "_dmat3x4", GL_DOUBLE_MAT3x4 },
187 { NULL, }
188 }
189 },
190 {
191 "#version 150\n"
192 "#extension GL_ARB_vertex_attrib_64bit: require\n"
193 "#extension GL_ARB_gpu_shader_fp64: require\n"
194 "in dmat4x2 _dmat4x2;\n"
195 "void main() { gl_Position = vec4(float(_dmat4x2[0][0])); }\n",
196 {
197 { "_dmat4x2", GL_DOUBLE_MAT4x2 },
198 { NULL, }
199 }
200 },
201 {
202 "#version 150\n"
203 "#extension GL_ARB_vertex_attrib_64bit: require\n"
204 "#extension GL_ARB_gpu_shader_fp64: require\n"
205 "in dmat4x3 _dmat4x3;\n"
206 "void main() { gl_Position = vec4(float(_dmat4x3[0][0])); }\n",
207 {
208 { "_dmat4x3", GL_DOUBLE_MAT4x3 },
209 { NULL, }
210 }
211 },
212 };
213
214 enum piglit_result
piglit_display(void)215 piglit_display(void)
216 {
217 return PIGLIT_FAIL;
218 }
219
220 int
find_attrib(const struct attribute * attribs,const char * name)221 find_attrib(const struct attribute *attribs, const char *name)
222 {
223 unsigned i;
224
225 for (i = 0; attribs[i].name != NULL; i++) {
226 if (strcmp(attribs[i].name, name) == 0)
227 return (int) i;
228 }
229
230 return -1;
231 }
232
233 #define DUMP_SHADER(code) \
234 do { \
235 if (!shader_dumped) { \
236 fprintf(stderr, "\nFailing shader:\n%s\n\n", \
237 code); \
238 shader_dumped = true; \
239 } \
240 } while (false)
241
242 bool
do_test(const struct test * tests,unsigned num_tests)243 do_test(const struct test *tests, unsigned num_tests)
244 {
245 bool pass = true;
246 unsigned i;
247
248 for (i = 0; i < num_tests; i++) {
249 GLint prog = piglit_build_simple_program(tests[i].code, 0);
250 GLint num_attr;
251 unsigned visited_count[64];
252 unsigned j;
253 bool shader_dumped = false;
254
255 memset(visited_count, 0, sizeof(visited_count));
256
257 /* From page 93 (page 109 of the PDF) says:
258 *
259 * "An attribute variable (either conventional or generic)
260 * is considered active if it is determined by the
261 * compiler and linker that the attribute may be accessed
262 * when the shader is executed. Attribute variables that
263 * are declared in a vertex shader but never used will not
264 * count against the limit. In cases where the compiler
265 * and linker cannot make a conclusive determination, an
266 * attribute will be considered active."
267 *
268 * Compare the set of active attributes against the list of
269 * expected active attributes.
270 */
271 glGetProgramiv(prog, GL_ACTIVE_ATTRIBUTES, &num_attr);
272
273 for (j = 0; j < num_attr; j++) {
274 const struct attribute *attr;
275 char name_buf[256];
276 int attr_idx;
277 GLsizei name_len;
278 GLint size;
279 GLenum type;
280
281 glGetActiveAttrib(prog, j,
282 sizeof(name_buf),
283 &name_len,
284 &size,
285 &type,
286 name_buf);
287 attr_idx = find_attrib(tests[i].attributes, name_buf);
288
289 /* If the named attribute is not in the list for the
290 * test, then it must not be active.
291 */
292 if (attr_idx < 0) {
293 DUMP_SHADER(tests[i].code);
294 fprintf(stderr,
295 "Attribute `%s' should not be active"
296 " but is.\n", name_buf);
297 pass = false;
298 continue;
299 }
300
301 attr = &tests[i].attributes[attr_idx];
302 if (visited_count[attr_idx] != 0) {
303 DUMP_SHADER(tests[i].code);
304 fprintf(stderr,
305 "Attribute `%s' listed multiple times"
306 " in active list.\n", name_buf);
307 pass = false;
308 } else if (attr->type != type) {
309 DUMP_SHADER(tests[i].code);
310 fprintf(stderr,
311 "Attribute `%s' should have type"
312 " %s, but had type %s.\n",
313 name_buf, piglit_get_gl_enum_name(attr->type),
314 piglit_get_gl_enum_name(type));
315 pass = false;
316 }
317
318 visited_count[attr_idx]++;
319 }
320
321 for (j = 0; tests[i].attributes[j].name != NULL; j++) {
322 if (visited_count[j] == 0) {
323 DUMP_SHADER(tests[i].code);
324 fprintf(stderr,
325 "Attribute `%s' should have been"
326 " active but wasn't.\n",
327 tests[i].attributes[j].name);
328 pass = false;
329 }
330 }
331 }
332
333 return pass;
334 }
335
piglit_init(int argc,char ** argv)336 void piglit_init(int argc, char **argv)
337 {
338 bool pass = true;
339
340 piglit_require_extension("GL_ARB_vertex_attrib_64bit");
341
342 pass = do_test(vertex_attrib_64bit_tests,
343 ARRAY_SIZE(vertex_attrib_64bit_tests));
344
345 piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
346 }
347