cl: Don't use device_infos if num_device_infos == 0
[piglit.git] / tests / general / draw-elements.c
blob66e0303e486a940796e7667dd825f0284a790b60
1 /*
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
13 * Software.
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.
23 * Authors:
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 offsets and various
29 * elements formats.
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 = GL_FALSE;
47 void piglit_init(int argc, char **argv)
49 unsigned i;
51 for (i = 1; i < argc; i++) {
52 if (!strcmp(argv[i], "user")) {
53 user = GL_TRUE;
54 puts("Testing user 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_ubyte_indices(float x1, float y1, float x2, float y2, int test)
68 bool use_multi = test / 4;
69 int index = test % 4;
70 float v[] = {
71 x1, y1,
72 x1, y2,
73 x2, y1,
75 x1, y1,
76 x1, y2,
77 x2, y1,
79 x1, y1,
80 x1, y2,
81 x2, y1,
83 x1, y1,
84 x1, y2,
85 x2, y1
87 unsigned char indx[] = {
88 /*aligned:*/ 0, 1, 2, /*unused:*/ 2,
89 2, 2, 3, 3,
90 3, /* unaligned:*/ 3, 4, 5,
91 /*unused:*/ 5, 5, 5, 6,
92 6, 6, /*unaligned:*/ 6, 7,
93 8, /*unused:*/ 8, 8, 8,
94 9, 9, 9, /*unaligned:*/ 9,
95 10, 11, /*unused:*/ 11, 11,
96 11, 11, 11, 11
98 GLuint buf;
100 glVertexPointer(2, GL_FLOAT, 0, v);
102 if (!user) {
103 glGenBuffers(1, &buf);
104 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
105 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indx), indx, GL_STATIC_DRAW);
106 if (use_multi) {
107 static const GLsizei count[] = {3, 3, 0};
108 /* We need 2 draws in order to get non-zero in
109 * pipe_draw_info::start, so make the second draw
110 * a zero-area triangle. */
111 const void *offset[] = {(void*)(intptr_t)(index*9),
112 (void*)(intptr_t)1,
113 (void*)(intptr_t)1};
114 glMultiDrawElements(GL_TRIANGLES, count,
115 GL_UNSIGNED_BYTE, offset,
116 ARRAY_SIZE(count));
117 } else {
118 glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE,
119 (void*)(intptr_t)(index*9));
121 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
122 glDeleteBuffers(1, &buf);
123 } else {
124 if (use_multi) {
125 static const GLsizei count[] = {3, 3, 0};
126 /* The second draw is a zero-area triangle. */
127 const void *indices[] = {indx + index*9, indx + 1, indx + 1};
128 glMultiDrawElements(GL_TRIANGLES, count,
129 GL_UNSIGNED_BYTE, indices,
130 ARRAY_SIZE(count));
131 } else {
132 glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE,
133 indx + index*9);
138 static void test_ushort_indices(float x1, float y1, float x2, float y2, int index)
140 float v[] = {
141 x1, y1,
142 x1, y2,
143 x2, y1,
145 x1, y1,
146 x1, y2,
147 x2, y1
149 unsigned short indx[] = {
150 /*aligned:*/ 0, 1,
151 2, /*unused:*/ 2,
152 2, 2,
153 3, 3,
154 3, /* unaligned:*/ 3,
155 4, 5,
156 /*unused:*/ 5, 5,
157 5, 5
159 GLuint buf;
161 glVertexPointer(2, GL_FLOAT, 0, v);
163 if (!user) {
164 glGenBuffers(1, &buf);
165 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
166 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indx), indx, GL_STATIC_DRAW);
167 glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, (void*)(intptr_t)(index*18));
168 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
169 glDeleteBuffers(1, &buf);
170 } else {
171 glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, (char*)indx + index*18);
175 static void test_large_index_count(float x1, float y1, float x2, float y2, int index)
177 float v[] = {
178 x1, y1,
179 x1, y2,
180 x2, y1
182 unsigned tris = 100000;
183 unsigned *indx = (unsigned*)malloc(sizeof(unsigned) * 3 * tris);
184 unsigned i;
186 /* A large index count for DrawElements */
187 for (i = 0; i < tris*3; i += 3) {
188 indx[i+0] = 0;
189 indx[i+1] = 1;
190 indx[i+2] = 2;
193 glVertexPointer(2, GL_FLOAT, 0, v);
194 glDrawElements(GL_TRIANGLES, tris*3, GL_UNSIGNED_INT, indx);
196 free(indx);
199 static void test_large_indexbuf_offset(float x1, float y1, float x2, float y2, int index)
201 float v[] = {
202 x1, y1,
203 x1, y2,
204 x2, y1
206 GLuint buf;
207 unsigned *map;
208 unsigned num = 1000000;
210 glGenBuffers(1, &buf);
211 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
212 glBufferData(GL_ELEMENT_ARRAY_BUFFER, num*4, 0, GL_STATIC_DRAW);
213 map = (unsigned*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
214 memset(map, 0, num*4);
215 map[num-2] = 1;
216 map[num-1] = 2;
217 glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
219 glVertexPointer(2, GL_FLOAT, 0, v);
220 glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, (void*)(intptr_t)((num-3)*4));
222 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
223 glDeleteBuffers(1, &buf);
226 enum {
227 USER,
228 VBO,
229 BOTH
231 struct test {
232 void (*test)(float x1, float y1, float x2, float y2, int index);
233 int index;
234 float expected_color[3];
235 int flag;
236 const char *name;
239 struct test tests[] = {
240 {test_ubyte_indices, 0, {1, 1, 1}, BOTH, "Ubyte indices - offset: 0"},
241 {test_ubyte_indices, 1, {1, 1, 1}, BOTH, "Ubyte indices - offset: 1"},
242 {test_ubyte_indices, 2, {1, 1, 1}, BOTH, "Ubyte indices - offset: 2"},
243 {test_ubyte_indices, 3, {1, 1, 1}, BOTH, "Ubyte indices - offset: 3"},
245 {test_ubyte_indices, 4, {1, 1, 1}, BOTH, "Ubyte indices - offset: 0 (glMultiDraw)"},
246 {test_ubyte_indices, 5, {1, 1, 1}, BOTH, "Ubyte indices - offset: 1 (glMultiDraw)"},
247 {test_ubyte_indices, 6, {1, 1, 1}, BOTH, "Ubyte indices - offset: 2 (glMultiDraw)"},
248 {test_ubyte_indices, 7, {1, 1, 1}, BOTH, "Ubyte indices - offset: 3 (glMultiDraw)"},
250 {test_ushort_indices, 0, {1, 1, 1}, BOTH, "Ushort indices - offset: 0"},
251 {test_ushort_indices, 1, {1, 1, 1}, BOTH, "Ushort indices - offset: 2"},
253 {test_large_index_count, 1, {1, 1, 1}, USER, "Large index count"},
254 {test_large_indexbuf_offset, 0, {1, 1, 1}, VBO, "Large index offset"},
259 enum piglit_result
260 piglit_display(void)
262 GLboolean pass = GL_TRUE;
263 unsigned i;
264 float x = 0, y = 0;
266 glClear(GL_COLOR_BUFFER_BIT);
267 glEnableClientState(GL_VERTEX_ARRAY);
269 for (i = 0; tests[i].test; i++) {
270 if (user && tests[i].flag == VBO)
271 continue;
272 if (!user && tests[i].flag == USER)
273 continue;
275 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
277 printf("%s\n", tests[i].name);
278 tests[i].test(x, y, x+20, y+20, tests[i].index);
279 if (!piglit_check_gl_error(GL_NO_ERROR))
280 piglit_report_result(PIGLIT_FAIL);
281 pass = piglit_probe_pixel_rgb(x+5, y+5, tests[i].expected_color) && pass;
283 x += 20;
284 if (x > 300) {
285 x = 0;
286 y += 20;
290 glFinish();
291 piglit_present_results();
293 return pass ? PIGLIT_PASS : PIGLIT_FAIL;