mesa: optimize get_index_size
[mesa.git] / src / mesa / main / draw.c
1 /**************************************************************************
2 *
3 * Copyright 2003 VMware, Inc.
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 VMWARE 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 <stdio.h>
30 #include "arrayobj.h"
31 #include "glheader.h"
32 #include "c99_alloca.h"
33 #include "context.h"
34 #include "state.h"
35 #include "draw.h"
36 #include "draw_validate.h"
37 #include "dispatch.h"
38 #include "varray.h"
39 #include "bufferobj.h"
40 #include "enums.h"
41 #include "macros.h"
42 #include "transformfeedback.h"
43
44 typedef struct {
45 GLuint count;
46 GLuint primCount;
47 GLuint first;
48 GLuint baseInstance;
49 } DrawArraysIndirectCommand;
50
51 typedef struct {
52 GLuint count;
53 GLuint primCount;
54 GLuint firstIndex;
55 GLint baseVertex;
56 GLuint baseInstance;
57 } DrawElementsIndirectCommand;
58
59
60 /**
61 * Check that element 'j' of the array has reasonable data.
62 * Map VBO if needed.
63 * For debugging purposes; not normally used.
64 */
65 static void
66 check_array_data(struct gl_context *ctx, struct gl_vertex_array_object *vao,
67 GLuint attrib, GLuint j)
68 {
69 const struct gl_array_attributes *array = &vao->VertexAttrib[attrib];
70 if (vao->Enabled & VERT_BIT(attrib)) {
71 const struct gl_vertex_buffer_binding *binding =
72 &vao->BufferBinding[array->BufferBindingIndex];
73 struct gl_buffer_object *bo = binding->BufferObj;
74 const void *data = array->Ptr;
75 if (_mesa_is_bufferobj(bo)) {
76 data = ADD_POINTERS(_mesa_vertex_attrib_address(array, binding),
77 bo->Mappings[MAP_INTERNAL].Pointer);
78 }
79 switch (array->Format.Type) {
80 case GL_FLOAT:
81 {
82 GLfloat *f = (GLfloat *) ((GLubyte *) data + binding->Stride * j);
83 GLint k;
84 for (k = 0; k < array->Format.Size; k++) {
85 if (IS_INF_OR_NAN(f[k]) || f[k] >= 1.0e20F || f[k] <= -1.0e10F) {
86 printf("Bad array data:\n");
87 printf(" Element[%u].%u = %f\n", j, k, f[k]);
88 printf(" Array %u at %p\n", attrib, (void *) array);
89 printf(" Type 0x%x, Size %d, Stride %d\n",
90 array->Format.Type, array->Format.Size,
91 binding->Stride);
92 printf(" Address/offset %p in Buffer Object %u\n",
93 array->Ptr, bo->Name);
94 f[k] = 1.0F; /* XXX replace the bad value! */
95 }
96 /*assert(!IS_INF_OR_NAN(f[k])); */
97 }
98 }
99 break;
100 default:
101 ;
102 }
103 }
104 }
105
106
107 static inline void
108 get_index_size(GLenum type, struct _mesa_index_buffer *ib)
109 {
110 /* The type is already validated, so use a fast conversion.
111 *
112 * GL_UNSIGNED_BYTE - GL_UNSIGNED_BYTE = 0
113 * GL_UNSIGNED_SHORT - GL_UNSIGNED_BYTE = 2
114 * GL_UNSIGNED_INT - GL_UNSIGNED_BYTE = 4
115 *
116 * Divide by 2 to get 0,1,2.
117 */
118 ib->index_size_shift = (type - GL_UNSIGNED_BYTE) >> 1;
119 }
120
121 /**
122 * Examine the array's data for NaNs, etc.
123 * For debug purposes; not normally used.
124 */
125 static void
126 check_draw_elements_data(struct gl_context *ctx, GLsizei count,
127 GLenum elemType, const void *elements,
128 GLint basevertex)
129 {
130 struct gl_vertex_array_object *vao = ctx->Array.VAO;
131 GLint i;
132 GLuint k;
133
134 _mesa_vao_map(ctx, vao, GL_MAP_READ_BIT);
135
136 if (_mesa_is_bufferobj(vao->IndexBufferObj))
137 elements =
138 ADD_POINTERS(vao->IndexBufferObj->Mappings[MAP_INTERNAL].Pointer, elements);
139
140 for (i = 0; i < count; i++) {
141 GLuint j;
142
143 /* j = element[i] */
144 switch (elemType) {
145 case GL_UNSIGNED_BYTE:
146 j = ((const GLubyte *) elements)[i];
147 break;
148 case GL_UNSIGNED_SHORT:
149 j = ((const GLushort *) elements)[i];
150 break;
151 case GL_UNSIGNED_INT:
152 j = ((const GLuint *) elements)[i];
153 break;
154 default:
155 unreachable("Unexpected index buffer type");
156 }
157
158 /* check element j of each enabled array */
159 for (k = 0; k < VERT_ATTRIB_MAX; k++) {
160 check_array_data(ctx, vao, k, j);
161 }
162 }
163
164 _mesa_vao_unmap(ctx, vao);
165 }
166
167
168 /**
169 * Check array data, looking for NaNs, etc.
170 */
171 static void
172 check_draw_arrays_data(struct gl_context *ctx, GLint start, GLsizei count)
173 {
174 /* TO DO */
175 }
176
177
178 /**
179 * Check if we should skip the draw call even after validation was successful.
180 */
181 static bool
182 skip_validated_draw(struct gl_context *ctx)
183 {
184 switch (ctx->API) {
185 case API_OPENGLES2:
186 /* For ES2, we can draw if we have a vertex program/shader). */
187 return ctx->VertexProgram._Current == NULL;
188
189 case API_OPENGLES:
190 /* For OpenGL ES, only draw if we have vertex positions
191 */
192 if (!(ctx->Array.VAO->Enabled & VERT_BIT_POS))
193 return true;
194 break;
195
196 case API_OPENGL_CORE:
197 /* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec
198 * says:
199 *
200 * "If there is no active program for the vertex or fragment shader
201 * stages, the results of vertex and/or fragment processing will be
202 * undefined. However, this is not an error."
203 *
204 * The fragment shader is not tested here because other state (e.g.,
205 * GL_RASTERIZER_DISCARD) affects whether or not we actually care.
206 */
207 return ctx->VertexProgram._Current == NULL;
208
209 case API_OPENGL_COMPAT:
210 if (ctx->VertexProgram._Current != NULL) {
211 /* Draw regardless of whether or not we have any vertex arrays.
212 * (Ex: could draw a point using a constant vertex pos)
213 */
214 return false;
215 } else {
216 /* Draw if we have vertex positions (GL_VERTEX_ARRAY or generic
217 * array [0]).
218 */
219 return !(ctx->Array.VAO->Enabled & (VERT_BIT_POS|VERT_BIT_GENERIC0));
220 }
221 break;
222
223 default:
224 unreachable("Invalid API value in check_valid_to_render()");
225 }
226
227 return false;
228 }
229
230
231 /**
232 * Print info/data for glDrawArrays(), for debugging.
233 */
234 static void
235 print_draw_arrays(struct gl_context *ctx,
236 GLenum mode, GLint start, GLsizei count)
237 {
238 struct gl_vertex_array_object *vao = ctx->Array.VAO;
239
240 printf("_mesa_DrawArrays(mode 0x%x, start %d, count %d):\n",
241 mode, start, count);
242
243 _mesa_vao_map_arrays(ctx, vao, GL_MAP_READ_BIT);
244
245 GLbitfield mask = vao->Enabled;
246 while (mask) {
247 const gl_vert_attrib i = u_bit_scan(&mask);
248 const struct gl_array_attributes *array = &vao->VertexAttrib[i];
249
250 const struct gl_vertex_buffer_binding *binding =
251 &vao->BufferBinding[array->BufferBindingIndex];
252 struct gl_buffer_object *bufObj = binding->BufferObj;
253
254 printf("attr %s: size %d stride %d "
255 "ptr %p Bufobj %u\n",
256 gl_vert_attrib_name((gl_vert_attrib) i),
257 array->Format.Size, binding->Stride,
258 array->Ptr, bufObj->Name);
259
260 if (_mesa_is_bufferobj(bufObj)) {
261 GLubyte *p = bufObj->Mappings[MAP_INTERNAL].Pointer;
262 int offset = (int) (GLintptr)
263 _mesa_vertex_attrib_address(array, binding);
264
265 unsigned multiplier;
266 switch (array->Format.Type) {
267 case GL_DOUBLE:
268 case GL_INT64_ARB:
269 case GL_UNSIGNED_INT64_ARB:
270 multiplier = 2;
271 break;
272 default:
273 multiplier = 1;
274 }
275
276 float *f = (float *) (p + offset);
277 int *k = (int *) f;
278 int i = 0;
279 int n = (count - 1) * (binding->Stride / (4 * multiplier))
280 + array->Format.Size;
281 if (n > 32)
282 n = 32;
283 printf(" Data at offset %d:\n", offset);
284 do {
285 if (multiplier == 2)
286 printf(" double[%d] = 0x%016llx %lf\n", i,
287 ((unsigned long long *) k)[i], ((double *) f)[i]);
288 else
289 printf(" float[%d] = 0x%08x %f\n", i, k[i], f[i]);
290 i++;
291 } while (i < n);
292 }
293 }
294
295 _mesa_vao_unmap_arrays(ctx, vao);
296 }
297
298
299 /**
300 * Return a filter mask for the net enabled vao arrays.
301 * This is to mask out arrays that would otherwise supersed required current
302 * values for the fixed function shaders for example.
303 */
304 static GLbitfield
305 enabled_filter(const struct gl_context *ctx)
306 {
307 switch (ctx->VertexProgram._VPMode) {
308 case VP_MODE_FF:
309 /* When no vertex program is active (or the vertex program is generated
310 * from fixed-function state). We put the material values into the
311 * generic slots. Since the vao has no material arrays, mute these
312 * slots from the enabled arrays so that the current material values
313 * are pulled instead of the vao arrays.
314 */
315 return VERT_BIT_FF_ALL;
316
317 case VP_MODE_SHADER:
318 /* There are no shaders in OpenGL ES 1.x, so this code path should be
319 * impossible to reach. The meta code is careful to not use shaders in
320 * ES1.
321 */
322 assert(ctx->API != API_OPENGLES);
323
324 /* Other parts of the code assume that inputs[VERT_ATTRIB_POS] through
325 * inputs[VERT_ATTRIB_FF_MAX] will be non-NULL. However, in OpenGL
326 * ES 2.0+ or OpenGL core profile, none of these arrays should ever
327 * be enabled.
328 */
329 if (ctx->API != API_OPENGL_COMPAT)
330 return VERT_BIT_GENERIC_ALL;
331
332 return VERT_BIT_ALL;
333
334 default:
335 assert(0);
336 return 0;
337 }
338 }
339
340
341 /**
342 * Helper function called by the other DrawArrays() functions below.
343 * This is where we handle primitive restart for drawing non-indexed
344 * arrays. If primitive restart is enabled, it typically means
345 * splitting one DrawArrays() into two.
346 */
347 static void
348 _mesa_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
349 GLsizei count, GLuint numInstances, GLuint baseInstance,
350 GLuint drawID)
351 {
352 if (skip_validated_draw(ctx))
353 return;
354
355 /* OpenGL 4.5 says that primitive restart is ignored with non-indexed
356 * draws.
357 */
358 struct _mesa_prim prim = {
359 .begin = 1,
360 .end = 1,
361 .mode = mode,
362 .draw_id = drawID,
363 .start = start,
364 .count = count,
365 };
366
367 ctx->Driver.Draw(ctx, &prim, 1, NULL,
368 GL_TRUE, start, start + count - 1,
369 numInstances, baseInstance, NULL, 0);
370
371 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
372 _mesa_flush(ctx);
373 }
374 }
375
376
377 /**
378 * Execute a glRectf() function.
379 */
380 static void GLAPIENTRY
381 _mesa_exec_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
382 {
383 GET_CURRENT_CONTEXT(ctx);
384 ASSERT_OUTSIDE_BEGIN_END(ctx);
385
386 CALL_Begin(GET_DISPATCH(), (GL_QUADS));
387 CALL_Vertex2f(GET_DISPATCH(), (x1, y1));
388 CALL_Vertex2f(GET_DISPATCH(), (x2, y1));
389 CALL_Vertex2f(GET_DISPATCH(), (x2, y2));
390 CALL_Vertex2f(GET_DISPATCH(), (x1, y2));
391 CALL_End(GET_DISPATCH(), ());
392 }
393
394
395 static void GLAPIENTRY
396 _mesa_exec_EvalMesh1(GLenum mode, GLint i1, GLint i2)
397 {
398 GET_CURRENT_CONTEXT(ctx);
399 GLint i;
400 GLfloat u, du;
401 GLenum prim;
402
403 switch (mode) {
404 case GL_POINT:
405 prim = GL_POINTS;
406 break;
407 case GL_LINE:
408 prim = GL_LINE_STRIP;
409 break;
410 default:
411 _mesa_error(ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)");
412 return;
413 }
414
415 /* No effect if vertex maps disabled.
416 */
417 if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3)
418 return;
419
420 du = ctx->Eval.MapGrid1du;
421 u = ctx->Eval.MapGrid1u1 + i1 * du;
422
423 CALL_Begin(GET_DISPATCH(), (prim));
424 for (i = i1; i <= i2; i++, u += du) {
425 CALL_EvalCoord1f(GET_DISPATCH(), (u));
426 }
427 CALL_End(GET_DISPATCH(), ());
428 }
429
430
431 static void GLAPIENTRY
432 _mesa_exec_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
433 {
434 GET_CURRENT_CONTEXT(ctx);
435 GLfloat u, du, v, dv, v1, u1;
436 GLint i, j;
437
438 switch (mode) {
439 case GL_POINT:
440 case GL_LINE:
441 case GL_FILL:
442 break;
443 default:
444 _mesa_error(ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)");
445 return;
446 }
447
448 /* No effect if vertex maps disabled.
449 */
450 if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3)
451 return;
452
453 du = ctx->Eval.MapGrid2du;
454 dv = ctx->Eval.MapGrid2dv;
455 v1 = ctx->Eval.MapGrid2v1 + j1 * dv;
456 u1 = ctx->Eval.MapGrid2u1 + i1 * du;
457
458 switch (mode) {
459 case GL_POINT:
460 CALL_Begin(GET_DISPATCH(), (GL_POINTS));
461 for (v = v1, j = j1; j <= j2; j++, v += dv) {
462 for (u = u1, i = i1; i <= i2; i++, u += du) {
463 CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
464 }
465 }
466 CALL_End(GET_DISPATCH(), ());
467 break;
468 case GL_LINE:
469 for (v = v1, j = j1; j <= j2; j++, v += dv) {
470 CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP));
471 for (u = u1, i = i1; i <= i2; i++, u += du) {
472 CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
473 }
474 CALL_End(GET_DISPATCH(), ());
475 }
476 for (u = u1, i = i1; i <= i2; i++, u += du) {
477 CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP));
478 for (v = v1, j = j1; j <= j2; j++, v += dv) {
479 CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
480 }
481 CALL_End(GET_DISPATCH(), ());
482 }
483 break;
484 case GL_FILL:
485 for (v = v1, j = j1; j < j2; j++, v += dv) {
486 CALL_Begin(GET_DISPATCH(), (GL_TRIANGLE_STRIP));
487 for (u = u1, i = i1; i <= i2; i++, u += du) {
488 CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
489 CALL_EvalCoord2f(GET_DISPATCH(), (u, v + dv));
490 }
491 CALL_End(GET_DISPATCH(), ());
492 }
493 break;
494 }
495 }
496
497
498 /**
499 * Called from glDrawArrays when in immediate mode (not display list mode).
500 */
501 void GLAPIENTRY
502 _mesa_DrawArrays(GLenum mode, GLint start, GLsizei count)
503 {
504 GET_CURRENT_CONTEXT(ctx);
505
506 if (MESA_VERBOSE & VERBOSE_DRAW)
507 _mesa_debug(ctx, "glDrawArrays(%s, %d, %d)\n",
508 _mesa_enum_to_string(mode), start, count);
509
510 FLUSH_FOR_DRAW(ctx);
511
512 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
513
514 if (_mesa_is_no_error_enabled(ctx)) {
515 if (ctx->NewState)
516 _mesa_update_state(ctx);
517 } else {
518 if (!_mesa_validate_DrawArrays(ctx, mode, count))
519 return;
520 }
521
522 if (0)
523 check_draw_arrays_data(ctx, start, count);
524
525 _mesa_draw_arrays(ctx, mode, start, count, 1, 0, 0);
526
527 if (0)
528 print_draw_arrays(ctx, mode, start, count);
529 }
530
531
532 /**
533 * Called from glDrawArraysInstanced when in immediate mode (not
534 * display list mode).
535 */
536 void GLAPIENTRY
537 _mesa_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count,
538 GLsizei numInstances)
539 {
540 GET_CURRENT_CONTEXT(ctx);
541
542 if (MESA_VERBOSE & VERBOSE_DRAW)
543 _mesa_debug(ctx, "glDrawArraysInstanced(%s, %d, %d, %d)\n",
544 _mesa_enum_to_string(mode), start, count, numInstances);
545
546 FLUSH_FOR_DRAW(ctx);
547
548 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
549
550 if (_mesa_is_no_error_enabled(ctx)) {
551 if (ctx->NewState)
552 _mesa_update_state(ctx);
553 } else {
554 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, start, count,
555 numInstances))
556 return;
557 }
558
559 if (0)
560 check_draw_arrays_data(ctx, start, count);
561
562 _mesa_draw_arrays(ctx, mode, start, count, numInstances, 0, 0);
563
564 if (0)
565 print_draw_arrays(ctx, mode, start, count);
566 }
567
568
569 /**
570 * Called from glDrawArraysInstancedBaseInstance when in immediate mode.
571 */
572 static void GLAPIENTRY
573 _mesa_exec_DrawArraysInstancedBaseInstance(GLenum mode, GLint first,
574 GLsizei count, GLsizei numInstances,
575 GLuint baseInstance)
576 {
577 GET_CURRENT_CONTEXT(ctx);
578
579 if (MESA_VERBOSE & VERBOSE_DRAW)
580 _mesa_debug(ctx,
581 "glDrawArraysInstancedBaseInstance(%s, %d, %d, %d, %d)\n",
582 _mesa_enum_to_string(mode), first, count,
583 numInstances, baseInstance);
584
585 FLUSH_FOR_DRAW(ctx);
586
587 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
588
589 if (_mesa_is_no_error_enabled(ctx)) {
590 if (ctx->NewState)
591 _mesa_update_state(ctx);
592 } else {
593 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, first, count,
594 numInstances))
595 return;
596 }
597
598 if (0)
599 check_draw_arrays_data(ctx, first, count);
600
601 _mesa_draw_arrays(ctx, mode, first, count, numInstances, baseInstance, 0);
602
603 if (0)
604 print_draw_arrays(ctx, mode, first, count);
605 }
606
607
608 #define MAX_ALLOCA_PRIMS (50000 / sizeof(*prim))
609
610 /* Use calloc for large allocations and alloca for small allocations. */
611 /* We have to use a macro because alloca is local within the function. */
612 #define ALLOC_PRIMS(prim, primcount, func) do { \
613 if (unlikely(primcount > MAX_ALLOCA_PRIMS)) { \
614 prim = calloc(primcount, sizeof(*prim)); \
615 if (!prim) { \
616 _mesa_error(ctx, GL_OUT_OF_MEMORY, func); \
617 return; \
618 } \
619 } else { \
620 prim = alloca(primcount * sizeof(*prim)); \
621 } \
622 } while (0)
623
624 #define FREE_PRIMS(prim, primcount) do { \
625 if (primcount > MAX_ALLOCA_PRIMS) \
626 free(prim); \
627 } while (0)
628
629
630 /**
631 * Called from glMultiDrawArrays when in immediate mode.
632 */
633 static void GLAPIENTRY
634 _mesa_exec_MultiDrawArrays(GLenum mode, const GLint *first,
635 const GLsizei *count, GLsizei primcount)
636 {
637 GET_CURRENT_CONTEXT(ctx);
638 GLint i;
639
640 if (MESA_VERBOSE & VERBOSE_DRAW)
641 _mesa_debug(ctx,
642 "glMultiDrawArrays(%s, %p, %p, %d)\n",
643 _mesa_enum_to_string(mode), first, count, primcount);
644
645 FLUSH_FOR_DRAW(ctx);
646
647 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
648
649 if (_mesa_is_no_error_enabled(ctx)) {
650 if (ctx->NewState)
651 _mesa_update_state(ctx);
652 } else {
653 if (!_mesa_validate_MultiDrawArrays(ctx, mode, count, primcount))
654 return;
655 }
656
657 if (skip_validated_draw(ctx))
658 return;
659
660 struct _mesa_prim *prim;
661
662 ALLOC_PRIMS(prim, primcount, "glMultiDrawElements");
663
664 for (i = 0; i < primcount; i++) {
665 prim[i].begin = 1;
666 prim[i].end = 1;
667 prim[i].mode = mode;
668 prim[i].draw_id = i;
669 prim[i].start = first[i];
670 prim[i].count = count[i];
671 prim[i].basevertex = 0;
672 }
673
674 ctx->Driver.Draw(ctx, prim, primcount, NULL, GL_FALSE, 0, 0, 1, 0,
675 NULL, 0);
676
677 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
678 _mesa_flush(ctx);
679
680 FREE_PRIMS(prim, primcount);
681 }
682
683
684
685 /**
686 * Map GL_ELEMENT_ARRAY_BUFFER and print contents.
687 * For debugging.
688 */
689 #if 0
690 static void
691 dump_element_buffer(struct gl_context *ctx, GLenum type)
692 {
693 const GLvoid *map =
694 ctx->Driver.MapBufferRange(ctx, 0,
695 ctx->Array.VAO->IndexBufferObj->Size,
696 GL_MAP_READ_BIT,
697 ctx->Array.VAO->IndexBufferObj,
698 MAP_INTERNAL);
699 switch (type) {
700 case GL_UNSIGNED_BYTE:
701 {
702 const GLubyte *us = (const GLubyte *) map;
703 GLint i;
704 for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size; i++) {
705 printf("%02x ", us[i]);
706 if (i % 32 == 31)
707 printf("\n");
708 }
709 printf("\n");
710 }
711 break;
712 case GL_UNSIGNED_SHORT:
713 {
714 const GLushort *us = (const GLushort *) map;
715 GLint i;
716 for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size / 2; i++) {
717 printf("%04x ", us[i]);
718 if (i % 16 == 15)
719 printf("\n");
720 }
721 printf("\n");
722 }
723 break;
724 case GL_UNSIGNED_INT:
725 {
726 const GLuint *us = (const GLuint *) map;
727 GLint i;
728 for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size / 4; i++) {
729 printf("%08x ", us[i]);
730 if (i % 8 == 7)
731 printf("\n");
732 }
733 printf("\n");
734 }
735 break;
736 default:
737 ;
738 }
739
740 ctx->Driver.UnmapBuffer(ctx, ctx->Array.VAO->IndexBufferObj, MAP_INTERNAL);
741 }
742 #endif
743
744
745 static bool
746 skip_draw_elements(struct gl_context *ctx, GLsizei count,
747 const GLvoid *indices)
748 {
749 if (count == 0)
750 return true;
751
752 /* Not using a VBO for indices, so avoid NULL pointer derefs later.
753 */
754 if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj) && indices == NULL)
755 return true;
756
757 if (skip_validated_draw(ctx))
758 return true;
759
760 return false;
761 }
762
763
764 /**
765 * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements.
766 * Do the rendering for a glDrawElements or glDrawRangeElements call after
767 * we've validated buffer bounds, etc.
768 */
769 static void
770 _mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
771 GLboolean index_bounds_valid,
772 GLuint start, GLuint end,
773 GLsizei count, GLenum type,
774 const GLvoid * indices,
775 GLint basevertex, GLuint numInstances,
776 GLuint baseInstance)
777 {
778 struct _mesa_index_buffer ib;
779 struct _mesa_prim prim;
780
781 if (!index_bounds_valid) {
782 assert(start == 0u);
783 assert(end == ~0u);
784 }
785
786 if (skip_draw_elements(ctx, count, indices))
787 return;
788
789 ib.count = count;
790 ib.obj = ctx->Array.VAO->IndexBufferObj;
791 ib.ptr = indices;
792 get_index_size(type, &ib);
793
794 prim.begin = 1;
795 prim.end = 1;
796 prim.mode = mode;
797 prim.start = 0;
798 prim.count = count;
799 prim.basevertex = basevertex;
800 prim.draw_id = 0;
801
802 /* Need to give special consideration to rendering a range of
803 * indices starting somewhere above zero. Typically the
804 * application is issuing multiple DrawRangeElements() to draw
805 * successive primitives layed out linearly in the vertex arrays.
806 * Unless the vertex arrays are all in a VBO (or locked as with
807 * CVA), the OpenGL semantics imply that we need to re-read or
808 * re-upload the vertex data on each draw call.
809 *
810 * In the case of hardware tnl, we want to avoid starting the
811 * upload at zero, as it will mean every draw call uploads an
812 * increasing amount of not-used vertex data. Worse - in the
813 * software tnl module, all those vertices might be transformed and
814 * lit but never rendered.
815 *
816 * If we just upload or transform the vertices in start..end,
817 * however, the indices will be incorrect.
818 *
819 * At this level, we don't know exactly what the requirements of
820 * the backend are going to be, though it will likely boil down to
821 * either:
822 *
823 * 1) Do nothing, everything is in a VBO and is processed once
824 * only.
825 *
826 * 2) Adjust the indices and vertex arrays so that start becomes
827 * zero.
828 *
829 * Rather than doing anything here, I'll provide a helper function
830 * for the latter case elsewhere.
831 */
832
833 ctx->Driver.Draw(ctx, &prim, 1, &ib,
834 index_bounds_valid, start, end,
835 numInstances, baseInstance, NULL, 0);
836
837 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
838 _mesa_flush(ctx);
839 }
840 }
841
842
843 /**
844 * Called by glDrawRangeElementsBaseVertex() in immediate mode.
845 */
846 void GLAPIENTRY
847 _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
848 GLsizei count, GLenum type,
849 const GLvoid * indices, GLint basevertex)
850 {
851 static GLuint warnCount = 0;
852 GLboolean index_bounds_valid = GL_TRUE;
853
854 /* This is only useful to catch invalid values in the "end" parameter
855 * like ~0.
856 */
857 GLuint max_element = 2 * 1000 * 1000 * 1000; /* just a big number */
858
859 GET_CURRENT_CONTEXT(ctx);
860
861 if (MESA_VERBOSE & VERBOSE_DRAW)
862 _mesa_debug(ctx,
863 "glDrawRangeElementsBaseVertex(%s, %u, %u, %d, %s, %p, %d)\n",
864 _mesa_enum_to_string(mode), start, end, count,
865 _mesa_enum_to_string(type), indices, basevertex);
866
867 FLUSH_FOR_DRAW(ctx);
868
869 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
870
871 if (_mesa_is_no_error_enabled(ctx)) {
872 if (ctx->NewState)
873 _mesa_update_state(ctx);
874 } else {
875 if (!_mesa_validate_DrawRangeElements(ctx, mode, start, end, count,
876 type, indices))
877 return;
878 }
879
880 if ((int) end + basevertex < 0 || start + basevertex >= max_element) {
881 /* The application requested we draw using a range of indices that's
882 * outside the bounds of the current VBO. This is invalid and appears
883 * to give undefined results. The safest thing to do is to simply
884 * ignore the range, in case the application botched their range tracking
885 * but did provide valid indices. Also issue a warning indicating that
886 * the application is broken.
887 */
888 if (warnCount++ < 10) {
889 _mesa_warning(ctx, "glDrawRangeElements(start %u, end %u, "
890 "basevertex %d, count %d, type 0x%x, indices=%p):\n"
891 "\trange is outside VBO bounds (max=%u); ignoring.\n"
892 "\tThis should be fixed in the application.",
893 start, end, basevertex, count, type, indices,
894 max_element - 1);
895 }
896 index_bounds_valid = GL_FALSE;
897 }
898
899 /* NOTE: It's important that 'end' is a reasonable value.
900 * in _tnl_draw_prims(), we use end to determine how many vertices
901 * to transform. If it's too large, we can unnecessarily split prims
902 * or we can read/write out of memory in several different places!
903 */
904
905 /* Catch/fix some potential user errors */
906 if (type == GL_UNSIGNED_BYTE) {
907 start = MIN2(start, 0xff);
908 end = MIN2(end, 0xff);
909 }
910 else if (type == GL_UNSIGNED_SHORT) {
911 start = MIN2(start, 0xffff);
912 end = MIN2(end, 0xffff);
913 }
914
915 if (0) {
916 printf("glDraw[Range]Elements{,BaseVertex}"
917 "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, "
918 "base %d\n",
919 start, end, type, count,
920 ctx->Array.VAO->IndexBufferObj->Name, basevertex);
921 }
922
923 if ((int) start + basevertex < 0 || end + basevertex >= max_element)
924 index_bounds_valid = GL_FALSE;
925
926 #if 0
927 check_draw_elements_data(ctx, count, type, indices, basevertex);
928 #else
929 (void) check_draw_elements_data;
930 #endif
931
932 if (!index_bounds_valid) {
933 start = 0;
934 end = ~0;
935 }
936
937 _mesa_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end,
938 count, type, indices, basevertex, 1, 0);
939 }
940
941
942 /**
943 * Called by glDrawRangeElements() in immediate mode.
944 */
945 void GLAPIENTRY
946 _mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
947 GLsizei count, GLenum type, const GLvoid * indices)
948 {
949 if (MESA_VERBOSE & VERBOSE_DRAW) {
950 GET_CURRENT_CONTEXT(ctx);
951 _mesa_debug(ctx,
952 "glDrawRangeElements(%s, %u, %u, %d, %s, %p)\n",
953 _mesa_enum_to_string(mode), start, end, count,
954 _mesa_enum_to_string(type), indices);
955 }
956
957 _mesa_DrawRangeElementsBaseVertex(mode, start, end, count, type,
958 indices, 0);
959 }
960
961
962 /**
963 * Called by glDrawElements() in immediate mode.
964 */
965 void GLAPIENTRY
966 _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
967 const GLvoid * indices)
968 {
969 GET_CURRENT_CONTEXT(ctx);
970
971 if (MESA_VERBOSE & VERBOSE_DRAW)
972 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n",
973 _mesa_enum_to_string(mode), count,
974 _mesa_enum_to_string(type), indices);
975
976 FLUSH_FOR_DRAW(ctx);
977
978 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
979
980 if (_mesa_is_no_error_enabled(ctx)) {
981 if (ctx->NewState)
982 _mesa_update_state(ctx);
983 } else {
984 if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices))
985 return;
986 }
987
988 _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0,
989 count, type, indices, 0, 1, 0);
990 }
991
992
993 /**
994 * Called by glDrawElementsBaseVertex() in immediate mode.
995 */
996 void GLAPIENTRY
997 _mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
998 const GLvoid * indices, GLint basevertex)
999 {
1000 GET_CURRENT_CONTEXT(ctx);
1001
1002 if (MESA_VERBOSE & VERBOSE_DRAW)
1003 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n",
1004 _mesa_enum_to_string(mode), count,
1005 _mesa_enum_to_string(type), indices);
1006
1007 FLUSH_FOR_DRAW(ctx);
1008
1009 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1010
1011 if (_mesa_is_no_error_enabled(ctx)) {
1012 if (ctx->NewState)
1013 _mesa_update_state(ctx);
1014 } else {
1015 if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices))
1016 return;
1017 }
1018
1019 _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0,
1020 count, type, indices, basevertex, 1, 0);
1021 }
1022
1023
1024 /**
1025 * Called by glDrawElementsInstanced() in immediate mode.
1026 */
1027 static void GLAPIENTRY
1028 _mesa_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
1029 const GLvoid * indices, GLsizei numInstances)
1030 {
1031 GET_CURRENT_CONTEXT(ctx);
1032
1033 if (MESA_VERBOSE & VERBOSE_DRAW)
1034 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n",
1035 _mesa_enum_to_string(mode), count,
1036 _mesa_enum_to_string(type), indices);
1037
1038 FLUSH_FOR_DRAW(ctx);
1039
1040 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1041
1042 if (_mesa_is_no_error_enabled(ctx)) {
1043 if (ctx->NewState)
1044 _mesa_update_state(ctx);
1045 } else {
1046 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type,
1047 indices, numInstances))
1048 return;
1049 }
1050
1051 _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0,
1052 count, type, indices, 0, numInstances, 0);
1053 }
1054
1055
1056 /**
1057 * Called by glDrawElementsInstancedBaseVertex() in immediate mode.
1058 */
1059 static void GLAPIENTRY
1060 _mesa_exec_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count,
1061 GLenum type, const GLvoid * indices,
1062 GLsizei numInstances,
1063 GLint basevertex)
1064 {
1065 GET_CURRENT_CONTEXT(ctx);
1066
1067 if (MESA_VERBOSE & VERBOSE_DRAW)
1068 _mesa_debug(ctx,
1069 "glDrawElementsInstancedBaseVertex"
1070 "(%s, %d, %s, %p, %d; %d)\n",
1071 _mesa_enum_to_string(mode), count,
1072 _mesa_enum_to_string(type), indices,
1073 numInstances, basevertex);
1074
1075 FLUSH_FOR_DRAW(ctx);
1076
1077 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1078
1079 if (_mesa_is_no_error_enabled(ctx)) {
1080 if (ctx->NewState)
1081 _mesa_update_state(ctx);
1082 } else {
1083 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type,
1084 indices, numInstances))
1085 return;
1086 }
1087
1088 _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0,
1089 count, type, indices,
1090 basevertex, numInstances, 0);
1091 }
1092
1093
1094 /**
1095 * Called by glDrawElementsInstancedBaseInstance() in immediate mode.
1096 */
1097 static void GLAPIENTRY
1098 _mesa_exec_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count,
1099 GLenum type,
1100 const GLvoid *indices,
1101 GLsizei numInstances,
1102 GLuint baseInstance)
1103 {
1104 GET_CURRENT_CONTEXT(ctx);
1105
1106 if (MESA_VERBOSE & VERBOSE_DRAW)
1107 _mesa_debug(ctx,
1108 "glDrawElementsInstancedBaseInstance"
1109 "(%s, %d, %s, %p, %d, %d)\n",
1110 _mesa_enum_to_string(mode), count,
1111 _mesa_enum_to_string(type), indices,
1112 numInstances, baseInstance);
1113
1114 FLUSH_FOR_DRAW(ctx);
1115
1116 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1117
1118 if (_mesa_is_no_error_enabled(ctx)) {
1119 if (ctx->NewState)
1120 _mesa_update_state(ctx);
1121 } else {
1122 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type,
1123 indices, numInstances))
1124 return;
1125 }
1126
1127 _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0,
1128 count, type, indices, 0, numInstances,
1129 baseInstance);
1130 }
1131
1132
1133 /**
1134 * Called by glDrawElementsInstancedBaseVertexBaseInstance() in immediate mode.
1135 */
1136 static void GLAPIENTRY
1137 _mesa_exec_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode,
1138 GLsizei count,
1139 GLenum type,
1140 const GLvoid *indices,
1141 GLsizei numInstances,
1142 GLint basevertex,
1143 GLuint baseInstance)
1144 {
1145 GET_CURRENT_CONTEXT(ctx);
1146
1147 if (MESA_VERBOSE & VERBOSE_DRAW)
1148 _mesa_debug(ctx,
1149 "glDrawElementsInstancedBaseVertexBaseInstance"
1150 "(%s, %d, %s, %p, %d, %d, %d)\n",
1151 _mesa_enum_to_string(mode), count,
1152 _mesa_enum_to_string(type), indices,
1153 numInstances, basevertex, baseInstance);
1154
1155 FLUSH_FOR_DRAW(ctx);
1156
1157 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1158
1159 if (_mesa_is_no_error_enabled(ctx)) {
1160 if (ctx->NewState)
1161 _mesa_update_state(ctx);
1162 } else {
1163 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type,
1164 indices, numInstances))
1165 return;
1166 }
1167
1168 _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0,
1169 count, type, indices, basevertex,
1170 numInstances, baseInstance);
1171 }
1172
1173
1174 /**
1175 * Inner support for both _mesa_MultiDrawElements() and
1176 * _mesa_MultiDrawRangeElements().
1177 * This does the actual rendering after we've checked array indexes, etc.
1178 */
1179 static void
1180 _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
1181 const GLsizei *count, GLenum type,
1182 const GLvoid * const *indices,
1183 GLsizei primcount, const GLint *basevertex)
1184 {
1185 struct _mesa_index_buffer ib;
1186 uintptr_t min_index_ptr, max_index_ptr;
1187 GLboolean fallback = GL_FALSE;
1188 int i;
1189
1190 if (primcount == 0)
1191 return;
1192
1193 get_index_size(type, &ib);
1194
1195 min_index_ptr = (uintptr_t) indices[0];
1196 max_index_ptr = 0;
1197 for (i = 0; i < primcount; i++) {
1198 min_index_ptr = MIN2(min_index_ptr, (uintptr_t) indices[i]);
1199 max_index_ptr = MAX2(max_index_ptr, (uintptr_t) indices[i] +
1200 (count[i] << ib.index_size_shift));
1201 }
1202
1203 /* Check if we can handle this thing as a bunch of index offsets from the
1204 * same index pointer. If we can't, then we have to fall back to doing
1205 * a draw_prims per primitive.
1206 * Check that the difference between each prim's indexes is a multiple of
1207 * the index/element size.
1208 */
1209 if (ib.index_size_shift) {
1210 for (i = 0; i < primcount; i++) {
1211 if ((((uintptr_t) indices[i] - min_index_ptr) &
1212 ((1 << ib.index_size_shift) - 1)) != 0) {
1213 fallback = GL_TRUE;
1214 break;
1215 }
1216 }
1217 }
1218
1219 /* If the index buffer isn't in a VBO, then treating the application's
1220 * subranges of the index buffer as one large index buffer may lead to
1221 * us reading unmapped memory.
1222 */
1223 if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj))
1224 fallback = GL_TRUE;
1225
1226 if (!fallback) {
1227 struct _mesa_prim *prim;
1228
1229 ALLOC_PRIMS(prim, primcount, "glMultiDrawElements");
1230
1231 ib.count = (max_index_ptr - min_index_ptr) >> ib.index_size_shift;
1232 ib.obj = ctx->Array.VAO->IndexBufferObj;
1233 ib.ptr = (void *) min_index_ptr;
1234
1235 for (i = 0; i < primcount; i++) {
1236 prim[i].begin = 1;
1237 prim[i].end = 1;
1238 prim[i].mode = mode;
1239 prim[i].start =
1240 ((uintptr_t) indices[i] - min_index_ptr) >> ib.index_size_shift;
1241 prim[i].count = count[i];
1242 prim[i].draw_id = i;
1243 if (basevertex != NULL)
1244 prim[i].basevertex = basevertex[i];
1245 else
1246 prim[i].basevertex = 0;
1247 }
1248
1249 ctx->Driver.Draw(ctx, prim, primcount, &ib,
1250 false, 0, ~0, 1, 0, NULL, 0);
1251 FREE_PRIMS(prim, primcount);
1252 }
1253 else {
1254 /* render one prim at a time */
1255 for (i = 0; i < primcount; i++) {
1256 if (count[i] == 0)
1257 continue;
1258
1259 ib.count = count[i];
1260 ib.obj = ctx->Array.VAO->IndexBufferObj;
1261 ib.ptr = indices[i];
1262
1263 struct _mesa_prim prim;
1264 prim.begin = 1;
1265 prim.end = 1;
1266 prim.mode = mode;
1267 prim.start = 0;
1268 prim.count = count[i];
1269 prim.draw_id = i;
1270 if (basevertex != NULL)
1271 prim.basevertex = basevertex[i];
1272 else
1273 prim.basevertex = 0;
1274
1275 ctx->Driver.Draw(ctx, &prim, 1, &ib, false, 0, ~0, 1, 0, NULL, 0);
1276 }
1277 }
1278
1279 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1280 _mesa_flush(ctx);
1281 }
1282 }
1283
1284
1285 void GLAPIENTRY
1286 _mesa_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type,
1287 const GLvoid * const *indices, GLsizei primcount)
1288 {
1289 GET_CURRENT_CONTEXT(ctx);
1290
1291 FLUSH_FOR_DRAW(ctx);
1292
1293 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1294
1295 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
1296 primcount))
1297 return;
1298
1299 if (skip_validated_draw(ctx))
1300 return;
1301
1302 _mesa_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
1303 NULL);
1304 }
1305
1306
1307 void GLAPIENTRY
1308 _mesa_MultiDrawElementsBaseVertex(GLenum mode,
1309 const GLsizei *count, GLenum type,
1310 const GLvoid * const *indices,
1311 GLsizei primcount,
1312 const GLsizei *basevertex)
1313 {
1314 GET_CURRENT_CONTEXT(ctx);
1315
1316 FLUSH_FOR_DRAW(ctx);
1317
1318 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1319
1320 if (_mesa_is_no_error_enabled(ctx)) {
1321 if (ctx->NewState)
1322 _mesa_update_state(ctx);
1323 } else {
1324 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
1325 primcount))
1326 return;
1327 }
1328
1329 if (skip_validated_draw(ctx))
1330 return;
1331
1332 _mesa_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
1333 basevertex);
1334 }
1335
1336
1337 /**
1338 * Draw a GL primitive using a vertex count obtained from transform feedback.
1339 * \param mode the type of GL primitive to draw
1340 * \param obj the transform feedback object to use
1341 * \param stream index of the transform feedback stream from which to
1342 * get the primitive count.
1343 * \param numInstances number of instances to draw
1344 */
1345 static void
1346 _mesa_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
1347 struct gl_transform_feedback_object *obj,
1348 GLuint stream, GLuint numInstances)
1349 {
1350 struct _mesa_prim prim;
1351
1352 FLUSH_FOR_DRAW(ctx);
1353
1354 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1355
1356 if (_mesa_is_no_error_enabled(ctx)) {
1357 if (ctx->NewState)
1358 _mesa_update_state(ctx);
1359 } else {
1360 if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream,
1361 numInstances)) {
1362 return;
1363 }
1364 }
1365
1366 if (ctx->Driver.GetTransformFeedbackVertexCount &&
1367 (ctx->Const.AlwaysUseGetTransformFeedbackVertexCount ||
1368 !_mesa_all_varyings_in_vbos(ctx->Array.VAO))) {
1369 GLsizei n =
1370 ctx->Driver.GetTransformFeedbackVertexCount(ctx, obj, stream);
1371 _mesa_draw_arrays(ctx, mode, 0, n, numInstances, 0, 0);
1372 return;
1373 }
1374
1375 if (skip_validated_draw(ctx))
1376 return;
1377
1378 /* init most fields to zero */
1379 memset(&prim, 0, sizeof(prim));
1380 prim.begin = 1;
1381 prim.end = 1;
1382 prim.mode = mode;
1383
1384 /* Maybe we should do some primitive splitting for primitive restart
1385 * (like in DrawArrays), but we have no way to know how many vertices
1386 * will be rendered. */
1387
1388 ctx->Driver.Draw(ctx, &prim, 1, NULL, GL_FALSE, 0, ~0, numInstances, 0,
1389 obj, stream);
1390
1391 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1392 _mesa_flush(ctx);
1393 }
1394 }
1395
1396
1397 /**
1398 * Like DrawArrays, but take the count from a transform feedback object.
1399 * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc.
1400 * \param name the transform feedback object
1401 * User still has to setup of the vertex attribute info with
1402 * glVertexPointer, glColorPointer, etc.
1403 * Part of GL_ARB_transform_feedback2.
1404 */
1405 void GLAPIENTRY
1406 _mesa_DrawTransformFeedback(GLenum mode, GLuint name)
1407 {
1408 GET_CURRENT_CONTEXT(ctx);
1409 struct gl_transform_feedback_object *obj =
1410 _mesa_lookup_transform_feedback_object(ctx, name);
1411
1412 if (MESA_VERBOSE & VERBOSE_DRAW)
1413 _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n",
1414 _mesa_enum_to_string(mode), name);
1415
1416 _mesa_draw_transform_feedback(ctx, mode, obj, 0, 1);
1417 }
1418
1419
1420 static void GLAPIENTRY
1421 _mesa_exec_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream)
1422 {
1423 GET_CURRENT_CONTEXT(ctx);
1424 struct gl_transform_feedback_object *obj =
1425 _mesa_lookup_transform_feedback_object(ctx, name);
1426
1427 if (MESA_VERBOSE & VERBOSE_DRAW)
1428 _mesa_debug(ctx, "glDrawTransformFeedbackStream(%s, %u, %u)\n",
1429 _mesa_enum_to_string(mode), name, stream);
1430
1431 _mesa_draw_transform_feedback(ctx, mode, obj, stream, 1);
1432 }
1433
1434
1435 static void GLAPIENTRY
1436 _mesa_exec_DrawTransformFeedbackInstanced(GLenum mode, GLuint name,
1437 GLsizei primcount)
1438 {
1439 GET_CURRENT_CONTEXT(ctx);
1440 struct gl_transform_feedback_object *obj =
1441 _mesa_lookup_transform_feedback_object(ctx, name);
1442
1443 if (MESA_VERBOSE & VERBOSE_DRAW)
1444 _mesa_debug(ctx, "glDrawTransformFeedbackInstanced(%s, %d)\n",
1445 _mesa_enum_to_string(mode), name);
1446
1447 _mesa_draw_transform_feedback(ctx, mode, obj, 0, primcount);
1448 }
1449
1450
1451 static void GLAPIENTRY
1452 _mesa_exec_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name,
1453 GLuint stream,
1454 GLsizei primcount)
1455 {
1456 GET_CURRENT_CONTEXT(ctx);
1457 struct gl_transform_feedback_object *obj =
1458 _mesa_lookup_transform_feedback_object(ctx, name);
1459
1460 if (MESA_VERBOSE & VERBOSE_DRAW)
1461 _mesa_debug(ctx, "glDrawTransformFeedbackStreamInstanced"
1462 "(%s, %u, %u, %i)\n",
1463 _mesa_enum_to_string(mode), name, stream, primcount);
1464
1465 _mesa_draw_transform_feedback(ctx, mode, obj, stream, primcount);
1466 }
1467
1468
1469 static void
1470 _mesa_validated_drawarraysindirect(struct gl_context *ctx,
1471 GLenum mode, const GLvoid *indirect)
1472 {
1473 ctx->Driver.DrawIndirect(ctx, mode,
1474 ctx->DrawIndirectBuffer, (GLsizeiptr) indirect,
1475 1 /* draw_count */ , 16 /* stride */ ,
1476 NULL, 0, NULL);
1477
1478 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1479 _mesa_flush(ctx);
1480 }
1481
1482
1483 static void
1484 _mesa_validated_multidrawarraysindirect(struct gl_context *ctx,
1485 GLenum mode,
1486 const GLvoid *indirect,
1487 GLsizei primcount, GLsizei stride)
1488 {
1489 GLsizeiptr offset = (GLsizeiptr) indirect;
1490
1491 if (primcount == 0)
1492 return;
1493
1494 ctx->Driver.DrawIndirect(ctx, mode, ctx->DrawIndirectBuffer, offset,
1495 primcount, stride, NULL, 0, NULL);
1496
1497 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1498 _mesa_flush(ctx);
1499 }
1500
1501
1502 static void
1503 _mesa_validated_drawelementsindirect(struct gl_context *ctx,
1504 GLenum mode, GLenum type,
1505 const GLvoid *indirect)
1506 {
1507 struct _mesa_index_buffer ib;
1508
1509 ib.count = 0; /* unknown */
1510 ib.obj = ctx->Array.VAO->IndexBufferObj;
1511 ib.ptr = NULL;
1512 get_index_size(type, &ib);
1513
1514 ctx->Driver.DrawIndirect(ctx, mode,
1515 ctx->DrawIndirectBuffer, (GLsizeiptr) indirect,
1516 1 /* draw_count */ , 20 /* stride */ ,
1517 NULL, 0, &ib);
1518
1519 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1520 _mesa_flush(ctx);
1521 }
1522
1523
1524 static void
1525 _mesa_validated_multidrawelementsindirect(struct gl_context *ctx,
1526 GLenum mode, GLenum type,
1527 const GLvoid *indirect,
1528 GLsizei primcount, GLsizei stride)
1529 {
1530 struct _mesa_index_buffer ib;
1531 GLsizeiptr offset = (GLsizeiptr) indirect;
1532
1533 if (primcount == 0)
1534 return;
1535
1536 /* NOTE: IndexBufferObj is guaranteed to be a VBO. */
1537
1538 ib.count = 0; /* unknown */
1539 ib.obj = ctx->Array.VAO->IndexBufferObj;
1540 ib.ptr = NULL;
1541 get_index_size(type, &ib);
1542
1543 ctx->Driver.DrawIndirect(ctx, mode,
1544 ctx->DrawIndirectBuffer, offset,
1545 primcount, stride, NULL, 0, &ib);
1546
1547 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1548 _mesa_flush(ctx);
1549 }
1550
1551
1552 /**
1553 * Like [Multi]DrawArrays/Elements, but they take most arguments from
1554 * a buffer object.
1555 */
1556 static void GLAPIENTRY
1557 _mesa_exec_DrawArraysIndirect(GLenum mode, const GLvoid *indirect)
1558 {
1559 GET_CURRENT_CONTEXT(ctx);
1560
1561 if (MESA_VERBOSE & VERBOSE_DRAW)
1562 _mesa_debug(ctx, "glDrawArraysIndirect(%s, %p)\n",
1563 _mesa_enum_to_string(mode), indirect);
1564
1565 /* From the ARB_draw_indirect spec:
1566 *
1567 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
1568 * compatibility profile, this indicates that DrawArraysIndirect and
1569 * DrawElementsIndirect are to source their arguments directly from the
1570 * pointer passed as their <indirect> parameters."
1571 */
1572 if (ctx->API == API_OPENGL_COMPAT &&
1573 !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) {
1574 DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) indirect;
1575
1576 _mesa_exec_DrawArraysInstancedBaseInstance(mode, cmd->first, cmd->count,
1577 cmd->primCount,
1578 cmd->baseInstance);
1579 return;
1580 }
1581
1582 FLUSH_FOR_DRAW(ctx);
1583
1584 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1585
1586 if (_mesa_is_no_error_enabled(ctx)) {
1587 if (ctx->NewState)
1588 _mesa_update_state(ctx);
1589 } else {
1590 if (!_mesa_validate_DrawArraysIndirect(ctx, mode, indirect))
1591 return;
1592 }
1593
1594 if (skip_validated_draw(ctx))
1595 return;
1596
1597 _mesa_validated_drawarraysindirect(ctx, mode, indirect);
1598 }
1599
1600
1601 static void GLAPIENTRY
1602 _mesa_exec_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1603 {
1604 GET_CURRENT_CONTEXT(ctx);
1605
1606 if (MESA_VERBOSE & VERBOSE_DRAW)
1607 _mesa_debug(ctx, "glDrawElementsIndirect(%s, %s, %p)\n",
1608 _mesa_enum_to_string(mode),
1609 _mesa_enum_to_string(type), indirect);
1610
1611 /* From the ARB_draw_indirect spec:
1612 *
1613 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
1614 * compatibility profile, this indicates that DrawArraysIndirect and
1615 * DrawElementsIndirect are to source their arguments directly from the
1616 * pointer passed as their <indirect> parameters."
1617 */
1618 if (ctx->API == API_OPENGL_COMPAT &&
1619 !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) {
1620 /*
1621 * Unlike regular DrawElementsInstancedBaseVertex commands, the indices
1622 * may not come from a client array and must come from an index buffer.
1623 * If no element array buffer is bound, an INVALID_OPERATION error is
1624 * generated.
1625 */
1626 if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) {
1627 _mesa_error(ctx, GL_INVALID_OPERATION,
1628 "glDrawElementsIndirect(no buffer bound "
1629 "to GL_ELEMENT_ARRAY_BUFFER)");
1630 } else {
1631 DrawElementsIndirectCommand *cmd =
1632 (DrawElementsIndirectCommand *) indirect;
1633
1634 /* Convert offset to pointer */
1635 void *offset = (void *)
1636 (uintptr_t)((cmd->firstIndex * _mesa_sizeof_type(type)) & 0xffffffffUL);
1637
1638 _mesa_exec_DrawElementsInstancedBaseVertexBaseInstance(mode, cmd->count,
1639 type, offset,
1640 cmd->primCount,
1641 cmd->baseVertex,
1642 cmd->baseInstance);
1643 }
1644
1645 return;
1646 }
1647
1648 FLUSH_FOR_DRAW(ctx);
1649
1650 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1651
1652 if (_mesa_is_no_error_enabled(ctx)) {
1653 if (ctx->NewState)
1654 _mesa_update_state(ctx);
1655 } else {
1656 if (!_mesa_validate_DrawElementsIndirect(ctx, mode, type, indirect))
1657 return;
1658 }
1659
1660 if (skip_validated_draw(ctx))
1661 return;
1662
1663 _mesa_validated_drawelementsindirect(ctx, mode, type, indirect);
1664 }
1665
1666
1667 static void GLAPIENTRY
1668 _mesa_exec_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect,
1669 GLsizei primcount, GLsizei stride)
1670 {
1671 GET_CURRENT_CONTEXT(ctx);
1672
1673 if (MESA_VERBOSE & VERBOSE_DRAW)
1674 _mesa_debug(ctx, "glMultiDrawArraysIndirect(%s, %p, %i, %i)\n",
1675 _mesa_enum_to_string(mode), indirect, primcount, stride);
1676
1677 /* If <stride> is zero, the array elements are treated as tightly packed. */
1678 if (stride == 0)
1679 stride = sizeof(DrawArraysIndirectCommand);
1680
1681 /* From the ARB_draw_indirect spec:
1682 *
1683 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
1684 * compatibility profile, this indicates that DrawArraysIndirect and
1685 * DrawElementsIndirect are to source their arguments directly from the
1686 * pointer passed as their <indirect> parameters."
1687 */
1688 if (ctx->API == API_OPENGL_COMPAT &&
1689 !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) {
1690
1691 if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
1692 "glMultiDrawArraysIndirect"))
1693 return;
1694
1695 const uint8_t *ptr = (const uint8_t *) indirect;
1696 for (unsigned i = 0; i < primcount; i++) {
1697 DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) ptr;
1698 _mesa_exec_DrawArraysInstancedBaseInstance(mode, cmd->first,
1699 cmd->count, cmd->primCount,
1700 cmd->baseInstance);
1701
1702 if (stride == 0) {
1703 ptr += sizeof(DrawArraysIndirectCommand);
1704 } else {
1705 ptr += stride;
1706 }
1707 }
1708
1709 return;
1710 }
1711
1712 FLUSH_FOR_DRAW(ctx);
1713
1714 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1715
1716 if (_mesa_is_no_error_enabled(ctx)) {
1717 if (ctx->NewState)
1718 _mesa_update_state(ctx);
1719 } else {
1720 if (!_mesa_validate_MultiDrawArraysIndirect(ctx, mode, indirect,
1721 primcount, stride))
1722 return;
1723 }
1724
1725 if (skip_validated_draw(ctx))
1726 return;
1727
1728 _mesa_validated_multidrawarraysindirect(ctx, mode, indirect,
1729 primcount, stride);
1730 }
1731
1732
1733 static void GLAPIENTRY
1734 _mesa_exec_MultiDrawElementsIndirect(GLenum mode, GLenum type,
1735 const GLvoid *indirect,
1736 GLsizei primcount, GLsizei stride)
1737 {
1738 GET_CURRENT_CONTEXT(ctx);
1739
1740 if (MESA_VERBOSE & VERBOSE_DRAW)
1741 _mesa_debug(ctx, "glMultiDrawElementsIndirect(%s, %s, %p, %i, %i)\n",
1742 _mesa_enum_to_string(mode),
1743 _mesa_enum_to_string(type), indirect, primcount, stride);
1744
1745 /* If <stride> is zero, the array elements are treated as tightly packed. */
1746 if (stride == 0)
1747 stride = sizeof(DrawElementsIndirectCommand);
1748
1749
1750 /* From the ARB_draw_indirect spec:
1751 *
1752 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
1753 * compatibility profile, this indicates that DrawArraysIndirect and
1754 * DrawElementsIndirect are to source their arguments directly from the
1755 * pointer passed as their <indirect> parameters."
1756 */
1757 if (ctx->API == API_OPENGL_COMPAT &&
1758 !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) {
1759 /*
1760 * Unlike regular DrawElementsInstancedBaseVertex commands, the indices
1761 * may not come from a client array and must come from an index buffer.
1762 * If no element array buffer is bound, an INVALID_OPERATION error is
1763 * generated.
1764 */
1765 if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) {
1766 _mesa_error(ctx, GL_INVALID_OPERATION,
1767 "glMultiDrawElementsIndirect(no buffer bound "
1768 "to GL_ELEMENT_ARRAY_BUFFER)");
1769
1770 return;
1771 }
1772
1773 if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
1774 "glMultiDrawArraysIndirect"))
1775 return;
1776
1777 const uint8_t *ptr = (const uint8_t *) indirect;
1778 for (unsigned i = 0; i < primcount; i++) {
1779 _mesa_exec_DrawElementsIndirect(mode, type, ptr);
1780
1781 if (stride == 0) {
1782 ptr += sizeof(DrawElementsIndirectCommand);
1783 } else {
1784 ptr += stride;
1785 }
1786 }
1787
1788 return;
1789 }
1790
1791 FLUSH_FOR_DRAW(ctx);
1792
1793 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1794
1795 if (_mesa_is_no_error_enabled(ctx)) {
1796 if (ctx->NewState)
1797 _mesa_update_state(ctx);
1798 } else {
1799 if (!_mesa_validate_MultiDrawElementsIndirect(ctx, mode, type, indirect,
1800 primcount, stride))
1801 return;
1802 }
1803
1804 if (skip_validated_draw(ctx))
1805 return;
1806
1807 _mesa_validated_multidrawelementsindirect(ctx, mode, type, indirect,
1808 primcount, stride);
1809 }
1810
1811
1812 static void
1813 _mesa_validated_multidrawarraysindirectcount(struct gl_context *ctx,
1814 GLenum mode,
1815 GLintptr indirect,
1816 GLintptr drawcount_offset,
1817 GLsizei maxdrawcount,
1818 GLsizei stride)
1819 {
1820 GLsizeiptr offset = indirect;
1821
1822 if (maxdrawcount == 0)
1823 return;
1824
1825 ctx->Driver.DrawIndirect(ctx, mode,
1826 ctx->DrawIndirectBuffer, offset,
1827 maxdrawcount, stride,
1828 ctx->ParameterBuffer, drawcount_offset, NULL);
1829
1830 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1831 _mesa_flush(ctx);
1832 }
1833
1834
1835 static void
1836 _mesa_validated_multidrawelementsindirectcount(struct gl_context *ctx,
1837 GLenum mode, GLenum type,
1838 GLintptr indirect,
1839 GLintptr drawcount_offset,
1840 GLsizei maxdrawcount,
1841 GLsizei stride)
1842 {
1843 struct _mesa_index_buffer ib;
1844 GLsizeiptr offset = (GLsizeiptr) indirect;
1845
1846 if (maxdrawcount == 0)
1847 return;
1848
1849 /* NOTE: IndexBufferObj is guaranteed to be a VBO. */
1850
1851 ib.count = 0; /* unknown */
1852 ib.obj = ctx->Array.VAO->IndexBufferObj;
1853 ib.ptr = NULL;
1854 get_index_size(type, &ib);
1855
1856 ctx->Driver.DrawIndirect(ctx, mode,
1857 ctx->DrawIndirectBuffer, offset,
1858 maxdrawcount, stride,
1859 ctx->ParameterBuffer, drawcount_offset, &ib);
1860
1861 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1862 _mesa_flush(ctx);
1863 }
1864
1865
1866 static void GLAPIENTRY
1867 _mesa_exec_MultiDrawArraysIndirectCount(GLenum mode, GLintptr indirect,
1868 GLintptr drawcount_offset,
1869 GLsizei maxdrawcount, GLsizei stride)
1870 {
1871 GET_CURRENT_CONTEXT(ctx);
1872
1873 if (MESA_VERBOSE & VERBOSE_DRAW)
1874 _mesa_debug(ctx, "glMultiDrawArraysIndirectCountARB"
1875 "(%s, %lx, %lx, %i, %i)\n",
1876 _mesa_enum_to_string(mode),
1877 (unsigned long) indirect, (unsigned long) drawcount_offset,
1878 maxdrawcount, stride);
1879
1880 /* If <stride> is zero, the array elements are treated as tightly packed. */
1881 if (stride == 0)
1882 stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */
1883
1884 FLUSH_FOR_DRAW(ctx);
1885
1886 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1887
1888 if (_mesa_is_no_error_enabled(ctx)) {
1889 if (ctx->NewState)
1890 _mesa_update_state(ctx);
1891 } else {
1892 if (!_mesa_validate_MultiDrawArraysIndirectCount(ctx, mode,
1893 indirect,
1894 drawcount_offset,
1895 maxdrawcount, stride))
1896 return;
1897 }
1898
1899 if (skip_validated_draw(ctx))
1900 return;
1901
1902 _mesa_validated_multidrawarraysindirectcount(ctx, mode, indirect,
1903 drawcount_offset,
1904 maxdrawcount, stride);
1905 }
1906
1907
1908 static void GLAPIENTRY
1909 _mesa_exec_MultiDrawElementsIndirectCount(GLenum mode, GLenum type,
1910 GLintptr indirect,
1911 GLintptr drawcount_offset,
1912 GLsizei maxdrawcount, GLsizei stride)
1913 {
1914 GET_CURRENT_CONTEXT(ctx);
1915
1916 if (MESA_VERBOSE & VERBOSE_DRAW)
1917 _mesa_debug(ctx, "glMultiDrawElementsIndirectCountARB"
1918 "(%s, %s, %lx, %lx, %i, %i)\n",
1919 _mesa_enum_to_string(mode), _mesa_enum_to_string(type),
1920 (unsigned long) indirect, (unsigned long) drawcount_offset,
1921 maxdrawcount, stride);
1922
1923 /* If <stride> is zero, the array elements are treated as tightly packed. */
1924 if (stride == 0)
1925 stride = 5 * sizeof(GLuint); /* sizeof(DrawElementsIndirectCommand) */
1926
1927 FLUSH_FOR_DRAW(ctx);
1928
1929 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1930
1931 if (_mesa_is_no_error_enabled(ctx)) {
1932 if (ctx->NewState)
1933 _mesa_update_state(ctx);
1934 } else {
1935 if (!_mesa_validate_MultiDrawElementsIndirectCount(ctx, mode, type,
1936 indirect,
1937 drawcount_offset,
1938 maxdrawcount, stride))
1939 return;
1940 }
1941
1942 if (skip_validated_draw(ctx))
1943 return;
1944
1945 _mesa_validated_multidrawelementsindirectcount(ctx, mode, type, indirect,
1946 drawcount_offset, maxdrawcount,
1947 stride);
1948 }
1949
1950
1951 /**
1952 * Initialize the dispatch table with the VBO functions for drawing.
1953 */
1954 void
1955 _mesa_initialize_exec_dispatch(const struct gl_context *ctx,
1956 struct _glapi_table *exec)
1957 {
1958 SET_DrawArrays(exec, _mesa_DrawArrays);
1959 SET_DrawElements(exec, _mesa_DrawElements);
1960
1961 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1962 SET_DrawRangeElements(exec, _mesa_DrawRangeElements);
1963 }
1964
1965 SET_MultiDrawArrays(exec, _mesa_exec_MultiDrawArrays);
1966 SET_MultiDrawElementsEXT(exec, _mesa_MultiDrawElements);
1967
1968 if (ctx->API == API_OPENGL_COMPAT) {
1969 SET_Rectf(exec, _mesa_exec_Rectf);
1970 SET_EvalMesh1(exec, _mesa_exec_EvalMesh1);
1971 SET_EvalMesh2(exec, _mesa_exec_EvalMesh2);
1972 }
1973
1974 if (ctx->API != API_OPENGLES &&
1975 ctx->Extensions.ARB_draw_elements_base_vertex) {
1976 SET_DrawElementsBaseVertex(exec, _mesa_DrawElementsBaseVertex);
1977 SET_MultiDrawElementsBaseVertex(exec,
1978 _mesa_MultiDrawElementsBaseVertex);
1979
1980 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1981 SET_DrawRangeElementsBaseVertex(exec,
1982 _mesa_DrawRangeElementsBaseVertex);
1983 SET_DrawElementsInstancedBaseVertex(exec,
1984 _mesa_exec_DrawElementsInstancedBaseVertex);
1985 }
1986 }
1987
1988 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1989 SET_DrawArraysInstancedBaseInstance(exec,
1990 _mesa_exec_DrawArraysInstancedBaseInstance);
1991 SET_DrawElementsInstancedBaseInstance(exec,
1992 _mesa_exec_DrawElementsInstancedBaseInstance);
1993 SET_DrawElementsInstancedBaseVertexBaseInstance(exec,
1994 _mesa_exec_DrawElementsInstancedBaseVertexBaseInstance);
1995 }
1996
1997 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) {
1998 SET_DrawArraysIndirect(exec, _mesa_exec_DrawArraysIndirect);
1999 SET_DrawElementsIndirect(exec, _mesa_exec_DrawElementsIndirect);
2000 }
2001
2002 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
2003 SET_DrawArraysInstancedARB(exec, _mesa_DrawArraysInstanced);
2004 SET_DrawElementsInstancedARB(exec, _mesa_exec_DrawElementsInstanced);
2005 }
2006
2007 if (_mesa_is_desktop_gl(ctx)) {
2008 SET_DrawTransformFeedback(exec, _mesa_DrawTransformFeedback);
2009 SET_DrawTransformFeedbackStream(exec,
2010 _mesa_exec_DrawTransformFeedbackStream);
2011 SET_DrawTransformFeedbackInstanced(exec,
2012 _mesa_exec_DrawTransformFeedbackInstanced);
2013 SET_DrawTransformFeedbackStreamInstanced(exec,
2014 _mesa_exec_DrawTransformFeedbackStreamInstanced);
2015 SET_MultiDrawArraysIndirect(exec, _mesa_exec_MultiDrawArraysIndirect);
2016 SET_MultiDrawElementsIndirect(exec, _mesa_exec_MultiDrawElementsIndirect);
2017 SET_MultiDrawArraysIndirectCountARB(exec,
2018 _mesa_exec_MultiDrawArraysIndirectCount);
2019 SET_MultiDrawElementsIndirectCountARB(exec,
2020 _mesa_exec_MultiDrawElementsIndirectCount);
2021 }
2022 }
2023
2024
2025
2026 /* GL_IBM_multimode_draw_arrays */
2027 void GLAPIENTRY
2028 _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
2029 const GLsizei * count,
2030 GLsizei primcount, GLint modestride )
2031 {
2032 GET_CURRENT_CONTEXT(ctx);
2033 GLint i;
2034
2035 FLUSH_VERTICES(ctx, 0);
2036
2037 for ( i = 0 ; i < primcount ; i++ ) {
2038 if ( count[i] > 0 ) {
2039 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
2040 CALL_DrawArrays(ctx->CurrentServerDispatch, ( m, first[i], count[i] ));
2041 }
2042 }
2043 }
2044
2045
2046 /* GL_IBM_multimode_draw_arrays */
2047 void GLAPIENTRY
2048 _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
2049 GLenum type, const GLvoid * const * indices,
2050 GLsizei primcount, GLint modestride )
2051 {
2052 GET_CURRENT_CONTEXT(ctx);
2053 GLint i;
2054
2055 FLUSH_VERTICES(ctx, 0);
2056
2057 /* XXX not sure about ARB_vertex_buffer_object handling here */
2058
2059 for ( i = 0 ; i < primcount ; i++ ) {
2060 if ( count[i] > 0 ) {
2061 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
2062 CALL_DrawElements(ctx->CurrentServerDispatch, ( m, count[i], type,
2063 indices[i] ));
2064 }
2065 }
2066 }