2 * Copyright © 2010 Marek Olšák <maraeo@gmail.com>
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
21 * DEALINGS IN THE SOFTWARE.
24 * Marek Olšák <maraeo@gmail.com>
27 /* The test for some tricky bits of the OpenGL vertex submission.
28 * The emphasis is taken on non-dword-aligned strides and offsets,
29 * but tests for various vertex formats are provided too.
32 #include "piglit-util-gl.h"
34 PIGLIT_GL_TEST_CONFIG_BEGIN
36 config
.supports_gl_compat_version
= 10;
38 config
.window_width
= 320;
39 config
.window_height
= 60;
40 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
| PIGLIT_GL_VISUAL_DOUBLE
;
41 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
43 PIGLIT_GL_TEST_CONFIG_END
45 GLboolean user_va
= GL_FALSE
;
47 void piglit_init(int argc
, char **argv
)
51 for (i
= 1; i
< argc
; i
++) {
52 if (!strcmp(argv
[i
], "user")) {
54 puts("Testing user vertex arrays.");
58 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
60 piglit_require_gl_version(15);
62 glShadeModel(GL_FLAT
);
63 glClearColor(0.2, 0.2, 0.2, 1.0);
66 static void test_large_vertex_count(float x1
, float y1
, float x2
, float y2
, int index
)
68 unsigned tris
= 100000;
69 float *v
= (float*)malloc(sizeof(float) * 6 * tris
);
72 /* A large vertex count for DrawArrays */
73 for (i
= 0; i
< tris
*6; i
+= 6) {
84 glVertexPointer(2, GL_FLOAT
, 0, v
);
85 glDrawArrays(GL_TRIANGLES
, 0, tris
*3);
90 static GLuint
vboVertexPointer(GLint size
, GLenum type
, GLsizei stride
,
91 const GLvoid
*buf
, GLsizei bufSize
, intptr_t bufOffset
)
95 glVertexPointer(size
, type
, stride
, (char*)buf
+ bufOffset
);
99 glBindBuffer(GL_ARRAY_BUFFER
, id
);
100 glBufferData(GL_ARRAY_BUFFER
, bufSize
, buf
, GL_STATIC_DRAW
);
101 glVertexPointer(size
, type
, stride
, (void*)bufOffset
);
105 static GLuint
vboColorPointer(GLint size
, GLenum type
, GLsizei stride
,
106 const GLvoid
*buf
, GLsizei bufSize
, intptr_t bufOffset
)
110 glColorPointer(size
, type
, stride
, (char*)buf
+ bufOffset
);
113 glGenBuffers(1, &id
);
114 glBindBuffer(GL_ARRAY_BUFFER
, id
);
115 glBufferData(GL_ARRAY_BUFFER
, bufSize
, buf
, GL_STATIC_DRAW
);
116 glColorPointer(size
, type
, stride
, (void*)bufOffset
);
120 static GLuint
vboVertexColorPointer(GLint vSize
, GLenum vType
, GLint vStride
, intptr_t vOffset
,
121 GLint cSize
, GLenum cType
, GLint cStride
, intptr_t cOffset
,
122 const GLvoid
*buf
, GLsizei bufSize
)
126 glVertexPointer(vSize
, vType
, vStride
, (char*)buf
+ vOffset
);
127 glColorPointer(cSize
, cType
, cStride
, (char*)buf
+ cOffset
);
130 glGenBuffers(1, &id
);
131 glBindBuffer(GL_ARRAY_BUFFER
, id
);
132 glBufferData(GL_ARRAY_BUFFER
, bufSize
, buf
, GL_STATIC_DRAW
);
133 glVertexPointer(vSize
, vType
, vStride
, (void*)vOffset
);
134 glColorPointer(cSize
, cType
, cStride
, (void*)cOffset
);
138 static void test_ubyte_colors(float x1
, float y1
, float x2
, float y2
, int index
)
145 unsigned char c3
[] = {
150 unsigned char c4
[] = {
155 unsigned char c3o1
[] = {
161 unsigned char c4o1
[] = {
167 unsigned char c3o2
[] = {
173 unsigned char c4o2
[] = {
179 unsigned char c3o3
[] = {
185 unsigned char c4o3
[] = {
193 glVertexPointer(2, GL_FLOAT
, 0, v
);
195 glEnableClientState(GL_COLOR_ARRAY
);
197 case 0: vbo
= vboColorPointer(3, GL_UNSIGNED_BYTE
, 3, c3
, sizeof(c3
), 0); break;
198 case 1: vbo
= vboColorPointer(3, GL_UNSIGNED_BYTE
, 4, c4
, sizeof(c4
), 0); break;
199 case 2: vbo
= vboColorPointer(4, GL_UNSIGNED_BYTE
, 4, c4
, sizeof(c4
), 0); break;
201 case 3: vbo
= vboColorPointer(3, GL_UNSIGNED_BYTE
, 3, c3o1
, sizeof(c3o1
), 1); break;
202 case 4: vbo
= vboColorPointer(3, GL_UNSIGNED_BYTE
, 4, c4o1
, sizeof(c4o1
), 1); break;
203 case 5: vbo
= vboColorPointer(4, GL_UNSIGNED_BYTE
, 4, c4o1
, sizeof(c4o1
), 1); break;
205 case 6: vbo
= vboColorPointer(3, GL_UNSIGNED_BYTE
, 3, c3o2
, sizeof(c3o2
), 2); break;
206 case 7: vbo
= vboColorPointer(3, GL_UNSIGNED_BYTE
, 4, c4o2
, sizeof(c4o2
), 2); break;
207 case 8: vbo
= vboColorPointer(4, GL_UNSIGNED_BYTE
, 4, c4o2
, sizeof(c4o2
), 2); break;
209 case 9: vbo
= vboColorPointer(3, GL_UNSIGNED_BYTE
, 3, c3o3
, sizeof(c3o3
), 3); break;
210 case 10:vbo
= vboColorPointer(3, GL_UNSIGNED_BYTE
, 4, c4o3
, sizeof(c4o3
), 3); break;
211 case 11:vbo
= vboColorPointer(4, GL_UNSIGNED_BYTE
, 4, c4o3
, sizeof(c4o3
), 3); break;
213 default:vbo
= 0; assert(0); break;
216 glDrawArrays(GL_TRIANGLES
, 0, 3);
218 glDisableClientState(GL_COLOR_ARRAY
);
220 glDeleteBuffers(1, &vbo
);
223 static void test_short_vertices(float x1
, float y1
, float x2
, float y2
, int index
)
261 case 0: vbo
= vboVertexPointer(2, GL_SHORT
, 4, v2
, sizeof(v2
), 0); break;
263 case 1: vbo
= vboVertexPointer(2, GL_SHORT
, 6, v3
, sizeof(v3
), 0); break;
264 case 2: vbo
= vboVertexPointer(3, GL_SHORT
, 6, v3
, sizeof(v3
), 0); break;
266 case 3: vbo
= vboVertexPointer(2, GL_SHORT
, 8, v4
, sizeof(v4
), 0); break;
267 case 4: vbo
= vboVertexPointer(3, GL_SHORT
, 8, v4
, sizeof(v4
), 0); break;
268 case 5: vbo
= vboVertexPointer(4, GL_SHORT
, 8, v4
, sizeof(v4
), 0); break;
270 case 6: vbo
= vboVertexPointer(2, GL_SHORT
, 4, v2o
, sizeof(v2o
), 2); break;
272 case 7: vbo
= vboVertexPointer(2, GL_SHORT
, 6, v3o
, sizeof(v3o
), 2); break;
273 case 8: vbo
= vboVertexPointer(3, GL_SHORT
, 6, v3o
, sizeof(v3o
), 2); break;
275 case 9: vbo
= vboVertexPointer(2, GL_SHORT
, 8, v4o
, sizeof(v4o
), 2); break;
276 case 10:vbo
= vboVertexPointer(3, GL_SHORT
, 8, v4o
, sizeof(v4o
), 2); break;
277 case 11:vbo
= vboVertexPointer(4, GL_SHORT
, 8, v4o
, sizeof(v4o
), 2); break;
279 default:vbo
= 0; assert(0); break;
282 glDrawArrays(GL_TRIANGLES
, 0, 3);
285 glDeleteBuffers(1, &vbo
);
288 static void test_int_vertices(float x1
, float y1
, float x2
, float y2
, int index
)
326 case 0: vbo
= vboVertexPointer(2, GL_INT
, 8, v2
, sizeof(v2
), 0); break;
327 case 1: vbo
= vboVertexPointer(3, GL_INT
, 12, v3
, sizeof(v3
), 0); break;
328 case 2: vbo
= vboVertexPointer(4, GL_INT
, 16, v4
, sizeof(v4
), 0); break;
329 case 3: vbo
= vboVertexPointer(2, GL_INT
, 8, v2o
, sizeof(v2o
), 4); break;
330 case 4: vbo
= vboVertexPointer(3, GL_INT
, 12, v3o
, sizeof(v3o
), 4); break;
331 case 5: vbo
= vboVertexPointer(4, GL_INT
, 16, v4o
, sizeof(v4o
), 4); break;
332 default: vbo
= 0; assert(0); break;
335 glDrawArrays(GL_TRIANGLES
, 0, 3);
338 glDeleteBuffers(1, &vbo
);
341 static void test_double_vertices(float x1
, float y1
, float x2
, float y2
, int index
)
397 case 0: vbo
= vboVertexPointer(2, GL_DOUBLE
, 16, v2
, sizeof(v2
), 0); break;
398 case 1: vbo
= vboVertexPointer(3, GL_DOUBLE
, 24, v3
, sizeof(v3
), 0); break;
399 case 2: vbo
= vboVertexPointer(4, GL_DOUBLE
, 32, v4
, sizeof(v4
), 0); break;
400 case 3: vbo
= vboVertexPointer(2, GL_DOUBLE
, 16, v2o
, sizeof(v2o
), 8); break;
401 case 4: vbo
= vboVertexPointer(3, GL_DOUBLE
, 24, v3o
, sizeof(v3o
), 8); break;
402 case 5: vbo
= vboVertexPointer(4, GL_DOUBLE
, 32, v4o
, sizeof(v4o
), 8); break;
403 case 6: vbo
= vboVertexPointer(2, GL_DOUBLE
, 16, v2s
, sizeof(v2s
), 0); break;
404 case 7: vbo
= vboVertexPointer(3, GL_DOUBLE
, 24, v3s
, sizeof(v3s
), 0); break;
405 case 8: vbo
= vboVertexPointer(4, GL_DOUBLE
, 32, v4s
, sizeof(v4s
), 0); break;
406 default: vbo
= 0; assert(0); break;
410 glDrawArrays(GL_TRIANGLES
, 0, 3);
412 glDrawArrays(GL_TRIANGLES
, 1, 3);
415 glDeleteBuffers(1, &vbo
);
418 static void test_interleaved_vertices(float x1
, float y1
, float x2
, float y2
, int index
)
420 static const unsigned int offset
[] = {4, 5, 6, 8};
434 /* Set color green */
435 for (i
= 0; i
< 3; ++i
)
436 v
[i
].c
[offset
[index
] - 3] = 0xff;
438 glEnableClientState(GL_COLOR_ARRAY
);
439 vbo
= vboVertexColorPointer(2, GL_SHORT
, sizeof(struct vertex
), 0,
440 3, GL_UNSIGNED_BYTE
, sizeof(struct vertex
), offset
[index
],
443 glDrawArrays(GL_TRIANGLES
, 0, 3);
445 glDisableClientState(GL_COLOR_ARRAY
);
447 glDeleteBuffers(1, &vbo
);
450 static void test_mixed_user_and_vbo_buffers(float x1
, float y1
, float x2
, float y2
, int index
)
464 glEnableClientState(GL_COLOR_ARRAY
);
467 glColorPointer(3, GL_FLOAT
, 0, c3
);
468 vbo
= vboVertexPointer(3, GL_FLOAT
, 0, v3
, sizeof(v3
), 0);
470 glVertexPointer(3, GL_FLOAT
, 0, v3
);
471 vbo
= vboColorPointer(3, GL_FLOAT
, 0, c3
, sizeof(c3
), 0);
474 glDrawArrays(GL_TRIANGLES
, 0, 3);
476 glDisableClientState(GL_COLOR_ARRAY
);
478 glDeleteBuffers(1, &vbo
);
487 void (*test
)(float x1
, float y1
, float x2
, float y2
, int index
);
489 float expected_color
[3];
494 struct test tests
[] = {
495 {test_ubyte_colors
, 0, {1, 0, 0}, BOTH
, "Ubyte colors - components: 3, stride: 3,"},
496 {test_ubyte_colors
, 1, {1, 0, 0}, BOTH
, "Ubyte colors - components: 3, stride: 4,"},
497 {test_ubyte_colors
, 2, {1, 0, 0}, BOTH
, "Ubyte colors - components: 4, stride: 4,"},
498 {test_ubyte_colors
, 3, {1, 0, 0}, BOTH
, "Ubyte colors - components: 3, stride: 3, offset: 1"},
499 {test_ubyte_colors
, 4, {1, 0, 0}, BOTH
, "Ubyte colors - components: 3, stride: 4, offset: 1"},
500 {test_ubyte_colors
, 5, {1, 0, 0}, BOTH
, "Ubyte colors - components: 4, stride: 4, offset: 1"},
501 {test_ubyte_colors
, 6, {1, 0, 0}, BOTH
, "Ubyte colors - components: 3, stride: 3, offset: 2"},
502 {test_ubyte_colors
, 7, {1, 0, 0}, BOTH
, "Ubyte colors - components: 3, stride: 4, offset: 2"},
503 {test_ubyte_colors
, 8, {1, 0, 0}, BOTH
, "Ubyte colors - components: 4, stride: 4, offset: 2"},
504 {test_ubyte_colors
, 9, {1, 0, 0}, BOTH
, "Ubyte colors - components: 3, stride: 3, offset: 3"},
505 {test_ubyte_colors
, 10, {1, 0, 0}, BOTH
, "Ubyte colors - components: 3, stride: 4, offset: 3"},
506 {test_ubyte_colors
, 11, {1, 0, 0}, BOTH
, "Ubyte colors - components: 4, stride: 4, offset: 3"},
508 {test_short_vertices
, 0, {1, 1, 1}, BOTH
, "Short vertices - components: 2, stride: 4,"},
509 {test_short_vertices
, 1, {1, 1, 1}, BOTH
, "Short vertices - components: 2, stride: 6,"},
510 {test_short_vertices
, 2, {1, 1, 1}, BOTH
, "Short vertices - components: 3, stride: 6,"},
511 {test_short_vertices
, 3, {1, 1, 1}, BOTH
, "Short vertices - components: 2, stride: 8,"},
512 {test_short_vertices
, 4, {1, 1, 1}, BOTH
, "Short vertices - components: 3, stride: 8,"},
513 {test_short_vertices
, 5, {1, 1, 1}, BOTH
, "Short vertices - components: 4, stride: 8,"},
514 {test_short_vertices
, 6, {1, 1, 1}, BOTH
, "Short vertices - components: 2, stride: 4, offset: 2"},
515 {test_short_vertices
, 7, {1, 1, 1}, BOTH
, "Short vertices - components: 2, stride: 6, offset: 2"},
516 {test_short_vertices
, 8, {1, 1, 1}, BOTH
, "Short vertices - components: 3, stride: 6, offset: 2"},
517 {test_short_vertices
, 9, {1, 1, 1}, BOTH
, "Short vertices - components: 2, stride: 8, offset: 2"},
518 {test_short_vertices
, 10, {1, 1, 1}, BOTH
, "Short vertices - components: 3, stride: 8, offset: 2"},
519 {test_short_vertices
, 11, {1, 1, 1}, BOTH
, "Short vertices - components: 4, stride: 8, offset: 2"},
521 {test_int_vertices
, 0, {1, 1, 1}, BOTH
, "Int vertices - components: 2, stride: 8"},
522 {test_int_vertices
, 1, {1, 1, 1}, BOTH
, "Int vertices - components: 3, stride: 12"},
523 {test_int_vertices
, 2, {1, 1, 1}, BOTH
, "Int vertices - components: 4, stride: 16"},
524 {test_int_vertices
, 3, {1, 1, 1}, BOTH
, "Int vertices - components: 2, stride: 8, offset: 4"},
525 {test_int_vertices
, 4, {1, 1, 1}, BOTH
, "Int vertices - components: 3, stride: 12, offset: 4"},
526 {test_int_vertices
, 5, {1, 1, 1}, BOTH
, "Int vertices - components: 4, stride: 16, offset: 4"},
528 {test_double_vertices
, 0, {1, 1, 1}, BOTH
, "Double vertices - components: 2, stride: 16"},
529 {test_double_vertices
, 1, {1, 1, 1}, BOTH
, "Double vertices - components: 3, stride: 24"},
530 {test_double_vertices
, 2, {1, 1, 1}, BOTH
, "Double vertices - components: 4, stride: 32"},
531 {test_double_vertices
, 3, {1, 1, 1}, BOTH
, "Double vertices - components: 2, stride: 16, offset: 8"},
532 {test_double_vertices
, 4, {1, 1, 1}, BOTH
, "Double vertices - components: 3, stride: 24, offset: 8"},
533 {test_double_vertices
, 5, {1, 1, 1}, BOTH
, "Double vertices - components: 4, stride: 32, offset: 8"},
534 {test_double_vertices
, 6, {1, 1, 1}, BOTH
, "Double vertices - components: 2, stride: 16, start: 1"},
535 {test_double_vertices
, 7, {1, 1, 1}, BOTH
, "Double vertices - components: 3, stride: 24, start: 1"},
536 {test_double_vertices
, 8, {1, 1, 1}, BOTH
, "Double vertices - components: 4, stride: 32, start: 1"},
538 {test_interleaved_vertices
, 0, {0, 1, 0}, BOTH
, "Interleaved VBO - gap: 0"},
539 {test_interleaved_vertices
, 1, {0, 1, 0}, BOTH
, "Interleaved VBO - gap: 1"},
540 {test_interleaved_vertices
, 2, {0, 1, 0}, BOTH
, "Interleaved VBO - gap: 2"},
541 {test_interleaved_vertices
, 3, {0, 1, 0}, BOTH
, "Interleaved VBO - gap: 4"},
543 {test_mixed_user_and_vbo_buffers
, 0, {0, 0, 1}, BOTH
, "Mixed buffers - 0: vbo, 1: user"},
544 {test_mixed_user_and_vbo_buffers
, 1, {0, 0, 1}, BOTH
, "Mixed buffers - 0: user, 1: vbo"},
546 {test_large_vertex_count
, 0, {1, 1, 1}, USER
, "Large vertex count"},
554 GLboolean pass
= GL_TRUE
;
558 glClear(GL_COLOR_BUFFER_BIT
);
559 glEnableClientState(GL_VERTEX_ARRAY
);
561 for (i
= 0; tests
[i
].test
; i
++) {
562 if (!user_va
&& tests
[i
].flag
== USER
)
565 glBindBuffer(GL_ARRAY_BUFFER
, 0);
567 printf("%s\n", tests
[i
].name
);
568 tests
[i
].test(x
, y
, x
+20, y
+20, tests
[i
].index
);
569 if (!piglit_check_gl_error(GL_NO_ERROR
))
570 piglit_report_result(PIGLIT_FAIL
);
571 pass
= piglit_probe_pixel_rgb(x
+5, y
+5, tests
[i
].expected_color
) && pass
;
581 piglit_present_results();
583 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;