Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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