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