Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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