• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "main/arrayobj.h"
31 #include "main/glheader.h"
32 #include "main/context.h"
33 #include "main/state.h"
34 #include "main/api_validate.h"
35 #include "main/dispatch.h"
36 #include "main/varray.h"
37 #include "main/bufferobj.h"
38 #include "main/enums.h"
39 #include "main/macros.h"
40 #include "main/transformfeedback.h"
41 
42 #include "vbo_context.h"
43 
44 
45 /**
46  * Check that element 'j' of the array has reasonable data.
47  * Map VBO if needed.
48  * For debugging purposes; not normally used.
49  */
50 static void
check_array_data(struct gl_context * ctx,struct gl_vertex_array_object * vao,GLuint attrib,GLuint j)51 check_array_data(struct gl_context *ctx, struct gl_vertex_array_object *vao,
52                  GLuint attrib, GLuint j)
53 {
54    const struct gl_array_attributes *array = &vao->VertexAttrib[attrib];
55    if (array->Enabled) {
56       const struct gl_vertex_buffer_binding *binding =
57          &vao->BufferBinding[array->BufferBindingIndex];
58       struct gl_buffer_object *bo = binding->BufferObj;
59       const void *data = array->Ptr;
60       if (_mesa_is_bufferobj(bo)) {
61          if (!bo->Mappings[MAP_INTERNAL].Pointer) {
62             /* need to map now */
63             bo->Mappings[MAP_INTERNAL].Pointer =
64                ctx->Driver.MapBufferRange(ctx, 0, bo->Size,
65                                           GL_MAP_READ_BIT, bo, MAP_INTERNAL);
66          }
67          data = ADD_POINTERS(_mesa_vertex_attrib_address(array, binding),
68                              bo->Mappings[MAP_INTERNAL].Pointer);
69       }
70       switch (array->Type) {
71       case GL_FLOAT:
72          {
73             GLfloat *f = (GLfloat *) ((GLubyte *) data + binding->Stride * j);
74             GLint k;
75             for (k = 0; k < array->Size; k++) {
76                if (IS_INF_OR_NAN(f[k]) || f[k] >= 1.0e20F || f[k] <= -1.0e10F) {
77                   printf("Bad array data:\n");
78                   printf("  Element[%u].%u = %f\n", j, k, f[k]);
79                   printf("  Array %u at %p\n", attrib, (void *) array);
80                   printf("  Type 0x%x, Size %d, Stride %d\n",
81                          array->Type, array->Size, binding->Stride);
82                   printf("  Address/offset %p in Buffer Object %u\n",
83                          array->Ptr, bo->Name);
84                   f[k] = 1.0F;  /* XXX replace the bad value! */
85                }
86                /*assert(!IS_INF_OR_NAN(f[k])); */
87             }
88          }
89          break;
90       default:
91          ;
92       }
93    }
94 }
95 
96 
97 /**
98  * Unmap the buffer object referenced by given array, if mapped.
99  */
100 static void
unmap_array_buffer(struct gl_context * ctx,struct gl_vertex_array_object * vao,GLuint attrib)101 unmap_array_buffer(struct gl_context *ctx, struct gl_vertex_array_object *vao,
102                    GLuint attrib)
103 {
104    const struct gl_array_attributes *array = &vao->VertexAttrib[attrib];
105    if (array->Enabled) {
106       const struct gl_vertex_buffer_binding *binding =
107          &vao->BufferBinding[array->BufferBindingIndex];
108       struct gl_buffer_object *bo = binding->BufferObj;
109       if (_mesa_is_bufferobj(bo) && _mesa_bufferobj_mapped(bo, MAP_INTERNAL)) {
110          ctx->Driver.UnmapBuffer(ctx, bo, MAP_INTERNAL);
111       }
112    }
113 }
114 
115 
116 /**
117  * Examine the array's data for NaNs, etc.
118  * For debug purposes; not normally used.
119  */
120 static void
check_draw_elements_data(struct gl_context * ctx,GLsizei count,GLenum elemType,const void * elements,GLint basevertex)121 check_draw_elements_data(struct gl_context *ctx, GLsizei count,
122                          GLenum elemType, const void *elements,
123                          GLint basevertex)
124 {
125    struct gl_vertex_array_object *vao = ctx->Array.VAO;
126    const void *elemMap;
127    GLint i;
128    GLuint k;
129 
130    if (_mesa_is_bufferobj(vao->IndexBufferObj)) {
131       elemMap = ctx->Driver.MapBufferRange(ctx, 0,
132                                            vao->IndexBufferObj->Size,
133                                            GL_MAP_READ_BIT,
134                                            vao->IndexBufferObj, MAP_INTERNAL);
135       elements = ADD_POINTERS(elements, elemMap);
136    }
137 
138    for (i = 0; i < count; i++) {
139       GLuint j;
140 
141       /* j = element[i] */
142       switch (elemType) {
143       case GL_UNSIGNED_BYTE:
144          j = ((const GLubyte *) elements)[i];
145          break;
146       case GL_UNSIGNED_SHORT:
147          j = ((const GLushort *) elements)[i];
148          break;
149       case GL_UNSIGNED_INT:
150          j = ((const GLuint *) elements)[i];
151          break;
152       default:
153          assert(0);
154       }
155 
156       /* check element j of each enabled array */
157       for (k = 0; k < VERT_ATTRIB_MAX; k++) {
158          check_array_data(ctx, vao, k, j);
159       }
160    }
161 
162    if (_mesa_is_bufferobj(vao->IndexBufferObj)) {
163       ctx->Driver.UnmapBuffer(ctx, vao->IndexBufferObj, MAP_INTERNAL);
164    }
165 
166    for (k = 0; k < VERT_ATTRIB_MAX; k++) {
167       unmap_array_buffer(ctx, vao, k);
168    }
169 }
170 
171 
172 /**
173  * Check array data, looking for NaNs, etc.
174  */
175 static void
check_draw_arrays_data(struct gl_context * ctx,GLint start,GLsizei count)176 check_draw_arrays_data(struct gl_context *ctx, GLint start, GLsizei count)
177 {
178    /* TO DO */
179 }
180 
181 
182 /**
183  * Print info/data for glDrawArrays(), for debugging.
184  */
185 static void
print_draw_arrays(struct gl_context * ctx,GLenum mode,GLint start,GLsizei count)186 print_draw_arrays(struct gl_context *ctx,
187                   GLenum mode, GLint start, GLsizei count)
188 {
189    const struct gl_vertex_array_object *vao = ctx->Array.VAO;
190 
191    printf("vbo_exec_DrawArrays(mode 0x%x, start %d, count %d):\n",
192           mode, start, count);
193 
194    unsigned i;
195    for (i = 0; i < VERT_ATTRIB_MAX; ++i) {
196       const struct gl_array_attributes *array = &vao->VertexAttrib[i];
197       if (!array->Enabled)
198          continue;
199 
200       const struct gl_vertex_buffer_binding *binding =
201          &vao->BufferBinding[array->BufferBindingIndex];
202       struct gl_buffer_object *bufObj = binding->BufferObj;
203 
204       printf("attr %s: size %d stride %d  enabled %d  "
205              "ptr %p  Bufobj %u\n",
206              gl_vert_attrib_name((gl_vert_attrib) i),
207              array->Size, binding->Stride, array->Enabled,
208              array->Ptr, bufObj->Name);
209 
210       if (_mesa_is_bufferobj(bufObj)) {
211          GLubyte *p = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size,
212                                                  GL_MAP_READ_BIT, bufObj,
213                                                  MAP_INTERNAL);
214          int offset = (int) (GLintptr)
215             _mesa_vertex_attrib_address(array, binding);
216          float *f = (float *) (p + offset);
217          int *k = (int *) f;
218          int i;
219          int n = (count * binding->Stride) / 4;
220          if (n > 32)
221             n = 32;
222          printf("  Data at offset %d:\n", offset);
223          for (i = 0; i < n; i++) {
224             printf("    float[%d] = 0x%08x %f\n", i, k[i], f[i]);
225          }
226          ctx->Driver.UnmapBuffer(ctx, bufObj, MAP_INTERNAL);
227       }
228    }
229 }
230 
231 
232 /**
233  * Set the vbo->exec->inputs[] pointers to point to the enabled
234  * vertex arrays.  This depends on the current vertex program/shader
235  * being executed because of whether or not generic vertex arrays
236  * alias the conventional vertex arrays.
237  * For arrays that aren't enabled, we set the input[attrib] pointer
238  * to point at a zero-stride current value "array".
239  */
240 static void
recalculate_input_bindings(struct gl_context * ctx)241 recalculate_input_bindings(struct gl_context *ctx)
242 {
243    struct vbo_context *vbo = vbo_context(ctx);
244    struct vbo_exec_context *exec = &vbo->exec;
245    const struct gl_array_attributes *array = ctx->Array.VAO->VertexAttrib;
246    struct gl_vertex_array *vertexAttrib = ctx->Array.VAO->_VertexAttrib;
247    const struct gl_vertex_array **inputs = &exec->array.inputs[0];
248    GLbitfield64 const_inputs = 0x0;
249    GLuint i;
250 
251    switch (get_program_mode(ctx)) {
252    case VP_NONE:
253       /* When no vertex program is active (or the vertex program is generated
254        * from fixed-function state).  We put the material values into the
255        * generic slots.  This is the only situation where material values
256        * are available as per-vertex attributes.
257        */
258       for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) {
259          if (array[VERT_ATTRIB_FF(i)].Enabled)
260             inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)];
261          else {
262             inputs[i] = &vbo->currval[VBO_ATTRIB_POS + i];
263             const_inputs |= VERT_BIT(i);
264          }
265       }
266 
267       for (i = 0; i < MAT_ATTRIB_MAX; i++) {
268          inputs[VERT_ATTRIB_GENERIC(i)] =
269             &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT + i];
270          const_inputs |= VERT_BIT_GENERIC(i);
271       }
272 
273       /* Could use just about anything, just to fill in the empty
274        * slots:
275        */
276       for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_GENERIC_MAX; i++) {
277          inputs[VERT_ATTRIB_GENERIC(i)] =
278             &vbo->currval[VBO_ATTRIB_GENERIC0 + i];
279          const_inputs |= VERT_BIT_GENERIC(i);
280       }
281       break;
282 
283    case VP_ARB:
284       /* There are no shaders in OpenGL ES 1.x, so this code path should be
285        * impossible to reach.  The meta code is careful to not use shaders in
286        * ES1.
287        */
288       assert(ctx->API != API_OPENGLES);
289 
290       /* In the compatibility profile of desktop OpenGL, the generic[0]
291        * attribute array aliases and overrides the legacy position array.
292        * Otherwise, legacy attributes available in the legacy slots,
293        * generic attributes in the generic slots and materials are not
294        * available as per-vertex attributes.
295        *
296        * In all other APIs, only the generic attributes exist, and none of the
297        * slots are considered "magic."
298        */
299       if (ctx->API == API_OPENGL_COMPAT) {
300          if (array[VERT_ATTRIB_GENERIC0].Enabled)
301             inputs[0] = &vertexAttrib[VERT_ATTRIB_GENERIC0];
302          else if (array[VERT_ATTRIB_POS].Enabled)
303             inputs[0] = &vertexAttrib[VERT_ATTRIB_POS];
304          else {
305             inputs[0] = &vbo->currval[VBO_ATTRIB_POS];
306             const_inputs |= VERT_BIT_POS;
307          }
308 
309          for (i = 1; i < VERT_ATTRIB_FF_MAX; i++) {
310             if (array[VERT_ATTRIB_FF(i)].Enabled)
311                inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)];
312             else {
313                inputs[i] = &vbo->currval[VBO_ATTRIB_POS + i];
314                const_inputs |= VERT_BIT_FF(i);
315             }
316          }
317 
318          for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) {
319             if (array[VERT_ATTRIB_GENERIC(i)].Enabled)
320                inputs[VERT_ATTRIB_GENERIC(i)] =
321                   &vertexAttrib[VERT_ATTRIB_GENERIC(i)];
322             else {
323                inputs[VERT_ATTRIB_GENERIC(i)] =
324                   &vbo->currval[VBO_ATTRIB_GENERIC0 + i];
325                const_inputs |= VERT_BIT_GENERIC(i);
326             }
327          }
328 
329          inputs[VERT_ATTRIB_GENERIC0] = inputs[0];
330       } else {
331          /* Other parts of the code assume that inputs[0] through
332           * inputs[VERT_ATTRIB_FF_MAX] will be non-NULL.  However, in OpenGL
333           * ES 2.0+ or OpenGL core profile, none of these arrays should ever
334           * be enabled.
335           */
336          for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) {
337             assert(!array[VERT_ATTRIB_FF(i)].Enabled);
338 
339             inputs[i] = &vbo->currval[VBO_ATTRIB_POS + i];
340             const_inputs |= VERT_BIT_FF(i);
341          }
342 
343          for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) {
344             if (array[VERT_ATTRIB_GENERIC(i)].Enabled)
345                inputs[VERT_ATTRIB_GENERIC(i)] =
346                   &vertexAttrib[VERT_ATTRIB_GENERIC(i)];
347             else {
348                inputs[VERT_ATTRIB_GENERIC(i)] =
349                   &vbo->currval[VBO_ATTRIB_GENERIC0 + i];
350                const_inputs |= VERT_BIT_GENERIC(i);
351             }
352          }
353       }
354 
355       break;
356    }
357 
358    _mesa_set_varying_vp_inputs(ctx, VERT_BIT_ALL & (~const_inputs));
359    ctx->NewDriverState |= ctx->DriverFlags.NewArray;
360 }
361 
362 
363 /**
364  * Examine the enabled vertex arrays to set the exec->array.inputs[] values.
365  * These will point to the arrays to actually use for drawing.  Some will
366  * be user-provided arrays, other will be zero-stride const-valued arrays.
367  * Note that this might set the _NEW_VARYING_VP_INPUTS dirty flag so state
368  * validation must be done after this call.
369  */
370 void
vbo_bind_arrays(struct gl_context * ctx)371 vbo_bind_arrays(struct gl_context *ctx)
372 {
373    struct vbo_context *vbo = vbo_context(ctx);
374    struct vbo_exec_context *exec = &vbo->exec;
375 
376    vbo_draw_method(vbo, DRAW_ARRAYS);
377 
378    if (exec->array.recalculate_inputs) {
379       recalculate_input_bindings(ctx);
380       exec->array.recalculate_inputs = GL_FALSE;
381 
382       /* Again... because we may have changed the bitmask of per-vertex varying
383        * attributes.  If we regenerate the fixed-function vertex program now
384        * we may be able to prune down the number of vertex attributes which we
385        * need in the shader.
386        */
387       if (ctx->NewState) {
388          /* Setting "validating" to TRUE prevents _mesa_update_state from
389           * invalidating what we just did.
390           */
391          exec->validating = GL_TRUE;
392          _mesa_update_state(ctx);
393          exec->validating = GL_FALSE;
394       }
395    }
396 }
397 
398 
399 /**
400  * Helper function called by the other DrawArrays() functions below.
401  * This is where we handle primitive restart for drawing non-indexed
402  * arrays.  If primitive restart is enabled, it typically means
403  * splitting one DrawArrays() into two.
404  */
405 static void
vbo_draw_arrays(struct gl_context * ctx,GLenum mode,GLint start,GLsizei count,GLuint numInstances,GLuint baseInstance)406 vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
407                 GLsizei count, GLuint numInstances, GLuint baseInstance)
408 {
409    struct vbo_context *vbo = vbo_context(ctx);
410    struct _mesa_prim prim[2];
411 
412    vbo_bind_arrays(ctx);
413 
414    /* init most fields to zero */
415    memset(prim, 0, sizeof(prim));
416    prim[0].begin = 1;
417    prim[0].end = 1;
418    prim[0].mode = mode;
419    prim[0].num_instances = numInstances;
420    prim[0].base_instance = baseInstance;
421    prim[0].is_indirect = 0;
422 
423    /* Implement the primitive restart index */
424    if (ctx->Array.PrimitiveRestart &&
425        !ctx->Array.PrimitiveRestartFixedIndex &&
426        ctx->Array.RestartIndex < count) {
427       GLuint primCount = 0;
428 
429       if (ctx->Array.RestartIndex == start) {
430          /* special case: RestartIndex at beginning */
431          if (count > 1) {
432             prim[0].start = start + 1;
433             prim[0].count = count - 1;
434             primCount = 1;
435          }
436       }
437       else if (ctx->Array.RestartIndex == start + count - 1) {
438          /* special case: RestartIndex at end */
439          if (count > 1) {
440             prim[0].start = start;
441             prim[0].count = count - 1;
442             primCount = 1;
443          }
444       }
445       else {
446          /* general case: RestartIndex in middle, split into two prims */
447          prim[0].start = start;
448          prim[0].count = ctx->Array.RestartIndex - start;
449 
450          prim[1] = prim[0];
451          prim[1].start = ctx->Array.RestartIndex + 1;
452          prim[1].count = count - prim[1].start;
453 
454          primCount = 2;
455       }
456 
457       if (primCount > 0) {
458          /* draw one or two prims */
459          vbo->draw_prims(ctx, prim, primCount, NULL,
460                          GL_TRUE, start, start + count - 1, NULL, 0, NULL);
461       }
462    }
463    else {
464       /* no prim restart */
465       prim[0].start = start;
466       prim[0].count = count;
467 
468       vbo->draw_prims(ctx, prim, 1, NULL,
469                       GL_TRUE, start, start + count - 1, NULL, 0, NULL);
470    }
471 
472    if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
473       _mesa_flush(ctx);
474    }
475 }
476 
477 
478 /**
479  * Execute a glRectf() function.
480  */
481 static void GLAPIENTRY
vbo_exec_Rectf(GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2)482 vbo_exec_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
483 {
484    GET_CURRENT_CONTEXT(ctx);
485    ASSERT_OUTSIDE_BEGIN_END(ctx);
486 
487    CALL_Begin(GET_DISPATCH(), (GL_QUADS));
488    CALL_Vertex2f(GET_DISPATCH(), (x1, y1));
489    CALL_Vertex2f(GET_DISPATCH(), (x2, y1));
490    CALL_Vertex2f(GET_DISPATCH(), (x2, y2));
491    CALL_Vertex2f(GET_DISPATCH(), (x1, y2));
492    CALL_End(GET_DISPATCH(), ());
493 }
494 
495 
496 static void GLAPIENTRY
vbo_exec_EvalMesh1(GLenum mode,GLint i1,GLint i2)497 vbo_exec_EvalMesh1(GLenum mode, GLint i1, GLint i2)
498 {
499    GET_CURRENT_CONTEXT(ctx);
500    GLint i;
501    GLfloat u, du;
502    GLenum prim;
503 
504    switch (mode) {
505    case GL_POINT:
506       prim = GL_POINTS;
507       break;
508    case GL_LINE:
509       prim = GL_LINE_STRIP;
510       break;
511    default:
512       _mesa_error(ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)");
513       return;
514    }
515 
516    /* No effect if vertex maps disabled.
517     */
518    if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3)
519       return;
520 
521    du = ctx->Eval.MapGrid1du;
522    u = ctx->Eval.MapGrid1u1 + i1 * du;
523 
524    CALL_Begin(GET_DISPATCH(), (prim));
525    for (i = i1; i <= i2; i++, u += du) {
526       CALL_EvalCoord1f(GET_DISPATCH(), (u));
527    }
528    CALL_End(GET_DISPATCH(), ());
529 }
530 
531 
532 static void GLAPIENTRY
vbo_exec_EvalMesh2(GLenum mode,GLint i1,GLint i2,GLint j1,GLint j2)533 vbo_exec_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
534 {
535    GET_CURRENT_CONTEXT(ctx);
536    GLfloat u, du, v, dv, v1, u1;
537    GLint i, j;
538 
539    switch (mode) {
540    case GL_POINT:
541    case GL_LINE:
542    case GL_FILL:
543       break;
544    default:
545       _mesa_error(ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)");
546       return;
547    }
548 
549    /* No effect if vertex maps disabled.
550     */
551    if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3)
552       return;
553 
554    du = ctx->Eval.MapGrid2du;
555    dv = ctx->Eval.MapGrid2dv;
556    v1 = ctx->Eval.MapGrid2v1 + j1 * dv;
557    u1 = ctx->Eval.MapGrid2u1 + i1 * du;
558 
559    switch (mode) {
560    case GL_POINT:
561       CALL_Begin(GET_DISPATCH(), (GL_POINTS));
562       for (v = v1, j = j1; j <= j2; j++, v += dv) {
563          for (u = u1, i = i1; i <= i2; i++, u += du) {
564             CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
565          }
566       }
567       CALL_End(GET_DISPATCH(), ());
568       break;
569    case GL_LINE:
570       for (v = v1, j = j1; j <= j2; j++, v += dv) {
571          CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP));
572          for (u = u1, i = i1; i <= i2; i++, u += du) {
573             CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
574          }
575          CALL_End(GET_DISPATCH(), ());
576       }
577       for (u = u1, i = i1; i <= i2; i++, u += du) {
578          CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP));
579          for (v = v1, j = j1; j <= j2; j++, v += dv) {
580             CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
581          }
582          CALL_End(GET_DISPATCH(), ());
583       }
584       break;
585    case GL_FILL:
586       for (v = v1, j = j1; j < j2; j++, v += dv) {
587          CALL_Begin(GET_DISPATCH(), (GL_TRIANGLE_STRIP));
588          for (u = u1, i = i1; i <= i2; i++, u += du) {
589             CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
590             CALL_EvalCoord2f(GET_DISPATCH(), (u, v + dv));
591          }
592          CALL_End(GET_DISPATCH(), ());
593       }
594       break;
595    }
596 }
597 
598 
599 /**
600  * Called from glDrawArrays when in immediate mode (not display list mode).
601  */
602 static void GLAPIENTRY
vbo_exec_DrawArrays(GLenum mode,GLint start,GLsizei count)603 vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
604 {
605    GET_CURRENT_CONTEXT(ctx);
606 
607    if (MESA_VERBOSE & VERBOSE_DRAW)
608       _mesa_debug(ctx, "glDrawArrays(%s, %d, %d)\n",
609                   _mesa_enum_to_string(mode), start, count);
610 
611    if (!_mesa_validate_DrawArrays(ctx, mode, count))
612       return;
613 
614    if (0)
615       check_draw_arrays_data(ctx, start, count);
616 
617    vbo_draw_arrays(ctx, mode, start, count, 1, 0);
618 
619    if (0)
620       print_draw_arrays(ctx, mode, start, count);
621 }
622 
623 
624 /**
625  * Called from glDrawArraysInstanced when in immediate mode (not
626  * display list mode).
627  */
628 static void GLAPIENTRY
vbo_exec_DrawArraysInstanced(GLenum mode,GLint start,GLsizei count,GLsizei numInstances)629 vbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count,
630                              GLsizei numInstances)
631 {
632    GET_CURRENT_CONTEXT(ctx);
633 
634    if (MESA_VERBOSE & VERBOSE_DRAW)
635       _mesa_debug(ctx, "glDrawArraysInstanced(%s, %d, %d, %d)\n",
636                   _mesa_enum_to_string(mode), start, count, numInstances);
637 
638    if (!_mesa_validate_DrawArraysInstanced(ctx, mode, start, count,
639                                            numInstances))
640       return;
641 
642    if (0)
643       check_draw_arrays_data(ctx, start, count);
644 
645    vbo_draw_arrays(ctx, mode, start, count, numInstances, 0);
646 
647    if (0)
648       print_draw_arrays(ctx, mode, start, count);
649 }
650 
651 
652 /**
653  * Called from glDrawArraysInstancedBaseInstance when in immediate mode.
654  */
655 static void GLAPIENTRY
vbo_exec_DrawArraysInstancedBaseInstance(GLenum mode,GLint first,GLsizei count,GLsizei numInstances,GLuint baseInstance)656 vbo_exec_DrawArraysInstancedBaseInstance(GLenum mode, GLint first,
657                                          GLsizei count, GLsizei numInstances,
658                                          GLuint baseInstance)
659 {
660    GET_CURRENT_CONTEXT(ctx);
661 
662    if (MESA_VERBOSE & VERBOSE_DRAW)
663       _mesa_debug(ctx,
664                   "glDrawArraysInstancedBaseInstance(%s, %d, %d, %d, %d)\n",
665                   _mesa_enum_to_string(mode), first, count,
666                   numInstances, baseInstance);
667 
668    if (!_mesa_validate_DrawArraysInstanced(ctx, mode, first, count,
669                                            numInstances))
670       return;
671 
672    if (0)
673       check_draw_arrays_data(ctx, first, count);
674 
675    vbo_draw_arrays(ctx, mode, first, count, numInstances, baseInstance);
676 
677    if (0)
678       print_draw_arrays(ctx, mode, first, count);
679 }
680 
681 
682 
683 /**
684  * Map GL_ELEMENT_ARRAY_BUFFER and print contents.
685  * For debugging.
686  */
687 #if 0
688 static void
689 dump_element_buffer(struct gl_context *ctx, GLenum type)
690 {
691    const GLvoid *map =
692       ctx->Driver.MapBufferRange(ctx, 0,
693                                  ctx->Array.VAO->IndexBufferObj->Size,
694                                  GL_MAP_READ_BIT,
695                                  ctx->Array.VAO->IndexBufferObj,
696                                  MAP_INTERNAL);
697    switch (type) {
698    case GL_UNSIGNED_BYTE:
699       {
700          const GLubyte *us = (const GLubyte *) map;
701          GLint i;
702          for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size; i++) {
703             printf("%02x ", us[i]);
704             if (i % 32 == 31)
705                printf("\n");
706          }
707          printf("\n");
708       }
709       break;
710    case GL_UNSIGNED_SHORT:
711       {
712          const GLushort *us = (const GLushort *) map;
713          GLint i;
714          for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size / 2; i++) {
715             printf("%04x ", us[i]);
716             if (i % 16 == 15)
717                printf("\n");
718          }
719          printf("\n");
720       }
721       break;
722    case GL_UNSIGNED_INT:
723       {
724          const GLuint *us = (const GLuint *) map;
725          GLint i;
726          for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size / 4; i++) {
727             printf("%08x ", us[i]);
728             if (i % 8 == 7)
729                printf("\n");
730          }
731          printf("\n");
732       }
733       break;
734    default:
735       ;
736    }
737 
738    ctx->Driver.UnmapBuffer(ctx, ctx->Array.VAO->IndexBufferObj, MAP_INTERNAL);
739 }
740 #endif
741 
742 
743 /**
744  * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements.
745  * Do the rendering for a glDrawElements or glDrawRangeElements call after
746  * we've validated buffer bounds, etc.
747  */
748 static void
vbo_validated_drawrangeelements(struct gl_context * ctx,GLenum mode,GLboolean index_bounds_valid,GLuint start,GLuint end,GLsizei count,GLenum type,const GLvoid * indices,GLint basevertex,GLuint numInstances,GLuint baseInstance)749 vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
750                                 GLboolean index_bounds_valid,
751                                 GLuint start, GLuint end,
752                                 GLsizei count, GLenum type,
753                                 const GLvoid * indices,
754                                 GLint basevertex, GLuint numInstances,
755                                 GLuint baseInstance)
756 {
757    struct vbo_context *vbo = vbo_context(ctx);
758    struct _mesa_index_buffer ib;
759    struct _mesa_prim prim[1];
760 
761    vbo_bind_arrays(ctx);
762 
763    ib.count = count;
764    ib.type = type;
765    ib.obj = ctx->Array.VAO->IndexBufferObj;
766    ib.ptr = indices;
767 
768    prim[0].begin = 1;
769    prim[0].end = 1;
770    prim[0].weak = 0;
771    prim[0].pad = 0;
772    prim[0].mode = mode;
773    prim[0].start = 0;
774    prim[0].count = count;
775    prim[0].indexed = 1;
776    prim[0].is_indirect = 0;
777    prim[0].basevertex = basevertex;
778    prim[0].num_instances = numInstances;
779    prim[0].base_instance = baseInstance;
780    prim[0].draw_id = 0;
781 
782    /* Need to give special consideration to rendering a range of
783     * indices starting somewhere above zero.  Typically the
784     * application is issuing multiple DrawRangeElements() to draw
785     * successive primitives layed out linearly in the vertex arrays.
786     * Unless the vertex arrays are all in a VBO (or locked as with
787     * CVA), the OpenGL semantics imply that we need to re-read or
788     * re-upload the vertex data on each draw call.
789     *
790     * In the case of hardware tnl, we want to avoid starting the
791     * upload at zero, as it will mean every draw call uploads an
792     * increasing amount of not-used vertex data.  Worse - in the
793     * software tnl module, all those vertices might be transformed and
794     * lit but never rendered.
795     *
796     * If we just upload or transform the vertices in start..end,
797     * however, the indices will be incorrect.
798     *
799     * At this level, we don't know exactly what the requirements of
800     * the backend are going to be, though it will likely boil down to
801     * either:
802     *
803     * 1) Do nothing, everything is in a VBO and is processed once
804     *       only.
805     *
806     * 2) Adjust the indices and vertex arrays so that start becomes
807     *    zero.
808     *
809     * Rather than doing anything here, I'll provide a helper function
810     * for the latter case elsewhere.
811     */
812 
813    vbo->draw_prims(ctx, prim, 1, &ib,
814                    index_bounds_valid, start, end, NULL, 0, NULL);
815 
816    if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
817       _mesa_flush(ctx);
818    }
819 }
820 
821 
822 /**
823  * Called by glDrawRangeElementsBaseVertex() in immediate mode.
824  */
825 static void GLAPIENTRY
vbo_exec_DrawRangeElementsBaseVertex(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const GLvoid * indices,GLint basevertex)826 vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
827                                      GLsizei count, GLenum type,
828                                      const GLvoid * indices, GLint basevertex)
829 {
830    static GLuint warnCount = 0;
831    GLboolean index_bounds_valid = GL_TRUE;
832 
833    /* This is only useful to catch invalid values in the "end" parameter
834     * like ~0.
835     */
836    GLuint max_element = 2 * 1000 * 1000 * 1000; /* just a big number */
837 
838    GET_CURRENT_CONTEXT(ctx);
839 
840    if (MESA_VERBOSE & VERBOSE_DRAW)
841       _mesa_debug(ctx,
842                   "glDrawRangeElementsBaseVertex(%s, %u, %u, %d, %s, %p, %d)\n",
843                   _mesa_enum_to_string(mode), start, end, count,
844                   _mesa_enum_to_string(type), indices, basevertex);
845 
846    if (!_mesa_validate_DrawRangeElements(ctx, mode, start, end, count,
847                                          type, indices))
848       return;
849 
850    if ((int) end + basevertex < 0 || start + basevertex >= max_element) {
851       /* The application requested we draw using a range of indices that's
852        * outside the bounds of the current VBO.  This is invalid and appears
853        * to give undefined results.  The safest thing to do is to simply
854        * ignore the range, in case the application botched their range tracking
855        * but did provide valid indices.  Also issue a warning indicating that
856        * the application is broken.
857        */
858       if (warnCount++ < 10) {
859          _mesa_warning(ctx, "glDrawRangeElements(start %u, end %u, "
860                        "basevertex %d, count %d, type 0x%x, indices=%p):\n"
861                        "\trange is outside VBO bounds (max=%u); ignoring.\n"
862                        "\tThis should be fixed in the application.",
863                        start, end, basevertex, count, type, indices,
864                        max_element - 1);
865       }
866       index_bounds_valid = GL_FALSE;
867    }
868 
869    /* NOTE: It's important that 'end' is a reasonable value.
870     * in _tnl_draw_prims(), we use end to determine how many vertices
871     * to transform.  If it's too large, we can unnecessarily split prims
872     * or we can read/write out of memory in several different places!
873     */
874 
875    /* Catch/fix some potential user errors */
876    if (type == GL_UNSIGNED_BYTE) {
877       start = MIN2(start, 0xff);
878       end = MIN2(end, 0xff);
879    }
880    else if (type == GL_UNSIGNED_SHORT) {
881       start = MIN2(start, 0xffff);
882       end = MIN2(end, 0xffff);
883    }
884 
885    if (0) {
886       printf("glDraw[Range]Elements{,BaseVertex}"
887              "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, "
888              "base %d\n",
889              start, end, type, count,
890              ctx->Array.VAO->IndexBufferObj->Name, basevertex);
891    }
892 
893    if ((int) start + basevertex < 0 || end + basevertex >= max_element)
894       index_bounds_valid = GL_FALSE;
895 
896 #if 0
897    check_draw_elements_data(ctx, count, type, indices, basevertex);
898 #else
899    (void) check_draw_elements_data;
900 #endif
901 
902    vbo_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end,
903                                    count, type, indices, basevertex, 1, 0);
904 }
905 
906 
907 /**
908  * Called by glDrawRangeElements() in immediate mode.
909  */
910 static void GLAPIENTRY
vbo_exec_DrawRangeElements(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const GLvoid * indices)911 vbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
912                            GLsizei count, GLenum type, const GLvoid * indices)
913 {
914    if (MESA_VERBOSE & VERBOSE_DRAW) {
915       GET_CURRENT_CONTEXT(ctx);
916       _mesa_debug(ctx,
917                   "glDrawRangeElements(%s, %u, %u, %d, %s, %p)\n",
918                   _mesa_enum_to_string(mode), start, end, count,
919                   _mesa_enum_to_string(type), indices);
920    }
921 
922    vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
923                                         indices, 0);
924 }
925 
926 
927 /**
928  * Called by glDrawElements() in immediate mode.
929  */
930 static void GLAPIENTRY
vbo_exec_DrawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)931 vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
932                       const GLvoid * indices)
933 {
934    GET_CURRENT_CONTEXT(ctx);
935 
936    if (MESA_VERBOSE & VERBOSE_DRAW)
937       _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n",
938                   _mesa_enum_to_string(mode), count,
939                   _mesa_enum_to_string(type), indices);
940 
941    if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices))
942       return;
943 
944    vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
945                                    count, type, indices, 0, 1, 0);
946 }
947 
948 
949 /**
950  * Called by glDrawElementsBaseVertex() in immediate mode.
951  */
952 static void GLAPIENTRY
vbo_exec_DrawElementsBaseVertex(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices,GLint basevertex)953 vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
954                                 const GLvoid * indices, GLint basevertex)
955 {
956    GET_CURRENT_CONTEXT(ctx);
957 
958    if (MESA_VERBOSE & VERBOSE_DRAW)
959       _mesa_debug(ctx, "glDrawElementsBaseVertex(%s, %d, %s, %p, %d)\n",
960                   _mesa_enum_to_string(mode), count,
961                   _mesa_enum_to_string(type), indices, basevertex);
962 
963    if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices))
964       return;
965 
966    vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
967                                    count, type, indices, basevertex, 1, 0);
968 }
969 
970 
971 /**
972  * Called by glDrawElementsInstanced() in immediate mode.
973  */
974 static void GLAPIENTRY
vbo_exec_DrawElementsInstanced(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices,GLsizei numInstances)975 vbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
976                                const GLvoid * indices, GLsizei numInstances)
977 {
978    GET_CURRENT_CONTEXT(ctx);
979 
980    if (MESA_VERBOSE & VERBOSE_DRAW)
981       _mesa_debug(ctx, "glDrawElementsInstanced(%s, %d, %s, %p, %d)\n",
982                   _mesa_enum_to_string(mode), count,
983                   _mesa_enum_to_string(type), indices, numInstances);
984 
985    if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
986                                              numInstances))
987       return;
988 
989    vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
990                                    count, type, indices, 0, numInstances, 0);
991 }
992 
993 
994 /**
995  * Called by glDrawElementsInstancedBaseVertex() in immediate mode.
996  */
997 static void GLAPIENTRY
vbo_exec_DrawElementsInstancedBaseVertex(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices,GLsizei numInstances,GLint basevertex)998 vbo_exec_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count,
999                                          GLenum type, const GLvoid * indices,
1000                                          GLsizei numInstances,
1001                                          GLint basevertex)
1002 {
1003    GET_CURRENT_CONTEXT(ctx);
1004 
1005    if (MESA_VERBOSE & VERBOSE_DRAW)
1006       _mesa_debug(ctx,
1007                   "glDrawElementsInstancedBaseVertex(%s, %d, %s, %p, %d; %d)\n",
1008                   _mesa_enum_to_string(mode), count,
1009                   _mesa_enum_to_string(type), indices,
1010                   numInstances, basevertex);
1011 
1012    if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
1013                                              numInstances))
1014       return;
1015 
1016    vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1017                                    count, type, indices,
1018                                    basevertex, numInstances, 0);
1019 }
1020 
1021 
1022 /**
1023  * Called by glDrawElementsInstancedBaseInstance() in immediate mode.
1024  */
1025 static void GLAPIENTRY
vbo_exec_DrawElementsInstancedBaseInstance(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices,GLsizei numInstances,GLuint baseInstance)1026 vbo_exec_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count,
1027                                            GLenum type,
1028                                            const GLvoid *indices,
1029                                            GLsizei numInstances,
1030                                            GLuint baseInstance)
1031 {
1032    GET_CURRENT_CONTEXT(ctx);
1033 
1034    if (MESA_VERBOSE & VERBOSE_DRAW)
1035       _mesa_debug(ctx,
1036                   "glDrawElementsInstancedBaseInstance"
1037                   "(%s, %d, %s, %p, %d, %d)\n",
1038                   _mesa_enum_to_string(mode), count,
1039                   _mesa_enum_to_string(type), indices,
1040                   numInstances, baseInstance);
1041 
1042    if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
1043                                              numInstances))
1044       return;
1045 
1046    vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1047                                    count, type, indices, 0, numInstances,
1048                                    baseInstance);
1049 }
1050 
1051 
1052 /**
1053  * Called by glDrawElementsInstancedBaseVertexBaseInstance() in immediate mode.
1054  */
1055 static void GLAPIENTRY
vbo_exec_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices,GLsizei numInstances,GLint basevertex,GLuint baseInstance)1056 vbo_exec_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode,
1057                                                      GLsizei count,
1058                                                      GLenum type,
1059                                                      const GLvoid *indices,
1060                                                      GLsizei numInstances,
1061                                                      GLint basevertex,
1062                                                      GLuint baseInstance)
1063 {
1064    GET_CURRENT_CONTEXT(ctx);
1065 
1066    if (MESA_VERBOSE & VERBOSE_DRAW)
1067       _mesa_debug(ctx,
1068                   "glDrawElementsInstancedBaseVertexBaseInstance"
1069                   "(%s, %d, %s, %p, %d, %d, %d)\n",
1070                   _mesa_enum_to_string(mode), count,
1071                   _mesa_enum_to_string(type), indices,
1072                   numInstances, basevertex, baseInstance);
1073 
1074    if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
1075                                              numInstances))
1076       return;
1077 
1078    vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1079                                    count, type, indices, basevertex,
1080                                    numInstances, baseInstance);
1081 }
1082 
1083 
1084 /**
1085  * Inner support for both _mesa_MultiDrawElements() and
1086  * _mesa_MultiDrawRangeElements().
1087  * This does the actual rendering after we've checked array indexes, etc.
1088  */
1089 static void
vbo_validated_multidrawelements(struct gl_context * ctx,GLenum mode,const GLsizei * count,GLenum type,const GLvoid * const * indices,GLsizei primcount,const GLint * basevertex)1090 vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
1091                                 const GLsizei *count, GLenum type,
1092                                 const GLvoid * const *indices,
1093                                 GLsizei primcount, const GLint *basevertex)
1094 {
1095    struct vbo_context *vbo = vbo_context(ctx);
1096    struct _mesa_index_buffer ib;
1097    struct _mesa_prim *prim;
1098    unsigned int index_type_size = vbo_sizeof_ib_type(type);
1099    uintptr_t min_index_ptr, max_index_ptr;
1100    GLboolean fallback = GL_FALSE;
1101    int i;
1102 
1103    if (primcount == 0)
1104       return;
1105 
1106    prim = calloc(primcount, sizeof(*prim));
1107    if (prim == NULL) {
1108       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements");
1109       return;
1110    }
1111 
1112    vbo_bind_arrays(ctx);
1113 
1114    min_index_ptr = (uintptr_t) indices[0];
1115    max_index_ptr = 0;
1116    for (i = 0; i < primcount; i++) {
1117       min_index_ptr = MIN2(min_index_ptr, (uintptr_t) indices[i]);
1118       max_index_ptr = MAX2(max_index_ptr, (uintptr_t) indices[i] +
1119                            index_type_size * count[i]);
1120    }
1121 
1122    /* Check if we can handle this thing as a bunch of index offsets from the
1123     * same index pointer.  If we can't, then we have to fall back to doing
1124     * a draw_prims per primitive.
1125     * Check that the difference between each prim's indexes is a multiple of
1126     * the index/element size.
1127     */
1128    if (index_type_size != 1) {
1129       for (i = 0; i < primcount; i++) {
1130          if ((((uintptr_t) indices[i] - min_index_ptr) % index_type_size) !=
1131              0) {
1132             fallback = GL_TRUE;
1133             break;
1134          }
1135       }
1136    }
1137 
1138    /* Draw primitives individually if one count is zero, so we can easily skip
1139     * that primitive.
1140     */
1141    for (i = 0; i < primcount; i++) {
1142       if (count[i] == 0) {
1143          fallback = GL_TRUE;
1144          break;
1145       }
1146    }
1147 
1148    /* If the index buffer isn't in a VBO, then treating the application's
1149     * subranges of the index buffer as one large index buffer may lead to
1150     * us reading unmapped memory.
1151     */
1152    if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj))
1153       fallback = GL_TRUE;
1154 
1155    if (!fallback) {
1156       ib.count = (max_index_ptr - min_index_ptr) / index_type_size;
1157       ib.type = type;
1158       ib.obj = ctx->Array.VAO->IndexBufferObj;
1159       ib.ptr = (void *) min_index_ptr;
1160 
1161       for (i = 0; i < primcount; i++) {
1162          prim[i].begin = (i == 0);
1163          prim[i].end = (i == primcount - 1);
1164          prim[i].weak = 0;
1165          prim[i].pad = 0;
1166          prim[i].mode = mode;
1167          prim[i].start =
1168             ((uintptr_t) indices[i] - min_index_ptr) / index_type_size;
1169          prim[i].count = count[i];
1170          prim[i].indexed = 1;
1171          prim[i].num_instances = 1;
1172          prim[i].base_instance = 0;
1173          prim[i].draw_id = i;
1174          prim[i].is_indirect = 0;
1175          if (basevertex != NULL)
1176             prim[i].basevertex = basevertex[i];
1177          else
1178             prim[i].basevertex = 0;
1179       }
1180 
1181       vbo->draw_prims(ctx, prim, primcount, &ib,
1182                       false, ~0, ~0, NULL, 0, NULL);
1183    }
1184    else {
1185       /* render one prim at a time */
1186       for (i = 0; i < primcount; i++) {
1187          if (count[i] == 0)
1188             continue;
1189          ib.count = count[i];
1190          ib.type = type;
1191          ib.obj = ctx->Array.VAO->IndexBufferObj;
1192          ib.ptr = indices[i];
1193 
1194          prim[0].begin = 1;
1195          prim[0].end = 1;
1196          prim[0].weak = 0;
1197          prim[0].pad = 0;
1198          prim[0].mode = mode;
1199          prim[0].start = 0;
1200          prim[0].count = count[i];
1201          prim[0].indexed = 1;
1202          prim[0].num_instances = 1;
1203          prim[0].base_instance = 0;
1204          prim[0].draw_id = i;
1205          prim[0].is_indirect = 0;
1206          if (basevertex != NULL)
1207             prim[0].basevertex = basevertex[i];
1208          else
1209             prim[0].basevertex = 0;
1210 
1211          vbo->draw_prims(ctx, prim, 1, &ib, false, ~0, ~0, NULL, 0, NULL);
1212       }
1213    }
1214 
1215    free(prim);
1216 
1217    if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1218       _mesa_flush(ctx);
1219    }
1220 }
1221 
1222 
1223 static void GLAPIENTRY
vbo_exec_MultiDrawElements(GLenum mode,const GLsizei * count,GLenum type,const GLvoid * const * indices,GLsizei primcount)1224 vbo_exec_MultiDrawElements(GLenum mode,
1225                            const GLsizei *count, GLenum type,
1226                            const GLvoid * const *indices, GLsizei primcount)
1227 {
1228    GET_CURRENT_CONTEXT(ctx);
1229 
1230    if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
1231                                          primcount))
1232       return;
1233 
1234    vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
1235                                    NULL);
1236 }
1237 
1238 
1239 static void GLAPIENTRY
vbo_exec_MultiDrawElementsBaseVertex(GLenum mode,const GLsizei * count,GLenum type,const GLvoid * const * indices,GLsizei primcount,const GLsizei * basevertex)1240 vbo_exec_MultiDrawElementsBaseVertex(GLenum mode,
1241                                      const GLsizei *count, GLenum type,
1242                                      const GLvoid * const *indices,
1243                                      GLsizei primcount,
1244                                      const GLsizei *basevertex)
1245 {
1246    GET_CURRENT_CONTEXT(ctx);
1247 
1248    if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
1249                                          primcount))
1250       return;
1251 
1252    vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
1253                                    basevertex);
1254 }
1255 
1256 
1257 static void
vbo_draw_transform_feedback(struct gl_context * ctx,GLenum mode,struct gl_transform_feedback_object * obj,GLuint stream,GLuint numInstances)1258 vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
1259                             struct gl_transform_feedback_object *obj,
1260                             GLuint stream, GLuint numInstances)
1261 {
1262    struct vbo_context *vbo = vbo_context(ctx);
1263    struct _mesa_prim prim[2];
1264 
1265    if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream,
1266                                              numInstances)) {
1267       return;
1268    }
1269 
1270    if (ctx->Driver.GetTransformFeedbackVertexCount &&
1271        (ctx->Const.AlwaysUseGetTransformFeedbackVertexCount ||
1272         !_mesa_all_varyings_in_vbos(ctx->Array.VAO))) {
1273       GLsizei n =
1274          ctx->Driver.GetTransformFeedbackVertexCount(ctx, obj, stream);
1275       vbo_draw_arrays(ctx, mode, 0, n, numInstances, 0);
1276       return;
1277    }
1278 
1279    vbo_bind_arrays(ctx);
1280 
1281    /* init most fields to zero */
1282    memset(prim, 0, sizeof(prim));
1283    prim[0].begin = 1;
1284    prim[0].end = 1;
1285    prim[0].mode = mode;
1286    prim[0].num_instances = numInstances;
1287    prim[0].base_instance = 0;
1288    prim[0].is_indirect = 0;
1289 
1290    /* Maybe we should do some primitive splitting for primitive restart
1291     * (like in DrawArrays), but we have no way to know how many vertices
1292     * will be rendered. */
1293 
1294    vbo->draw_prims(ctx, prim, 1, NULL, GL_FALSE, ~0, ~0, obj, stream, NULL);
1295 
1296    if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1297       _mesa_flush(ctx);
1298    }
1299 }
1300 
1301 
1302 /**
1303  * Like DrawArrays, but take the count from a transform feedback object.
1304  * \param mode  GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc.
1305  * \param name  the transform feedback object
1306  * User still has to setup of the vertex attribute info with
1307  * glVertexPointer, glColorPointer, etc.
1308  * Part of GL_ARB_transform_feedback2.
1309  */
1310 static void GLAPIENTRY
vbo_exec_DrawTransformFeedback(GLenum mode,GLuint name)1311 vbo_exec_DrawTransformFeedback(GLenum mode, GLuint name)
1312 {
1313    GET_CURRENT_CONTEXT(ctx);
1314    struct gl_transform_feedback_object *obj =
1315       _mesa_lookup_transform_feedback_object(ctx, name);
1316 
1317    if (MESA_VERBOSE & VERBOSE_DRAW)
1318       _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n",
1319                   _mesa_enum_to_string(mode), name);
1320 
1321    vbo_draw_transform_feedback(ctx, mode, obj, 0, 1);
1322 }
1323 
1324 
1325 static void GLAPIENTRY
vbo_exec_DrawTransformFeedbackStream(GLenum mode,GLuint name,GLuint stream)1326 vbo_exec_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream)
1327 {
1328    GET_CURRENT_CONTEXT(ctx);
1329    struct gl_transform_feedback_object *obj =
1330       _mesa_lookup_transform_feedback_object(ctx, name);
1331 
1332    if (MESA_VERBOSE & VERBOSE_DRAW)
1333       _mesa_debug(ctx, "glDrawTransformFeedbackStream(%s, %u, %u)\n",
1334                   _mesa_enum_to_string(mode), name, stream);
1335 
1336    vbo_draw_transform_feedback(ctx, mode, obj, stream, 1);
1337 }
1338 
1339 
1340 static void GLAPIENTRY
vbo_exec_DrawTransformFeedbackInstanced(GLenum mode,GLuint name,GLsizei primcount)1341 vbo_exec_DrawTransformFeedbackInstanced(GLenum mode, GLuint name,
1342                                         GLsizei primcount)
1343 {
1344    GET_CURRENT_CONTEXT(ctx);
1345    struct gl_transform_feedback_object *obj =
1346       _mesa_lookup_transform_feedback_object(ctx, name);
1347 
1348    if (MESA_VERBOSE & VERBOSE_DRAW)
1349       _mesa_debug(ctx, "glDrawTransformFeedbackInstanced(%s, %d)\n",
1350                   _mesa_enum_to_string(mode), name);
1351 
1352    vbo_draw_transform_feedback(ctx, mode, obj, 0, primcount);
1353 }
1354 
1355 
1356 static void GLAPIENTRY
vbo_exec_DrawTransformFeedbackStreamInstanced(GLenum mode,GLuint name,GLuint stream,GLsizei primcount)1357 vbo_exec_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name,
1358                                               GLuint stream,
1359                                               GLsizei primcount)
1360 {
1361    GET_CURRENT_CONTEXT(ctx);
1362    struct gl_transform_feedback_object *obj =
1363       _mesa_lookup_transform_feedback_object(ctx, name);
1364 
1365    if (MESA_VERBOSE & VERBOSE_DRAW)
1366       _mesa_debug(ctx, "glDrawTransformFeedbackStreamInstanced"
1367                   "(%s, %u, %u, %i)\n",
1368                   _mesa_enum_to_string(mode), name, stream, primcount);
1369 
1370    vbo_draw_transform_feedback(ctx, mode, obj, stream, primcount);
1371 }
1372 
1373 
1374 static void
vbo_validated_drawarraysindirect(struct gl_context * ctx,GLenum mode,const GLvoid * indirect)1375 vbo_validated_drawarraysindirect(struct gl_context *ctx,
1376                                  GLenum mode, const GLvoid *indirect)
1377 {
1378    struct vbo_context *vbo = vbo_context(ctx);
1379 
1380    vbo_bind_arrays(ctx);
1381 
1382    vbo->draw_indirect_prims(ctx, mode,
1383                             ctx->DrawIndirectBuffer, (GLsizeiptr) indirect,
1384                             1 /* draw_count */ , 16 /* stride */ ,
1385                             NULL, 0, NULL);
1386 
1387    if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1388       _mesa_flush(ctx);
1389 }
1390 
1391 
1392 static void
vbo_validated_multidrawarraysindirect(struct gl_context * ctx,GLenum mode,const GLvoid * indirect,GLsizei primcount,GLsizei stride)1393 vbo_validated_multidrawarraysindirect(struct gl_context *ctx,
1394                                       GLenum mode,
1395                                       const GLvoid *indirect,
1396                                       GLsizei primcount, GLsizei stride)
1397 {
1398    struct vbo_context *vbo = vbo_context(ctx);
1399    GLsizeiptr offset = (GLsizeiptr) indirect;
1400 
1401    if (primcount == 0)
1402       return;
1403 
1404    vbo_bind_arrays(ctx);
1405 
1406    vbo->draw_indirect_prims(ctx, mode, ctx->DrawIndirectBuffer, offset,
1407                             primcount, stride, NULL, 0, NULL);
1408 
1409    if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1410       _mesa_flush(ctx);
1411 }
1412 
1413 
1414 static void
vbo_validated_drawelementsindirect(struct gl_context * ctx,GLenum mode,GLenum type,const GLvoid * indirect)1415 vbo_validated_drawelementsindirect(struct gl_context *ctx,
1416                                    GLenum mode, GLenum type,
1417                                    const GLvoid *indirect)
1418 {
1419    struct vbo_context *vbo = vbo_context(ctx);
1420    struct _mesa_index_buffer ib;
1421 
1422    vbo_bind_arrays(ctx);
1423 
1424    ib.count = 0;                /* unknown */
1425    ib.type = type;
1426    ib.obj = ctx->Array.VAO->IndexBufferObj;
1427    ib.ptr = NULL;
1428 
1429    vbo->draw_indirect_prims(ctx, mode,
1430                             ctx->DrawIndirectBuffer, (GLsizeiptr) indirect,
1431                             1 /* draw_count */ , 20 /* stride */ ,
1432                             NULL, 0, &ib);
1433 
1434    if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1435       _mesa_flush(ctx);
1436 }
1437 
1438 
1439 static void
vbo_validated_multidrawelementsindirect(struct gl_context * ctx,GLenum mode,GLenum type,const GLvoid * indirect,GLsizei primcount,GLsizei stride)1440 vbo_validated_multidrawelementsindirect(struct gl_context *ctx,
1441                                         GLenum mode, GLenum type,
1442                                         const GLvoid *indirect,
1443                                         GLsizei primcount, GLsizei stride)
1444 {
1445    struct vbo_context *vbo = vbo_context(ctx);
1446    struct _mesa_index_buffer ib;
1447    GLsizeiptr offset = (GLsizeiptr) indirect;
1448 
1449    if (primcount == 0)
1450       return;
1451 
1452    vbo_bind_arrays(ctx);
1453 
1454    /* NOTE: IndexBufferObj is guaranteed to be a VBO. */
1455 
1456    ib.count = 0;                /* unknown */
1457    ib.type = type;
1458    ib.obj = ctx->Array.VAO->IndexBufferObj;
1459    ib.ptr = NULL;
1460 
1461    vbo->draw_indirect_prims(ctx, mode,
1462                             ctx->DrawIndirectBuffer, offset,
1463                             primcount, stride, NULL, 0, &ib);
1464 
1465    if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1466       _mesa_flush(ctx);
1467 }
1468 
1469 
1470 /**
1471  * Like [Multi]DrawArrays/Elements, but they take most arguments from
1472  * a buffer object.
1473  */
1474 static void GLAPIENTRY
vbo_exec_DrawArraysIndirect(GLenum mode,const GLvoid * indirect)1475 vbo_exec_DrawArraysIndirect(GLenum mode, const GLvoid *indirect)
1476 {
1477    GET_CURRENT_CONTEXT(ctx);
1478 
1479    if (MESA_VERBOSE & VERBOSE_DRAW)
1480       _mesa_debug(ctx, "glDrawArraysIndirect(%s, %p)\n",
1481                   _mesa_enum_to_string(mode), indirect);
1482 
1483    if (!_mesa_validate_DrawArraysIndirect(ctx, mode, indirect))
1484       return;
1485 
1486    vbo_validated_drawarraysindirect(ctx, mode, indirect);
1487 }
1488 
1489 
1490 static void GLAPIENTRY
vbo_exec_DrawElementsIndirect(GLenum mode,GLenum type,const GLvoid * indirect)1491 vbo_exec_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1492 {
1493    GET_CURRENT_CONTEXT(ctx);
1494 
1495    if (MESA_VERBOSE & VERBOSE_DRAW)
1496       _mesa_debug(ctx, "glDrawElementsIndirect(%s, %s, %p)\n",
1497                   _mesa_enum_to_string(mode),
1498                   _mesa_enum_to_string(type), indirect);
1499 
1500    if (!_mesa_validate_DrawElementsIndirect(ctx, mode, type, indirect))
1501       return;
1502 
1503    vbo_validated_drawelementsindirect(ctx, mode, type, indirect);
1504 }
1505 
1506 
1507 static void GLAPIENTRY
vbo_exec_MultiDrawArraysIndirect(GLenum mode,const GLvoid * indirect,GLsizei primcount,GLsizei stride)1508 vbo_exec_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect,
1509                                  GLsizei primcount, GLsizei stride)
1510 {
1511    GET_CURRENT_CONTEXT(ctx);
1512 
1513    if (MESA_VERBOSE & VERBOSE_DRAW)
1514       _mesa_debug(ctx, "glMultiDrawArraysIndirect(%s, %p, %i, %i)\n",
1515                   _mesa_enum_to_string(mode), indirect, primcount, stride);
1516 
1517    /* If <stride> is zero, the array elements are treated as tightly packed. */
1518    if (stride == 0)
1519       stride = 4 * sizeof(GLuint);      /* sizeof(DrawArraysIndirectCommand) */
1520 
1521    if (!_mesa_validate_MultiDrawArraysIndirect(ctx, mode, indirect,
1522                                                primcount, stride))
1523       return;
1524 
1525    vbo_validated_multidrawarraysindirect(ctx, mode, indirect,
1526                                          primcount, stride);
1527 }
1528 
1529 
1530 static void GLAPIENTRY
vbo_exec_MultiDrawElementsIndirect(GLenum mode,GLenum type,const GLvoid * indirect,GLsizei primcount,GLsizei stride)1531 vbo_exec_MultiDrawElementsIndirect(GLenum mode, GLenum type,
1532                                    const GLvoid *indirect,
1533                                    GLsizei primcount, GLsizei stride)
1534 {
1535    GET_CURRENT_CONTEXT(ctx);
1536 
1537    if (MESA_VERBOSE & VERBOSE_DRAW)
1538       _mesa_debug(ctx, "glMultiDrawElementsIndirect(%s, %s, %p, %i, %i)\n",
1539                   _mesa_enum_to_string(mode),
1540                   _mesa_enum_to_string(type), indirect, primcount, stride);
1541 
1542    /* If <stride> is zero, the array elements are treated as tightly packed. */
1543    if (stride == 0)
1544       stride = 5 * sizeof(GLuint);      /* sizeof(DrawElementsIndirectCommand) */
1545 
1546    if (!_mesa_validate_MultiDrawElementsIndirect(ctx, mode, type, indirect,
1547                                                  primcount, stride))
1548       return;
1549 
1550    vbo_validated_multidrawelementsindirect(ctx, mode, type, indirect,
1551                                            primcount, stride);
1552 }
1553 
1554 
1555 static void
vbo_validated_multidrawarraysindirectcount(struct gl_context * ctx,GLenum mode,GLintptr indirect,GLintptr drawcount,GLsizei maxdrawcount,GLsizei stride)1556 vbo_validated_multidrawarraysindirectcount(struct gl_context *ctx,
1557                                            GLenum mode,
1558                                            GLintptr indirect,
1559                                            GLintptr drawcount,
1560                                            GLsizei maxdrawcount,
1561                                            GLsizei stride)
1562 {
1563    struct vbo_context *vbo = vbo_context(ctx);
1564    GLsizeiptr offset = indirect;
1565 
1566    if (maxdrawcount == 0)
1567       return;
1568 
1569    vbo_bind_arrays(ctx);
1570 
1571    vbo->draw_indirect_prims(ctx, mode,
1572                             ctx->DrawIndirectBuffer, offset,
1573                             maxdrawcount, stride,
1574                             ctx->ParameterBuffer, drawcount, NULL);
1575 
1576    if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1577       _mesa_flush(ctx);
1578 }
1579 
1580 
1581 static void
vbo_validated_multidrawelementsindirectcount(struct gl_context * ctx,GLenum mode,GLenum type,GLintptr indirect,GLintptr drawcount,GLsizei maxdrawcount,GLsizei stride)1582 vbo_validated_multidrawelementsindirectcount(struct gl_context *ctx,
1583                                              GLenum mode, GLenum type,
1584                                              GLintptr indirect,
1585                                              GLintptr drawcount,
1586                                              GLsizei maxdrawcount,
1587                                              GLsizei stride)
1588 {
1589    struct vbo_context *vbo = vbo_context(ctx);
1590    struct _mesa_index_buffer ib;
1591    GLsizeiptr offset = (GLsizeiptr) indirect;
1592 
1593    if (maxdrawcount == 0)
1594       return;
1595 
1596    vbo_bind_arrays(ctx);
1597 
1598    /* NOTE: IndexBufferObj is guaranteed to be a VBO. */
1599 
1600    ib.count = 0;                /* unknown */
1601    ib.type = type;
1602    ib.obj = ctx->Array.VAO->IndexBufferObj;
1603    ib.ptr = NULL;
1604 
1605    vbo->draw_indirect_prims(ctx, mode,
1606                             ctx->DrawIndirectBuffer, offset,
1607                             maxdrawcount, stride,
1608                             ctx->ParameterBuffer, drawcount, &ib);
1609 
1610    if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1611       _mesa_flush(ctx);
1612 }
1613 
1614 
1615 static void GLAPIENTRY
vbo_exec_MultiDrawArraysIndirectCount(GLenum mode,GLintptr indirect,GLintptr drawcount,GLsizei maxdrawcount,GLsizei stride)1616 vbo_exec_MultiDrawArraysIndirectCount(GLenum mode, GLintptr indirect,
1617                                       GLintptr drawcount,
1618                                       GLsizei maxdrawcount, GLsizei stride)
1619 {
1620    GET_CURRENT_CONTEXT(ctx);
1621 
1622    if (MESA_VERBOSE & VERBOSE_DRAW)
1623       _mesa_debug(ctx, "glMultiDrawArraysIndirectCountARB"
1624                   "(%s, %lx, %lx, %i, %i)\n",
1625                   _mesa_enum_to_string(mode),
1626                   (unsigned long) indirect, (unsigned long) drawcount,
1627                   maxdrawcount, stride);
1628 
1629    /* If <stride> is zero, the array elements are treated as tightly packed. */
1630    if (stride == 0)
1631       stride = 4 * sizeof(GLuint);      /* sizeof(DrawArraysIndirectCommand) */
1632 
1633    if (!_mesa_validate_MultiDrawArraysIndirectCount(ctx, mode,
1634                                                     indirect, drawcount,
1635                                                     maxdrawcount, stride))
1636       return;
1637 
1638    vbo_validated_multidrawarraysindirectcount(ctx, mode, indirect, drawcount,
1639                                               maxdrawcount, stride);
1640 }
1641 
1642 
1643 static void GLAPIENTRY
vbo_exec_MultiDrawElementsIndirectCount(GLenum mode,GLenum type,GLintptr indirect,GLintptr drawcount,GLsizei maxdrawcount,GLsizei stride)1644 vbo_exec_MultiDrawElementsIndirectCount(GLenum mode, GLenum type,
1645                                         GLintptr indirect, GLintptr drawcount,
1646                                         GLsizei maxdrawcount, GLsizei stride)
1647 {
1648    GET_CURRENT_CONTEXT(ctx);
1649 
1650    if (MESA_VERBOSE & VERBOSE_DRAW)
1651       _mesa_debug(ctx, "glMultiDrawElementsIndirectCountARB"
1652                   "(%s, %s, %lx, %lx, %i, %i)\n",
1653                   _mesa_enum_to_string(mode), _mesa_enum_to_string(type),
1654                   (unsigned long) indirect, (unsigned long) drawcount,
1655                   maxdrawcount, stride);
1656 
1657    /* If <stride> is zero, the array elements are treated as tightly packed. */
1658    if (stride == 0)
1659       stride = 5 * sizeof(GLuint);      /* sizeof(DrawElementsIndirectCommand) */
1660 
1661    if (!_mesa_validate_MultiDrawElementsIndirectCount(ctx, mode, type,
1662                                                       indirect, drawcount,
1663                                                       maxdrawcount, stride))
1664       return;
1665 
1666    vbo_validated_multidrawelementsindirectcount(ctx, mode, type, indirect,
1667                                                 drawcount, maxdrawcount,
1668                                                 stride);
1669 }
1670 
1671 
1672 /**
1673  * Initialize the dispatch table with the VBO functions for drawing.
1674  */
1675 void
vbo_initialize_exec_dispatch(const struct gl_context * ctx,struct _glapi_table * exec)1676 vbo_initialize_exec_dispatch(const struct gl_context *ctx,
1677                              struct _glapi_table *exec)
1678 {
1679    SET_DrawArrays(exec, vbo_exec_DrawArrays);
1680    SET_DrawElements(exec, vbo_exec_DrawElements);
1681 
1682    if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1683       SET_DrawRangeElements(exec, vbo_exec_DrawRangeElements);
1684    }
1685 
1686    SET_MultiDrawElementsEXT(exec, vbo_exec_MultiDrawElements);
1687 
1688    if (ctx->API == API_OPENGL_COMPAT) {
1689       SET_Rectf(exec, vbo_exec_Rectf);
1690       SET_EvalMesh1(exec, vbo_exec_EvalMesh1);
1691       SET_EvalMesh2(exec, vbo_exec_EvalMesh2);
1692    }
1693 
1694    if (ctx->API != API_OPENGLES &&
1695        ctx->Extensions.ARB_draw_elements_base_vertex) {
1696       SET_DrawElementsBaseVertex(exec, vbo_exec_DrawElementsBaseVertex);
1697       SET_MultiDrawElementsBaseVertex(exec,
1698                                       vbo_exec_MultiDrawElementsBaseVertex);
1699 
1700       if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1701          SET_DrawRangeElementsBaseVertex(exec,
1702                                          vbo_exec_DrawRangeElementsBaseVertex);
1703          SET_DrawElementsInstancedBaseVertex(exec,
1704                                              vbo_exec_DrawElementsInstancedBaseVertex);
1705       }
1706    }
1707 
1708    if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1709       SET_DrawArraysInstancedBaseInstance(exec,
1710                                           vbo_exec_DrawArraysInstancedBaseInstance);
1711       SET_DrawElementsInstancedBaseInstance(exec,
1712                                             vbo_exec_DrawElementsInstancedBaseInstance);
1713       SET_DrawElementsInstancedBaseVertexBaseInstance(exec,
1714                                                       vbo_exec_DrawElementsInstancedBaseVertexBaseInstance);
1715    }
1716 
1717    if (ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) {
1718       SET_DrawArraysIndirect(exec, vbo_exec_DrawArraysIndirect);
1719       SET_DrawElementsIndirect(exec, vbo_exec_DrawElementsIndirect);
1720    }
1721 
1722    if (ctx->API == API_OPENGL_CORE) {
1723       SET_MultiDrawArraysIndirect(exec, vbo_exec_MultiDrawArraysIndirect);
1724       SET_MultiDrawElementsIndirect(exec, vbo_exec_MultiDrawElementsIndirect);
1725       SET_MultiDrawArraysIndirectCountARB(exec,
1726                                           vbo_exec_MultiDrawArraysIndirectCount);
1727       SET_MultiDrawElementsIndirectCountARB(exec,
1728                                             vbo_exec_MultiDrawElementsIndirectCount);
1729    }
1730 
1731    if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1732       SET_DrawArraysInstancedARB(exec, vbo_exec_DrawArraysInstanced);
1733       SET_DrawElementsInstancedARB(exec, vbo_exec_DrawElementsInstanced);
1734    }
1735 
1736    if (_mesa_is_desktop_gl(ctx)) {
1737       SET_DrawTransformFeedback(exec, vbo_exec_DrawTransformFeedback);
1738       SET_DrawTransformFeedbackStream(exec,
1739                                       vbo_exec_DrawTransformFeedbackStream);
1740       SET_DrawTransformFeedbackInstanced(exec,
1741                                          vbo_exec_DrawTransformFeedbackInstanced);
1742       SET_DrawTransformFeedbackStreamInstanced(exec,
1743                                                vbo_exec_DrawTransformFeedbackStreamInstanced);
1744    }
1745 }
1746 
1747 
1748 
1749 /**
1750  * The following functions are only used for OpenGL ES 1/2 support.
1751  * And some aren't even supported (yet) in ES 1/2.
1752  */
1753 
1754 
1755 void GLAPIENTRY
_mesa_DrawArrays(GLenum mode,GLint first,GLsizei count)1756 _mesa_DrawArrays(GLenum mode, GLint first, GLsizei count)
1757 {
1758    vbo_exec_DrawArrays(mode, first, count);
1759 }
1760 
1761 
1762 void GLAPIENTRY
_mesa_DrawArraysInstanced(GLenum mode,GLint first,GLsizei count,GLsizei primcount)1763 _mesa_DrawArraysInstanced(GLenum mode, GLint first, GLsizei count,
1764                           GLsizei primcount)
1765 {
1766    vbo_exec_DrawArraysInstanced(mode, first, count, primcount);
1767 }
1768 
1769 
1770 void GLAPIENTRY
_mesa_DrawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)1771 _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
1772                    const GLvoid *indices)
1773 {
1774    vbo_exec_DrawElements(mode, count, type, indices);
1775 }
1776 
1777 
1778 void GLAPIENTRY
_mesa_DrawElementsBaseVertex(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices,GLint basevertex)1779 _mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
1780                              const GLvoid *indices, GLint basevertex)
1781 {
1782    vbo_exec_DrawElementsBaseVertex(mode, count, type, indices, basevertex);
1783 }
1784 
1785 
1786 void GLAPIENTRY
_mesa_DrawRangeElements(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const GLvoid * indices)1787 _mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
1788                         GLenum type, const GLvoid * indices)
1789 {
1790    vbo_exec_DrawRangeElements(mode, start, end, count, type, indices);
1791 }
1792 
1793 
1794 void GLAPIENTRY
_mesa_DrawRangeElementsBaseVertex(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const GLvoid * indices,GLint basevertex)1795 _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
1796                                   GLsizei count, GLenum type,
1797                                   const GLvoid *indices, GLint basevertex)
1798 {
1799    vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
1800                                         indices, basevertex);
1801 }
1802 
1803 
1804 void GLAPIENTRY
_mesa_MultiDrawElementsEXT(GLenum mode,const GLsizei * count,GLenum type,const GLvoid ** indices,GLsizei primcount)1805 _mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type,
1806                            const GLvoid ** indices, GLsizei primcount)
1807 {
1808    vbo_exec_MultiDrawElements(mode, count, type, indices, primcount);
1809 }
1810 
1811 
1812 void GLAPIENTRY
_mesa_MultiDrawElementsBaseVertex(GLenum mode,const GLsizei * count,GLenum type,const GLvoid ** indices,GLsizei primcount,const GLint * basevertex)1813 _mesa_MultiDrawElementsBaseVertex(GLenum mode,
1814                                   const GLsizei *count, GLenum type,
1815                                   const GLvoid **indices, GLsizei primcount,
1816                                   const GLint *basevertex)
1817 {
1818    vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices,
1819                                         primcount, basevertex);
1820 }
1821 
1822 
1823 void GLAPIENTRY
_mesa_DrawTransformFeedback(GLenum mode,GLuint name)1824 _mesa_DrawTransformFeedback(GLenum mode, GLuint name)
1825 {
1826    vbo_exec_DrawTransformFeedback(mode, name);
1827 }
1828