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