Home | History | Annotate | Download | only in vbo
      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 (at) tungstengraphics.com>
     27  */
     28 
     29 /* Deal with hardware and/or swtnl maximums:
     30  * - maximum number of vertices in buffer
     31  * - maximum number of elements (maybe zero)
     32  *
     33  * The maximums may vary with opengl state (eg if a larger hardware
     34  * vertex is required in this state, the maximum number of vertices
     35  * may be smaller than in another state).
     36  *
     37  * We want buffer splitting to be a convenience function for the code
     38  * actually drawing the primitives rather than a system-wide maximum,
     39  * otherwise it is hard to avoid pessimism.
     40  *
     41  * For instance, if a driver has no hardware limits on vertex buffer
     42  * dimensions, it would not ordinarily want to split vbos.  But if
     43  * there is an unexpected fallback, eg memory manager fails to upload
     44  * textures, it will want to pass the drawing commands onto swtnl,
     45  * which does have limitations.  A convenience function allows swtnl
     46  * to split the drawing and vbos internally without imposing its
     47  * limitations on drivers which want to use it as a fallback path.
     48  */
     49 
     50 #include "main/glheader.h"
     51 #include "main/imports.h"
     52 #include "main/mtypes.h"
     53 #include "main/macros.h"
     54 
     55 #include "vbo_split.h"
     56 #include "vbo.h"
     57 
     58 /* True if a primitive can be split without copying of vertices, false
     59  * otherwise.
     60  */
     61 GLboolean split_prim_inplace(GLenum mode, GLuint *first, GLuint *incr)
     62 {
     63    switch (mode) {
     64    case GL_POINTS:
     65       *first = 1;
     66       *incr = 1;
     67       return GL_TRUE;
     68    case GL_LINES:
     69       *first = 2;
     70       *incr = 2;
     71       return GL_TRUE;
     72    case GL_LINE_STRIP:
     73       *first = 2;
     74       *incr = 1;
     75       return GL_TRUE;
     76    case GL_TRIANGLES:
     77       *first = 3;
     78       *incr = 3;
     79       return GL_TRUE;
     80    case GL_TRIANGLE_STRIP:
     81       *first = 3;
     82       *incr = 1;
     83       return GL_TRUE;
     84    case GL_QUADS:
     85       *first = 4;
     86       *incr = 4;
     87       return GL_TRUE;
     88    case GL_QUAD_STRIP:
     89       *first = 4;
     90       *incr = 2;
     91       return GL_TRUE;
     92    default:
     93       *first = 0;
     94       *incr = 1;		/* so that count % incr works */
     95       return GL_FALSE;
     96    }
     97 }
     98 
     99 
    100 
    101 void vbo_split_prims( struct gl_context *ctx,
    102 		      const struct gl_client_array *arrays[],
    103 		      const struct _mesa_prim *prim,
    104 		      GLuint nr_prims,
    105 		      const struct _mesa_index_buffer *ib,
    106 		      GLuint min_index,
    107 		      GLuint max_index,
    108 		      vbo_draw_func draw,
    109 		      const struct split_limits *limits )
    110 {
    111    GLint max_basevertex = prim->basevertex;
    112    GLuint i;
    113 
    114    for (i = 1; i < nr_prims; i++)
    115       max_basevertex = MAX2(max_basevertex, prim[i].basevertex);
    116 
    117    /* XXX max_basevertex is computed but not used, why? */
    118 
    119    if (ib) {
    120       if (limits->max_indices == 0) {
    121 	 /* Could traverse the indices, re-emitting vertices in turn.
    122 	  * But it's hard to see why this case would be needed - for
    123 	  * software tnl, it is better to convert to non-indexed
    124 	  * rendering after transformation is complete.  Are there any devices
    125 	  * with hardware tnl that cannot do indexed rendering?
    126 	  *
    127 	  * For now, this path is disabled.
    128 	  */
    129 	 assert(0);
    130       }
    131       else if (max_index - min_index >= limits->max_verts) {
    132 	 /* The vertex buffers are too large for hardware (or the
    133 	  * swtnl module).  Traverse the indices, re-emitting vertices
    134 	  * in turn.  Use a vertex cache to preserve some of the
    135 	  * sharing from the original index list.
    136 	  */
    137 	 vbo_split_copy(ctx, arrays, prim, nr_prims, ib,
    138 			draw, limits );
    139       }
    140       else if (ib->count > limits->max_indices) {
    141 	 /* The index buffer is too large for hardware.  Try to split
    142 	  * on whole-primitive boundaries, otherwise try to split the
    143 	  * individual primitives.
    144 	  */
    145 	 vbo_split_inplace(ctx, arrays, prim, nr_prims, ib,
    146 			   min_index, max_index, draw, limits );
    147       }
    148       else {
    149 	 /* Why were we called? */
    150 	 assert(0);
    151       }
    152    }
    153    else {
    154       if (max_index - min_index >= limits->max_verts) {
    155 	 /* The vertex buffer is too large for hardware (or the swtnl
    156 	  * module).  Try to split on whole-primitive boundaries,
    157 	  * otherwise try to split the individual primitives.
    158 	  */
    159 	 vbo_split_inplace(ctx, arrays, prim, nr_prims, ib,
    160 			   min_index, max_index, draw, limits );
    161       }
    162       else {
    163 	 /* Why were we called? */
    164 	 assert(0);
    165       }
    166    }
    167 }
    168 
    169