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