Home | History | Annotate | Download | only in vbo
      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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   1756 _mesa_DrawArrays(GLenum mode, GLint first, GLsizei count)
   1757 {
   1758    vbo_exec_DrawArrays(mode, first, count);
   1759 }
   1760 
   1761 
   1762 void GLAPIENTRY
   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
   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
   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
   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
   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
   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
   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
   1824 _mesa_DrawTransformFeedback(GLenum mode, GLuint name)
   1825 {
   1826    vbo_exec_DrawTransformFeedback(mode, name);
   1827 }
   1828