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