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