ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

vbo_rebase.c
Go to the documentation of this file.
00001 
00002 /*
00003  * Mesa 3-D graphics library
00004  * Version:  6.5
00005  *
00006  * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
00007  *
00008  * Permission is hereby granted, free of charge, to any person obtaining a
00009  * copy of this software and associated documentation files (the "Software"),
00010  * to deal in the Software without restriction, including without limitation
00011  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00012  * and/or sell copies of the Software, and to permit persons to whom the
00013  * Software is furnished to do so, subject to the following conditions:
00014  *
00015  * The above copyright notice and this permission notice shall be included
00016  * in all copies or substantial portions of the Software.
00017  *
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00020  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00021  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00022  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00023  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00024  *
00025  * Authors:
00026  *    Keith Whitwell <keith@tungstengraphics.com>
00027  */
00028 
00029 /* Helper for drivers which find themselves rendering a range of
00030  * indices starting somewhere above zero.  Typically the application
00031  * is issuing multiple DrawArrays() or DrawElements() to draw
00032  * successive primitives layed out linearly in the vertex arrays.
00033  * Unless the vertex arrays are all in a VBO, the OpenGL semantics
00034  * imply that we need to re-upload the vertex data on each draw call.
00035  * In that case, we want to avoid starting the upload at zero, as it
00036  * will mean every draw call uploads an increasing amount of not-used
00037  * vertex data.  Worse - in the software tnl module, all those
00038  * vertices will be transformed and lit.
00039  *
00040  * If we just upload the new data, however, the indices will be
00041  * incorrect as we tend to upload each set of vertex data to a new
00042  * region.  
00043  *
00044  * This file provides a helper to adjust the arrays, primitives and
00045  * indices of a draw call so that it can be re-issued with a min_index
00046  * of zero.
00047  */
00048 
00049 #include "main/glheader.h"
00050 #include "main/imports.h"
00051 #include "main/mtypes.h"
00052 
00053 #include "vbo.h"
00054 
00055 
00056 #define REBASE(TYPE)                        \
00057 static void *rebase_##TYPE( const void *ptr,            \
00058               GLuint count,             \
00059               TYPE min_index )          \
00060 {                               \
00061    const TYPE *in = (TYPE *)ptr;                \
00062    TYPE *tmp_indices = malloc(count * sizeof(TYPE));    \
00063    GLuint i;                            \
00064                                 \
00065    for (i = 0; i < count; i++)                  \
00066       tmp_indices[i] = in[i] - min_index;           \
00067                                 \
00068    return (void *)tmp_indices;                  \
00069 }
00070 
00071 
00072 REBASE(GLuint)
00073 REBASE(GLushort)
00074 REBASE(GLubyte)
00075 
00076 GLboolean vbo_all_varyings_in_vbos( const struct gl_client_array *arrays[] )
00077 {
00078    GLuint i;
00079    
00080    for (i = 0; i < VERT_ATTRIB_MAX; i++)
00081       if (arrays[i]->StrideB &&
00082       arrays[i]->BufferObj->Name == 0)
00083      return GL_FALSE;
00084 
00085    return GL_TRUE;
00086 }
00087 
00088 /* Adjust primitives, indices and vertex definitions so that min_index
00089  * becomes zero. There are lots of reasons for wanting to do this, eg:
00090  *
00091  * Software tnl:
00092  *    - any time min_index != 0, otherwise unused vertices lower than
00093  *      min_index will be transformed.
00094  *
00095  * Hardware tnl:
00096  *    - if ib != NULL and min_index != 0, otherwise vertices lower than 
00097  *      min_index will be uploaded.  Requires adjusting index values.
00098  *
00099  *    - if ib == NULL and min_index != 0, just for convenience so this doesn't
00100  *      have to be handled within the driver.
00101  *
00102  * Hardware tnl with VBO support:
00103  *    - as above, but only when vertices are not (all?) in VBO's.
00104  *    - can't save time by trying to upload half a vbo - typically it is
00105  *      all or nothing.
00106  */
00107 void vbo_rebase_prims( GLcontext *ctx,
00108                const struct gl_client_array *arrays[],
00109                const struct _mesa_prim *prim,
00110                GLuint nr_prims,
00111                const struct _mesa_index_buffer *ib,
00112                GLuint min_index,
00113                GLuint max_index,
00114                vbo_draw_func draw )
00115 {
00116    struct gl_client_array tmp_arrays[VERT_ATTRIB_MAX];
00117    const struct gl_client_array *tmp_array_pointers[VERT_ATTRIB_MAX];
00118 
00119    struct _mesa_index_buffer tmp_ib;
00120    struct _mesa_prim *tmp_prims = NULL;
00121    void *tmp_indices = NULL;
00122    GLuint i;
00123 
00124    assert(min_index != 0);
00125 
00126    if (0)
00127       _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
00128 
00129    if (ib) {
00130       /* Unfortunately need to adjust each index individually.
00131        */
00132       GLboolean map_ib = ib->obj->Name && !ib->obj->Pointer;
00133       void *ptr;
00134 
00135       if (map_ib) 
00136      ctx->Driver.MapBuffer(ctx, 
00137                    GL_ELEMENT_ARRAY_BUFFER,
00138                    GL_READ_ONLY_ARB,
00139                    ib->obj);
00140 
00141 
00142       ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr);
00143 
00144       /* Some users might prefer it if we translated elements to
00145        * GLuints here.  Others wouldn't...
00146        */
00147       switch (ib->type) {
00148       case GL_UNSIGNED_INT: 
00149      tmp_indices = rebase_GLuint( ptr, ib->count, min_index );
00150      break;
00151       case GL_UNSIGNED_SHORT: 
00152      tmp_indices = rebase_GLushort( ptr, ib->count, min_index );
00153      break;
00154       case GL_UNSIGNED_BYTE: 
00155      tmp_indices = rebase_GLubyte( ptr, ib->count, min_index );
00156      break;
00157       }      
00158 
00159       if (map_ib) 
00160      ctx->Driver.UnmapBuffer(ctx, 
00161                  GL_ELEMENT_ARRAY_BUFFER,
00162                  ib->obj);
00163 
00164       tmp_ib.obj = ctx->Array.NullBufferObj;
00165       tmp_ib.ptr = tmp_indices;
00166       tmp_ib.count = ib->count;
00167       tmp_ib.type = ib->type;
00168 
00169       ib = &tmp_ib;
00170    }
00171    else {
00172       /* Otherwise the primitives need adjustment.
00173        */
00174       tmp_prims = (struct _mesa_prim *)_mesa_malloc(sizeof(*prim) * nr_prims);
00175 
00176       for (i = 0; i < nr_prims; i++) {
00177      /* If this fails, it could indicate an application error:
00178       */
00179      assert(prim[i].start >= min_index);
00180 
00181      tmp_prims[i] = prim[i];
00182      tmp_prims[i].start -= min_index;
00183       }
00184 
00185       prim = tmp_prims;
00186    }
00187 
00188    /* Just need to adjust the pointer values on each incoming array.
00189     * This works for VBO and non-vbo rendering and shouldn't pesimize
00190     * VBO-based upload schemes.  However this may still not be a fast
00191     * path for hardware tnl for VBO based rendering as most machines
00192     * will be happier if you just specify a starting vertex value in
00193     * each primitive.
00194     *
00195     * For drivers with hardware tnl, you only want to do this if you
00196     * are forced to, eg non-VBO indexed rendering with start != 0.
00197     */
00198    for (i = 0; i < VERT_ATTRIB_MAX; i++) {
00199       tmp_arrays[i] = *arrays[i];
00200       tmp_arrays[i].Ptr += min_index * tmp_arrays[i].StrideB;
00201       tmp_array_pointers[i] = &tmp_arrays[i];
00202    }
00203    
00204    /* Re-issue the draw call.
00205     */
00206    draw( ctx, 
00207      tmp_array_pointers, 
00208      prim, 
00209      nr_prims, 
00210      ib, 
00211      0, 
00212      max_index - min_index );
00213    
00214    if (tmp_indices)
00215       _mesa_free(tmp_indices);
00216    
00217    if (tmp_prims)
00218       _mesa_free(tmp_prims);
00219 }
00220 
00221 
00222 

Generated on Sun May 27 2012 04:20:48 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.