Subversion Repositories Kolibri OS

Rev

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

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28. /*
  29.  * This file implements the st_draw_vbo() function which is called from
  30.  * Mesa's VBO module.  All point/line/triangle rendering is done through
  31.  * this function whether the user called glBegin/End, glDrawArrays,
  32.  * glDrawElements, glEvalMesh, or glCalList, etc.
  33.  *
  34.  * We basically convert the VBO's vertex attribute/array information into
  35.  * Gallium vertex state, bind the vertex buffer objects and call
  36.  * pipe->draw_elements(), pipe->draw_range_elements() or pipe->draw_arrays().
  37.  *
  38.  * Authors:
  39.  *   Keith Whitwell <keith@tungstengraphics.com>
  40.  */
  41.  
  42.  
  43. #include "main/imports.h"
  44. #include "main/image.h"
  45. #include "main/macros.h"
  46. #include "program/prog_uniform.h"
  47.  
  48. #include "vbo/vbo.h"
  49.  
  50. #include "st_context.h"
  51. #include "st_atom.h"
  52. #include "st_cb_bufferobjects.h"
  53. #include "st_draw.h"
  54. #include "st_program.h"
  55.  
  56. #include "pipe/p_context.h"
  57. #include "pipe/p_defines.h"
  58. #include "util/u_inlines.h"
  59. #include "util/u_format.h"
  60. #include "util/u_prim.h"
  61. #include "util/u_draw_quad.h"
  62. #include "draw/draw_context.h"
  63. #include "cso_cache/cso_context.h"
  64.  
  65.  
  66. static GLuint double_types[4] = {
  67.    PIPE_FORMAT_R64_FLOAT,
  68.    PIPE_FORMAT_R64G64_FLOAT,
  69.    PIPE_FORMAT_R64G64B64_FLOAT,
  70.    PIPE_FORMAT_R64G64B64A64_FLOAT
  71. };
  72.  
  73. static GLuint float_types[4] = {
  74.    PIPE_FORMAT_R32_FLOAT,
  75.    PIPE_FORMAT_R32G32_FLOAT,
  76.    PIPE_FORMAT_R32G32B32_FLOAT,
  77.    PIPE_FORMAT_R32G32B32A32_FLOAT
  78. };
  79.  
  80. static GLuint half_float_types[4] = {
  81.    PIPE_FORMAT_R16_FLOAT,
  82.    PIPE_FORMAT_R16G16_FLOAT,
  83.    PIPE_FORMAT_R16G16B16_FLOAT,
  84.    PIPE_FORMAT_R16G16B16A16_FLOAT
  85. };
  86.  
  87. static GLuint uint_types_norm[4] = {
  88.    PIPE_FORMAT_R32_UNORM,
  89.    PIPE_FORMAT_R32G32_UNORM,
  90.    PIPE_FORMAT_R32G32B32_UNORM,
  91.    PIPE_FORMAT_R32G32B32A32_UNORM
  92. };
  93.  
  94. static GLuint uint_types_scale[4] = {
  95.    PIPE_FORMAT_R32_USCALED,
  96.    PIPE_FORMAT_R32G32_USCALED,
  97.    PIPE_FORMAT_R32G32B32_USCALED,
  98.    PIPE_FORMAT_R32G32B32A32_USCALED
  99. };
  100.  
  101. static GLuint int_types_norm[4] = {
  102.    PIPE_FORMAT_R32_SNORM,
  103.    PIPE_FORMAT_R32G32_SNORM,
  104.    PIPE_FORMAT_R32G32B32_SNORM,
  105.    PIPE_FORMAT_R32G32B32A32_SNORM
  106. };
  107.  
  108. static GLuint int_types_scale[4] = {
  109.    PIPE_FORMAT_R32_SSCALED,
  110.    PIPE_FORMAT_R32G32_SSCALED,
  111.    PIPE_FORMAT_R32G32B32_SSCALED,
  112.    PIPE_FORMAT_R32G32B32A32_SSCALED
  113. };
  114.  
  115. static GLuint ushort_types_norm[4] = {
  116.    PIPE_FORMAT_R16_UNORM,
  117.    PIPE_FORMAT_R16G16_UNORM,
  118.    PIPE_FORMAT_R16G16B16_UNORM,
  119.    PIPE_FORMAT_R16G16B16A16_UNORM
  120. };
  121.  
  122. static GLuint ushort_types_scale[4] = {
  123.    PIPE_FORMAT_R16_USCALED,
  124.    PIPE_FORMAT_R16G16_USCALED,
  125.    PIPE_FORMAT_R16G16B16_USCALED,
  126.    PIPE_FORMAT_R16G16B16A16_USCALED
  127. };
  128.  
  129. static GLuint short_types_norm[4] = {
  130.    PIPE_FORMAT_R16_SNORM,
  131.    PIPE_FORMAT_R16G16_SNORM,
  132.    PIPE_FORMAT_R16G16B16_SNORM,
  133.    PIPE_FORMAT_R16G16B16A16_SNORM
  134. };
  135.  
  136. static GLuint short_types_scale[4] = {
  137.    PIPE_FORMAT_R16_SSCALED,
  138.    PIPE_FORMAT_R16G16_SSCALED,
  139.    PIPE_FORMAT_R16G16B16_SSCALED,
  140.    PIPE_FORMAT_R16G16B16A16_SSCALED
  141. };
  142.  
  143. static GLuint ubyte_types_norm[4] = {
  144.    PIPE_FORMAT_R8_UNORM,
  145.    PIPE_FORMAT_R8G8_UNORM,
  146.    PIPE_FORMAT_R8G8B8_UNORM,
  147.    PIPE_FORMAT_R8G8B8A8_UNORM
  148. };
  149.  
  150. static GLuint ubyte_types_scale[4] = {
  151.    PIPE_FORMAT_R8_USCALED,
  152.    PIPE_FORMAT_R8G8_USCALED,
  153.    PIPE_FORMAT_R8G8B8_USCALED,
  154.    PIPE_FORMAT_R8G8B8A8_USCALED
  155. };
  156.  
  157. static GLuint byte_types_norm[4] = {
  158.    PIPE_FORMAT_R8_SNORM,
  159.    PIPE_FORMAT_R8G8_SNORM,
  160.    PIPE_FORMAT_R8G8B8_SNORM,
  161.    PIPE_FORMAT_R8G8B8A8_SNORM
  162. };
  163.  
  164. static GLuint byte_types_scale[4] = {
  165.    PIPE_FORMAT_R8_SSCALED,
  166.    PIPE_FORMAT_R8G8_SSCALED,
  167.    PIPE_FORMAT_R8G8B8_SSCALED,
  168.    PIPE_FORMAT_R8G8B8A8_SSCALED
  169. };
  170.  
  171. static GLuint fixed_types[4] = {
  172.    PIPE_FORMAT_R32_FIXED,
  173.    PIPE_FORMAT_R32G32_FIXED,
  174.    PIPE_FORMAT_R32G32B32_FIXED,
  175.    PIPE_FORMAT_R32G32B32A32_FIXED
  176. };
  177.  
  178.  
  179.  
  180. /**
  181.  * Return a PIPE_FORMAT_x for the given GL datatype and size.
  182.  */
  183. GLuint
  184. st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
  185.                       GLboolean normalized)
  186. {
  187.    assert((type >= GL_BYTE && type <= GL_DOUBLE) ||
  188.           type == GL_FIXED || type == GL_HALF_FLOAT);
  189.    assert(size >= 1);
  190.    assert(size <= 4);
  191.    assert(format == GL_RGBA || format == GL_BGRA);
  192.  
  193.    if (format == GL_BGRA) {
  194.       /* this is an odd-ball case */
  195.       assert(type == GL_UNSIGNED_BYTE);
  196.       assert(normalized);
  197.       return PIPE_FORMAT_B8G8R8A8_UNORM;
  198.    }
  199.  
  200.    if (normalized) {
  201.       switch (type) {
  202.       case GL_DOUBLE: return double_types[size-1];
  203.       case GL_FLOAT: return float_types[size-1];
  204.       case GL_HALF_FLOAT: return half_float_types[size-1];
  205.       case GL_INT: return int_types_norm[size-1];
  206.       case GL_SHORT: return short_types_norm[size-1];
  207.       case GL_BYTE: return byte_types_norm[size-1];
  208.       case GL_UNSIGNED_INT: return uint_types_norm[size-1];
  209.       case GL_UNSIGNED_SHORT: return ushort_types_norm[size-1];
  210.       case GL_UNSIGNED_BYTE: return ubyte_types_norm[size-1];
  211.       case GL_FIXED: return fixed_types[size-1];
  212.       default: assert(0); return 0;
  213.       }      
  214.    }
  215.    else {
  216.       switch (type) {
  217.       case GL_DOUBLE: return double_types[size-1];
  218.       case GL_FLOAT: return float_types[size-1];
  219.       case GL_HALF_FLOAT: return half_float_types[size-1];
  220.       case GL_INT: return int_types_scale[size-1];
  221.       case GL_SHORT: return short_types_scale[size-1];
  222.       case GL_BYTE: return byte_types_scale[size-1];
  223.       case GL_UNSIGNED_INT: return uint_types_scale[size-1];
  224.       case GL_UNSIGNED_SHORT: return ushort_types_scale[size-1];
  225.       case GL_UNSIGNED_BYTE: return ubyte_types_scale[size-1];
  226.       case GL_FIXED: return fixed_types[size-1];
  227.       default: assert(0); return 0;
  228.       }      
  229.    }
  230.    return 0; /* silence compiler warning */
  231. }
  232.  
  233.  
  234.  
  235.  
  236.  
  237. /**
  238.  * Examine the active arrays to determine if we have interleaved
  239.  * vertex arrays all living in one VBO, or all living in user space.
  240.  * \param userSpace  returns whether the arrays are in user space.
  241.  */
  242. static GLboolean
  243. is_interleaved_arrays(const struct st_vertex_program *vp,
  244.                       const struct st_vp_varient *vpv,
  245.                       const struct gl_client_array **arrays,
  246.                       GLboolean *userSpace)
  247. {
  248.    GLuint attr;
  249.    const struct gl_buffer_object *firstBufObj = NULL;
  250.    GLint firstStride = -1;
  251.    GLuint num_client_arrays = 0;
  252.    const GLubyte *client_addr = NULL;
  253.  
  254.    for (attr = 0; attr < vpv->num_inputs; attr++) {
  255.       const GLuint mesaAttr = vp->index_to_input[attr];
  256.       const struct gl_buffer_object *bufObj = arrays[mesaAttr]->BufferObj;
  257.       const GLsizei stride = arrays[mesaAttr]->StrideB; /* in bytes */
  258.  
  259.       if (firstStride < 0) {
  260.          firstStride = stride;
  261.       }
  262.       else if (firstStride != stride) {
  263.          return GL_FALSE;
  264.       }
  265.          
  266.       if (!bufObj || !bufObj->Name) {
  267.          num_client_arrays++;
  268.          /* Try to detect if the client-space arrays are
  269.           * "close" to each other.
  270.           */
  271.          if (!client_addr) {
  272.             client_addr = arrays[mesaAttr]->Ptr;
  273.          }
  274.          else if (abs(arrays[mesaAttr]->Ptr - client_addr) > firstStride) {
  275.             /* arrays start too far apart */
  276.             return GL_FALSE;
  277.          }
  278.       }
  279.       else if (!firstBufObj) {
  280.          firstBufObj = bufObj;
  281.       }
  282.       else if (bufObj != firstBufObj) {
  283.          return GL_FALSE;
  284.       }
  285.    }
  286.  
  287.    *userSpace = (num_client_arrays == vpv->num_inputs);
  288.    /* debug_printf("user space: %s (%d arrays, %d inputs)\n",
  289.       (int)*userSpace ? "Yes" : "No", num_client_arrays, vp->num_inputs); */
  290.  
  291.    return GL_TRUE;
  292. }
  293.  
  294.  
  295. /**
  296.  * Compute the memory range occupied by the arrays.
  297.  */
  298. static void
  299. get_arrays_bounds(const struct st_vertex_program *vp,
  300.                   const struct st_vp_varient *vpv,
  301.                   const struct gl_client_array **arrays,
  302.                   GLuint max_index,
  303.                   const GLubyte **low, const GLubyte **high)
  304. {
  305.    const GLubyte *low_addr = NULL;
  306.    const GLubyte *high_addr = NULL;
  307.    GLuint attr;
  308.  
  309.    /* debug_printf("get_arrays_bounds: Handling %u attrs\n", vpv->num_inputs); */
  310.  
  311.    for (attr = 0; attr < vpv->num_inputs; attr++) {
  312.       const GLuint mesaAttr = vp->index_to_input[attr];
  313.       const GLint stride = arrays[mesaAttr]->StrideB;
  314.       const GLubyte *start = arrays[mesaAttr]->Ptr;
  315.       const unsigned sz = (arrays[mesaAttr]->Size *
  316.                            _mesa_sizeof_type(arrays[mesaAttr]->Type));
  317.       const GLubyte *end = start + (max_index * stride) + sz;
  318.  
  319.       /* debug_printf("attr %u: stride %d size %u start %p end %p\n",
  320.          attr, stride, sz, start, end); */
  321.  
  322.       if (attr == 0) {
  323.          low_addr = start;
  324.          high_addr = end;
  325.       }
  326.       else {
  327.          low_addr = MIN2(low_addr, start);
  328.          high_addr = MAX2(high_addr, end);
  329.       }
  330.    }
  331.  
  332.    *low = low_addr;
  333.    *high = high_addr;
  334. }
  335.  
  336.  
  337. /**
  338.  * Set up for drawing interleaved arrays that all live in one VBO
  339.  * or all live in user space.
  340.  * \param vbuffer  returns vertex buffer info
  341.  * \param velements  returns vertex element info
  342.  */
  343. static void
  344. setup_interleaved_attribs(struct gl_context *ctx,
  345.                           const struct st_vertex_program *vp,
  346.                           const struct st_vp_varient *vpv,
  347.                           const struct gl_client_array **arrays,
  348.                           GLuint max_index,
  349.                           GLboolean userSpace,
  350.                           struct pipe_vertex_buffer *vbuffer,
  351.                           struct pipe_vertex_element velements[])
  352. {
  353.    struct st_context *st = st_context(ctx);
  354.    struct pipe_context *pipe = st->pipe;
  355.    GLuint attr;
  356.    const GLubyte *offset0 = NULL;
  357.  
  358.    for (attr = 0; attr < vpv->num_inputs; attr++) {
  359.       const GLuint mesaAttr = vp->index_to_input[attr];
  360.       struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj;
  361.       struct st_buffer_object *stobj = st_buffer_object(bufobj);
  362.       GLsizei stride = arrays[mesaAttr]->StrideB;
  363.  
  364.       /*printf("stobj %u = %p\n", attr, (void*)stobj);*/
  365.  
  366.       if (attr == 0) {
  367.          const GLubyte *low, *high;
  368.  
  369.          get_arrays_bounds(vp, vpv, arrays, max_index, &low, &high);
  370.          /* debug_printf("buffer range: %p %p range %d max index %u\n",
  371.             low, high, high - low, max_index); */
  372.  
  373.          offset0 = low;
  374.          if (userSpace) {
  375.             vbuffer->buffer =
  376.                pipe_user_buffer_create(pipe->screen, (void *) low, high - low,
  377.                                        PIPE_BIND_VERTEX_BUFFER);
  378.             vbuffer->buffer_offset = 0;
  379.          }
  380.          else {
  381.             vbuffer->buffer = NULL;
  382.             pipe_resource_reference(&vbuffer->buffer, stobj->buffer);
  383.             vbuffer->buffer_offset = pointer_to_offset(low);
  384.          }
  385.          vbuffer->stride = stride; /* in bytes */
  386.          vbuffer->max_index = max_index;
  387.       }
  388.  
  389.       velements[attr].src_offset =
  390.          (unsigned) (arrays[mesaAttr]->Ptr - offset0);
  391.       velements[attr].instance_divisor = 0;
  392.       velements[attr].vertex_buffer_index = 0;
  393.       velements[attr].src_format =
  394.          st_pipe_vertex_format(arrays[mesaAttr]->Type,
  395.                                arrays[mesaAttr]->Size,
  396.                                arrays[mesaAttr]->Format,
  397.                                arrays[mesaAttr]->Normalized);
  398.       assert(velements[attr].src_format);
  399.    }
  400. }
  401.  
  402.  
  403. /**
  404.  * Set up a separate pipe_vertex_buffer and pipe_vertex_element for each
  405.  * vertex attribute.
  406.  * \param vbuffer  returns vertex buffer info
  407.  * \param velements  returns vertex element info
  408.  */
  409. static void
  410. setup_non_interleaved_attribs(struct gl_context *ctx,
  411.                               const struct st_vertex_program *vp,
  412.                               const struct st_vp_varient *vpv,
  413.                               const struct gl_client_array **arrays,
  414.                               GLuint max_index,
  415.                               GLboolean *userSpace,
  416.                               struct pipe_vertex_buffer vbuffer[],
  417.                               struct pipe_vertex_element velements[])
  418. {
  419.    struct st_context *st = st_context(ctx);
  420.    struct pipe_context *pipe = st->pipe;
  421.    GLuint attr;
  422.  
  423.    for (attr = 0; attr < vpv->num_inputs; attr++) {
  424.       const GLuint mesaAttr = vp->index_to_input[attr];
  425.       struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj;
  426.       GLsizei stride = arrays[mesaAttr]->StrideB;
  427.  
  428.       *userSpace = GL_FALSE;
  429.  
  430.       if (bufobj && bufobj->Name) {
  431.          /* Attribute data is in a VBO.
  432.           * Recall that for VBOs, the gl_client_array->Ptr field is
  433.           * really an offset from the start of the VBO, not a pointer.
  434.           */
  435.          struct st_buffer_object *stobj = st_buffer_object(bufobj);
  436.          assert(stobj->buffer);
  437.          /*printf("stobj %u = %p\n", attr, (void*) stobj);*/
  438.  
  439.          vbuffer[attr].buffer = NULL;
  440.          pipe_resource_reference(&vbuffer[attr].buffer, stobj->buffer);
  441.          vbuffer[attr].buffer_offset = pointer_to_offset(arrays[mesaAttr]->Ptr);
  442.          velements[attr].src_offset = 0;
  443.       }
  444.       else {
  445.          /* attribute data is in user-space memory, not a VBO */
  446.          uint bytes;
  447.          /*printf("user-space array %d stride %d\n", attr, stride);*/
  448.        
  449.          *userSpace = GL_TRUE;
  450.  
  451.          /* wrap user data */
  452.          if (arrays[mesaAttr]->Ptr) {
  453.             /* user's vertex array */
  454.             if (arrays[mesaAttr]->StrideB) {
  455.                bytes = arrays[mesaAttr]->StrideB * (max_index + 1);
  456.             }
  457.             else {
  458.                bytes = arrays[mesaAttr]->Size
  459.                   * _mesa_sizeof_type(arrays[mesaAttr]->Type);
  460.             }
  461.             vbuffer[attr].buffer =
  462.                pipe_user_buffer_create(pipe->screen,
  463.                                        (void *) arrays[mesaAttr]->Ptr, bytes,
  464.                                        PIPE_BIND_VERTEX_BUFFER);
  465.          }
  466.          else {
  467.             /* no array, use ctx->Current.Attrib[] value */
  468.             bytes = sizeof(ctx->Current.Attrib[0]);
  469.             vbuffer[attr].buffer =
  470.                pipe_user_buffer_create(pipe->screen,
  471.                                        (void *) ctx->Current.Attrib[mesaAttr],
  472.                                        bytes,
  473.                                        PIPE_BIND_VERTEX_BUFFER);
  474.             stride = 0;
  475.          }
  476.  
  477.          vbuffer[attr].buffer_offset = 0;
  478.          velements[attr].src_offset = 0;
  479.       }
  480.  
  481.       assert(velements[attr].src_offset <= 2048); /* 11-bit field */
  482.  
  483.       /* common-case setup */
  484.       vbuffer[attr].stride = stride; /* in bytes */
  485.       vbuffer[attr].max_index = max_index;
  486.       velements[attr].instance_divisor = 0;
  487.       velements[attr].vertex_buffer_index = attr;
  488.       velements[attr].src_format
  489.          = st_pipe_vertex_format(arrays[mesaAttr]->Type,
  490.                                  arrays[mesaAttr]->Size,
  491.                                  arrays[mesaAttr]->Format,
  492.                                  arrays[mesaAttr]->Normalized);
  493.       assert(velements[attr].src_format);
  494.    }
  495. }
  496.  
  497.  
  498. static void
  499. setup_index_buffer(struct gl_context *ctx,
  500.                    const struct _mesa_index_buffer *ib,
  501.                    struct pipe_index_buffer *ibuffer)
  502. {
  503.    struct st_context *st = st_context(ctx);
  504.    struct pipe_context *pipe = st->pipe;
  505.  
  506.    memset(ibuffer, 0, sizeof(*ibuffer));
  507.    if (ib) {
  508.       struct gl_buffer_object *bufobj = ib->obj;
  509.  
  510.       switch (ib->type) {
  511.       case GL_UNSIGNED_INT:
  512.          ibuffer->index_size = 4;
  513.          break;
  514.       case GL_UNSIGNED_SHORT:
  515.          ibuffer->index_size = 2;
  516.          break;
  517.       case GL_UNSIGNED_BYTE:
  518.          ibuffer->index_size = 1;
  519.          break;
  520.       default:
  521.          assert(0);
  522.          return;
  523.       }
  524.  
  525.       /* get/create the index buffer object */
  526.       if (bufobj && bufobj->Name) {
  527.          /* elements/indexes are in a real VBO */
  528.          struct st_buffer_object *stobj = st_buffer_object(bufobj);
  529.          pipe_resource_reference(&ibuffer->buffer, stobj->buffer);
  530.          ibuffer->offset = pointer_to_offset(ib->ptr);
  531.       }
  532.       else {
  533.          /* element/indicies are in user space memory */
  534.          ibuffer->buffer =
  535.             pipe_user_buffer_create(pipe->screen, (void *) ib->ptr,
  536.                                     ib->count * ibuffer->index_size,
  537.                                     PIPE_BIND_INDEX_BUFFER);
  538.       }
  539.    }
  540. }
  541.  
  542. /**
  543.  * Prior to drawing, check that any uniforms referenced by the
  544.  * current shader have been set.  If a uniform has not been set,
  545.  * issue a warning.
  546.  */
  547. static void
  548. check_uniforms(struct gl_context *ctx)
  549. {
  550.    struct gl_shader_program *shProg[3] = {
  551.       ctx->Shader.CurrentVertexProgram,
  552.       ctx->Shader.CurrentGeometryProgram,
  553.       ctx->Shader.CurrentFragmentProgram,
  554.    };
  555.    unsigned j;
  556.  
  557.    for (j = 0; j < 3; j++) {
  558.       unsigned i;
  559.  
  560.       if (shProg[j] == NULL || !shProg[j]->LinkStatus)
  561.          continue;
  562.  
  563.       for (i = 0; i < shProg[j]->Uniforms->NumUniforms; i++) {
  564.          const struct gl_uniform *u = &shProg[j]->Uniforms->Uniforms[i];
  565.          if (!u->Initialized) {
  566.             _mesa_warning(ctx,
  567.                           "Using shader with uninitialized uniform: %s",
  568.                           u->Name);
  569.          }
  570.       }
  571.    }
  572. }
  573.  
  574.  
  575. /**
  576.  * Translate OpenGL primtive type (GL_POINTS, GL_TRIANGLE_STRIP, etc) to
  577.  * the corresponding Gallium type.
  578.  */
  579. static unsigned
  580. translate_prim(const struct gl_context *ctx, unsigned prim)
  581. {
  582.    /* GL prims should match Gallium prims, spot-check a few */
  583.    assert(GL_POINTS == PIPE_PRIM_POINTS);
  584.    assert(GL_QUADS == PIPE_PRIM_QUADS);
  585.    assert(GL_TRIANGLE_STRIP_ADJACENCY == PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY);
  586.  
  587.    /* Avoid quadstrips if it's easy to do so:
  588.     * Note: it's imporant to do the correct trimming if we change the prim type!
  589.     * We do that wherever this function is called.
  590.     */
  591.    if (prim == GL_QUAD_STRIP &&
  592.        ctx->Light.ShadeModel != GL_FLAT &&
  593.        ctx->Polygon.FrontMode == GL_FILL &&
  594.        ctx->Polygon.BackMode == GL_FILL)
  595.       prim = GL_TRIANGLE_STRIP;
  596.  
  597.    return prim;
  598. }
  599.  
  600.  
  601.  
  602. /**
  603.  * This function gets plugged into the VBO module and is called when
  604.  * we have something to render.
  605.  * Basically, translate the information into the format expected by gallium.
  606.  */
  607. void
  608. st_draw_vbo(struct gl_context *ctx,
  609.             const struct gl_client_array **arrays,
  610.             const struct _mesa_prim *prims,
  611.             GLuint nr_prims,
  612.             const struct _mesa_index_buffer *ib,
  613.             GLboolean index_bounds_valid,
  614.             GLuint min_index,
  615.             GLuint max_index)
  616. {
  617.    struct st_context *st = st_context(ctx);
  618.    struct pipe_context *pipe = st->pipe;
  619.    const struct st_vertex_program *vp;
  620.    const struct st_vp_varient *vpv;
  621.    struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS];
  622.    GLuint attr;
  623.    struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
  624.    unsigned num_vbuffers, num_velements;
  625.    struct pipe_index_buffer ibuffer;
  626.    GLboolean userSpace = GL_FALSE;
  627.    GLboolean vertDataEdgeFlags;
  628.    struct pipe_draw_info info;
  629.    unsigned i;
  630.  
  631.    /* Mesa core state should have been validated already */
  632.    assert(ctx->NewState == 0x0);
  633.  
  634.    /* Gallium probably doesn't want this in some cases. */
  635.    if (!index_bounds_valid)
  636.       if (!vbo_all_varyings_in_vbos(arrays))
  637.          vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
  638.  
  639.    /* sanity check for pointer arithmetic below */
  640.    assert(sizeof(arrays[0]->Ptr[0]) == 1);
  641.  
  642.    vertDataEdgeFlags = arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj &&
  643.                        arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj->Name;
  644.    if (vertDataEdgeFlags != st->vertdata_edgeflags) {
  645.       st->vertdata_edgeflags = vertDataEdgeFlags;
  646.       st->dirty.st |= ST_NEW_EDGEFLAGS_DATA;
  647.    }
  648.  
  649.    st_validate_state(st);
  650.  
  651.    /* must get these after state validation! */
  652.    vp = st->vp;
  653.    vpv = st->vp_varient;
  654.  
  655. #if 0
  656.    if (MESA_VERBOSE & VERBOSE_GLSL) {
  657.       check_uniforms(ctx);
  658.    }
  659. #else
  660.    (void) check_uniforms;
  661. #endif
  662.  
  663.    memset(velements, 0, sizeof(struct pipe_vertex_element) * vpv->num_inputs);
  664.    /*
  665.     * Setup the vbuffer[] and velements[] arrays.
  666.     */
  667.    if (is_interleaved_arrays(vp, vpv, arrays, &userSpace)) {
  668.       /*printf("Draw interleaved\n");*/
  669.       setup_interleaved_attribs(ctx, vp, vpv, arrays, max_index, userSpace,
  670.                                 vbuffer, velements);
  671.       num_vbuffers = 1;
  672.       num_velements = vpv->num_inputs;
  673.       if (num_velements == 0)
  674.          num_vbuffers = 0;
  675.    }
  676.    else {
  677.       /*printf("Draw non-interleaved\n");*/
  678.       setup_non_interleaved_attribs(ctx, vp, vpv, arrays, max_index,
  679.                                     &userSpace, vbuffer, velements);
  680.       num_vbuffers = vpv->num_inputs;
  681.       num_velements = vpv->num_inputs;
  682.    }
  683.  
  684. #if 0
  685.    {
  686.       GLuint i;
  687.       for (i = 0; i < num_vbuffers; i++) {
  688.          printf("buffers[%d].stride = %u\n", i, vbuffer[i].stride);
  689.          printf("buffers[%d].max_index = %u\n", i, vbuffer[i].max_index);
  690.          printf("buffers[%d].buffer_offset = %u\n", i, vbuffer[i].buffer_offset);
  691.          printf("buffers[%d].buffer = %p\n", i, (void*) vbuffer[i].buffer);
  692.       }
  693.       for (i = 0; i < num_velements; i++) {
  694.          printf("vlements[%d].vbuffer_index = %u\n", i, velements[i].vertex_buffer_index);
  695.          printf("vlements[%d].src_offset = %u\n", i, velements[i].src_offset);
  696.          printf("vlements[%d].format = %s\n", i, util_format_name(velements[i].src_format));
  697.       }
  698.    }
  699. #endif
  700.  
  701.    pipe->set_vertex_buffers(pipe, num_vbuffers, vbuffer);
  702.    cso_set_vertex_elements(st->cso_context, num_velements, velements);
  703.  
  704.    setup_index_buffer(ctx, ib, &ibuffer);
  705.    pipe->set_index_buffer(pipe, &ibuffer);
  706.  
  707.    util_draw_init_info(&info);
  708.    if (ib) {
  709.       info.indexed = TRUE;
  710.       if (min_index != ~0 && max_index != ~0) {
  711.          info.min_index = min_index;
  712.          info.max_index = max_index;
  713.       }
  714.    }
  715.  
  716.    info.primitive_restart = st->ctx->Array.PrimitiveRestart;
  717.    info.restart_index = st->ctx->Array.RestartIndex;
  718.  
  719.    /* do actual drawing */
  720.    for (i = 0; i < nr_prims; i++) {
  721.       info.mode = translate_prim( ctx, prims[i].mode );
  722.       info.start = prims[i].start;
  723.       info.count = prims[i].count;
  724.       info.instance_count = prims[i].num_instances;
  725.       info.index_bias = prims[i].basevertex;
  726.       if (!ib) {
  727.          info.min_index = info.start;
  728.          info.max_index = info.start + info.count - 1;
  729.       }
  730.  
  731.       if (u_trim_pipe_prim(info.mode, &info.count))
  732.          pipe->draw_vbo(pipe, &info);
  733.    }
  734.  
  735.    pipe_resource_reference(&ibuffer.buffer, NULL);
  736.  
  737.    /* unreference buffers (frees wrapped user-space buffer objects) */
  738.    for (attr = 0; attr < num_vbuffers; attr++) {
  739.       pipe_resource_reference(&vbuffer[attr].buffer, NULL);
  740.       assert(!vbuffer[attr].buffer);
  741.    }
  742.  
  743.    if (userSpace)
  744.    {
  745.       pipe->set_vertex_buffers(pipe, 0, NULL);
  746.    }
  747. }
  748.  
  749.  
  750. void st_init_draw( struct st_context *st )
  751. {
  752.    struct gl_context *ctx = st->ctx;
  753.  
  754.    vbo_set_draw_func(ctx, st_draw_vbo);
  755.  
  756. #if FEATURE_feedback || FEATURE_rastpos
  757.    st->draw = draw_create(st->pipe); /* for selection/feedback */
  758.  
  759.    /* Disable draw options that might convert points/lines to tris, etc.
  760.     * as that would foul-up feedback/selection mode.
  761.     */
  762.    draw_wide_line_threshold(st->draw, 1000.0f);
  763.    draw_wide_point_threshold(st->draw, 1000.0f);
  764.    draw_enable_line_stipple(st->draw, FALSE);
  765.    draw_enable_point_sprites(st->draw, FALSE);
  766. #endif
  767. }
  768.  
  769.  
  770. void st_destroy_draw( struct st_context *st )
  771. {
  772. #if FEATURE_feedback || FEATURE_rastpos
  773.    draw_destroy(st->draw);
  774. #endif
  775. }
  776.  
  777.  
  778.