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