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