Home | History | Annotate | Download | only in vbo
      1 
      2 /*
      3  * Mesa 3-D graphics library
      4  *
      5  * Copyright (C) 1999-2006  Brian Paul   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 "Software"),
      9  * to deal in the Software without restriction, including without limitation
     10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     11  * and/or sell copies of the Software, and to permit persons to whom the
     12  * Software is furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included
     15  * in all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     21  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     22  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     23  * OTHER DEALINGS IN THE SOFTWARE.
     24  *
     25  * Authors:
     26  *    Keith Whitwell <keithw (at) vmware.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_vertex_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    if (ib) {
    112       if (limits->max_indices == 0) {
    113 	 /* Could traverse the indices, re-emitting vertices in turn.
    114 	  * But it's hard to see why this case would be needed - for
    115 	  * software tnl, it is better to convert to non-indexed
    116 	  * rendering after transformation is complete.  Are there any devices
    117 	  * with hardware tnl that cannot do indexed rendering?
    118 	  *
    119 	  * For now, this path is disabled.
    120 	  */
    121 	 assert(0);
    122       }
    123       else if (max_index - min_index >= limits->max_verts) {
    124 	 /* The vertex buffers are too large for hardware (or the
    125 	  * swtnl module).  Traverse the indices, re-emitting vertices
    126 	  * in turn.  Use a vertex cache to preserve some of the
    127 	  * sharing from the original index list.
    128 	  */
    129 	 vbo_split_copy(ctx, arrays, prim, nr_prims, ib,
    130 			draw, limits );
    131       }
    132       else if (ib->count > limits->max_indices) {
    133 	 /* The index buffer is too large for hardware.  Try to split
    134 	  * on whole-primitive boundaries, otherwise try to split the
    135 	  * individual primitives.
    136 	  */
    137 	 vbo_split_inplace(ctx, arrays, prim, nr_prims, ib,
    138 			   min_index, max_index, draw, limits );
    139       }
    140       else {
    141 	 /* Why were we called? */
    142 	 assert(0);
    143       }
    144    }
    145    else {
    146       if (max_index - min_index >= limits->max_verts) {
    147 	 /* The vertex buffer is too large for hardware (or the swtnl
    148 	  * module).  Try to split on whole-primitive boundaries,
    149 	  * otherwise try to split the individual primitives.
    150 	  */
    151 	 vbo_split_inplace(ctx, arrays, prim, nr_prims, ib,
    152 			   min_index, max_index, draw, limits );
    153       }
    154       else {
    155 	 /* Why were we called? */
    156 	 assert(0);
    157       }
    158    }
    159 }
    160 
    161