1 /*
2 * Copyright (c) 2010 VMware, Inc.
3 * Copyright (c) 2015 Red Hat Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NON-INFRINGEMENT. IN NO EVENT SHALL VMWARE AND/OR THEIR SUPPLIERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26 /**
27 * Test GL_ARB_vertex_attrib_64bit vertex attributes.
28 * derived from Brian's gpu_shader4 tests.
29 */
30
31 #include "piglit-util-gl.h"
32
33 PIGLIT_GL_TEST_CONFIG_BEGIN
34
35 config.supports_gl_core_version = 32;
36
37 config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
38
39 config.khr_no_error_support = PIGLIT_NO_ERRORS;
40
41 PIGLIT_GL_TEST_CONFIG_END
42
43 static const char *TestName = "double_attribs";
44 static const GLuint Index = 3;
45
46 static void
gen_double_values(GLdouble values[4],GLuint size)47 gen_double_values(GLdouble values[4], GLuint size)
48 {
49 assert(size >= 1 && size <=4 );
50
51 values[0] = 1.7976931348623157E+308;
52 values[1] = 0.0;
53 values[2] = -1.3;
54 values[3] = 9.88888;
55 }
56
57 static void
gen_float_values(GLfloat values[4],GLuint size)58 gen_float_values(GLfloat values[4], GLuint size)
59 {
60 assert(size >= 1 && size <=4 );
61
62 values[0] = 0.5;
63 values[1] = 0.25;
64 values[2] = -1.3;
65 values[3] = 9.88888;
66 if (size < 4)
67 values[3] = 1;
68 if (size < 3)
69 values[2] = 0;
70 if (size < 2)
71 values[1] = 0;
72 }
73
74 /* doubles don't get default values */
75 static GLboolean
check_double_attrib(const GLdouble expected[4],GLuint size,const char * func)76 check_double_attrib(const GLdouble expected[4], GLuint size, const char *func)
77 {
78 GLdouble vals[4];
79 int i;
80 glGetVertexAttribLdv(Index, GL_CURRENT_VERTEX_ATTRIB_ARB, vals);
81
82 switch (size) {
83 case 4:
84 if (expected[3] != vals[3])
85 goto fail_print;
86 case 3:
87 if (expected[2] != vals[2])
88 goto fail_print;
89 case 2:
90 if (expected[1] != vals[1])
91 goto fail_print;
92 case 1:
93 if (expected[0] != vals[0])
94 goto fail_print;
95 }
96 return GL_TRUE;
97 fail_print:
98
99 fprintf(stderr, "%s: %s failed\n", TestName, func);
100 fprintf(stderr, " Expected: ");
101 for (i = 0; i < size; i++)
102 fprintf(stderr, " %g", expected[i]);
103 fprintf(stderr, " Found: ");
104 for (i = 0; i < size; i++)
105 fprintf(stderr, " %g", vals[i]);
106 fprintf(stderr, "\n");
107 return GL_FALSE;
108 }
109
110 static GLboolean
check_float_attrib(const GLfloat expected[4])111 check_float_attrib(const GLfloat expected[4])
112 {
113 GLfloat vals[4];
114 glGetVertexAttribfv(Index, GL_CURRENT_VERTEX_ATTRIB_ARB, vals);
115 if (expected[0] != vals[0] ||
116 expected[1] != vals[1] ||
117 expected[2] != vals[2] ||
118 expected[3] != vals[3]) {
119 fprintf(stderr, "%s: failed\n", TestName);
120 fprintf(stderr, " Expected: %f, %f, %f, %f\n",
121 expected[0], expected[1], expected[2], expected[3]);
122 fprintf(stderr, " Found: %f, %f, %f, %f\n",
123 vals[0], vals[1], vals[2], vals[3]);
124 return GL_FALSE;
125 }
126 return GL_TRUE;
127 }
128
129
130 static GLboolean
test_attrib_funcs(void)131 test_attrib_funcs(void)
132 {
133 GLdouble vals[4];
134
135 gen_double_values(vals, 1);
136 glVertexAttribL1d(Index, vals[0]);
137 if (!check_double_attrib(vals, 1, "glVertexAttribL1d"))
138 return GL_FALSE;
139
140 gen_double_values(vals, 2);
141 glVertexAttribL2d(Index, vals[0], vals[1]);
142 if (!check_double_attrib(vals, 2, "glVertexAttribL2d"))
143 return GL_FALSE;
144
145 gen_double_values(vals, 3);
146 glVertexAttribL3d(Index, vals[0], vals[1], vals[2]);
147 if (!check_double_attrib(vals, 3, "glVertexAttribL3d"))
148 return GL_FALSE;
149
150 gen_double_values(vals, 4);
151 glVertexAttribL4d(Index, vals[0], vals[1], vals[2], vals[3]);
152 if (!check_double_attrib(vals, 4, "glVertexAttribL4d"))
153 return GL_FALSE;
154
155
156 gen_double_values(vals, 1);
157 glVertexAttribL1dv(Index, vals);
158 if (!check_double_attrib(vals, 1, "glVertexAttribL1dv"))
159 return GL_FALSE;
160
161 gen_double_values(vals, 2);
162 glVertexAttribL2dv(Index, vals);
163 if (!check_double_attrib(vals, 2, "glVertexAttribL2dv"))
164 return GL_FALSE;
165
166 gen_double_values(vals, 3);
167 glVertexAttribL3dv(Index, vals);
168 if (!check_double_attrib(vals, 3, "glVertexAttribL3dv"))
169 return GL_FALSE;
170
171 gen_double_values(vals, 4);
172 glVertexAttribL4dv(Index, vals);
173 if (!check_double_attrib(vals, 4, "glVertexAttribL4dv"))
174 return GL_FALSE;
175
176 return GL_TRUE;
177 }
178
179 /** Check which datatypes are accepted by glVertexAttribLPointer() */
180 static GLboolean
test_attrib_array(void)181 test_attrib_array(void)
182 {
183 static const GLenum badTypes[] = {
184 GL_BYTE, GL_UNSIGNED_BYTE,
185 GL_SHORT, GL_UNSIGNED_SHORT,
186 GL_INT, GL_UNSIGNED_INT, GL_FLOAT,
187 GL_HALF_FLOAT_ARB, GL_BGRA,
188 };
189 static const GLenum goodTypes[] = {
190 GL_DOUBLE,
191 };
192 GLint i;
193 GLuint index = 1;
194 GLint size = 4;
195 GLsizei stride = 0;
196 GLenum err;
197 GLuint vao, vbo;
198
199 glGenVertexArrays(1, &vao);
200 glBindVertexArray(vao);
201
202 glGenBuffers(1, &vbo);
203 glBindBuffer(GL_ARRAY_BUFFER, vbo);
204
205 /* clear any prev errors */
206 while (glGetError() != GL_NO_ERROR)
207 ;
208
209 /* These should not generate a GL error */
210 for (i = 0; i < ARRAY_SIZE(goodTypes); i++) {
211 glVertexAttribLPointer(index, size, goodTypes[i], stride, NULL);
212 err = glGetError();
213 if (err != GL_NO_ERROR) {
214 fprintf(stderr,
215 "%s: glVertexAttribLPointer(type=0x%x) generated error 0x%x\n",
216 TestName, goodTypes[i], err);
217 return GL_FALSE;
218 }
219 }
220
221 if (!piglit_khr_no_error) {
222 for (i = 0; i < ARRAY_SIZE(badTypes); i++) {
223 glVertexAttribLPointer(index, size, badTypes[i], stride, NULL);
224 err = glGetError();
225 if (err != GL_INVALID_ENUM) {
226 fprintf(stderr,
227 "%s: glVertexAttribLPointer(type=0x%x) failed to generate "
228 "GL_INVALID_ENUM\n",
229 TestName, badTypes[i]);
230 return GL_FALSE;
231 }
232 }
233 }
234
235 return GL_TRUE;
236 }
237
238
239 /* these tests try and exercise the mesa vbo code */
240 /* write a double to an attribute slot,
241 * then write some floats, then rewrite the double,
242 * and read it back */
243 static GLboolean
test_attrib_mixed_1(void)244 test_attrib_mixed_1(void)
245 {
246 GLdouble vals[4];
247 GLfloat fvals[4];
248
249 gen_double_values(vals, 4);
250 glVertexAttribL4dv(Index, vals);
251
252 if (!check_double_attrib(vals, 1, "glVertexAttribL1d"))
253 return GL_FALSE;
254
255 gen_float_values(fvals, 4);
256 glVertexAttrib4fv(Index, fvals);
257
258 gen_double_values(vals, 4);
259 glVertexAttribL4dv(Index, vals);
260
261 if (!check_double_attrib(vals, 1, "glVertexAttribL1d"))
262 return GL_FALSE;
263 return GL_TRUE;
264 }
265
266 /* write a double to an attribute slot,
267 * then write some floats, read them back,
268 * then rewrite the double, and read it back */
269 static GLboolean
test_attrib_mixed_2(void)270 test_attrib_mixed_2(void)
271 {
272 GLdouble vals[4];
273 GLfloat fvals[4];
274
275 gen_double_values(vals, 4);
276 glVertexAttribL4dv(Index, vals);
277
278 if (!check_double_attrib(vals, 1, "glVertexAttribL1d"))
279 return GL_FALSE;
280
281 gen_float_values(fvals, 4);
282 glVertexAttrib4fv(Index, fvals);
283
284 if (!check_float_attrib(fvals))
285 return GL_FALSE;
286
287 gen_double_values(vals, 4);
288 glVertexAttribL4dv(Index, vals);
289
290 if (!check_double_attrib(vals, 1, "glVertexAttribL1d"))
291 return GL_FALSE;
292 return GL_TRUE;
293 }
294
295 /* write a float to an attribute slot,
296 * then write a double. and read it back */
297 static GLboolean
test_attrib_mixed_3(void)298 test_attrib_mixed_3(void)
299 {
300 GLdouble vals[4];
301 GLfloat fvals[4];
302
303 gen_float_values(fvals, 4);
304 glVertexAttrib4fv(Index, fvals);
305
306 gen_double_values(vals, 4);
307 glVertexAttribL4dv(Index, vals);
308
309 if (!check_double_attrib(vals, 1, "glVertexAttribL1d"))
310 return GL_FALSE;
311 return GL_TRUE;
312 }
313
314 enum piglit_result
piglit_display(void)315 piglit_display(void)
316 {
317 return PIGLIT_FAIL;
318 }
319
320 void
piglit_init(int argc,char ** argv)321 piglit_init(int argc, char **argv)
322 {
323 int ret = PIGLIT_PASS;
324 piglit_require_extension("GL_ARB_vertex_attrib_64bit");
325
326 if (!test_attrib_funcs())
327 ret = PIGLIT_FAIL;
328
329 if (!test_attrib_array())
330 ret = PIGLIT_FAIL;
331
332 if (!test_attrib_mixed_1())
333 ret = PIGLIT_FAIL;
334
335 if (!test_attrib_mixed_2())
336 ret = PIGLIT_FAIL;
337
338 if (!test_attrib_mixed_3())
339 ret = PIGLIT_FAIL;
340
341 piglit_report_result(ret);
342 }
343