• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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  */
split_prim_inplace(GLenum mode,GLuint * first,GLuint * incr)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 
vbo_split_prims(struct gl_context * ctx,const struct gl_vertex_array * arrays[],const struct _mesa_prim * prim,GLuint nr_prims,const struct _mesa_index_buffer * ib,GLuint min_index,GLuint max_index,vbo_draw_func draw,const struct split_limits * limits)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