xref: /third_party/mesa3d/src/mesa/main/draw.c (revision bf215546)
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#include "pipe/p_state.h"
44#include "api_exec_decl.h"
45
46#include "state_tracker/st_context.h"
47#include "state_tracker/st_draw.h"
48
49typedef struct {
50   GLuint count;
51   GLuint primCount;
52   GLuint first;
53   GLuint baseInstance;
54} DrawArraysIndirectCommand;
55
56typedef struct {
57   GLuint count;
58   GLuint primCount;
59   GLuint firstIndex;
60   GLint  baseVertex;
61   GLuint baseInstance;
62} DrawElementsIndirectCommand;
63
64
65/**
66 * Want to figure out which fragment program inputs are actually
67 * constant/current values from ctx->Current.  These should be
68 * referenced as a tracked state variable rather than a fragment
69 * program input, to save the overhead of putting a constant value in
70 * every submitted vertex, transferring it to hardware, interpolating
71 * it across the triangle, etc...
72 *
73 * When there is a VP bound, just use vp->outputs.  But when we're
74 * generating vp from fixed function state, basically want to
75 * calculate:
76 *
77 * vp_out_2_fp_in( vp_in_2_vp_out( varying_inputs ) |
78 *                 potential_vp_outputs )
79 *
80 * Where potential_vp_outputs is calculated by looking at enabled
81 * texgen, etc.
82 *
83 * The generated fragment program should then only declare inputs that
84 * may vary or otherwise differ from the ctx->Current values.
85 * Otherwise, the fp should track them as state values instead.
86 */
87void
88_mesa_set_varying_vp_inputs(struct gl_context *ctx, GLbitfield varying_inputs)
89{
90   if (ctx->VertexProgram._VPModeOptimizesConstantAttribs &&
91       ctx->VertexProgram._VaryingInputs != varying_inputs) {
92      ctx->VertexProgram._VaryingInputs = varying_inputs;
93      ctx->NewState |= _NEW_FF_VERT_PROGRAM | _NEW_FF_FRAG_PROGRAM;
94   }
95}
96
97
98/**
99 * Set the _DrawVAO and the net enabled arrays.
100 * The vao->_Enabled bitmask is transformed due to position/generic0
101 * as stored in vao->_AttributeMapMode. Then the filter bitmask is applied
102 * to filter out arrays unwanted for the currently executed draw operation.
103 * For example, the generic attributes are masked out form the _DrawVAO's
104 * enabled arrays when a fixed function array draw is executed.
105 */
106void
107_mesa_set_draw_vao(struct gl_context *ctx, struct gl_vertex_array_object *vao,
108                   GLbitfield filter)
109{
110   struct gl_vertex_array_object **ptr = &ctx->Array._DrawVAO;
111   bool new_vertex_buffers = false, new_vertex_elements = false;
112
113   if (*ptr != vao) {
114      _mesa_reference_vao_(ctx, ptr, vao);
115      new_vertex_buffers = true;
116      new_vertex_elements = true;
117   }
118
119   if (vao->NewVertexBuffers || vao->NewVertexElements) {
120      _mesa_update_vao_derived_arrays(ctx, vao);
121      new_vertex_buffers |= vao->NewVertexBuffers;
122      new_vertex_elements |= vao->NewVertexElements;
123      vao->NewVertexBuffers = false;
124      vao->NewVertexElements = false;
125   }
126
127   assert(vao->_EnabledWithMapMode ==
128          _mesa_vao_enable_to_vp_inputs(vao->_AttributeMapMode, vao->Enabled));
129
130   /* Filter out unwanted arrays. */
131   const GLbitfield enabled = filter & vao->_EnabledWithMapMode;
132   if (ctx->Array._DrawVAOEnabledAttribs != enabled) {
133      ctx->Array._DrawVAOEnabledAttribs = enabled;
134      new_vertex_buffers = true;
135      new_vertex_elements = true;
136   }
137
138   if (new_vertex_buffers || new_vertex_elements) {
139      ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS;
140      ctx->Array.NewVertexElements |= new_vertex_elements;
141   }
142
143   _mesa_set_varying_vp_inputs(ctx, enabled);
144}
145
146
147/**
148 * Is 'mode' a valid value for glBegin(), glDrawArrays(), glDrawElements(),
149 * etc?  Also, do additional checking related to transformation feedback.
150 * Note: this function cannot be called during glNewList(GL_COMPILE) because
151 * this code depends on current transform feedback state.
152 * Also, do additional checking related to tessellation shaders.
153 */
154static GLenum
155valid_prim_mode_custom(struct gl_context *ctx, GLenum mode,
156                       GLbitfield valid_prim_mask)
157{
158#if DEBUG
159   unsigned mask = ctx->ValidPrimMask;
160   unsigned mask_indexed = ctx->ValidPrimMaskIndexed;
161   bool drawpix_valid = ctx->DrawPixValid;
162   _mesa_update_valid_to_render_state(ctx);
163   assert(mask == ctx->ValidPrimMask &&
164          mask_indexed == ctx->ValidPrimMaskIndexed &&
165          drawpix_valid == ctx->DrawPixValid);
166#endif
167
168   /* All primitive type enums are less than 32, so we can use the shift. */
169   if (mode >= 32 || !((1u << mode) & valid_prim_mask)) {
170      /* If the primitive type is not in SupportedPrimMask, set GL_INVALID_ENUM,
171       * else set DrawGLError (e.g. GL_INVALID_OPERATION).
172       */
173      return mode >= 32 || !((1u << mode) & ctx->SupportedPrimMask) ?
174               GL_INVALID_ENUM : ctx->DrawGLError;
175   }
176
177   return GL_NO_ERROR;
178}
179
180GLenum
181_mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode)
182{
183   return valid_prim_mode_custom(ctx, mode, ctx->ValidPrimMask);
184}
185
186static GLenum
187valid_prim_mode_indexed(struct gl_context *ctx, GLenum mode)
188{
189   return valid_prim_mode_custom(ctx, mode, ctx->ValidPrimMaskIndexed);
190}
191
192/**
193 * Verify that the element type is valid.
194 *
195 * Generates \c GL_INVALID_ENUM and returns \c false if it is not.
196 */
197static GLenum
198valid_elements_type(struct gl_context *ctx, GLenum type)
199{
200   /* GL_UNSIGNED_BYTE  = 0x1401
201    * GL_UNSIGNED_SHORT = 0x1403
202    * GL_UNSIGNED_INT   = 0x1405
203    *
204    * The trick is that bit 1 and bit 2 mean USHORT and UINT, respectively.
205    * After clearing those two bits (with ~6), we should get UBYTE.
206    * Both bits can't be set, because the enum would be greater than UINT.
207    */
208   if (!(type <= GL_UNSIGNED_INT && (type & ~6) == GL_UNSIGNED_BYTE))
209      return GL_INVALID_ENUM;
210
211   return GL_NO_ERROR;
212}
213
214static inline bool
215indices_aligned(unsigned index_size_shift, const GLvoid *indices)
216{
217   /* Require that indices are aligned to the element size. GL doesn't specify
218    * an error for this, but the ES 3.0 spec says:
219    *
220    *    "Clients must align data elements consistently with the requirements
221    *     of the client platform, with an additional base-level requirement
222    *     that an offset within a buffer to a datum comprising N basic machine
223    *     units be a multiple of N"
224    *
225    * This is only required by index buffers, not user indices.
226    */
227   return ((uintptr_t)indices & ((1 << index_size_shift) - 1)) == 0;
228}
229
230static GLenum
231validate_DrawElements_common(struct gl_context *ctx, GLenum mode,
232                             GLsizei count, GLsizei numInstances, GLenum type)
233{
234   if (count < 0 || numInstances < 0)
235      return GL_INVALID_VALUE;
236
237   GLenum error = valid_prim_mode_indexed(ctx, mode);
238   if (error)
239      return error;
240
241   return valid_elements_type(ctx, type);
242}
243
244/**
245 * Error checking for glDrawElements().  Includes parameter checking
246 * and VBO bounds checking.
247 * \return GL_TRUE if OK to render, GL_FALSE if error found
248 */
249static GLboolean
250_mesa_validate_DrawElements(struct gl_context *ctx,
251                            GLenum mode, GLsizei count, GLenum type)
252{
253   GLenum error = validate_DrawElements_common(ctx, mode, count, 1, type);
254   if (error)
255      _mesa_error(ctx, error, "glDrawElements");
256
257   return !error;
258}
259
260
261/**
262 * Error checking for glMultiDrawElements().  Includes parameter checking
263 * and VBO bounds checking.
264 * \return GL_TRUE if OK to render, GL_FALSE if error found
265 */
266static GLboolean
267_mesa_validate_MultiDrawElements(struct gl_context *ctx,
268                                 GLenum mode, const GLsizei *count,
269                                 GLenum type, const GLvoid * const *indices,
270                                 GLsizei primcount)
271{
272   GLenum error;
273
274   /*
275    * Section 2.3.1 (Errors) of the OpenGL 4.5 (Core Profile) spec says:
276    *
277    *    "If a negative number is provided where an argument of type sizei or
278    *     sizeiptr is specified, an INVALID_VALUE error is generated."
279    *
280    * and in the same section:
281    *
282    *    "In other cases, there are no side effects unless otherwise noted;
283    *     the command which generates the error is ignored so that it has no
284    *     effect on GL state or framebuffer contents."
285    *
286    * Hence, check both primcount and all the count[i].
287    */
288   if (primcount < 0) {
289      error = GL_INVALID_VALUE;
290   } else {
291      error = valid_prim_mode_indexed(ctx, mode);
292
293      if (!error) {
294         error = valid_elements_type(ctx, type);
295
296         if (!error) {
297            for (int i = 0; i < primcount; i++) {
298               if (count[i] < 0) {
299                  error = GL_INVALID_VALUE;
300                  break;
301               }
302            }
303         }
304      }
305   }
306
307   if (error)
308      _mesa_error(ctx, error, "glMultiDrawElements");
309
310   /* Not using a VBO for indices, so avoid NULL pointer derefs later.
311    */
312   if (!ctx->Array.VAO->IndexBufferObj) {
313      for (int i = 0; i < primcount; i++) {
314         if (!indices[i])
315            return GL_FALSE;
316      }
317   }
318
319   return !error;
320}
321
322
323/**
324 * Error checking for glDrawRangeElements().  Includes parameter checking
325 * and VBO bounds checking.
326 * \return GL_TRUE if OK to render, GL_FALSE if error found
327 */
328static GLboolean
329_mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode,
330                                 GLuint start, GLuint end,
331                                 GLsizei count, GLenum type)
332{
333   GLenum error;
334
335   if (end < start) {
336      error = GL_INVALID_VALUE;
337   } else {
338      error = validate_DrawElements_common(ctx, mode, count, 1, type);
339   }
340
341   if (error)
342      _mesa_error(ctx, error, "glDrawRangeElements");
343
344   return !error;
345}
346
347
348static bool
349need_xfb_remaining_prims_check(const struct gl_context *ctx)
350{
351   /* From the GLES3 specification, section 2.14.2 (Transform Feedback
352    * Primitive Capture):
353    *
354    *   The error INVALID_OPERATION is generated by DrawArrays and
355    *   DrawArraysInstanced if recording the vertices of a primitive to the
356    *   buffer objects being used for transform feedback purposes would result
357    *   in either exceeding the limits of any buffer object’s size, or in
358    *   exceeding the end position offset + size − 1, as set by
359    *   BindBufferRange.
360    *
361    * This is in contrast to the behaviour of desktop GL, where the extra
362    * primitives are silently dropped from the transform feedback buffer.
363    *
364    * This text is removed in ES 3.2, presumably because it's not really
365    * implementable with geometry and tessellation shaders.  In fact,
366    * the OES_geometry_shader spec says:
367    *
368    *    "(13) Does this extension change how transform feedback operates
369    *     compared to unextended OpenGL ES 3.0 or 3.1?
370    *
371    *     RESOLVED: Yes. Because dynamic geometry amplification in a geometry
372    *     shader can make it difficult if not impossible to predict the amount
373    *     of geometry that may be generated in advance of executing the shader,
374    *     the draw-time error for transform feedback buffer overflow conditions
375    *     is removed and replaced with the GL behavior (primitives are not
376    *     written and the corresponding counter is not updated)..."
377    */
378   return _mesa_is_gles3(ctx) && _mesa_is_xfb_active_and_unpaused(ctx) &&
379          !_mesa_has_OES_geometry_shader(ctx) &&
380          !_mesa_has_OES_tessellation_shader(ctx);
381}
382
383
384/**
385 * Figure out the number of transform feedback primitives that will be output
386 * considering the drawing mode, number of vertices, and instance count,
387 * assuming that no geometry shading is done and primitive restart is not
388 * used.
389 *
390 * This is used by driver back-ends in implementing the PRIMITIVES_GENERATED
391 * and TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN queries.  It is also used to
392 * pre-validate draw calls in GLES3 (where draw calls only succeed if there is
393 * enough room in the transform feedback buffer for the result).
394 */
395static size_t
396count_tessellated_primitives(GLenum mode, GLuint count, GLuint num_instances)
397{
398   size_t num_primitives;
399   switch (mode) {
400   case GL_POINTS:
401      num_primitives = count;
402      break;
403   case GL_LINE_STRIP:
404      num_primitives = count >= 2 ? count - 1 : 0;
405      break;
406   case GL_LINE_LOOP:
407      num_primitives = count >= 2 ? count : 0;
408      break;
409   case GL_LINES:
410      num_primitives = count / 2;
411      break;
412   case GL_TRIANGLE_STRIP:
413   case GL_TRIANGLE_FAN:
414   case GL_POLYGON:
415      num_primitives = count >= 3 ? count - 2 : 0;
416      break;
417   case GL_TRIANGLES:
418      num_primitives = count / 3;
419      break;
420   case GL_QUAD_STRIP:
421      num_primitives = count >= 4 ? ((count / 2) - 1) * 2 : 0;
422      break;
423   case GL_QUADS:
424      num_primitives = (count / 4) * 2;
425      break;
426   case GL_LINES_ADJACENCY:
427      num_primitives = count / 4;
428      break;
429   case GL_LINE_STRIP_ADJACENCY:
430      num_primitives = count >= 4 ? count - 3 : 0;
431      break;
432   case GL_TRIANGLES_ADJACENCY:
433      num_primitives = count / 6;
434      break;
435   case GL_TRIANGLE_STRIP_ADJACENCY:
436      num_primitives = count >= 6 ? (count - 4) / 2 : 0;
437      break;
438   default:
439      assert(!"Unexpected primitive type in count_tessellated_primitives");
440      num_primitives = 0;
441      break;
442   }
443   return num_primitives * num_instances;
444}
445
446
447static GLenum
448validate_draw_arrays(struct gl_context *ctx,
449                     GLenum mode, GLsizei count, GLsizei numInstances)
450{
451   if (count < 0 || numInstances < 0)
452      return GL_INVALID_VALUE;
453
454   GLenum error = _mesa_valid_prim_mode(ctx, mode);
455   if (error)
456      return error;
457
458   if (need_xfb_remaining_prims_check(ctx)) {
459      struct gl_transform_feedback_object *xfb_obj
460         = ctx->TransformFeedback.CurrentObject;
461      size_t prim_count = count_tessellated_primitives(mode, count, numInstances);
462      if (xfb_obj->GlesRemainingPrims < prim_count)
463         return GL_INVALID_OPERATION;
464
465      xfb_obj->GlesRemainingPrims -= prim_count;
466   }
467
468   return GL_NO_ERROR;
469}
470
471/**
472 * Called from the tnl module to error check the function parameters and
473 * verify that we really can draw something.
474 * \return GL_TRUE if OK to render, GL_FALSE if error found
475 */
476static GLboolean
477_mesa_validate_DrawArrays(struct gl_context *ctx, GLenum mode, GLsizei count)
478{
479   GLenum error = validate_draw_arrays(ctx, mode, count, 1);
480
481   if (error)
482      _mesa_error(ctx, error, "glDrawArrays");
483
484   return !error;
485}
486
487
488static GLboolean
489_mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint first,
490                                   GLsizei count, GLsizei numInstances)
491{
492   GLenum error;
493
494   if (first < 0) {
495      error = GL_INVALID_VALUE;
496   } else {
497      error = validate_draw_arrays(ctx, mode, count, numInstances);
498   }
499
500   if (error)
501      _mesa_error(ctx, error, "glDrawArraysInstanced");
502
503   return !error;
504}
505
506
507/**
508 * Called to error check the function parameters.
509 *
510 * Note that glMultiDrawArrays is not part of GLES, so there's limited scope
511 * for sharing code with the validation of glDrawArrays.
512 */
513static bool
514_mesa_validate_MultiDrawArrays(struct gl_context *ctx, GLenum mode,
515                               const GLsizei *count, GLsizei primcount)
516{
517   GLenum error;
518
519   if (primcount < 0) {
520      error = GL_INVALID_VALUE;
521   } else {
522      error = _mesa_valid_prim_mode(ctx, mode);
523
524      if (!error) {
525         for (int i = 0; i < primcount; ++i) {
526            if (count[i] < 0) {
527               error = GL_INVALID_VALUE;
528               break;
529            }
530         }
531
532         if (!error) {
533            if (need_xfb_remaining_prims_check(ctx)) {
534               struct gl_transform_feedback_object *xfb_obj
535                  = ctx->TransformFeedback.CurrentObject;
536               size_t xfb_prim_count = 0;
537
538               for (int i = 0; i < primcount; ++i) {
539                  xfb_prim_count +=
540                     count_tessellated_primitives(mode, count[i], 1);
541               }
542
543               if (xfb_obj->GlesRemainingPrims < xfb_prim_count) {
544                  error = GL_INVALID_OPERATION;
545               } else {
546                  xfb_obj->GlesRemainingPrims -= xfb_prim_count;
547               }
548            }
549         }
550      }
551   }
552
553   if (error)
554      _mesa_error(ctx, error, "glMultiDrawArrays");
555
556   return !error;
557}
558
559
560static GLboolean
561_mesa_validate_DrawElementsInstanced(struct gl_context *ctx,
562                                     GLenum mode, GLsizei count, GLenum type,
563                                     GLsizei numInstances)
564{
565   GLenum error =
566      validate_DrawElements_common(ctx, mode, count, numInstances, type);
567
568   if (error)
569      _mesa_error(ctx, error, "glDrawElementsInstanced");
570
571   return !error;
572}
573
574
575static GLboolean
576_mesa_validate_DrawTransformFeedback(struct gl_context *ctx,
577                                     GLenum mode,
578                                     struct gl_transform_feedback_object *obj,
579                                     GLuint stream,
580                                     GLsizei numInstances)
581{
582   GLenum error;
583
584   /* From the GL 4.5 specification, page 429:
585    * "An INVALID_VALUE error is generated if id is not the name of a
586    *  transform feedback object."
587    */
588   if (!obj || !obj->EverBound || stream >= ctx->Const.MaxVertexStreams ||
589       numInstances < 0) {
590      error = GL_INVALID_VALUE;
591   } else {
592      error = _mesa_valid_prim_mode(ctx, mode);
593
594      if (!error) {
595         if (!obj->EndedAnytime)
596            error = GL_INVALID_OPERATION;
597      }
598   }
599
600   if (error)
601      _mesa_error(ctx, error, "glDrawTransformFeedback*");
602
603   return !error;
604}
605
606static GLenum
607valid_draw_indirect(struct gl_context *ctx,
608                    GLenum mode, const GLvoid *indirect,
609                    GLsizei size)
610{
611   const uint64_t end = (uint64_t) (uintptr_t) indirect + size;
612
613   /* OpenGL ES 3.1 spec. section 10.5:
614    *
615    *      "DrawArraysIndirect requires that all data sourced for the
616    *      command, including the DrawArraysIndirectCommand
617    *      structure,  be in buffer objects,  and may not be called when
618    *      the default vertex array object is bound."
619    */
620   if (ctx->API != API_OPENGL_COMPAT &&
621       ctx->Array.VAO == ctx->Array.DefaultVAO)
622      return GL_INVALID_OPERATION;
623
624   /* From OpenGL ES 3.1 spec. section 10.5:
625    *     "An INVALID_OPERATION error is generated if zero is bound to
626    *     VERTEX_ARRAY_BINDING, DRAW_INDIRECT_BUFFER or to any enabled
627    *     vertex array."
628    *
629    * Here we check that for each enabled vertex array we have a vertex
630    * buffer bound.
631    */
632   if (_mesa_is_gles31(ctx) &&
633       ctx->Array.VAO->Enabled & ~ctx->Array.VAO->VertexAttribBufferMask)
634      return GL_INVALID_OPERATION;
635
636   GLenum error = _mesa_valid_prim_mode(ctx, mode);
637   if (error)
638      return error;
639
640   /* OpenGL ES 3.1 specification, section 10.5:
641    *
642    *      "An INVALID_OPERATION error is generated if
643    *      transform feedback is active and not paused."
644    *
645    * The OES_geometry_shader spec says:
646    *
647    *    On p. 250 in the errors section for the DrawArraysIndirect command,
648    *    and on p. 254 in the errors section for the DrawElementsIndirect
649    *    command, delete the errors which state:
650    *
651    *    "An INVALID_OPERATION error is generated if transform feedback is
652    *    active and not paused."
653    *
654    *    (thus allowing transform feedback to work with indirect draw commands).
655    */
656   if (_mesa_is_gles31(ctx) && !ctx->Extensions.OES_geometry_shader &&
657       _mesa_is_xfb_active_and_unpaused(ctx))
658      return GL_INVALID_OPERATION;
659
660   /* From OpenGL version 4.4. section 10.5
661    * and OpenGL ES 3.1, section 10.6:
662    *
663    *      "An INVALID_VALUE error is generated if indirect is not a
664    *       multiple of the size, in basic machine units, of uint."
665    */
666   if ((GLsizeiptr)indirect & (sizeof(GLuint) - 1))
667      return GL_INVALID_VALUE;
668
669   if (!ctx->DrawIndirectBuffer)
670      return GL_INVALID_OPERATION;
671
672   if (_mesa_check_disallowed_mapping(ctx->DrawIndirectBuffer))
673      return GL_INVALID_OPERATION;
674
675   /* From the ARB_draw_indirect specification:
676    * "An INVALID_OPERATION error is generated if the commands source data
677    *  beyond the end of the buffer object [...]"
678    */
679   if (ctx->DrawIndirectBuffer->Size < end)
680      return GL_INVALID_OPERATION;
681
682   return GL_NO_ERROR;
683}
684
685static inline GLenum
686valid_draw_indirect_elements(struct gl_context *ctx,
687                             GLenum mode, GLenum type, const GLvoid *indirect,
688                             GLsizeiptr size)
689{
690   GLenum error = valid_elements_type(ctx, type);
691   if (error)
692      return error;
693
694   /*
695    * Unlike regular DrawElementsInstancedBaseVertex commands, the indices
696    * may not come from a client array and must come from an index buffer.
697    * If no element array buffer is bound, an INVALID_OPERATION error is
698    * generated.
699    */
700   if (!ctx->Array.VAO->IndexBufferObj)
701      return GL_INVALID_OPERATION;
702
703   return valid_draw_indirect(ctx, mode, indirect, size);
704}
705
706static GLboolean
707_mesa_valid_draw_indirect_multi(struct gl_context *ctx,
708                                GLsizei primcount, GLsizei stride,
709                                const char *name)
710{
711
712   /* From the ARB_multi_draw_indirect specification:
713    * "INVALID_VALUE is generated by MultiDrawArraysIndirect or
714    *  MultiDrawElementsIndirect if <primcount> is negative."
715    *
716    * "<primcount> must be positive, otherwise an INVALID_VALUE error will
717    *  be generated."
718    */
719   if (primcount < 0) {
720      _mesa_error(ctx, GL_INVALID_VALUE, "%s(primcount < 0)", name);
721      return GL_FALSE;
722   }
723
724
725   /* From the ARB_multi_draw_indirect specification:
726    * "<stride> must be a multiple of four, otherwise an INVALID_VALUE
727    *  error is generated."
728    */
729   if (stride % 4) {
730      _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride %% 4)", name);
731      return GL_FALSE;
732   }
733
734   return GL_TRUE;
735}
736
737static GLboolean
738_mesa_validate_DrawArraysIndirect(struct gl_context *ctx,
739                                  GLenum mode,
740                                  const GLvoid *indirect)
741{
742   const unsigned drawArraysNumParams = 4;
743   GLenum error =
744      valid_draw_indirect(ctx, mode, indirect,
745                          drawArraysNumParams * sizeof(GLuint));
746
747   if (error)
748      _mesa_error(ctx, error, "glDrawArraysIndirect");
749
750   return !error;
751}
752
753static GLboolean
754_mesa_validate_DrawElementsIndirect(struct gl_context *ctx,
755                                    GLenum mode, GLenum type,
756                                    const GLvoid *indirect)
757{
758   const unsigned drawElementsNumParams = 5;
759   GLenum error = valid_draw_indirect_elements(ctx, mode, type, indirect,
760                                               drawElementsNumParams *
761                                               sizeof(GLuint));
762   if (error)
763      _mesa_error(ctx, error, "glDrawElementsIndirect");
764
765   return !error;
766}
767
768static GLboolean
769_mesa_validate_MultiDrawArraysIndirect(struct gl_context *ctx,
770                                       GLenum mode,
771                                       const GLvoid *indirect,
772                                       GLsizei primcount, GLsizei stride)
773{
774   GLsizeiptr size = 0;
775   const unsigned drawArraysNumParams = 4;
776
777   /* caller has converted stride==0 to drawArraysNumParams * sizeof(GLuint) */
778   assert(stride != 0);
779
780   if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
781                                        "glMultiDrawArraysIndirect"))
782      return GL_FALSE;
783
784   /* number of bytes of the indirect buffer which will be read */
785   size = primcount
786      ? (primcount - 1) * stride + drawArraysNumParams * sizeof(GLuint)
787      : 0;
788
789   GLenum error = valid_draw_indirect(ctx, mode, indirect, size);
790   if (error)
791      _mesa_error(ctx, error, "glMultiDrawArraysIndirect");
792
793   return !error;
794}
795
796static GLboolean
797_mesa_validate_MultiDrawElementsIndirect(struct gl_context *ctx,
798                                         GLenum mode, GLenum type,
799                                         const GLvoid *indirect,
800                                         GLsizei primcount, GLsizei stride)
801{
802   GLsizeiptr size = 0;
803   const unsigned drawElementsNumParams = 5;
804
805   /* caller has converted stride==0 to drawElementsNumParams * sizeof(GLuint) */
806   assert(stride != 0);
807
808   if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
809                                        "glMultiDrawElementsIndirect"))
810      return GL_FALSE;
811
812   /* number of bytes of the indirect buffer which will be read */
813   size = primcount
814      ? (primcount - 1) * stride + drawElementsNumParams * sizeof(GLuint)
815      : 0;
816
817   GLenum error = valid_draw_indirect_elements(ctx, mode, type, indirect,
818                                               size);
819   if (error)
820      _mesa_error(ctx, error, "glMultiDrawElementsIndirect");
821
822   return !error;
823}
824
825static GLenum
826valid_draw_indirect_parameters(struct gl_context *ctx,
827                               GLintptr drawcount)
828{
829   /* From the ARB_indirect_parameters specification:
830    * "INVALID_VALUE is generated by MultiDrawArraysIndirectCountARB or
831    *  MultiDrawElementsIndirectCountARB if <drawcount> is not a multiple of
832    *  four."
833    */
834   if (drawcount & 3)
835      return GL_INVALID_VALUE;
836
837   /* From the ARB_indirect_parameters specification:
838    * "INVALID_OPERATION is generated by MultiDrawArraysIndirectCountARB or
839    *  MultiDrawElementsIndirectCountARB if no buffer is bound to the
840    *  PARAMETER_BUFFER_ARB binding point."
841    */
842   if (!ctx->ParameterBuffer)
843      return GL_INVALID_OPERATION;
844
845   if (_mesa_check_disallowed_mapping(ctx->ParameterBuffer))
846      return GL_INVALID_OPERATION;
847
848   /* From the ARB_indirect_parameters specification:
849    * "INVALID_OPERATION is generated by MultiDrawArraysIndirectCountARB or
850    *  MultiDrawElementsIndirectCountARB if reading a <sizei> typed value
851    *  from the buffer bound to the PARAMETER_BUFFER_ARB target at the offset
852    *  specified by <drawcount> would result in an out-of-bounds access."
853    */
854   if (ctx->ParameterBuffer->Size < drawcount + sizeof(GLsizei))
855      return GL_INVALID_OPERATION;
856
857   return GL_NO_ERROR;
858}
859
860static GLboolean
861_mesa_validate_MultiDrawArraysIndirectCount(struct gl_context *ctx,
862                                            GLenum mode,
863                                            GLintptr indirect,
864                                            GLintptr drawcount,
865                                            GLsizei maxdrawcount,
866                                            GLsizei stride)
867{
868   GLsizeiptr size = 0;
869   const unsigned drawArraysNumParams = 4;
870
871   /* caller has converted stride==0 to drawArraysNumParams * sizeof(GLuint) */
872   assert(stride != 0);
873
874   if (!_mesa_valid_draw_indirect_multi(ctx, maxdrawcount, stride,
875                                        "glMultiDrawArraysIndirectCountARB"))
876      return GL_FALSE;
877
878   /* number of bytes of the indirect buffer which will be read */
879   size = maxdrawcount
880      ? (maxdrawcount - 1) * stride + drawArraysNumParams * sizeof(GLuint)
881      : 0;
882
883   GLenum error = valid_draw_indirect(ctx, mode, (void *)indirect, size);
884   if (!error)
885      error = valid_draw_indirect_parameters(ctx, drawcount);
886
887   if (error)
888      _mesa_error(ctx, error, "glMultiDrawArraysIndirectCountARB");
889
890   return !error;
891}
892
893static GLboolean
894_mesa_validate_MultiDrawElementsIndirectCount(struct gl_context *ctx,
895                                              GLenum mode, GLenum type,
896                                              GLintptr indirect,
897                                              GLintptr drawcount,
898                                              GLsizei maxdrawcount,
899                                              GLsizei stride)
900{
901   GLsizeiptr size = 0;
902   const unsigned drawElementsNumParams = 5;
903
904   /* caller has converted stride==0 to drawElementsNumParams * sizeof(GLuint) */
905   assert(stride != 0);
906
907   if (!_mesa_valid_draw_indirect_multi(ctx, maxdrawcount, stride,
908                                        "glMultiDrawElementsIndirectCountARB"))
909      return GL_FALSE;
910
911   /* number of bytes of the indirect buffer which will be read */
912   size = maxdrawcount
913      ? (maxdrawcount - 1) * stride + drawElementsNumParams * sizeof(GLuint)
914      : 0;
915
916   GLenum error = valid_draw_indirect_elements(ctx, mode, type,
917                                               (void *)indirect, size);
918   if (!error)
919      error = valid_draw_indirect_parameters(ctx, drawcount);
920
921   if (error)
922      _mesa_error(ctx, error, "glMultiDrawElementsIndirectCountARB");
923
924   return !error;
925}
926
927
928#define MAX_ALLOCA_PRIMS(prim) (50000 / sizeof(*prim))
929
930/* Use calloc for large allocations and alloca for small allocations. */
931/* We have to use a macro because alloca is local within the function. */
932#define ALLOC_PRIMS(prim, primcount, func) do { \
933   if (unlikely(primcount > MAX_ALLOCA_PRIMS(prim))) { \
934      prim = calloc(primcount, sizeof(*prim)); \
935      if (!prim) { \
936         _mesa_error(ctx, GL_OUT_OF_MEMORY, func); \
937         return; \
938      } \
939   } else { \
940      prim = alloca(primcount * sizeof(*prim)); \
941   } \
942} while (0)
943
944#define FREE_PRIMS(prim, primcount) do { \
945   if (primcount > MAX_ALLOCA_PRIMS(prim)) \
946      free(prim); \
947} while (0)
948
949
950/**
951 * Called via Driver.DrawGallium. This is a fallback invoking Driver.Draw.
952 */
953void
954_mesa_draw_gallium_fallback(struct gl_context *ctx,
955                            struct pipe_draw_info *info,
956                            unsigned drawid_offset,
957                            const struct pipe_draw_start_count_bias *draws,
958                            unsigned num_draws)
959{
960   struct _mesa_index_buffer ib;
961   unsigned index_size = info->index_size;
962   unsigned min_index = 0, max_index = ~0u;
963   bool index_bounds_valid = false;
964
965   if (!info->instance_count)
966      return;
967
968   if (index_size) {
969      if (info->index_bounds_valid) {
970         min_index = info->min_index;
971         max_index = info->max_index;
972         index_bounds_valid = true;
973      }
974   } else {
975      /* The index_bounds_valid field and min/max_index are not used for
976       * non-indexed draw calls (they are undefined), but classic drivers
977       * need the index bounds. They will be computed manually.
978       */
979      index_bounds_valid = true;
980   }
981
982   ib.index_size_shift = util_logbase2(index_size);
983
984   /* Single draw or a fallback for user indices. */
985   if (num_draws == 1) {
986      if (!draws[0].count)
987         return;
988
989      if (index_size) {
990         ib.count = draws[0].count;
991
992         if (info->has_user_indices) {
993            ib.obj = NULL;
994            ib.ptr = (const char*)info->index.user;
995         } else {
996            ib.obj = info->index.gl_bo;
997            ib.ptr = NULL;
998         }
999      }
1000
1001      struct _mesa_prim prim;
1002      prim.mode = info->mode;
1003      prim.begin = 1;
1004      prim.end = 1;
1005      prim.start = draws[0].start;
1006      prim.count = draws[0].count;
1007      prim.basevertex = index_size ? draws[0].index_bias : 0;
1008      prim.draw_id = drawid_offset;
1009
1010      if (!index_size) {
1011         min_index = draws[0].start;
1012         max_index = draws[0].start + draws[0].count - 1;
1013      }
1014
1015      st_feedback_draw_vbo(ctx, &prim, 1, index_size ? &ib : NULL,
1016                           index_bounds_valid, info->primitive_restart,
1017                           info->restart_index, min_index, max_index,
1018                           info->instance_count, info->start_instance);
1019      return;
1020   }
1021
1022   struct _mesa_prim *prim;
1023   unsigned max_count = 0;
1024   unsigned num_prims = 0;
1025
1026   ALLOC_PRIMS(prim, num_draws, "DrawGallium");
1027
1028   min_index = ~0u;
1029   max_index = 0;
1030
1031   for (unsigned i = 0; i < num_draws; i++) {
1032      if (!draws[i].count)
1033         continue;
1034
1035      prim[num_prims].mode = info->mode;
1036      prim[num_prims].begin = 1;
1037      prim[num_prims].end = 1;
1038      prim[num_prims].start = draws[i].start;
1039      prim[num_prims].count = draws[i].count;
1040      prim[num_prims].basevertex = info->index_size ? draws[i].index_bias : 0;
1041      prim[num_prims].draw_id = drawid_offset + (info->increment_draw_id ? i : 0);
1042
1043      if (!index_size) {
1044         min_index = MIN2(min_index, draws[i].start);
1045         max_index = MAX2(max_index, draws[i].start + draws[i].count - 1);
1046      }
1047
1048      max_count = MAX2(max_count, prim[num_prims].count);
1049      num_prims++;
1050   }
1051
1052   if (info->index_size) {
1053      ib.count = max_count;
1054      ib.index_size_shift = util_logbase2(index_size);
1055
1056      if (info->has_user_indices) {
1057         ib.obj = NULL;
1058         ib.ptr = (const char*)info->index.user;
1059      } else {
1060         ib.obj = info->index.gl_bo;
1061         ib.ptr = NULL;
1062      }
1063   }
1064
1065   if (num_prims)
1066      st_feedback_draw_vbo(ctx, prim, num_prims, index_size ? &ib : NULL,
1067                           index_bounds_valid, info->primitive_restart,
1068                           info->restart_index, min_index, max_index,
1069                           info->instance_count, info->start_instance);
1070   FREE_PRIMS(prim, num_draws);
1071}
1072
1073
1074/**
1075 * Called via Driver.DrawGallium. This is a fallback invoking Driver.Draw.
1076 */
1077void
1078_mesa_draw_gallium_multimode_fallback(struct gl_context *ctx,
1079                                      struct pipe_draw_info *info,
1080                                      const struct pipe_draw_start_count_bias *draws,
1081                                      const unsigned char *mode,
1082                                      unsigned num_draws)
1083{
1084   unsigned i, first;
1085
1086   /* Find consecutive draws where mode doesn't vary. */
1087   for (i = 0, first = 0; i <= num_draws; i++) {
1088      if (i == num_draws || mode[i] != mode[first]) {
1089         info->mode = mode[first];
1090         ctx->Driver.DrawGallium(ctx, info, 0, &draws[first], i - first);
1091         first = i;
1092      }
1093   }
1094}
1095
1096/**
1097 * Check that element 'j' of the array has reasonable data.
1098 * Map VBO if needed.
1099 * For debugging purposes; not normally used.
1100 */
1101static void
1102check_array_data(struct gl_context *ctx, struct gl_vertex_array_object *vao,
1103                 GLuint attrib, GLuint j)
1104{
1105   const struct gl_array_attributes *array = &vao->VertexAttrib[attrib];
1106   if (vao->Enabled & VERT_BIT(attrib)) {
1107      const struct gl_vertex_buffer_binding *binding =
1108         &vao->BufferBinding[array->BufferBindingIndex];
1109      struct gl_buffer_object *bo = binding->BufferObj;
1110      const void *data = array->Ptr;
1111      if (bo) {
1112         data = ADD_POINTERS(_mesa_vertex_attrib_address(array, binding),
1113                             bo->Mappings[MAP_INTERNAL].Pointer);
1114      }
1115      switch (array->Format.Type) {
1116      case GL_FLOAT:
1117         {
1118            GLfloat *f = (GLfloat *) ((GLubyte *) data + binding->Stride * j);
1119            GLint k;
1120            for (k = 0; k < array->Format.Size; k++) {
1121               if (util_is_inf_or_nan(f[k]) || f[k] >= 1.0e20F || f[k] <= -1.0e10F) {
1122                  printf("Bad array data:\n");
1123                  printf("  Element[%u].%u = %f\n", j, k, f[k]);
1124                  printf("  Array %u at %p\n", attrib, (void *) array);
1125                  printf("  Type 0x%x, Size %d, Stride %d\n",
1126                         array->Format.Type, array->Format.Size,
1127                         binding->Stride);
1128                  printf("  Address/offset %p in Buffer Object %u\n",
1129                         array->Ptr, bo ? bo->Name : 0);
1130                  f[k] = 1.0F;  /* XXX replace the bad value! */
1131               }
1132               /*assert(!util_is_inf_or_nan(f[k])); */
1133            }
1134         }
1135         break;
1136      default:
1137         ;
1138      }
1139   }
1140}
1141
1142
1143static inline unsigned
1144get_index_size_shift(GLenum type)
1145{
1146   /* The type is already validated, so use a fast conversion.
1147    *
1148    * GL_UNSIGNED_BYTE  - GL_UNSIGNED_BYTE = 0
1149    * GL_UNSIGNED_SHORT - GL_UNSIGNED_BYTE = 2
1150    * GL_UNSIGNED_INT   - GL_UNSIGNED_BYTE = 4
1151    *
1152    * Divide by 2 to get 0,1,2.
1153    */
1154   return (type - GL_UNSIGNED_BYTE) >> 1;
1155}
1156
1157/**
1158 * Examine the array's data for NaNs, etc.
1159 * For debug purposes; not normally used.
1160 */
1161static void
1162check_draw_elements_data(struct gl_context *ctx, GLsizei count,
1163                         GLenum elemType, const void *elements,
1164                         GLint basevertex)
1165{
1166   struct gl_vertex_array_object *vao = ctx->Array.VAO;
1167   GLint i;
1168   GLuint k;
1169
1170   _mesa_vao_map(ctx, vao, GL_MAP_READ_BIT);
1171
1172   if (vao->IndexBufferObj)
1173       elements =
1174          ADD_POINTERS(vao->IndexBufferObj->Mappings[MAP_INTERNAL].Pointer, elements);
1175
1176   for (i = 0; i < count; i++) {
1177      GLuint j;
1178
1179      /* j = element[i] */
1180      switch (elemType) {
1181      case GL_UNSIGNED_BYTE:
1182         j = ((const GLubyte *) elements)[i];
1183         break;
1184      case GL_UNSIGNED_SHORT:
1185         j = ((const GLushort *) elements)[i];
1186         break;
1187      case GL_UNSIGNED_INT:
1188         j = ((const GLuint *) elements)[i];
1189         break;
1190      default:
1191         unreachable("Unexpected index buffer type");
1192      }
1193
1194      /* check element j of each enabled array */
1195      for (k = 0; k < VERT_ATTRIB_MAX; k++) {
1196         check_array_data(ctx, vao, k, j);
1197      }
1198   }
1199
1200   _mesa_vao_unmap(ctx, vao);
1201}
1202
1203
1204/**
1205 * Check array data, looking for NaNs, etc.
1206 */
1207static void
1208check_draw_arrays_data(struct gl_context *ctx, GLint start, GLsizei count)
1209{
1210   /* TO DO */
1211}
1212
1213
1214/**
1215 * Print info/data for glDrawArrays(), for debugging.
1216 */
1217static void
1218print_draw_arrays(struct gl_context *ctx,
1219                  GLenum mode, GLint start, GLsizei count)
1220{
1221   struct gl_vertex_array_object *vao = ctx->Array.VAO;
1222
1223   printf("_mesa_DrawArrays(mode 0x%x, start %d, count %d):\n",
1224          mode, start, count);
1225
1226   _mesa_vao_map_arrays(ctx, vao, GL_MAP_READ_BIT);
1227
1228   GLbitfield mask = vao->Enabled;
1229   while (mask) {
1230      const gl_vert_attrib i = u_bit_scan(&mask);
1231      const struct gl_array_attributes *array = &vao->VertexAttrib[i];
1232
1233      const struct gl_vertex_buffer_binding *binding =
1234         &vao->BufferBinding[array->BufferBindingIndex];
1235      struct gl_buffer_object *bufObj = binding->BufferObj;
1236
1237      printf("attr %s: size %d stride %d  "
1238             "ptr %p  Bufobj %u\n",
1239             gl_vert_attrib_name((gl_vert_attrib) i),
1240             array->Format.Size, binding->Stride,
1241             array->Ptr, bufObj ? bufObj->Name : 0);
1242
1243      if (bufObj) {
1244         GLubyte *p = bufObj->Mappings[MAP_INTERNAL].Pointer;
1245         int offset = (int) (GLintptr)
1246            _mesa_vertex_attrib_address(array, binding);
1247
1248         unsigned multiplier;
1249         switch (array->Format.Type) {
1250         case GL_DOUBLE:
1251         case GL_INT64_ARB:
1252         case GL_UNSIGNED_INT64_ARB:
1253            multiplier = 2;
1254            break;
1255         default:
1256            multiplier = 1;
1257         }
1258
1259         float *f = (float *) (p + offset);
1260         int *k = (int *) f;
1261         int i = 0;
1262         int n = (count - 1) * (binding->Stride / (4 * multiplier))
1263            + array->Format.Size;
1264         if (n > 32)
1265            n = 32;
1266         printf("  Data at offset %d:\n", offset);
1267         do {
1268            if (multiplier == 2)
1269               printf("    double[%d] = 0x%016llx %lf\n", i,
1270                      ((unsigned long long *) k)[i], ((double *) f)[i]);
1271            else
1272               printf("    float[%d] = 0x%08x %f\n", i, k[i], f[i]);
1273            i++;
1274         } while (i < n);
1275      }
1276   }
1277
1278   _mesa_vao_unmap_arrays(ctx, vao);
1279}
1280
1281
1282/**
1283 * Helper function called by the other DrawArrays() functions below.
1284 * This is where we handle primitive restart for drawing non-indexed
1285 * arrays.  If primitive restart is enabled, it typically means
1286 * splitting one DrawArrays() into two.
1287 */
1288static void
1289_mesa_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
1290                  GLsizei count, GLuint numInstances, GLuint baseInstance)
1291{
1292   /* Viewperf has many draws with count=0. Discarding them is faster than
1293    * processing them.
1294    */
1295   if (!count || !numInstances)
1296      return;
1297
1298   /* OpenGL 4.5 says that primitive restart is ignored with non-indexed
1299    * draws.
1300    */
1301   struct pipe_draw_info info;
1302   struct pipe_draw_start_count_bias draw;
1303
1304   info.mode = mode;
1305   info.index_size = 0;
1306   /* Packed section begin. */
1307   info.primitive_restart = false;
1308   info.has_user_indices = false;
1309   info.index_bounds_valid = true;
1310   info.increment_draw_id = false;
1311   info.was_line_loop = false;
1312   info.take_index_buffer_ownership = false;
1313   info.index_bias_varies = false;
1314   /* Packed section end. */
1315   info.start_instance = baseInstance;
1316   info.instance_count = numInstances;
1317   info.view_mask = 0;
1318   info.min_index = start;
1319   info.max_index = start + count - 1;
1320
1321   draw.start = start;
1322   draw.count = count;
1323
1324   ctx->Driver.DrawGallium(ctx, &info, 0, &draw, 1);
1325
1326   if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1327      _mesa_flush(ctx);
1328   }
1329}
1330
1331
1332/**
1333 * Execute a glRectf() function.
1334 */
1335void GLAPIENTRY
1336_mesa_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
1337{
1338   GET_CURRENT_CONTEXT(ctx);
1339   ASSERT_OUTSIDE_BEGIN_END(ctx);
1340
1341   CALL_Begin(ctx->CurrentServerDispatch, (GL_QUADS));
1342   /* Begin can change CurrentServerDispatch. */
1343   struct _glapi_table *dispatch = ctx->CurrentServerDispatch;
1344   CALL_Vertex2f(dispatch, (x1, y1));
1345   CALL_Vertex2f(dispatch, (x2, y1));
1346   CALL_Vertex2f(dispatch, (x2, y2));
1347   CALL_Vertex2f(dispatch, (x1, y2));
1348   CALL_End(dispatch, ());
1349}
1350
1351
1352void GLAPIENTRY
1353_mesa_Rectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
1354{
1355   _mesa_Rectf((GLfloat) x1, (GLfloat) y1, (GLfloat) x2, (GLfloat) y2);
1356}
1357
1358void GLAPIENTRY
1359_mesa_Rectdv(const GLdouble *v1, const GLdouble *v2)
1360{
1361   _mesa_Rectf((GLfloat) v1[0], (GLfloat) v1[1], (GLfloat) v2[0], (GLfloat) v2[1]);
1362}
1363
1364void GLAPIENTRY
1365_mesa_Rectfv(const GLfloat *v1, const GLfloat *v2)
1366{
1367   _mesa_Rectf(v1[0], v1[1], v2[0], v2[1]);
1368}
1369
1370void GLAPIENTRY
1371_mesa_Recti(GLint x1, GLint y1, GLint x2, GLint y2)
1372{
1373   _mesa_Rectf((GLfloat) x1, (GLfloat) y1, (GLfloat) x2, (GLfloat) y2);
1374}
1375
1376void GLAPIENTRY
1377_mesa_Rectiv(const GLint *v1, const GLint *v2)
1378{
1379   _mesa_Rectf((GLfloat) v1[0], (GLfloat) v1[1], (GLfloat) v2[0], (GLfloat) v2[1]);
1380}
1381
1382void GLAPIENTRY
1383_mesa_Rects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
1384{
1385   _mesa_Rectf((GLfloat) x1, (GLfloat) y1, (GLfloat) x2, (GLfloat) y2);
1386}
1387
1388void GLAPIENTRY
1389_mesa_Rectsv(const GLshort *v1, const GLshort *v2)
1390{
1391   _mesa_Rectf((GLfloat) v1[0], (GLfloat) v1[1], (GLfloat) v2[0], (GLfloat) v2[1]);
1392}
1393
1394
1395void GLAPIENTRY
1396_mesa_EvalMesh1(GLenum mode, GLint i1, GLint i2)
1397{
1398   GET_CURRENT_CONTEXT(ctx);
1399   GLint i;
1400   GLfloat u, du;
1401   GLenum prim;
1402
1403   switch (mode) {
1404   case GL_POINT:
1405      prim = GL_POINTS;
1406      break;
1407   case GL_LINE:
1408      prim = GL_LINE_STRIP;
1409      break;
1410   default:
1411      _mesa_error(ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)");
1412      return;
1413   }
1414
1415   /* No effect if vertex maps disabled.
1416    */
1417   if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3)
1418      return;
1419
1420   du = ctx->Eval.MapGrid1du;
1421   u = ctx->Eval.MapGrid1u1 + i1 * du;
1422
1423
1424   CALL_Begin(ctx->CurrentServerDispatch, (prim));
1425   /* Begin can change CurrentServerDispatch. */
1426   struct _glapi_table *dispatch = ctx->CurrentServerDispatch;
1427   for (i = i1; i <= i2; i++, u += du) {
1428      CALL_EvalCoord1f(dispatch, (u));
1429   }
1430   CALL_End(dispatch, ());
1431}
1432
1433
1434void GLAPIENTRY
1435_mesa_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
1436{
1437   GET_CURRENT_CONTEXT(ctx);
1438   GLfloat u, du, v, dv, v1, u1;
1439   GLint i, j;
1440
1441   switch (mode) {
1442   case GL_POINT:
1443   case GL_LINE:
1444   case GL_FILL:
1445      break;
1446   default:
1447      _mesa_error(ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)");
1448      return;
1449   }
1450
1451   /* No effect if vertex maps disabled.
1452    */
1453   if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3)
1454      return;
1455
1456   du = ctx->Eval.MapGrid2du;
1457   dv = ctx->Eval.MapGrid2dv;
1458   v1 = ctx->Eval.MapGrid2v1 + j1 * dv;
1459   u1 = ctx->Eval.MapGrid2u1 + i1 * du;
1460
1461   struct _glapi_table *dispatch;
1462
1463   switch (mode) {
1464   case GL_POINT:
1465      CALL_Begin(ctx->CurrentServerDispatch, (GL_POINTS));
1466      /* Begin can change CurrentServerDispatch. */
1467      dispatch = ctx->CurrentServerDispatch;
1468      for (v = v1, j = j1; j <= j2; j++, v += dv) {
1469         for (u = u1, i = i1; i <= i2; i++, u += du) {
1470            CALL_EvalCoord2f(dispatch, (u, v));
1471         }
1472      }
1473      CALL_End(dispatch, ());
1474      break;
1475   case GL_LINE:
1476      for (v = v1, j = j1; j <= j2; j++, v += dv) {
1477         CALL_Begin(ctx->CurrentServerDispatch, (GL_LINE_STRIP));
1478         /* Begin can change CurrentServerDispatch. */
1479         dispatch = ctx->CurrentServerDispatch;
1480         for (u = u1, i = i1; i <= i2; i++, u += du) {
1481            CALL_EvalCoord2f(dispatch, (u, v));
1482         }
1483         CALL_End(dispatch, ());
1484      }
1485      for (u = u1, i = i1; i <= i2; i++, u += du) {
1486         CALL_Begin(ctx->CurrentServerDispatch, (GL_LINE_STRIP));
1487         /* Begin can change CurrentServerDispatch. */
1488         dispatch = ctx->CurrentServerDispatch;
1489         for (v = v1, j = j1; j <= j2; j++, v += dv) {
1490            CALL_EvalCoord2f(dispatch, (u, v));
1491         }
1492         CALL_End(dispatch, ());
1493      }
1494      break;
1495   case GL_FILL:
1496      for (v = v1, j = j1; j < j2; j++, v += dv) {
1497         CALL_Begin(ctx->CurrentServerDispatch, (GL_TRIANGLE_STRIP));
1498         /* Begin can change CurrentServerDispatch. */
1499         dispatch = ctx->CurrentServerDispatch;
1500         for (u = u1, i = i1; i <= i2; i++, u += du) {
1501            CALL_EvalCoord2f(dispatch, (u, v));
1502            CALL_EvalCoord2f(dispatch, (u, v + dv));
1503         }
1504         CALL_End(dispatch, ());
1505      }
1506      break;
1507   }
1508}
1509
1510
1511/**
1512 * Called from glDrawArrays when in immediate mode (not display list mode).
1513 */
1514void GLAPIENTRY
1515_mesa_DrawArrays(GLenum mode, GLint start, GLsizei count)
1516{
1517   GET_CURRENT_CONTEXT(ctx);
1518   FLUSH_FOR_DRAW(ctx);
1519
1520   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
1521                      ctx->VertexProgram._VPModeInputFilter);
1522
1523   if (ctx->NewState)
1524      _mesa_update_state(ctx);
1525
1526   if (!_mesa_is_no_error_enabled(ctx) &&
1527       !_mesa_validate_DrawArrays(ctx, mode, count))
1528      return;
1529
1530   if (0)
1531      check_draw_arrays_data(ctx, start, count);
1532
1533   _mesa_draw_arrays(ctx, mode, start, count, 1, 0);
1534
1535   if (0)
1536      print_draw_arrays(ctx, mode, start, count);
1537}
1538
1539
1540/**
1541 * Called from glDrawArraysInstanced when in immediate mode (not
1542 * display list mode).
1543 */
1544void GLAPIENTRY
1545_mesa_DrawArraysInstancedARB(GLenum mode, GLint start, GLsizei count,
1546                             GLsizei numInstances)
1547{
1548   GET_CURRENT_CONTEXT(ctx);
1549   FLUSH_FOR_DRAW(ctx);
1550
1551   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
1552                      ctx->VertexProgram._VPModeInputFilter);
1553
1554   if (ctx->NewState)
1555      _mesa_update_state(ctx);
1556
1557   if (!_mesa_is_no_error_enabled(ctx) &&
1558       !_mesa_validate_DrawArraysInstanced(ctx, mode, start, count,
1559                                           numInstances))
1560      return;
1561
1562   if (0)
1563      check_draw_arrays_data(ctx, start, count);
1564
1565   _mesa_draw_arrays(ctx, mode, start, count, numInstances, 0);
1566
1567   if (0)
1568      print_draw_arrays(ctx, mode, start, count);
1569}
1570
1571
1572/**
1573 * Called from glDrawArraysInstancedBaseInstance when in immediate mode.
1574 */
1575void GLAPIENTRY
1576_mesa_DrawArraysInstancedBaseInstance(GLenum mode, GLint first,
1577                                      GLsizei count, GLsizei numInstances,
1578                                      GLuint baseInstance)
1579{
1580   GET_CURRENT_CONTEXT(ctx);
1581   FLUSH_FOR_DRAW(ctx);
1582
1583   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
1584                      ctx->VertexProgram._VPModeInputFilter);
1585
1586   if (ctx->NewState)
1587      _mesa_update_state(ctx);
1588
1589   if (!_mesa_is_no_error_enabled(ctx) &&
1590       !_mesa_validate_DrawArraysInstanced(ctx, mode, first, count,
1591                                           numInstances))
1592      return;
1593
1594   if (0)
1595      check_draw_arrays_data(ctx, first, count);
1596
1597   _mesa_draw_arrays(ctx, mode, first, count, numInstances, baseInstance);
1598
1599   if (0)
1600      print_draw_arrays(ctx, mode, first, count);
1601}
1602
1603
1604/**
1605 * Called from glMultiDrawArrays when in immediate mode.
1606 */
1607void GLAPIENTRY
1608_mesa_MultiDrawArrays(GLenum mode, const GLint *first,
1609                      const GLsizei *count, GLsizei primcount)
1610{
1611   GET_CURRENT_CONTEXT(ctx);
1612   FLUSH_FOR_DRAW(ctx);
1613
1614   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
1615                      ctx->VertexProgram._VPModeInputFilter);
1616
1617   if (ctx->NewState)
1618      _mesa_update_state(ctx);
1619
1620   if (!_mesa_is_no_error_enabled(ctx) &&
1621       !_mesa_validate_MultiDrawArrays(ctx, mode, count, primcount))
1622      return;
1623
1624   if (primcount == 0)
1625      return;
1626
1627   struct pipe_draw_info info;
1628   struct pipe_draw_start_count_bias *draw;
1629
1630   ALLOC_PRIMS(draw, primcount, "glMultiDrawElements");
1631
1632   info.mode = mode;
1633   info.index_size = 0;
1634   /* Packed section begin. */
1635   info.primitive_restart = false;
1636   info.has_user_indices = false;
1637   info.index_bounds_valid = false;
1638   info.increment_draw_id = primcount > 1;
1639   info.was_line_loop = false;
1640   info.take_index_buffer_ownership = false;
1641   info.index_bias_varies = false;
1642   /* Packed section end. */
1643   info.start_instance = 0;
1644   info.instance_count = 1;
1645   info.view_mask = 0;
1646
1647   for (int i = 0; i < primcount; i++) {
1648      draw[i].start = first[i];
1649      draw[i].count = count[i];
1650   }
1651
1652   ctx->Driver.DrawGallium(ctx, &info, 0, draw, primcount);
1653
1654   if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1655      _mesa_flush(ctx);
1656
1657   FREE_PRIMS(draw, primcount);
1658}
1659
1660
1661
1662/**
1663 * Map GL_ELEMENT_ARRAY_BUFFER and print contents.
1664 * For debugging.
1665 */
1666#if 0
1667static void
1668dump_element_buffer(struct gl_context *ctx, GLenum type)
1669{
1670   const GLvoid *map =
1671      ctx->Driver.MapBufferRange(ctx, 0,
1672                                 ctx->Array.VAO->IndexBufferObj->Size,
1673                                 GL_MAP_READ_BIT,
1674                                 ctx->Array.VAO->IndexBufferObj,
1675                                 MAP_INTERNAL);
1676   switch (type) {
1677   case GL_UNSIGNED_BYTE:
1678      {
1679         const GLubyte *us = (const GLubyte *) map;
1680         GLint i;
1681         for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size; i++) {
1682            printf("%02x ", us[i]);
1683            if (i % 32 == 31)
1684               printf("\n");
1685         }
1686         printf("\n");
1687      }
1688      break;
1689   case GL_UNSIGNED_SHORT:
1690      {
1691         const GLushort *us = (const GLushort *) map;
1692         GLint i;
1693         for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size / 2; i++) {
1694            printf("%04x ", us[i]);
1695            if (i % 16 == 15)
1696               printf("\n");
1697         }
1698         printf("\n");
1699      }
1700      break;
1701   case GL_UNSIGNED_INT:
1702      {
1703         const GLuint *us = (const GLuint *) map;
1704         GLint i;
1705         for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size / 4; i++) {
1706            printf("%08x ", us[i]);
1707            if (i % 8 == 7)
1708               printf("\n");
1709         }
1710         printf("\n");
1711      }
1712      break;
1713   default:
1714      ;
1715   }
1716
1717   ctx->Driver.UnmapBuffer(ctx, ctx->Array.VAO->IndexBufferObj, MAP_INTERNAL);
1718}
1719#endif
1720
1721
1722/**
1723 * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements.
1724 * Do the rendering for a glDrawElements or glDrawRangeElements call after
1725 * we've validated buffer bounds, etc.
1726 */
1727static void
1728_mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
1729                                  bool index_bounds_valid,
1730                                  GLuint start, GLuint end,
1731                                  GLsizei count, GLenum type,
1732                                  const GLvoid * indices,
1733                                  GLint basevertex, GLuint numInstances,
1734                                  GLuint baseInstance)
1735{
1736   /* Viewperf has many draws with count=0. Discarding them is faster than
1737    * processing them.
1738    */
1739   if (!count || !numInstances)
1740      return;
1741
1742   if (!index_bounds_valid) {
1743      assert(start == 0u);
1744      assert(end == ~0u);
1745   }
1746
1747   struct pipe_draw_info info;
1748   struct pipe_draw_start_count_bias draw;
1749   unsigned index_size_shift = get_index_size_shift(type);
1750   struct gl_buffer_object *index_bo = ctx->Array.VAO->IndexBufferObj;
1751
1752   if (index_bo && !indices_aligned(index_size_shift, indices))
1753      return;
1754
1755   info.mode = mode;
1756   info.index_size = 1 << index_size_shift;
1757   /* Packed section begin. */
1758   info.primitive_restart = ctx->Array._PrimitiveRestart[index_size_shift];
1759   info.has_user_indices = index_bo == NULL;
1760   info.index_bounds_valid = index_bounds_valid;
1761   info.increment_draw_id = false;
1762   info.was_line_loop = false;
1763   info.take_index_buffer_ownership = false;
1764   info.index_bias_varies = false;
1765   /* Packed section end. */
1766   info.start_instance = baseInstance;
1767   info.instance_count = numInstances;
1768   info.view_mask = 0;
1769   info.restart_index = ctx->Array._RestartIndex[index_size_shift];
1770
1771   if (info.has_user_indices) {
1772      info.index.user = indices;
1773      draw.start = 0;
1774   } else {
1775      uintptr_t start = (uintptr_t) indices;
1776      if (unlikely(index_bo->Size < start)) {
1777         _mesa_warning(ctx, "Invalid indices offset 0x%" PRIxPTR
1778                            " (indices buffer size is %ld bytes)."
1779                            " Draw skipped.", start, index_bo->Size);
1780         return;
1781      }
1782      info.index.gl_bo = index_bo;
1783      draw.start = start >> index_size_shift;
1784   }
1785   draw.index_bias = basevertex;
1786
1787   info.min_index = start;
1788   info.max_index = end;
1789   draw.count = count;
1790
1791   /* Need to give special consideration to rendering a range of
1792    * indices starting somewhere above zero.  Typically the
1793    * application is issuing multiple DrawRangeElements() to draw
1794    * successive primitives layed out linearly in the vertex arrays.
1795    * Unless the vertex arrays are all in a VBO (or locked as with
1796    * CVA), the OpenGL semantics imply that we need to re-read or
1797    * re-upload the vertex data on each draw call.
1798    *
1799    * In the case of hardware tnl, we want to avoid starting the
1800    * upload at zero, as it will mean every draw call uploads an
1801    * increasing amount of not-used vertex data.  Worse - in the
1802    * software tnl module, all those vertices might be transformed and
1803    * lit but never rendered.
1804    *
1805    * If we just upload or transform the vertices in start..end,
1806    * however, the indices will be incorrect.
1807    *
1808    * At this level, we don't know exactly what the requirements of
1809    * the backend are going to be, though it will likely boil down to
1810    * either:
1811    *
1812    * 1) Do nothing, everything is in a VBO and is processed once
1813    *       only.
1814    *
1815    * 2) Adjust the indices and vertex arrays so that start becomes
1816    *    zero.
1817    *
1818    * Rather than doing anything here, I'll provide a helper function
1819    * for the latter case elsewhere.
1820    */
1821
1822   ctx->Driver.DrawGallium(ctx, &info, 0, &draw, 1);
1823
1824   if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1825      _mesa_flush(ctx);
1826   }
1827}
1828
1829
1830/**
1831 * Called by glDrawRangeElementsBaseVertex() in immediate mode.
1832 */
1833void GLAPIENTRY
1834_mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
1835                                  GLsizei count, GLenum type,
1836                                  const GLvoid * indices, GLint basevertex)
1837{
1838   static GLuint warnCount = 0;
1839   bool index_bounds_valid = true;
1840
1841   /* This is only useful to catch invalid values in the "end" parameter
1842    * like ~0.
1843    */
1844   GLuint max_element = 2 * 1000 * 1000 * 1000; /* just a big number */
1845
1846   GET_CURRENT_CONTEXT(ctx);
1847   FLUSH_FOR_DRAW(ctx);
1848
1849   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
1850                      ctx->VertexProgram._VPModeInputFilter);
1851
1852   if (ctx->NewState)
1853      _mesa_update_state(ctx);
1854
1855   if (!_mesa_is_no_error_enabled(ctx) &&
1856       !_mesa_validate_DrawRangeElements(ctx, mode, start, end, count,
1857                                         type))
1858      return;
1859
1860   if ((int) end + basevertex < 0 || start + basevertex >= max_element) {
1861      /* The application requested we draw using a range of indices that's
1862       * outside the bounds of the current VBO.  This is invalid and appears
1863       * to give undefined results.  The safest thing to do is to simply
1864       * ignore the range, in case the application botched their range tracking
1865       * but did provide valid indices.  Also issue a warning indicating that
1866       * the application is broken.
1867       */
1868      if (warnCount++ < 10) {
1869         _mesa_warning(ctx, "glDrawRangeElements(start %u, end %u, "
1870                       "basevertex %d, count %d, type 0x%x, indices=%p):\n"
1871                       "\trange is outside VBO bounds (max=%u); ignoring.\n"
1872                       "\tThis should be fixed in the application.",
1873                       start, end, basevertex, count, type, indices,
1874                       max_element - 1);
1875      }
1876      index_bounds_valid = false;
1877   }
1878
1879   /* NOTE: It's important that 'end' is a reasonable value.
1880    * in _tnl_draw_prims(), we use end to determine how many vertices
1881    * to transform.  If it's too large, we can unnecessarily split prims
1882    * or we can read/write out of memory in several different places!
1883    */
1884
1885   /* Catch/fix some potential user errors */
1886   if (type == GL_UNSIGNED_BYTE) {
1887      start = MIN2(start, 0xff);
1888      end = MIN2(end, 0xff);
1889   }
1890   else if (type == GL_UNSIGNED_SHORT) {
1891      start = MIN2(start, 0xffff);
1892      end = MIN2(end, 0xffff);
1893   }
1894
1895   if (0) {
1896      printf("glDraw[Range]Elements{,BaseVertex}"
1897             "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, "
1898             "base %d\n",
1899             start, end, type, count,
1900             ctx->Array.VAO->IndexBufferObj ?
1901                ctx->Array.VAO->IndexBufferObj->Name : 0, basevertex);
1902   }
1903
1904   if ((int) start + basevertex < 0 || end + basevertex >= max_element)
1905      index_bounds_valid = false;
1906
1907#if 0
1908   check_draw_elements_data(ctx, count, type, indices, basevertex);
1909#else
1910   (void) check_draw_elements_data;
1911#endif
1912
1913   if (!index_bounds_valid) {
1914      start = 0;
1915      end = ~0;
1916   }
1917
1918   _mesa_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end,
1919                                     count, type, indices, basevertex, 1, 0);
1920}
1921
1922
1923/**
1924 * Called by glDrawRangeElements() in immediate mode.
1925 */
1926void GLAPIENTRY
1927_mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
1928                        GLsizei count, GLenum type, const GLvoid * indices)
1929{
1930   _mesa_DrawRangeElementsBaseVertex(mode, start, end, count, type,
1931                                     indices, 0);
1932}
1933
1934
1935/**
1936 * Called by glDrawElements() in immediate mode.
1937 */
1938void GLAPIENTRY
1939_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
1940                   const GLvoid * indices)
1941{
1942   GET_CURRENT_CONTEXT(ctx);
1943   FLUSH_FOR_DRAW(ctx);
1944
1945   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
1946                      ctx->VertexProgram._VPModeInputFilter);
1947
1948   if (ctx->NewState)
1949      _mesa_update_state(ctx);
1950
1951   if (!_mesa_is_no_error_enabled(ctx) &&
1952       !_mesa_validate_DrawElements(ctx, mode, count, type))
1953      return;
1954
1955   _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0,
1956                                     count, type, indices, 0, 1, 0);
1957}
1958
1959
1960/**
1961 * Called by glDrawElementsBaseVertex() in immediate mode.
1962 */
1963void GLAPIENTRY
1964_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
1965                             const GLvoid * indices, GLint basevertex)
1966{
1967   GET_CURRENT_CONTEXT(ctx);
1968   FLUSH_FOR_DRAW(ctx);
1969
1970   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
1971                      ctx->VertexProgram._VPModeInputFilter);
1972
1973   if (ctx->NewState)
1974      _mesa_update_state(ctx);
1975
1976   if (!_mesa_is_no_error_enabled(ctx) &&
1977       !_mesa_validate_DrawElements(ctx, mode, count, type))
1978      return;
1979
1980   _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0,
1981                                     count, type, indices, basevertex, 1, 0);
1982}
1983
1984
1985/**
1986 * Called by glDrawElementsInstanced() in immediate mode.
1987 */
1988void GLAPIENTRY
1989_mesa_DrawElementsInstancedARB(GLenum mode, GLsizei count, GLenum type,
1990                               const GLvoid * indices, GLsizei numInstances)
1991{
1992   GET_CURRENT_CONTEXT(ctx);
1993   FLUSH_FOR_DRAW(ctx);
1994
1995   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
1996                      ctx->VertexProgram._VPModeInputFilter);
1997
1998   if (ctx->NewState)
1999      _mesa_update_state(ctx);
2000
2001   if (!_mesa_is_no_error_enabled(ctx) &&
2002       !_mesa_validate_DrawElementsInstanced(ctx, mode, count, type,
2003                                             numInstances))
2004      return;
2005
2006   _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0,
2007                                     count, type, indices, 0, numInstances, 0);
2008}
2009
2010
2011/**
2012 * Called by glDrawElementsInstancedBaseVertex() in immediate mode.
2013 */
2014void GLAPIENTRY
2015_mesa_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count,
2016                                      GLenum type, const GLvoid * indices,
2017                                      GLsizei numInstances,
2018                                      GLint basevertex)
2019{
2020   GET_CURRENT_CONTEXT(ctx);
2021   FLUSH_FOR_DRAW(ctx);
2022
2023   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
2024                      ctx->VertexProgram._VPModeInputFilter);
2025
2026   if (ctx->NewState)
2027      _mesa_update_state(ctx);
2028
2029   if (!_mesa_is_no_error_enabled(ctx) &&
2030       !_mesa_validate_DrawElementsInstanced(ctx, mode, count, type,
2031                                             numInstances))
2032      return;
2033
2034   _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0,
2035                                     count, type, indices,
2036                                     basevertex, numInstances, 0);
2037}
2038
2039
2040/**
2041 * Called by glDrawElementsInstancedBaseInstance() in immediate mode.
2042 */
2043void GLAPIENTRY
2044_mesa_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count,
2045                                        GLenum type,
2046                                        const GLvoid *indices,
2047                                        GLsizei numInstances,
2048                                        GLuint baseInstance)
2049{
2050   GET_CURRENT_CONTEXT(ctx);
2051   FLUSH_FOR_DRAW(ctx);
2052
2053   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
2054                      ctx->VertexProgram._VPModeInputFilter);
2055
2056   if (ctx->NewState)
2057      _mesa_update_state(ctx);
2058
2059   if (!_mesa_is_no_error_enabled(ctx) &&
2060       !_mesa_validate_DrawElementsInstanced(ctx, mode, count, type,
2061                                             numInstances))
2062      return;
2063
2064   _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0,
2065                                     count, type, indices, 0, numInstances,
2066                                     baseInstance);
2067}
2068
2069
2070/**
2071 * Called by glDrawElementsInstancedBaseVertexBaseInstance() in immediate mode.
2072 */
2073void GLAPIENTRY
2074_mesa_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode,
2075                                                  GLsizei count,
2076                                                  GLenum type,
2077                                                  const GLvoid *indices,
2078                                                  GLsizei numInstances,
2079                                                  GLint basevertex,
2080                                                  GLuint baseInstance)
2081{
2082   GET_CURRENT_CONTEXT(ctx);
2083   FLUSH_FOR_DRAW(ctx);
2084
2085   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
2086                      ctx->VertexProgram._VPModeInputFilter);
2087
2088   if (ctx->NewState)
2089      _mesa_update_state(ctx);
2090
2091   if (!_mesa_is_no_error_enabled(ctx) &&
2092       !_mesa_validate_DrawElementsInstanced(ctx, mode, count, type,
2093                                             numInstances))
2094      return;
2095
2096   _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0,
2097                                     count, type, indices, basevertex,
2098                                     numInstances, baseInstance);
2099}
2100
2101
2102/**
2103 * Inner support for both _mesa_MultiDrawElements() and
2104 * _mesa_MultiDrawRangeElements().
2105 * This does the actual rendering after we've checked array indexes, etc.
2106 */
2107static void
2108_mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
2109                                  const GLsizei *count, GLenum type,
2110                                  const GLvoid * const *indices,
2111                                  GLsizei primcount, const GLint *basevertex)
2112{
2113   uintptr_t min_index_ptr, max_index_ptr;
2114   bool fallback = false;
2115   int i;
2116
2117   if (primcount == 0)
2118      return;
2119
2120   unsigned index_size_shift = get_index_size_shift(type);
2121
2122   min_index_ptr = (uintptr_t) indices[0];
2123   max_index_ptr = 0;
2124   for (i = 0; i < primcount; i++) {
2125      min_index_ptr = MIN2(min_index_ptr, (uintptr_t) indices[i]);
2126      max_index_ptr = MAX2(max_index_ptr, (uintptr_t) indices[i] +
2127                           (count[i] << index_size_shift));
2128   }
2129
2130   /* Check if we can handle this thing as a bunch of index offsets from the
2131    * same index pointer.  If we can't, then we have to fall back to doing
2132    * a draw_prims per primitive.
2133    * Check that the difference between each prim's indexes is a multiple of
2134    * the index/element size.
2135    */
2136   if (index_size_shift) {
2137      for (i = 0; i < primcount; i++) {
2138         if ((((uintptr_t) indices[i] - min_index_ptr) &
2139              ((1 << index_size_shift) - 1)) != 0) {
2140            fallback = true;
2141            break;
2142         }
2143      }
2144   }
2145
2146   struct gl_buffer_object *index_bo = ctx->Array.VAO->IndexBufferObj;
2147   struct pipe_draw_info info;
2148
2149   info.mode = mode;
2150   info.index_size = 1 << index_size_shift;
2151   /* Packed section begin. */
2152   info.primitive_restart = ctx->Array._PrimitiveRestart[index_size_shift];
2153   info.has_user_indices = index_bo == NULL;
2154   info.index_bounds_valid = false;
2155   info.increment_draw_id = primcount > 1;
2156   info.was_line_loop = false;
2157   info.take_index_buffer_ownership = false;
2158   info.index_bias_varies = !!basevertex;
2159   /* Packed section end. */
2160   info.start_instance = 0;
2161   info.instance_count = 1;
2162   info.view_mask = 0;
2163   info.restart_index = ctx->Array._RestartIndex[index_size_shift];
2164
2165   if (info.has_user_indices)
2166      info.index.user = (void*)min_index_ptr;
2167   else
2168      info.index.gl_bo = index_bo;
2169
2170   if (!fallback &&
2171       (!info.has_user_indices ||
2172        /* "max_index_ptr - min_index_ptr >> index_size_shift" is stored
2173         * in draw[i].start. The driver will multiply it later by index_size
2174         * so make sure the final value won't overflow.
2175         *
2176         * For real index buffers, gallium doesn't support index buffer offsets
2177         * greater than UINT32_MAX bytes.
2178         */
2179        max_index_ptr - min_index_ptr <= UINT32_MAX)) {
2180      struct pipe_draw_start_count_bias *draw;
2181
2182      ALLOC_PRIMS(draw, primcount, "glMultiDrawElements");
2183
2184      if (info.has_user_indices) {
2185         for (int i = 0; i < primcount; i++) {
2186            draw[i].start =
2187               ((uintptr_t)indices[i] - min_index_ptr) >> index_size_shift;
2188            draw[i].count = count[i];
2189            draw[i].index_bias = basevertex ? basevertex[i] : 0;
2190         }
2191      } else {
2192         for (int i = 0; i < primcount; i++) {
2193            draw[i].start = (uintptr_t)indices[i] >> index_size_shift;
2194            draw[i].count =
2195               indices_aligned(index_size_shift, indices[i]) ? count[i] : 0;
2196            draw[i].index_bias = basevertex ? basevertex[i] : 0;
2197         }
2198      }
2199
2200      ctx->Driver.DrawGallium(ctx, &info, 0, draw, primcount);
2201      FREE_PRIMS(draw, primcount);
2202   } else {
2203      /* draw[i].start would overflow. Draw one at a time. */
2204      assert(info.has_user_indices);
2205      info.increment_draw_id = false;
2206
2207      for (int i = 0; i < primcount; i++) {
2208         struct pipe_draw_start_count_bias draw;
2209
2210         if (!count[i])
2211            continue;
2212
2213         /* Reset these, because the callee can change them. */
2214         info.index_bounds_valid = false;
2215         info.index.user = indices[i];
2216         draw.start = 0;
2217         draw.index_bias = basevertex ? basevertex[i] : 0;
2218         draw.count = count[i];
2219
2220         ctx->Driver.DrawGallium(ctx, &info, i, &draw, 1);
2221      }
2222   }
2223
2224   if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
2225      _mesa_flush(ctx);
2226   }
2227}
2228
2229
2230void GLAPIENTRY
2231_mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type,
2232                           const GLvoid * const *indices, GLsizei primcount)
2233{
2234   GET_CURRENT_CONTEXT(ctx);
2235   FLUSH_FOR_DRAW(ctx);
2236
2237   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
2238                      ctx->VertexProgram._VPModeInputFilter);
2239
2240   if (ctx->NewState)
2241      _mesa_update_state(ctx);
2242
2243   if (!_mesa_is_no_error_enabled(ctx) &&
2244       !_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
2245                                         primcount))
2246      return;
2247
2248   _mesa_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
2249                                     NULL);
2250}
2251
2252
2253void GLAPIENTRY
2254_mesa_MultiDrawElementsBaseVertex(GLenum mode,
2255                                  const GLsizei *count, GLenum type,
2256                                  const GLvoid * const *indices,
2257                                  GLsizei primcount,
2258                                  const GLsizei *basevertex)
2259{
2260   GET_CURRENT_CONTEXT(ctx);
2261   FLUSH_FOR_DRAW(ctx);
2262
2263   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
2264                      ctx->VertexProgram._VPModeInputFilter);
2265
2266   if (ctx->NewState)
2267      _mesa_update_state(ctx);
2268
2269   if (!_mesa_is_no_error_enabled(ctx) &&
2270       !_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
2271                                         primcount))
2272      return;
2273
2274   _mesa_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
2275                                     basevertex);
2276}
2277
2278
2279/**
2280 * Draw a GL primitive using a vertex count obtained from transform feedback.
2281 * \param mode  the type of GL primitive to draw
2282 * \param obj  the transform feedback object to use
2283 * \param stream  index of the transform feedback stream from which to
2284 *                get the primitive count.
2285 * \param numInstances  number of instances to draw
2286 */
2287static void
2288_mesa_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
2289                              struct gl_transform_feedback_object *obj,
2290                              GLuint stream, GLuint numInstances)
2291{
2292   FLUSH_FOR_DRAW(ctx);
2293
2294   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
2295                      ctx->VertexProgram._VPModeInputFilter);
2296
2297   if (ctx->NewState)
2298      _mesa_update_state(ctx);
2299
2300   if (!_mesa_is_no_error_enabled(ctx) &&
2301       !_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream,
2302                                             numInstances))
2303      return;
2304
2305   /* Maybe we should do some primitive splitting for primitive restart
2306    * (like in DrawArrays), but we have no way to know how many vertices
2307    * will be rendered. */
2308
2309   st_draw_transform_feedback(ctx, mode, numInstances, stream, obj);
2310
2311   if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
2312      _mesa_flush(ctx);
2313   }
2314}
2315
2316
2317/**
2318 * Like DrawArrays, but take the count from a transform feedback object.
2319 * \param mode  GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc.
2320 * \param name  the transform feedback object
2321 * User still has to setup of the vertex attribute info with
2322 * glVertexPointer, glColorPointer, etc.
2323 * Part of GL_ARB_transform_feedback2.
2324 */
2325void GLAPIENTRY
2326_mesa_DrawTransformFeedback(GLenum mode, GLuint name)
2327{
2328   GET_CURRENT_CONTEXT(ctx);
2329   struct gl_transform_feedback_object *obj =
2330      _mesa_lookup_transform_feedback_object(ctx, name);
2331
2332   _mesa_draw_transform_feedback(ctx, mode, obj, 0, 1);
2333}
2334
2335
2336void GLAPIENTRY
2337_mesa_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream)
2338{
2339   GET_CURRENT_CONTEXT(ctx);
2340   struct gl_transform_feedback_object *obj =
2341      _mesa_lookup_transform_feedback_object(ctx, name);
2342
2343   _mesa_draw_transform_feedback(ctx, mode, obj, stream, 1);
2344}
2345
2346
2347void GLAPIENTRY
2348_mesa_DrawTransformFeedbackInstanced(GLenum mode, GLuint name,
2349                                     GLsizei primcount)
2350{
2351   GET_CURRENT_CONTEXT(ctx);
2352   struct gl_transform_feedback_object *obj =
2353      _mesa_lookup_transform_feedback_object(ctx, name);
2354
2355   _mesa_draw_transform_feedback(ctx, mode, obj, 0, primcount);
2356}
2357
2358
2359void GLAPIENTRY
2360_mesa_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name,
2361                                           GLuint stream,
2362                                           GLsizei primcount)
2363{
2364   GET_CURRENT_CONTEXT(ctx);
2365   struct gl_transform_feedback_object *obj =
2366      _mesa_lookup_transform_feedback_object(ctx, name);
2367
2368   _mesa_draw_transform_feedback(ctx, mode, obj, stream, primcount);
2369}
2370
2371
2372static void
2373_mesa_validated_multidrawarraysindirect(struct gl_context *ctx, GLenum mode,
2374                                        GLintptr indirect,
2375                                        GLintptr drawcount_offset,
2376                                        GLsizei drawcount, GLsizei stride,
2377                                        struct gl_buffer_object *drawcount_buffer)
2378{
2379   /* If drawcount_buffer is set, drawcount is the maximum draw count.*/
2380   if (drawcount == 0)
2381      return;
2382
2383   st_indirect_draw_vbo(ctx, mode, ctx->DrawIndirectBuffer, indirect,
2384                        drawcount, stride, drawcount_buffer,
2385                        drawcount_offset, NULL, false, 0);
2386
2387   if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
2388      _mesa_flush(ctx);
2389}
2390
2391
2392static void
2393_mesa_validated_multidrawelementsindirect(struct gl_context *ctx,
2394                                          GLenum mode, GLenum type,
2395                                          GLintptr indirect,
2396                                          GLintptr drawcount_offset,
2397                                          GLsizei drawcount, GLsizei stride,
2398                                          struct gl_buffer_object *drawcount_buffer)
2399{
2400   /* If drawcount_buffer is set, drawcount is the maximum draw count.*/
2401   if (drawcount == 0)
2402      return;
2403
2404   /* NOTE: IndexBufferObj is guaranteed to be a VBO. */
2405   struct _mesa_index_buffer ib;
2406   ib.count = 0;                /* unknown */
2407   ib.obj = ctx->Array.VAO->IndexBufferObj;
2408   ib.ptr = NULL;
2409   ib.index_size_shift = get_index_size_shift(type);
2410
2411   st_indirect_draw_vbo(ctx, mode, ctx->DrawIndirectBuffer, indirect,
2412                        drawcount, stride, drawcount_buffer,
2413                        drawcount_offset, &ib,
2414                        ctx->Array._PrimitiveRestart[ib.index_size_shift],
2415                        ctx->Array._RestartIndex[ib.index_size_shift]);
2416
2417   if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
2418      _mesa_flush(ctx);
2419}
2420
2421
2422/**
2423 * Like [Multi]DrawArrays/Elements, but they take most arguments from
2424 * a buffer object.
2425 */
2426void GLAPIENTRY
2427_mesa_DrawArraysIndirect(GLenum mode, const GLvoid *indirect)
2428{
2429   GET_CURRENT_CONTEXT(ctx);
2430
2431   /* From the ARB_draw_indirect spec:
2432    *
2433    *    "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
2434    *    compatibility profile, this indicates that DrawArraysIndirect and
2435    *    DrawElementsIndirect are to source their arguments directly from the
2436    *    pointer passed as their <indirect> parameters."
2437    */
2438   if (ctx->API == API_OPENGL_COMPAT &&
2439       !ctx->DrawIndirectBuffer) {
2440      DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) indirect;
2441
2442      _mesa_DrawArraysInstancedBaseInstance(mode, cmd->first, cmd->count,
2443                                            cmd->primCount,
2444                                            cmd->baseInstance);
2445      return;
2446   }
2447
2448   FLUSH_FOR_DRAW(ctx);
2449
2450   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
2451                      ctx->VertexProgram._VPModeInputFilter);
2452
2453   if (ctx->NewState)
2454      _mesa_update_state(ctx);
2455
2456   if (!_mesa_is_no_error_enabled(ctx) &&
2457       !_mesa_validate_DrawArraysIndirect(ctx, mode, indirect))
2458      return;
2459
2460   _mesa_validated_multidrawarraysindirect(ctx, mode, (GLintptr)indirect,
2461                                           0, 1, 16, NULL);
2462}
2463
2464
2465void GLAPIENTRY
2466_mesa_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
2467{
2468   GET_CURRENT_CONTEXT(ctx);
2469
2470   /* From the ARB_draw_indirect spec:
2471    *
2472    *    "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
2473    *    compatibility profile, this indicates that DrawArraysIndirect and
2474    *    DrawElementsIndirect are to source their arguments directly from the
2475    *    pointer passed as their <indirect> parameters."
2476    */
2477   if (ctx->API == API_OPENGL_COMPAT &&
2478       !ctx->DrawIndirectBuffer) {
2479      /*
2480       * Unlike regular DrawElementsInstancedBaseVertex commands, the indices
2481       * may not come from a client array and must come from an index buffer.
2482       * If no element array buffer is bound, an INVALID_OPERATION error is
2483       * generated.
2484       */
2485      if (!ctx->Array.VAO->IndexBufferObj) {
2486         _mesa_error(ctx, GL_INVALID_OPERATION,
2487                     "glDrawElementsIndirect(no buffer bound "
2488                     "to GL_ELEMENT_ARRAY_BUFFER)");
2489      } else {
2490         DrawElementsIndirectCommand *cmd =
2491            (DrawElementsIndirectCommand *) indirect;
2492
2493         /* Convert offset to pointer */
2494         void *offset = (void *)
2495            (uintptr_t)((cmd->firstIndex * _mesa_sizeof_type(type)) & 0xffffffffUL);
2496
2497         _mesa_DrawElementsInstancedBaseVertexBaseInstance(mode, cmd->count,
2498                                                           type, offset,
2499                                                           cmd->primCount,
2500                                                           cmd->baseVertex,
2501                                                           cmd->baseInstance);
2502      }
2503
2504      return;
2505   }
2506
2507   FLUSH_FOR_DRAW(ctx);
2508
2509   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
2510                      ctx->VertexProgram._VPModeInputFilter);
2511
2512   if (ctx->NewState)
2513      _mesa_update_state(ctx);
2514
2515   if (!_mesa_is_no_error_enabled(ctx) &&
2516       !_mesa_validate_DrawElementsIndirect(ctx, mode, type, indirect))
2517      return;
2518
2519   _mesa_validated_multidrawelementsindirect(ctx, mode, type,
2520                                             (GLintptr)indirect, 0,
2521                                             1, 20, NULL);
2522}
2523
2524
2525void GLAPIENTRY
2526_mesa_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect,
2527                              GLsizei primcount, GLsizei stride)
2528{
2529   GET_CURRENT_CONTEXT(ctx);
2530
2531   /* If <stride> is zero, the array elements are treated as tightly packed. */
2532   if (stride == 0)
2533      stride = sizeof(DrawArraysIndirectCommand);
2534
2535   FLUSH_FOR_DRAW(ctx);
2536
2537   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
2538                      ctx->VertexProgram._VPModeInputFilter);
2539
2540   if (ctx->NewState)
2541      _mesa_update_state(ctx);
2542
2543   /* From the ARB_draw_indirect spec:
2544    *
2545    *    "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
2546    *    compatibility profile, this indicates that DrawArraysIndirect and
2547    *    DrawElementsIndirect are to source their arguments directly from the
2548    *    pointer passed as their <indirect> parameters."
2549    */
2550   if (ctx->API == API_OPENGL_COMPAT &&
2551       !ctx->DrawIndirectBuffer) {
2552
2553      if (!_mesa_is_no_error_enabled(ctx) &&
2554          (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
2555                                           "glMultiDrawArraysIndirect") ||
2556           !_mesa_validate_DrawArrays(ctx, mode, 1)))
2557         return;
2558
2559      struct pipe_draw_info info;
2560      info.mode = mode;
2561      info.index_size = 0;
2562      info.view_mask = 0;
2563      /* Packed section begin. */
2564      info.primitive_restart = false;
2565      info.has_user_indices = false;
2566      info.index_bounds_valid = false;
2567      info.increment_draw_id = primcount > 1;
2568      info.was_line_loop = false;
2569      info.take_index_buffer_ownership = false;
2570      info.index_bias_varies = false;
2571      /* Packed section end. */
2572
2573      const uint8_t *ptr = (const uint8_t *) indirect;
2574      for (unsigned i = 0; i < primcount; i++) {
2575         DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) ptr;
2576
2577         info.start_instance = cmd->baseInstance;
2578         info.instance_count = cmd->primCount;
2579
2580         struct pipe_draw_start_count_bias draw;
2581         draw.start = cmd->first;
2582         draw.count = cmd->count;
2583
2584         ctx->Driver.DrawGallium(ctx, &info, i, &draw, 1);
2585         ptr += stride;
2586      }
2587
2588      return;
2589   }
2590
2591   if (!_mesa_is_no_error_enabled(ctx) &&
2592       !_mesa_validate_MultiDrawArraysIndirect(ctx, mode, indirect,
2593                                               primcount, stride))
2594      return;
2595
2596   _mesa_validated_multidrawarraysindirect(ctx, mode, (GLintptr)indirect, 0,
2597                                           primcount, stride, NULL);
2598}
2599
2600
2601void GLAPIENTRY
2602_mesa_MultiDrawElementsIndirect(GLenum mode, GLenum type,
2603                                const GLvoid *indirect,
2604                                GLsizei primcount, GLsizei stride)
2605{
2606   GET_CURRENT_CONTEXT(ctx);
2607
2608   FLUSH_FOR_DRAW(ctx);
2609
2610   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
2611                      ctx->VertexProgram._VPModeInputFilter);
2612
2613   if (ctx->NewState)
2614      _mesa_update_state(ctx);
2615
2616   /* If <stride> is zero, the array elements are treated as tightly packed. */
2617   if (stride == 0)
2618      stride = sizeof(DrawElementsIndirectCommand);
2619
2620   /* From the ARB_draw_indirect spec:
2621    *
2622    *    "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
2623    *    compatibility profile, this indicates that DrawArraysIndirect and
2624    *    DrawElementsIndirect are to source their arguments directly from the
2625    *    pointer passed as their <indirect> parameters."
2626    */
2627   if (ctx->API == API_OPENGL_COMPAT &&
2628       !ctx->DrawIndirectBuffer) {
2629      /*
2630       * Unlike regular DrawElementsInstancedBaseVertex commands, the indices
2631       * may not come from a client array and must come from an index buffer.
2632       * If no element array buffer is bound, an INVALID_OPERATION error is
2633       * generated.
2634       */
2635      if (!ctx->Array.VAO->IndexBufferObj) {
2636         _mesa_error(ctx, GL_INVALID_OPERATION,
2637                     "glMultiDrawElementsIndirect(no buffer bound "
2638                     "to GL_ELEMENT_ARRAY_BUFFER)");
2639
2640         return;
2641      }
2642
2643      if (!_mesa_is_no_error_enabled(ctx) &&
2644          (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
2645                                           "glMultiDrawArraysIndirect") ||
2646           !_mesa_validate_DrawElements(ctx, mode, 1, type)))
2647         return;
2648
2649      unsigned index_size_shift = get_index_size_shift(type);
2650
2651      struct pipe_draw_info info;
2652      info.mode = mode;
2653      info.index_size = 1 << index_size_shift;
2654      info.view_mask = 0;
2655      /* Packed section begin. */
2656      info.primitive_restart = ctx->Array._PrimitiveRestart[index_size_shift];
2657      info.has_user_indices = false;
2658      info.index_bounds_valid = false;
2659      info.increment_draw_id = primcount > 1;
2660      info.was_line_loop = false;
2661      info.take_index_buffer_ownership = false;
2662      info.index_bias_varies = false;
2663      /* Packed section end. */
2664      info.restart_index = ctx->Array._RestartIndex[index_size_shift];
2665
2666      const uint8_t *ptr = (const uint8_t *) indirect;
2667      for (unsigned i = 0; i < primcount; i++) {
2668         DrawElementsIndirectCommand *cmd = (DrawElementsIndirectCommand*)ptr;
2669
2670         info.index.gl_bo = ctx->Array.VAO->IndexBufferObj;
2671         info.start_instance = cmd->baseInstance;
2672         info.instance_count = cmd->primCount;
2673
2674         struct pipe_draw_start_count_bias draw;
2675         draw.start = cmd->firstIndex;
2676         draw.count = cmd->count;
2677         draw.index_bias = cmd->baseVertex;
2678
2679         ctx->Driver.DrawGallium(ctx, &info, i, &draw, 1);
2680         ptr += stride;
2681      }
2682
2683      return;
2684   }
2685
2686   if (!_mesa_is_no_error_enabled(ctx) &&
2687       !_mesa_validate_MultiDrawElementsIndirect(ctx, mode, type, indirect,
2688                                                 primcount, stride))
2689      return;
2690
2691   _mesa_validated_multidrawelementsindirect(ctx, mode, type,
2692                                             (GLintptr)indirect, 0, primcount,
2693                                             stride, NULL);
2694}
2695
2696
2697void GLAPIENTRY
2698_mesa_MultiDrawArraysIndirectCountARB(GLenum mode, GLintptr indirect,
2699                                      GLintptr drawcount_offset,
2700                                      GLsizei maxdrawcount, GLsizei stride)
2701{
2702   GET_CURRENT_CONTEXT(ctx);
2703   FLUSH_FOR_DRAW(ctx);
2704
2705   /* If <stride> is zero, the array elements are treated as tightly packed. */
2706   if (stride == 0)
2707      stride = 4 * sizeof(GLuint);      /* sizeof(DrawArraysIndirectCommand) */
2708
2709   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
2710                      ctx->VertexProgram._VPModeInputFilter);
2711
2712   if (ctx->NewState)
2713      _mesa_update_state(ctx);
2714
2715   if (!_mesa_is_no_error_enabled(ctx) &&
2716       !_mesa_validate_MultiDrawArraysIndirectCount(ctx, mode, indirect,
2717                                                    drawcount_offset,
2718                                                    maxdrawcount, stride))
2719      return;
2720
2721   _mesa_validated_multidrawarraysindirect(ctx, mode, indirect,
2722                                           drawcount_offset, maxdrawcount,
2723                                           stride, ctx->ParameterBuffer);
2724}
2725
2726
2727void GLAPIENTRY
2728_mesa_MultiDrawElementsIndirectCountARB(GLenum mode, GLenum type,
2729                                        GLintptr indirect,
2730                                        GLintptr drawcount_offset,
2731                                        GLsizei maxdrawcount, GLsizei stride)
2732{
2733   GET_CURRENT_CONTEXT(ctx);
2734   FLUSH_FOR_DRAW(ctx);
2735
2736   /* If <stride> is zero, the array elements are treated as tightly packed. */
2737   if (stride == 0)
2738      stride = 5 * sizeof(GLuint);      /* sizeof(DrawElementsIndirectCommand) */
2739
2740   _mesa_set_draw_vao(ctx, ctx->Array.VAO,
2741                      ctx->VertexProgram._VPModeInputFilter);
2742
2743   if (ctx->NewState)
2744      _mesa_update_state(ctx);
2745
2746   if (!_mesa_is_no_error_enabled(ctx) &&
2747       !_mesa_validate_MultiDrawElementsIndirectCount(ctx, mode, type,
2748                                                      indirect,
2749                                                      drawcount_offset,
2750                                                      maxdrawcount, stride))
2751      return;
2752
2753   _mesa_validated_multidrawelementsindirect(ctx, mode, type, indirect,
2754                                             drawcount_offset, maxdrawcount,
2755                                             stride, ctx->ParameterBuffer);
2756}
2757
2758
2759/* GL_IBM_multimode_draw_arrays */
2760void GLAPIENTRY
2761_mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
2762                              const GLsizei * count,
2763                              GLsizei primcount, GLint modestride )
2764{
2765   GET_CURRENT_CONTEXT(ctx);
2766   GLint i;
2767
2768   for ( i = 0 ; i < primcount ; i++ ) {
2769      if ( count[i] > 0 ) {
2770         GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
2771         CALL_DrawArrays(ctx->CurrentServerDispatch, ( m, first[i], count[i] ));
2772      }
2773   }
2774}
2775
2776
2777/* GL_IBM_multimode_draw_arrays */
2778void GLAPIENTRY
2779_mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
2780                                GLenum type, const GLvoid * const * indices,
2781                                GLsizei primcount, GLint modestride )
2782{
2783   GET_CURRENT_CONTEXT(ctx);
2784   GLint i;
2785
2786   for ( i = 0 ; i < primcount ; i++ ) {
2787      if ( count[i] > 0 ) {
2788         GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
2789         CALL_DrawElements(ctx->CurrentServerDispatch, ( m, count[i], type,
2790                                                         indices[i] ));
2791      }
2792   }
2793}
2794