Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. /*
  3.  * Mesa 3-D graphics library
  4.  * Version:  6.5
  5.  *
  6.  * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
  7.  *
  8.  * Permission is hereby granted, free of charge, to any person obtaining a
  9.  * copy of this software and associated documentation files (the "Software"),
  10.  * to deal in the Software without restriction, including without limitation
  11.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  12.  * and/or sell copies of the Software, and to permit persons to whom the
  13.  * Software is furnished to do so, subject to the following conditions:
  14.  *
  15.  * The above copyright notice and this permission notice shall be included
  16.  * in all copies or substantial portions 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 MERCHANTABILITY,
  20.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  21.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  22.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  23.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24.  *
  25.  * Authors:
  26.  *    Keith Whitwell <keith@tungstengraphics.com>
  27.  */
  28.  
  29. /* Helper for drivers which find themselves rendering a range of
  30.  * indices starting somewhere above zero.  Typically the application
  31.  * is issuing multiple DrawArrays() or DrawElements() to draw
  32.  * successive primitives layed out linearly in the vertex arrays.
  33.  * Unless the vertex arrays are all in a VBO, the OpenGL semantics
  34.  * imply that we need to re-upload the vertex data on each draw call.
  35.  * In that case, we want to avoid starting the upload at zero, as it
  36.  * will mean every draw call uploads an increasing amount of not-used
  37.  * vertex data.  Worse - in the software tnl module, all those
  38.  * vertices will be transformed and lit.
  39.  *
  40.  * If we just upload the new data, however, the indices will be
  41.  * incorrect as we tend to upload each set of vertex data to a new
  42.  * region.  
  43.  *
  44.  * This file provides a helper to adjust the arrays, primitives and
  45.  * indices of a draw call so that it can be re-issued with a min_index
  46.  * of zero.
  47.  */
  48.  
  49. #include "main/glheader.h"
  50. #include "main/imports.h"
  51. #include "main/mtypes.h"
  52.  
  53. #include "vbo.h"
  54.  
  55.  
  56. #define REBASE(TYPE)                                            \
  57. static void *rebase_##TYPE( const void *ptr,                    \
  58.                           GLuint count,                         \
  59.                           TYPE min_index )                      \
  60. {                                                               \
  61.    const TYPE *in = (TYPE *)ptr;                                \
  62.    TYPE *tmp_indices = malloc(count * sizeof(TYPE));    \
  63.    GLuint i;                                                    \
  64.                                                                 \
  65.    for (i = 0; i < count; i++)                                  \
  66.       tmp_indices[i] = in[i] - min_index;                       \
  67.                                                                 \
  68.    return (void *)tmp_indices;                                  \
  69. }
  70.  
  71.  
  72. REBASE(GLuint)
  73. REBASE(GLushort)
  74. REBASE(GLubyte)
  75.  
  76. GLboolean vbo_all_varyings_in_vbos( const struct gl_client_array *arrays[] )
  77. {
  78.    GLuint i;
  79.    
  80.    for (i = 0; i < VERT_ATTRIB_MAX; i++)
  81.       if (arrays[i]->StrideB &&
  82.           arrays[i]->BufferObj->Name == 0)
  83.          return GL_FALSE;
  84.  
  85.    return GL_TRUE;
  86. }
  87.  
  88. GLboolean vbo_any_varyings_in_vbos( const struct gl_client_array *arrays[] )
  89. {
  90.    GLuint i;
  91.  
  92.    for (i = 0; i < VERT_ATTRIB_MAX; i++)
  93.       if (arrays[i]->StrideB &&
  94.           arrays[i]->BufferObj->Name != 0)
  95.          return GL_TRUE;
  96.  
  97.    return GL_FALSE;
  98. }
  99.  
  100. /* Adjust primitives, indices and vertex definitions so that min_index
  101.  * becomes zero. There are lots of reasons for wanting to do this, eg:
  102.  *
  103.  * Software tnl:
  104.  *    - any time min_index != 0, otherwise unused vertices lower than
  105.  *      min_index will be transformed.
  106.  *
  107.  * Hardware tnl:
  108.  *    - if ib != NULL and min_index != 0, otherwise vertices lower than
  109.  *      min_index will be uploaded.  Requires adjusting index values.
  110.  *
  111.  *    - if ib == NULL and min_index != 0, just for convenience so this doesn't
  112.  *      have to be handled within the driver.
  113.  *
  114.  * Hardware tnl with VBO support:
  115.  *    - as above, but only when vertices are not (all?) in VBO's.
  116.  *    - can't save time by trying to upload half a vbo - typically it is
  117.  *      all or nothing.
  118.  */
  119. void vbo_rebase_prims( struct gl_context *ctx,
  120.                        const struct gl_client_array *arrays[],
  121.                        const struct _mesa_prim *prim,
  122.                        GLuint nr_prims,
  123.                        const struct _mesa_index_buffer *ib,
  124.                        GLuint min_index,
  125.                        GLuint max_index,
  126.                        vbo_draw_func draw )
  127. {
  128.    struct gl_client_array tmp_arrays[VERT_ATTRIB_MAX];
  129.    const struct gl_client_array *tmp_array_pointers[VERT_ATTRIB_MAX];
  130.  
  131.    struct _mesa_index_buffer tmp_ib;
  132.    struct _mesa_prim *tmp_prims = NULL;
  133.    void *tmp_indices = NULL;
  134.    GLuint i;
  135.  
  136.    assert(min_index != 0);
  137.  
  138.    if (0)
  139.       printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
  140.  
  141.  
  142.    /* XXX this path is disabled for now.
  143.     * There's rendering corruption in some apps when it's enabled.
  144.     */
  145.    if (0 && ib && ctx->Extensions.ARB_draw_elements_base_vertex) {
  146.       /* If we can just tell the hardware or the TNL to interpret our
  147.        * indices with a different base, do so.
  148.        */
  149.       tmp_prims = (struct _mesa_prim *)malloc(sizeof(*prim) * nr_prims);
  150.  
  151.       for (i = 0; i < nr_prims; i++) {
  152.          tmp_prims[i] = prim[i];
  153.          tmp_prims[i].basevertex -= min_index;
  154.       }
  155.  
  156.       prim = tmp_prims;
  157.    } else if (ib) {
  158.       /* Unfortunately need to adjust each index individually.
  159.        */
  160.       GLboolean map_ib = ib->obj->Name && !ib->obj->Pointer;
  161.       void *ptr;
  162.  
  163.       if (map_ib)
  164.          ctx->Driver.MapBuffer(ctx,
  165.                                GL_ELEMENT_ARRAY_BUFFER,
  166.                                GL_READ_ONLY_ARB,
  167.                                ib->obj);
  168.  
  169.  
  170.       ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr);
  171.  
  172.       /* Some users might prefer it if we translated elements to
  173.        * GLuints here.  Others wouldn't...
  174.        */
  175.       switch (ib->type) {
  176.       case GL_UNSIGNED_INT:
  177.          tmp_indices = rebase_GLuint( ptr, ib->count, min_index );
  178.          break;
  179.       case GL_UNSIGNED_SHORT:
  180.          tmp_indices = rebase_GLushort( ptr, ib->count, min_index );
  181.          break;
  182.       case GL_UNSIGNED_BYTE:
  183.          tmp_indices = rebase_GLubyte( ptr, ib->count, min_index );
  184.          break;
  185.       }      
  186.  
  187.       if (map_ib)
  188.          ctx->Driver.UnmapBuffer(ctx,
  189.                                  GL_ELEMENT_ARRAY_BUFFER,
  190.                                  ib->obj);
  191.  
  192.       tmp_ib.obj = ctx->Shared->NullBufferObj;
  193.       tmp_ib.ptr = tmp_indices;
  194.       tmp_ib.count = ib->count;
  195.       tmp_ib.type = ib->type;
  196.  
  197.       ib = &tmp_ib;
  198.    }
  199.    else {
  200.       /* Otherwise the primitives need adjustment.
  201.        */
  202.       tmp_prims = (struct _mesa_prim *)malloc(sizeof(*prim) * nr_prims);
  203.  
  204.       for (i = 0; i < nr_prims; i++) {
  205.          /* If this fails, it could indicate an application error:
  206.           */
  207.          assert(prim[i].start >= min_index);
  208.  
  209.          tmp_prims[i] = prim[i];
  210.          tmp_prims[i].start -= min_index;
  211.       }
  212.  
  213.       prim = tmp_prims;
  214.    }
  215.  
  216.    /* Just need to adjust the pointer values on each incoming array.
  217.     * This works for VBO and non-vbo rendering and shouldn't pesimize
  218.     * VBO-based upload schemes.  However this may still not be a fast
  219.     * path for hardware tnl for VBO based rendering as most machines
  220.     * will be happier if you just specify a starting vertex value in
  221.     * each primitive.
  222.     *
  223.     * For drivers with hardware tnl, you only want to do this if you
  224.     * are forced to, eg non-VBO indexed rendering with start != 0.
  225.     */
  226.    for (i = 0; i < VERT_ATTRIB_MAX; i++) {
  227.       tmp_arrays[i] = *arrays[i];
  228.       tmp_arrays[i].Ptr += min_index * tmp_arrays[i].StrideB;
  229.       tmp_array_pointers[i] = &tmp_arrays[i];
  230.    }
  231.    
  232.    /* Re-issue the draw call.
  233.     */
  234.    draw( ctx,
  235.          tmp_array_pointers,
  236.          prim,
  237.          nr_prims,
  238.          ib,
  239.          GL_TRUE,
  240.          0,
  241.          max_index - min_index );
  242.    
  243.    if (tmp_indices)
  244.       free(tmp_indices);
  245.    
  246.    if (tmp_prims)
  247.       free(tmp_prims);
  248. }
  249.  
  250.  
  251.  
  252.