mesa/es3: Add support for GL_PRIMITIVE_RESTART_FIXED_INDEX
[mesa.git] / src / mesa / vbo / vbo_exec_array.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * Copyright 2009 VMware, Inc.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 **************************************************************************/
28
29 #include "main/glheader.h"
30 #include "main/context.h"
31 #include "main/state.h"
32 #include "main/api_validate.h"
33 #include "main/varray.h"
34 #include "main/bufferobj.h"
35 #include "main/enums.h"
36 #include "main/macros.h"
37 #include "main/transformfeedback.h"
38
39 #include "vbo_context.h"
40
41
42 /**
43 * All vertex buffers should be in an unmapped state when we're about
44 * to draw. This debug function checks that.
45 */
46 static void
47 check_buffers_are_unmapped(const struct gl_client_array **inputs)
48 {
49 #ifdef DEBUG
50 GLuint i;
51
52 for (i = 0; i < VERT_ATTRIB_MAX; i++) {
53 if (inputs[i]) {
54 struct gl_buffer_object *obj = inputs[i]->BufferObj;
55 assert(!_mesa_bufferobj_mapped(obj));
56 (void) obj;
57 }
58 }
59 #endif
60 }
61
62
63 /**
64 * A debug function that may be called from other parts of Mesa as
65 * needed during debugging.
66 */
67 void
68 vbo_check_buffers_are_unmapped(struct gl_context *ctx)
69 {
70 struct vbo_context *vbo = vbo_context(ctx);
71 struct vbo_exec_context *exec = &vbo->exec;
72 /* check the current vertex arrays */
73 check_buffers_are_unmapped(exec->array.inputs);
74 /* check the current glBegin/glVertex/glEnd-style VBO */
75 assert(!_mesa_bufferobj_mapped(exec->vtx.bufferobj));
76 }
77
78
79
80 /**
81 * Compute min and max elements by scanning the index buffer for
82 * glDraw[Range]Elements() calls.
83 * If primitive restart is enabled, we need to ignore restart
84 * indexes when computing min/max.
85 */
86 static void
87 vbo_get_minmax_index(struct gl_context *ctx,
88 const struct _mesa_prim *prim,
89 const struct _mesa_index_buffer *ib,
90 GLuint *min_index, GLuint *max_index,
91 const GLuint count)
92 {
93 const GLboolean restart = ctx->Array._PrimitiveRestart;
94 const GLuint restartIndex = ctx->Array._RestartIndex;
95 const int index_size = vbo_sizeof_ib_type(ib->type);
96 const char *indices;
97 GLuint i;
98
99 indices = (char *) ib->ptr + prim->start * index_size;
100 if (_mesa_is_bufferobj(ib->obj)) {
101 GLsizeiptr size = MIN2(count * index_size, ib->obj->Size);
102 indices = ctx->Driver.MapBufferRange(ctx, (GLintptr) indices, size,
103 GL_MAP_READ_BIT, ib->obj);
104 }
105
106 switch (ib->type) {
107 case GL_UNSIGNED_INT: {
108 const GLuint *ui_indices = (const GLuint *)indices;
109 GLuint max_ui = 0;
110 GLuint min_ui = ~0U;
111 if (restart) {
112 for (i = 0; i < count; i++) {
113 if (ui_indices[i] != restartIndex) {
114 if (ui_indices[i] > max_ui) max_ui = ui_indices[i];
115 if (ui_indices[i] < min_ui) min_ui = ui_indices[i];
116 }
117 }
118 }
119 else {
120 for (i = 0; i < count; i++) {
121 if (ui_indices[i] > max_ui) max_ui = ui_indices[i];
122 if (ui_indices[i] < min_ui) min_ui = ui_indices[i];
123 }
124 }
125 *min_index = min_ui;
126 *max_index = max_ui;
127 break;
128 }
129 case GL_UNSIGNED_SHORT: {
130 const GLushort *us_indices = (const GLushort *)indices;
131 GLuint max_us = 0;
132 GLuint min_us = ~0U;
133 if (restart) {
134 for (i = 0; i < count; i++) {
135 if (us_indices[i] != restartIndex) {
136 if (us_indices[i] > max_us) max_us = us_indices[i];
137 if (us_indices[i] < min_us) min_us = us_indices[i];
138 }
139 }
140 }
141 else {
142 for (i = 0; i < count; i++) {
143 if (us_indices[i] > max_us) max_us = us_indices[i];
144 if (us_indices[i] < min_us) min_us = us_indices[i];
145 }
146 }
147 *min_index = min_us;
148 *max_index = max_us;
149 break;
150 }
151 case GL_UNSIGNED_BYTE: {
152 const GLubyte *ub_indices = (const GLubyte *)indices;
153 GLuint max_ub = 0;
154 GLuint min_ub = ~0U;
155 if (restart) {
156 for (i = 0; i < count; i++) {
157 if (ub_indices[i] != restartIndex) {
158 if (ub_indices[i] > max_ub) max_ub = ub_indices[i];
159 if (ub_indices[i] < min_ub) min_ub = ub_indices[i];
160 }
161 }
162 }
163 else {
164 for (i = 0; i < count; i++) {
165 if (ub_indices[i] > max_ub) max_ub = ub_indices[i];
166 if (ub_indices[i] < min_ub) min_ub = ub_indices[i];
167 }
168 }
169 *min_index = min_ub;
170 *max_index = max_ub;
171 break;
172 }
173 default:
174 assert(0);
175 break;
176 }
177
178 if (_mesa_is_bufferobj(ib->obj)) {
179 ctx->Driver.UnmapBuffer(ctx, ib->obj);
180 }
181 }
182
183 /**
184 * Compute min and max elements for nr_prims
185 */
186 void
187 vbo_get_minmax_indices(struct gl_context *ctx,
188 const struct _mesa_prim *prims,
189 const struct _mesa_index_buffer *ib,
190 GLuint *min_index,
191 GLuint *max_index,
192 GLuint nr_prims)
193 {
194 GLuint tmp_min, tmp_max;
195 GLuint i;
196 GLuint count;
197
198 *min_index = ~0;
199 *max_index = 0;
200
201 for (i = 0; i < nr_prims; i++) {
202 const struct _mesa_prim *start_prim;
203
204 start_prim = &prims[i];
205 count = start_prim->count;
206 /* Do combination if possible to reduce map/unmap count */
207 while ((i + 1 < nr_prims) &&
208 (prims[i].start + prims[i].count == prims[i+1].start)) {
209 count += prims[i+1].count;
210 i++;
211 }
212 vbo_get_minmax_index(ctx, start_prim, ib, &tmp_min, &tmp_max, count);
213 *min_index = MIN2(*min_index, tmp_min);
214 *max_index = MAX2(*max_index, tmp_max);
215 }
216 }
217
218
219 /**
220 * Check that element 'j' of the array has reasonable data.
221 * Map VBO if needed.
222 * For debugging purposes; not normally used.
223 */
224 static void
225 check_array_data(struct gl_context *ctx, struct gl_client_array *array,
226 GLuint attrib, GLuint j)
227 {
228 if (array->Enabled) {
229 const void *data = array->Ptr;
230 if (_mesa_is_bufferobj(array->BufferObj)) {
231 if (!array->BufferObj->Pointer) {
232 /* need to map now */
233 array->BufferObj->Pointer =
234 ctx->Driver.MapBufferRange(ctx, 0, array->BufferObj->Size,
235 GL_MAP_READ_BIT, array->BufferObj);
236 }
237 data = ADD_POINTERS(data, array->BufferObj->Pointer);
238 }
239 switch (array->Type) {
240 case GL_FLOAT:
241 {
242 GLfloat *f = (GLfloat *) ((GLubyte *) data + array->StrideB * j);
243 GLint k;
244 for (k = 0; k < array->Size; k++) {
245 if (IS_INF_OR_NAN(f[k]) ||
246 f[k] >= 1.0e20 || f[k] <= -1.0e10) {
247 printf("Bad array data:\n");
248 printf(" Element[%u].%u = %f\n", j, k, f[k]);
249 printf(" Array %u at %p\n", attrib, (void* ) array);
250 printf(" Type 0x%x, Size %d, Stride %d\n",
251 array->Type, array->Size, array->Stride);
252 printf(" Address/offset %p in Buffer Object %u\n",
253 array->Ptr, array->BufferObj->Name);
254 f[k] = 1.0; /* XXX replace the bad value! */
255 }
256 /*assert(!IS_INF_OR_NAN(f[k]));*/
257 }
258 }
259 break;
260 default:
261 ;
262 }
263 }
264 }
265
266
267 /**
268 * Unmap the buffer object referenced by given array, if mapped.
269 */
270 static void
271 unmap_array_buffer(struct gl_context *ctx, struct gl_client_array *array)
272 {
273 if (array->Enabled &&
274 _mesa_is_bufferobj(array->BufferObj) &&
275 _mesa_bufferobj_mapped(array->BufferObj)) {
276 ctx->Driver.UnmapBuffer(ctx, array->BufferObj);
277 }
278 }
279
280
281 /**
282 * Examine the array's data for NaNs, etc.
283 * For debug purposes; not normally used.
284 */
285 static void
286 check_draw_elements_data(struct gl_context *ctx, GLsizei count, GLenum elemType,
287 const void *elements, GLint basevertex)
288 {
289 struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
290 const void *elemMap;
291 GLint i, k;
292
293 if (_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj)) {
294 elemMap = ctx->Driver.MapBufferRange(ctx, 0,
295 ctx->Array.ArrayObj->ElementArrayBufferObj->Size,
296 GL_MAP_READ_BIT,
297 ctx->Array.ArrayObj->ElementArrayBufferObj);
298 elements = ADD_POINTERS(elements, elemMap);
299 }
300
301 for (i = 0; i < count; i++) {
302 GLuint j;
303
304 /* j = element[i] */
305 switch (elemType) {
306 case GL_UNSIGNED_BYTE:
307 j = ((const GLubyte *) elements)[i];
308 break;
309 case GL_UNSIGNED_SHORT:
310 j = ((const GLushort *) elements)[i];
311 break;
312 case GL_UNSIGNED_INT:
313 j = ((const GLuint *) elements)[i];
314 break;
315 default:
316 assert(0);
317 }
318
319 /* check element j of each enabled array */
320 for (k = 0; k < Elements(arrayObj->VertexAttrib); k++) {
321 check_array_data(ctx, &arrayObj->VertexAttrib[k], k, j);
322 }
323 }
324
325 if (_mesa_is_bufferobj(arrayObj->ElementArrayBufferObj)) {
326 ctx->Driver.UnmapBuffer(ctx, ctx->Array.ArrayObj->ElementArrayBufferObj);
327 }
328
329 for (k = 0; k < Elements(arrayObj->VertexAttrib); k++) {
330 unmap_array_buffer(ctx, &arrayObj->VertexAttrib[k]);
331 }
332 }
333
334
335 /**
336 * Check array data, looking for NaNs, etc.
337 */
338 static void
339 check_draw_arrays_data(struct gl_context *ctx, GLint start, GLsizei count)
340 {
341 /* TO DO */
342 }
343
344
345 /**
346 * Print info/data for glDrawArrays(), for debugging.
347 */
348 static void
349 print_draw_arrays(struct gl_context *ctx,
350 GLenum mode, GLint start, GLsizei count)
351 {
352 struct vbo_context *vbo = vbo_context(ctx);
353 struct vbo_exec_context *exec = &vbo->exec;
354 struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
355 int i;
356
357 printf("vbo_exec_DrawArrays(mode 0x%x, start %d, count %d):\n",
358 mode, start, count);
359
360 for (i = 0; i < 32; i++) {
361 struct gl_buffer_object *bufObj = exec->array.inputs[i]->BufferObj;
362 GLuint bufName = bufObj->Name;
363 GLint stride = exec->array.inputs[i]->Stride;
364 printf("attr %2d: size %d stride %d enabled %d "
365 "ptr %p Bufobj %u\n",
366 i,
367 exec->array.inputs[i]->Size,
368 stride,
369 /*exec->array.inputs[i]->Enabled,*/
370 arrayObj->VertexAttrib[VERT_ATTRIB_FF(i)].Enabled,
371 exec->array.inputs[i]->Ptr,
372 bufName);
373
374 if (bufName) {
375 GLubyte *p = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size,
376 GL_MAP_READ_BIT, bufObj);
377 int offset = (int) (GLintptr) exec->array.inputs[i]->Ptr;
378 float *f = (float *) (p + offset);
379 int *k = (int *) f;
380 int i;
381 int n = (count * stride) / 4;
382 if (n > 32)
383 n = 32;
384 printf(" Data at offset %d:\n", offset);
385 for (i = 0; i < n; i++) {
386 printf(" float[%d] = 0x%08x %f\n", i, k[i], f[i]);
387 }
388 ctx->Driver.UnmapBuffer(ctx, bufObj);
389 }
390 }
391 }
392
393
394 /**
395 * Set the vbo->exec->inputs[] pointers to point to the enabled
396 * vertex arrays. This depends on the current vertex program/shader
397 * being executed because of whether or not generic vertex arrays
398 * alias the conventional vertex arrays.
399 * For arrays that aren't enabled, we set the input[attrib] pointer
400 * to point at a zero-stride current value "array".
401 */
402 static void
403 recalculate_input_bindings(struct gl_context *ctx)
404 {
405 struct vbo_context *vbo = vbo_context(ctx);
406 struct vbo_exec_context *exec = &vbo->exec;
407 struct gl_client_array *vertexAttrib = ctx->Array.ArrayObj->VertexAttrib;
408 const struct gl_client_array **inputs = &exec->array.inputs[0];
409 GLbitfield64 const_inputs = 0x0;
410 GLuint i;
411
412 switch (get_program_mode(ctx)) {
413 case VP_NONE:
414 /* When no vertex program is active (or the vertex program is generated
415 * from fixed-function state). We put the material values into the
416 * generic slots. This is the only situation where material values
417 * are available as per-vertex attributes.
418 */
419 for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) {
420 if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled)
421 inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)];
422 else {
423 inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i];
424 const_inputs |= VERT_BIT(i);
425 }
426 }
427
428 for (i = 0; i < MAT_ATTRIB_MAX; i++) {
429 inputs[VERT_ATTRIB_GENERIC(i)] =
430 &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT+i];
431 const_inputs |= VERT_BIT_GENERIC(i);
432 }
433
434 /* Could use just about anything, just to fill in the empty
435 * slots:
436 */
437 for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_GENERIC_MAX; i++) {
438 inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i];
439 const_inputs |= VERT_BIT_GENERIC(i);
440 }
441 break;
442
443 case VP_ARB:
444 /* GL_ARB_vertex_program or GLSL vertex shader - Only the generic[0]
445 * attribute array aliases and overrides the legacy position array.
446 *
447 * Otherwise, legacy attributes available in the legacy slots,
448 * generic attributes in the generic slots and materials are not
449 * available as per-vertex attributes.
450 */
451 if (vertexAttrib[VERT_ATTRIB_GENERIC0].Enabled)
452 inputs[0] = &vertexAttrib[VERT_ATTRIB_GENERIC0];
453 else if (vertexAttrib[VERT_ATTRIB_POS].Enabled)
454 inputs[0] = &vertexAttrib[VERT_ATTRIB_POS];
455 else {
456 inputs[0] = &vbo->currval[VBO_ATTRIB_POS];
457 const_inputs |= VERT_BIT_POS;
458 }
459
460 for (i = 1; i < VERT_ATTRIB_FF_MAX; i++) {
461 if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled)
462 inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)];
463 else {
464 inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i];
465 const_inputs |= VERT_BIT_FF(i);
466 }
467 }
468
469 for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) {
470 if (vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled)
471 inputs[VERT_ATTRIB_GENERIC(i)] = &vertexAttrib[VERT_ATTRIB_GENERIC(i)];
472 else {
473 inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i];
474 const_inputs |= VERT_BIT_GENERIC(i);
475 }
476 }
477
478 inputs[VERT_ATTRIB_GENERIC0] = inputs[0];
479 break;
480 }
481
482 _mesa_set_varying_vp_inputs( ctx, VERT_BIT_ALL & (~const_inputs) );
483 ctx->NewDriverState |= ctx->DriverFlags.NewArray;
484 }
485
486
487 /**
488 * Examine the enabled vertex arrays to set the exec->array.inputs[] values.
489 * These will point to the arrays to actually use for drawing. Some will
490 * be user-provided arrays, other will be zero-stride const-valued arrays.
491 * Note that this might set the _NEW_VARYING_VP_INPUTS dirty flag so state
492 * validation must be done after this call.
493 */
494 void
495 vbo_bind_arrays(struct gl_context *ctx)
496 {
497 struct vbo_context *vbo = vbo_context(ctx);
498 struct vbo_exec_context *exec = &vbo->exec;
499
500 vbo_draw_method(vbo, DRAW_ARRAYS);
501
502 if (exec->array.recalculate_inputs) {
503 recalculate_input_bindings(ctx);
504
505 /* Again... because we may have changed the bitmask of per-vertex varying
506 * attributes. If we regenerate the fixed-function vertex program now
507 * we may be able to prune down the number of vertex attributes which we
508 * need in the shader.
509 */
510 if (ctx->NewState) {
511 _mesa_update_state(ctx);
512 }
513
514 exec->array.recalculate_inputs = GL_FALSE;
515 }
516 }
517
518
519 /**
520 * Handle a draw case that potentially has primitive restart enabled.
521 *
522 * If primitive restart is enabled, and PrimitiveRestartInSoftware is
523 * set, then vbo_sw_primitive_restart is used to handle the primitive
524 * restart case in software.
525 */
526 static void
527 vbo_handle_primitive_restart(struct gl_context *ctx,
528 const struct _mesa_prim *prim,
529 GLuint nr_prims,
530 const struct _mesa_index_buffer *ib,
531 GLboolean index_bounds_valid,
532 GLuint min_index,
533 GLuint max_index)
534 {
535 struct vbo_context *vbo = vbo_context(ctx);
536
537 if ((ib != NULL) &&
538 ctx->Const.PrimitiveRestartInSoftware &&
539 ctx->Array._PrimitiveRestart) {
540 /* Handle primitive restart in software */
541 vbo_sw_primitive_restart(ctx, prim, nr_prims, ib);
542 } else {
543 /* Call driver directly for draw_prims */
544 vbo->draw_prims(ctx, prim, nr_prims, ib,
545 index_bounds_valid, min_index, max_index, NULL);
546 }
547 }
548
549
550 /**
551 * Helper function called by the other DrawArrays() functions below.
552 * This is where we handle primitive restart for drawing non-indexed
553 * arrays. If primitive restart is enabled, it typically means
554 * splitting one DrawArrays() into two.
555 */
556 static void
557 vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
558 GLsizei count, GLuint numInstances, GLuint baseInstance)
559 {
560 struct vbo_context *vbo = vbo_context(ctx);
561 struct vbo_exec_context *exec = &vbo->exec;
562 struct _mesa_prim prim[2];
563
564 vbo_bind_arrays(ctx);
565
566 /* init most fields to zero */
567 memset(prim, 0, sizeof(prim));
568 prim[0].begin = 1;
569 prim[0].end = 1;
570 prim[0].mode = mode;
571 prim[0].num_instances = numInstances;
572 prim[0].base_instance = baseInstance;
573
574 /* Implement the primitive restart index */
575 if (ctx->Array._PrimitiveRestart && ctx->Array._RestartIndex < count) {
576 GLuint primCount = 0;
577
578 if (ctx->Array._RestartIndex == start) {
579 /* special case: RestartIndex at beginning */
580 if (count > 1) {
581 prim[0].start = start + 1;
582 prim[0].count = count - 1;
583 primCount = 1;
584 }
585 }
586 else if (ctx->Array._RestartIndex == start + count - 1) {
587 /* special case: RestartIndex at end */
588 if (count > 1) {
589 prim[0].start = start;
590 prim[0].count = count - 1;
591 primCount = 1;
592 }
593 }
594 else {
595 /* general case: RestartIndex in middle, split into two prims */
596 prim[0].start = start;
597 prim[0].count = ctx->Array._RestartIndex - start;
598
599 prim[1] = prim[0];
600 prim[1].start = ctx->Array._RestartIndex + 1;
601 prim[1].count = count - prim[1].start;
602
603 primCount = 2;
604 }
605
606 if (primCount > 0) {
607 /* draw one or two prims */
608 check_buffers_are_unmapped(exec->array.inputs);
609 vbo->draw_prims(ctx, prim, primCount, NULL,
610 GL_TRUE, start, start + count - 1, NULL);
611 }
612 }
613 else {
614 /* no prim restart */
615 prim[0].start = start;
616 prim[0].count = count;
617
618 check_buffers_are_unmapped(exec->array.inputs);
619 vbo->draw_prims(ctx, prim, 1, NULL,
620 GL_TRUE, start, start + count - 1,
621 NULL);
622 }
623
624 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
625 _mesa_flush(ctx);
626 }
627 }
628
629
630
631 /**
632 * Called from glDrawArrays when in immediate mode (not display list mode).
633 */
634 static void GLAPIENTRY
635 vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
636 {
637 GET_CURRENT_CONTEXT(ctx);
638
639 if (MESA_VERBOSE & VERBOSE_DRAW)
640 _mesa_debug(ctx, "glDrawArrays(%s, %d, %d)\n",
641 _mesa_lookup_enum_by_nr(mode), start, count);
642
643 if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
644 return;
645
646 if (0)
647 check_draw_arrays_data(ctx, start, count);
648
649 vbo_draw_arrays(ctx, mode, start, count, 1, 0);
650
651 if (0)
652 print_draw_arrays(ctx, mode, start, count);
653 }
654
655
656 /**
657 * Called from glDrawArraysInstanced when in immediate mode (not
658 * display list mode).
659 */
660 static void GLAPIENTRY
661 vbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count,
662 GLsizei numInstances)
663 {
664 GET_CURRENT_CONTEXT(ctx);
665
666 if (MESA_VERBOSE & VERBOSE_DRAW)
667 _mesa_debug(ctx, "glDrawArraysInstanced(%s, %d, %d, %d)\n",
668 _mesa_lookup_enum_by_nr(mode), start, count, numInstances);
669
670 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, start, count, numInstances))
671 return;
672
673 if (0)
674 check_draw_arrays_data(ctx, start, count);
675
676 vbo_draw_arrays(ctx, mode, start, count, numInstances, 0);
677
678 if (0)
679 print_draw_arrays(ctx, mode, start, count);
680 }
681
682
683 /**
684 * Called from glDrawArraysInstancedBaseInstance when in immediate mode.
685 */
686 static void GLAPIENTRY
687 vbo_exec_DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count,
688 GLsizei numInstances, GLuint baseInstance)
689 {
690 GET_CURRENT_CONTEXT(ctx);
691
692 if (MESA_VERBOSE & VERBOSE_DRAW)
693 _mesa_debug(ctx, "glDrawArraysInstancedBaseInstance(%s, %d, %d, %d, %d)\n",
694 _mesa_lookup_enum_by_nr(mode), first, count,
695 numInstances, baseInstance);
696
697 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, first, count,
698 numInstances))
699 return;
700
701 if (0)
702 check_draw_arrays_data(ctx, first, count);
703
704 vbo_draw_arrays(ctx, mode, first, count, numInstances, baseInstance);
705
706 if (0)
707 print_draw_arrays(ctx, mode, first, count);
708 }
709
710
711
712 /**
713 * Map GL_ELEMENT_ARRAY_BUFFER and print contents.
714 * For debugging.
715 */
716 #if 0
717 static void
718 dump_element_buffer(struct gl_context *ctx, GLenum type)
719 {
720 const GLvoid *map =
721 ctx->Driver.MapBufferRange(ctx, 0,
722 ctx->Array.ArrayObj->ElementArrayBufferObj->Size,
723 GL_MAP_READ_BIT,
724 ctx->Array.ArrayObj->ElementArrayBufferObj);
725 switch (type) {
726 case GL_UNSIGNED_BYTE:
727 {
728 const GLubyte *us = (const GLubyte *) map;
729 GLint i;
730 for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size; i++) {
731 printf("%02x ", us[i]);
732 if (i % 32 == 31)
733 printf("\n");
734 }
735 printf("\n");
736 }
737 break;
738 case GL_UNSIGNED_SHORT:
739 {
740 const GLushort *us = (const GLushort *) map;
741 GLint i;
742 for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size / 2; i++) {
743 printf("%04x ", us[i]);
744 if (i % 16 == 15)
745 printf("\n");
746 }
747 printf("\n");
748 }
749 break;
750 case GL_UNSIGNED_INT:
751 {
752 const GLuint *us = (const GLuint *) map;
753 GLint i;
754 for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size / 4; i++) {
755 printf("%08x ", us[i]);
756 if (i % 8 == 7)
757 printf("\n");
758 }
759 printf("\n");
760 }
761 break;
762 default:
763 ;
764 }
765
766 ctx->Driver.UnmapBuffer(ctx, ctx->Array.ArrayObj->ElementArrayBufferObj);
767 }
768 #endif
769
770
771 /**
772 * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements.
773 * Do the rendering for a glDrawElements or glDrawRangeElements call after
774 * we've validated buffer bounds, etc.
775 */
776 static void
777 vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
778 GLboolean index_bounds_valid,
779 GLuint start, GLuint end,
780 GLsizei count, GLenum type,
781 const GLvoid *indices,
782 GLint basevertex, GLuint numInstances,
783 GLuint baseInstance)
784 {
785 struct vbo_context *vbo = vbo_context(ctx);
786 struct vbo_exec_context *exec = &vbo->exec;
787 struct _mesa_index_buffer ib;
788 struct _mesa_prim prim[1];
789
790 vbo_bind_arrays(ctx);
791
792 ib.count = count;
793 ib.type = type;
794 ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj;
795 ib.ptr = indices;
796
797 prim[0].begin = 1;
798 prim[0].end = 1;
799 prim[0].weak = 0;
800 prim[0].pad = 0;
801 prim[0].mode = mode;
802 prim[0].start = 0;
803 prim[0].count = count;
804 prim[0].indexed = 1;
805 prim[0].basevertex = basevertex;
806 prim[0].num_instances = numInstances;
807 prim[0].base_instance = baseInstance;
808
809 /* Need to give special consideration to rendering a range of
810 * indices starting somewhere above zero. Typically the
811 * application is issuing multiple DrawRangeElements() to draw
812 * successive primitives layed out linearly in the vertex arrays.
813 * Unless the vertex arrays are all in a VBO (or locked as with
814 * CVA), the OpenGL semantics imply that we need to re-read or
815 * re-upload the vertex data on each draw call.
816 *
817 * In the case of hardware tnl, we want to avoid starting the
818 * upload at zero, as it will mean every draw call uploads an
819 * increasing amount of not-used vertex data. Worse - in the
820 * software tnl module, all those vertices might be transformed and
821 * lit but never rendered.
822 *
823 * If we just upload or transform the vertices in start..end,
824 * however, the indices will be incorrect.
825 *
826 * At this level, we don't know exactly what the requirements of
827 * the backend are going to be, though it will likely boil down to
828 * either:
829 *
830 * 1) Do nothing, everything is in a VBO and is processed once
831 * only.
832 *
833 * 2) Adjust the indices and vertex arrays so that start becomes
834 * zero.
835 *
836 * Rather than doing anything here, I'll provide a helper function
837 * for the latter case elsewhere.
838 */
839
840 check_buffers_are_unmapped(exec->array.inputs);
841 vbo_handle_primitive_restart(ctx, prim, 1, &ib,
842 index_bounds_valid, start, end);
843
844 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
845 _mesa_flush(ctx);
846 }
847 }
848
849
850 /**
851 * Called by glDrawRangeElementsBaseVertex() in immediate mode.
852 */
853 static void GLAPIENTRY
854 vbo_exec_DrawRangeElementsBaseVertex(GLenum mode,
855 GLuint start, GLuint end,
856 GLsizei count, GLenum type,
857 const GLvoid *indices,
858 GLint basevertex)
859 {
860 static GLuint warnCount = 0;
861 GLboolean index_bounds_valid = GL_TRUE;
862 GET_CURRENT_CONTEXT(ctx);
863
864 if (MESA_VERBOSE & VERBOSE_DRAW)
865 _mesa_debug(ctx,
866 "glDrawRangeElementsBaseVertex(%s, %u, %u, %d, %s, %p, %d)\n",
867 _mesa_lookup_enum_by_nr(mode), start, end, count,
868 _mesa_lookup_enum_by_nr(type), indices, basevertex);
869
870 if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count,
871 type, indices, basevertex ))
872 return;
873
874 if ((int) end + basevertex < 0 ||
875 start + basevertex >= ctx->Array.ArrayObj->_MaxElement) {
876 /* The application requested we draw using a range of indices that's
877 * outside the bounds of the current VBO. This is invalid and appears
878 * to give undefined results. The safest thing to do is to simply
879 * ignore the range, in case the application botched their range tracking
880 * but did provide valid indices. Also issue a warning indicating that
881 * the application is broken.
882 */
883 if (warnCount++ < 10) {
884 _mesa_warning(ctx, "glDrawRangeElements(start %u, end %u, "
885 "basevertex %d, count %d, type 0x%x, indices=%p):\n"
886 "\trange is outside VBO bounds (max=%u); ignoring.\n"
887 "\tThis should be fixed in the application.",
888 start, end, basevertex, count, type, indices,
889 ctx->Array.ArrayObj->_MaxElement - 1);
890 }
891 index_bounds_valid = GL_FALSE;
892 }
893
894 /* NOTE: It's important that 'end' is a reasonable value.
895 * in _tnl_draw_prims(), we use end to determine how many vertices
896 * to transform. If it's too large, we can unnecessarily split prims
897 * or we can read/write out of memory in several different places!
898 */
899
900 /* Catch/fix some potential user errors */
901 if (type == GL_UNSIGNED_BYTE) {
902 start = MIN2(start, 0xff);
903 end = MIN2(end, 0xff);
904 }
905 else if (type == GL_UNSIGNED_SHORT) {
906 start = MIN2(start, 0xffff);
907 end = MIN2(end, 0xffff);
908 }
909
910 if (0) {
911 printf("glDraw[Range]Elements{,BaseVertex}"
912 "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, "
913 "base %d\n",
914 start, end, type, count,
915 ctx->Array.ArrayObj->ElementArrayBufferObj->Name,
916 basevertex);
917 }
918
919 if ((int) start + basevertex < 0 ||
920 end + basevertex >= ctx->Array.ArrayObj->_MaxElement)
921 index_bounds_valid = GL_FALSE;
922
923 #if 0
924 check_draw_elements_data(ctx, count, type, indices);
925 #else
926 (void) check_draw_elements_data;
927 #endif
928
929 vbo_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end,
930 count, type, indices, basevertex, 1, 0);
931 }
932
933
934 /**
935 * Called by glDrawRangeElements() in immediate mode.
936 */
937 static void GLAPIENTRY
938 vbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
939 GLsizei count, GLenum type, const GLvoid *indices)
940 {
941 if (MESA_VERBOSE & VERBOSE_DRAW) {
942 GET_CURRENT_CONTEXT(ctx);
943 _mesa_debug(ctx,
944 "glDrawRangeElements(%s, %u, %u, %d, %s, %p)\n",
945 _mesa_lookup_enum_by_nr(mode), start, end, count,
946 _mesa_lookup_enum_by_nr(type), indices);
947 }
948
949 vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
950 indices, 0);
951 }
952
953
954 /**
955 * Called by glDrawElements() in immediate mode.
956 */
957 static void GLAPIENTRY
958 vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
959 const GLvoid *indices)
960 {
961 GET_CURRENT_CONTEXT(ctx);
962
963 if (MESA_VERBOSE & VERBOSE_DRAW)
964 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n",
965 _mesa_lookup_enum_by_nr(mode), count,
966 _mesa_lookup_enum_by_nr(type), indices);
967
968 if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 ))
969 return;
970
971 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
972 count, type, indices, 0, 1, 0);
973 }
974
975
976 /**
977 * Called by glDrawElementsBaseVertex() in immediate mode.
978 */
979 static void GLAPIENTRY
980 vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
981 const GLvoid *indices, GLint basevertex)
982 {
983 GET_CURRENT_CONTEXT(ctx);
984
985 if (MESA_VERBOSE & VERBOSE_DRAW)
986 _mesa_debug(ctx, "glDrawElementsBaseVertex(%s, %d, %s, %p, %d)\n",
987 _mesa_lookup_enum_by_nr(mode), count,
988 _mesa_lookup_enum_by_nr(type), indices, basevertex);
989
990 if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices,
991 basevertex ))
992 return;
993
994 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
995 count, type, indices, basevertex, 1, 0);
996 }
997
998
999 /**
1000 * Called by glDrawElementsInstanced() in immediate mode.
1001 */
1002 static void GLAPIENTRY
1003 vbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
1004 const GLvoid *indices, GLsizei numInstances)
1005 {
1006 GET_CURRENT_CONTEXT(ctx);
1007
1008 if (MESA_VERBOSE & VERBOSE_DRAW)
1009 _mesa_debug(ctx, "glDrawElementsInstanced(%s, %d, %s, %p, %d)\n",
1010 _mesa_lookup_enum_by_nr(mode), count,
1011 _mesa_lookup_enum_by_nr(type), indices, numInstances);
1012
1013 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
1014 numInstances, 0))
1015 return;
1016
1017 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1018 count, type, indices, 0, numInstances, 0);
1019 }
1020
1021
1022 /**
1023 * Called by glDrawElementsInstancedBaseVertex() in immediate mode.
1024 */
1025 static void GLAPIENTRY
1026 vbo_exec_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type,
1027 const GLvoid *indices, GLsizei numInstances,
1028 GLint basevertex)
1029 {
1030 GET_CURRENT_CONTEXT(ctx);
1031
1032 if (MESA_VERBOSE & VERBOSE_DRAW)
1033 _mesa_debug(ctx, "glDrawElementsInstancedBaseVertex(%s, %d, %s, %p, %d; %d)\n",
1034 _mesa_lookup_enum_by_nr(mode), count,
1035 _mesa_lookup_enum_by_nr(type), indices,
1036 numInstances, basevertex);
1037
1038 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
1039 numInstances, basevertex))
1040 return;
1041
1042 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1043 count, type, indices, basevertex, numInstances, 0);
1044 }
1045
1046
1047 /**
1048 * Called by glDrawElementsInstancedBaseInstance() in immediate mode.
1049 */
1050 static void GLAPIENTRY
1051 vbo_exec_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type,
1052 const GLvoid *indices, GLsizei numInstances,
1053 GLuint baseInstance)
1054 {
1055 GET_CURRENT_CONTEXT(ctx);
1056
1057 if (MESA_VERBOSE & VERBOSE_DRAW)
1058 _mesa_debug(ctx, "glDrawElementsInstancedBaseInstance(%s, %d, %s, %p, %d, %d)\n",
1059 _mesa_lookup_enum_by_nr(mode), count,
1060 _mesa_lookup_enum_by_nr(type), indices,
1061 numInstances, baseInstance);
1062
1063 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
1064 numInstances, 0))
1065 return;
1066
1067 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1068 count, type, indices, 0, numInstances,
1069 baseInstance);
1070 }
1071
1072
1073 /**
1074 * Called by glDrawElementsInstancedBaseVertexBaseInstance() in immediate mode.
1075 */
1076 static void GLAPIENTRY
1077 vbo_exec_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type,
1078 const GLvoid *indices, GLsizei numInstances,
1079 GLint basevertex, GLuint baseInstance)
1080 {
1081 GET_CURRENT_CONTEXT(ctx);
1082
1083 if (MESA_VERBOSE & VERBOSE_DRAW)
1084 _mesa_debug(ctx, "glDrawElementsInstancedBaseVertexBaseInstance(%s, %d, %s, %p, %d, %d, %d)\n",
1085 _mesa_lookup_enum_by_nr(mode), count,
1086 _mesa_lookup_enum_by_nr(type), indices,
1087 numInstances, basevertex, baseInstance);
1088
1089 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
1090 numInstances, basevertex))
1091 return;
1092
1093 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1094 count, type, indices, basevertex, numInstances,
1095 baseInstance);
1096 }
1097
1098
1099 /**
1100 * Inner support for both _mesa_MultiDrawElements() and
1101 * _mesa_MultiDrawRangeElements().
1102 * This does the actual rendering after we've checked array indexes, etc.
1103 */
1104 static void
1105 vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
1106 const GLsizei *count, GLenum type,
1107 const GLvoid * const *indices,
1108 GLsizei primcount,
1109 const GLint *basevertex)
1110 {
1111 struct vbo_context *vbo = vbo_context(ctx);
1112 struct vbo_exec_context *exec = &vbo->exec;
1113 struct _mesa_index_buffer ib;
1114 struct _mesa_prim *prim;
1115 unsigned int index_type_size = vbo_sizeof_ib_type(type);
1116 uintptr_t min_index_ptr, max_index_ptr;
1117 GLboolean fallback = GL_FALSE;
1118 int i;
1119
1120 if (primcount == 0)
1121 return;
1122
1123 prim = calloc(1, primcount * sizeof(*prim));
1124 if (prim == NULL) {
1125 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements");
1126 return;
1127 }
1128
1129 vbo_bind_arrays(ctx);
1130
1131 min_index_ptr = (uintptr_t)indices[0];
1132 max_index_ptr = 0;
1133 for (i = 0; i < primcount; i++) {
1134 min_index_ptr = MIN2(min_index_ptr, (uintptr_t)indices[i]);
1135 max_index_ptr = MAX2(max_index_ptr, (uintptr_t)indices[i] +
1136 index_type_size * count[i]);
1137 }
1138
1139 /* Check if we can handle this thing as a bunch of index offsets from the
1140 * same index pointer. If we can't, then we have to fall back to doing
1141 * a draw_prims per primitive.
1142 * Check that the difference between each prim's indexes is a multiple of
1143 * the index/element size.
1144 */
1145 if (index_type_size != 1) {
1146 for (i = 0; i < primcount; i++) {
1147 if ((((uintptr_t)indices[i] - min_index_ptr) % index_type_size) != 0) {
1148 fallback = GL_TRUE;
1149 break;
1150 }
1151 }
1152 }
1153
1154 /* If the index buffer isn't in a VBO, then treating the application's
1155 * subranges of the index buffer as one large index buffer may lead to
1156 * us reading unmapped memory.
1157 */
1158 if (!_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj))
1159 fallback = GL_TRUE;
1160
1161 if (!fallback) {
1162 ib.count = (max_index_ptr - min_index_ptr) / index_type_size;
1163 ib.type = type;
1164 ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj;
1165 ib.ptr = (void *)min_index_ptr;
1166
1167 for (i = 0; i < primcount; i++) {
1168 prim[i].begin = (i == 0);
1169 prim[i].end = (i == primcount - 1);
1170 prim[i].weak = 0;
1171 prim[i].pad = 0;
1172 prim[i].mode = mode;
1173 prim[i].start = ((uintptr_t)indices[i] - min_index_ptr) / index_type_size;
1174 prim[i].count = count[i];
1175 prim[i].indexed = 1;
1176 prim[i].num_instances = 1;
1177 prim[i].base_instance = 0;
1178 if (basevertex != NULL)
1179 prim[i].basevertex = basevertex[i];
1180 else
1181 prim[i].basevertex = 0;
1182 }
1183
1184 check_buffers_are_unmapped(exec->array.inputs);
1185 vbo_handle_primitive_restart(ctx, prim, primcount, &ib,
1186 GL_FALSE, ~0, ~0);
1187 } else {
1188 /* render one prim at a time */
1189 for (i = 0; i < primcount; i++) {
1190 ib.count = count[i];
1191 ib.type = type;
1192 ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj;
1193 ib.ptr = indices[i];
1194
1195 prim[0].begin = 1;
1196 prim[0].end = 1;
1197 prim[0].weak = 0;
1198 prim[0].pad = 0;
1199 prim[0].mode = mode;
1200 prim[0].start = 0;
1201 prim[0].count = count[i];
1202 prim[0].indexed = 1;
1203 prim[0].num_instances = 1;
1204 prim[0].base_instance = 0;
1205 if (basevertex != NULL)
1206 prim[0].basevertex = basevertex[i];
1207 else
1208 prim[0].basevertex = 0;
1209
1210 check_buffers_are_unmapped(exec->array.inputs);
1211 vbo_handle_primitive_restart(ctx, prim, 1, &ib,
1212 GL_FALSE, ~0, ~0);
1213 }
1214 }
1215
1216 free(prim);
1217
1218 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1219 _mesa_flush(ctx);
1220 }
1221 }
1222
1223
1224 static void GLAPIENTRY
1225 vbo_exec_MultiDrawElements(GLenum mode,
1226 const GLsizei *count, GLenum type,
1227 const GLvoid **indices,
1228 GLsizei primcount)
1229 {
1230 GET_CURRENT_CONTEXT(ctx);
1231
1232 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
1233 primcount, NULL))
1234 return;
1235
1236 vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
1237 NULL);
1238 }
1239
1240
1241 static void GLAPIENTRY
1242 vbo_exec_MultiDrawElementsBaseVertex(GLenum mode,
1243 const GLsizei *count, GLenum type,
1244 const GLvoid * const *indices,
1245 GLsizei primcount,
1246 const GLsizei *basevertex)
1247 {
1248 GET_CURRENT_CONTEXT(ctx);
1249
1250 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
1251 primcount, basevertex))
1252 return;
1253
1254 vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
1255 basevertex);
1256 }
1257
1258 static void
1259 vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
1260 struct gl_transform_feedback_object *obj,
1261 GLuint stream, GLuint numInstances)
1262 {
1263 struct vbo_context *vbo = vbo_context(ctx);
1264 struct vbo_exec_context *exec = &vbo->exec;
1265 struct _mesa_prim prim[2];
1266
1267 if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream,
1268 numInstances)) {
1269 return;
1270 }
1271
1272 vbo_bind_arrays(ctx);
1273
1274 /* init most fields to zero */
1275 memset(prim, 0, sizeof(prim));
1276 prim[0].begin = 1;
1277 prim[0].end = 1;
1278 prim[0].mode = mode;
1279 prim[0].num_instances = numInstances;
1280 prim[0].base_instance = 0;
1281
1282 /* Maybe we should do some primitive splitting for primitive restart
1283 * (like in DrawArrays), but we have no way to know how many vertices
1284 * will be rendered. */
1285
1286 check_buffers_are_unmapped(exec->array.inputs);
1287 vbo->draw_prims(ctx, prim, 1, NULL,
1288 GL_TRUE, 0, 0, obj);
1289
1290 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1291 _mesa_flush(ctx);
1292 }
1293 }
1294
1295 /**
1296 * Like DrawArrays, but take the count from a transform feedback object.
1297 * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc.
1298 * \param name the transform feedback object
1299 * User still has to setup of the vertex attribute info with
1300 * glVertexPointer, glColorPointer, etc.
1301 * Part of GL_ARB_transform_feedback2.
1302 */
1303 static void GLAPIENTRY
1304 vbo_exec_DrawTransformFeedback(GLenum mode, GLuint name)
1305 {
1306 GET_CURRENT_CONTEXT(ctx);
1307 struct gl_transform_feedback_object *obj =
1308 _mesa_lookup_transform_feedback_object(ctx, name);
1309
1310 if (MESA_VERBOSE & VERBOSE_DRAW)
1311 _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n",
1312 _mesa_lookup_enum_by_nr(mode), name);
1313
1314 vbo_draw_transform_feedback(ctx, mode, obj, 0, 1);
1315 }
1316
1317 static void GLAPIENTRY
1318 vbo_exec_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream)
1319 {
1320 GET_CURRENT_CONTEXT(ctx);
1321 struct gl_transform_feedback_object *obj =
1322 _mesa_lookup_transform_feedback_object(ctx, name);
1323
1324 if (MESA_VERBOSE & VERBOSE_DRAW)
1325 _mesa_debug(ctx, "glDrawTransformFeedbackStream(%s, %u, %u)\n",
1326 _mesa_lookup_enum_by_nr(mode), name, stream);
1327
1328 vbo_draw_transform_feedback(ctx, mode, obj, stream, 1);
1329 }
1330
1331 static void GLAPIENTRY
1332 vbo_exec_DrawTransformFeedbackInstanced(GLenum mode, GLuint name,
1333 GLsizei primcount)
1334 {
1335 GET_CURRENT_CONTEXT(ctx);
1336 struct gl_transform_feedback_object *obj =
1337 _mesa_lookup_transform_feedback_object(ctx, name);
1338
1339 if (MESA_VERBOSE & VERBOSE_DRAW)
1340 _mesa_debug(ctx, "glDrawTransformFeedbackInstanced(%s, %d)\n",
1341 _mesa_lookup_enum_by_nr(mode), name);
1342
1343 vbo_draw_transform_feedback(ctx, mode, obj, 0, primcount);
1344 }
1345
1346 static void GLAPIENTRY
1347 vbo_exec_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name,
1348 GLuint stream, GLsizei primcount)
1349 {
1350 GET_CURRENT_CONTEXT(ctx);
1351 struct gl_transform_feedback_object *obj =
1352 _mesa_lookup_transform_feedback_object(ctx, name);
1353
1354 if (MESA_VERBOSE & VERBOSE_DRAW)
1355 _mesa_debug(ctx, "glDrawTransformFeedbackStreamInstanced"
1356 "(%s, %u, %u, %i)\n",
1357 _mesa_lookup_enum_by_nr(mode), name, stream, primcount);
1358
1359 vbo_draw_transform_feedback(ctx, mode, obj, stream, primcount);
1360 }
1361
1362 /**
1363 * Plug in the immediate-mode vertex array drawing commands into the
1364 * givven vbo_exec_context object.
1365 */
1366 void
1367 vbo_exec_array_init( struct vbo_exec_context *exec )
1368 {
1369 exec->vtxfmt.DrawArrays = vbo_exec_DrawArrays;
1370 exec->vtxfmt.DrawElements = vbo_exec_DrawElements;
1371 exec->vtxfmt.DrawRangeElements = vbo_exec_DrawRangeElements;
1372 exec->vtxfmt.MultiDrawElementsEXT = vbo_exec_MultiDrawElements;
1373 exec->vtxfmt.DrawElementsBaseVertex = vbo_exec_DrawElementsBaseVertex;
1374 exec->vtxfmt.DrawRangeElementsBaseVertex = vbo_exec_DrawRangeElementsBaseVertex;
1375 exec->vtxfmt.MultiDrawElementsBaseVertex = vbo_exec_MultiDrawElementsBaseVertex;
1376 exec->vtxfmt.DrawArraysInstanced = vbo_exec_DrawArraysInstanced;
1377 exec->vtxfmt.DrawArraysInstancedBaseInstance = vbo_exec_DrawArraysInstancedBaseInstance;
1378 exec->vtxfmt.DrawElementsInstanced = vbo_exec_DrawElementsInstanced;
1379 exec->vtxfmt.DrawElementsInstancedBaseInstance = vbo_exec_DrawElementsInstancedBaseInstance;
1380 exec->vtxfmt.DrawElementsInstancedBaseVertex = vbo_exec_DrawElementsInstancedBaseVertex;
1381 exec->vtxfmt.DrawElementsInstancedBaseVertexBaseInstance = vbo_exec_DrawElementsInstancedBaseVertexBaseInstance;
1382 exec->vtxfmt.DrawTransformFeedback = vbo_exec_DrawTransformFeedback;
1383 exec->vtxfmt.DrawTransformFeedbackStream =
1384 vbo_exec_DrawTransformFeedbackStream;
1385 exec->vtxfmt.DrawTransformFeedbackInstanced =
1386 vbo_exec_DrawTransformFeedbackInstanced;
1387 exec->vtxfmt.DrawTransformFeedbackStreamInstanced =
1388 vbo_exec_DrawTransformFeedbackStreamInstanced;
1389 }
1390
1391
1392 void
1393 vbo_exec_array_destroy( struct vbo_exec_context *exec )
1394 {
1395 /* nothing to do */
1396 }
1397
1398
1399
1400 /**
1401 * The following functions are only used for OpenGL ES 1/2 support.
1402 * And some aren't even supported (yet) in ES 1/2.
1403 */
1404
1405
1406 void GLAPIENTRY
1407 _mesa_DrawArrays(GLenum mode, GLint first, GLsizei count)
1408 {
1409 vbo_exec_DrawArrays(mode, first, count);
1410 }
1411
1412
1413 void GLAPIENTRY
1414 _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
1415 const GLvoid *indices)
1416 {
1417 vbo_exec_DrawElements(mode, count, type, indices);
1418 }
1419
1420
1421 void GLAPIENTRY
1422 _mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
1423 const GLvoid *indices, GLint basevertex)
1424 {
1425 vbo_exec_DrawElementsBaseVertex(mode, count, type, indices, basevertex);
1426 }
1427
1428
1429 void GLAPIENTRY
1430 _mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
1431 GLenum type, const GLvoid *indices)
1432 {
1433 vbo_exec_DrawRangeElements(mode, start, end, count, type, indices);
1434 }
1435
1436
1437 void GLAPIENTRY
1438 _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
1439 GLsizei count, GLenum type,
1440 const GLvoid *indices, GLint basevertex)
1441 {
1442 vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
1443 indices, basevertex);
1444 }
1445
1446
1447 void GLAPIENTRY
1448 _mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type,
1449 const GLvoid **indices, GLsizei primcount)
1450 {
1451 vbo_exec_MultiDrawElements(mode, count, type, indices, primcount);
1452 }
1453
1454
1455 void GLAPIENTRY
1456 _mesa_MultiDrawElementsBaseVertex(GLenum mode,
1457 const GLsizei *count, GLenum type,
1458 const GLvoid **indices, GLsizei primcount,
1459 const GLint *basevertex)
1460 {
1461 vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices,
1462 primcount, basevertex);
1463 }
1464
1465 void GLAPIENTRY
1466 _mesa_DrawTransformFeedback(GLenum mode, GLuint name)
1467 {
1468 vbo_exec_DrawTransformFeedback(mode, name);
1469 }