1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version:  6.5
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Authors:
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    Keith Whitwell <keith@tungstengraphics.com>
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Deal with hardware and/or swtnl maximums:
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - maximum number of vertices in buffer
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - maximum number of elements (maybe zero)
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The maximums may vary with opengl state (eg if a larger hardware
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * vertex is required in this state, the maximum number of vertices
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * may be smaller than in another state).
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We want buffer splitting to be a convenience function for the code
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * actually drawing the primitives rather than a system-wide maximum,
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * otherwise it is hard to avoid pessimism.
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * For instance, if a driver has no hardware limits on vertex buffer
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * dimensions, it would not ordinarily want to split vbos.  But if
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * there is an unexpected fallback, eg memory manager fails to upload
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * textures, it will want to pass the drawing commands onto swtnl,
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * which does have limitations.  A convenience function allows swtnl
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to split the drawing and vbos internally without imposing its
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * limitations on drivers which want to use it as a fallback path.
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/glheader.h"
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/imports.h"
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/mtypes.h"
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/macros.h"
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "vbo_split.h"
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "vbo.h"
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* True if a primitive can be split without copying of vertices, false
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * otherwise.
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgGLboolean split_prim_inplace(GLenum mode, GLuint *first, GLuint *incr)
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (mode) {
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_POINTS:
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *first = 1;
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *incr = 1;
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_TRUE;
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_LINES:
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *first = 2;
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *incr = 2;
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_TRUE;
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_LINE_STRIP:
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *first = 2;
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *incr = 1;
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_TRUE;
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_TRIANGLES:
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *first = 3;
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *incr = 3;
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_TRUE;
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_TRIANGLE_STRIP:
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *first = 3;
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *incr = 1;
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_TRUE;
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_QUADS:
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *first = 4;
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *incr = 4;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_TRUE;
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case GL_QUAD_STRIP:
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *first = 4;
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *incr = 2;
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_TRUE;
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *first = 0;
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *incr = 1;		/* so that count % incr works */
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GL_FALSE;
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid vbo_split_prims( struct gl_context *ctx,
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct gl_client_array *arrays[],
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct _mesa_prim *prim,
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      GLuint nr_prims,
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct _mesa_index_buffer *ib,
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      GLuint min_index,
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      GLuint max_index,
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      vbo_draw_func draw,
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct split_limits *limits )
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint max_basevertex = prim->basevertex;
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 1; i < nr_prims; i++)
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      max_basevertex = MAX2(max_basevertex, prim[i].basevertex);
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* XXX max_basevertex is computed but not used, why? */
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ib) {
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (limits->max_indices == 0) {
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Could traverse the indices, re-emitting vertices in turn.
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * But it's hard to see why this case would be needed - for
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * software tnl, it is better to convert to non-indexed
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * rendering after transformation is complete.  Are there any devices
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * with hardware tnl that cannot do indexed rendering?
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * For now, this path is disabled.
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(0);
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (max_index - min_index >= limits->max_verts) {
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* The vertex buffers are too large for hardware (or the
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * swtnl module).  Traverse the indices, re-emitting vertices
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * in turn.  Use a vertex cache to preserve some of the
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * sharing from the original index list.
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 vbo_split_copy(ctx, arrays, prim, nr_prims, ib,
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			draw, limits );
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (ib->count > limits->max_indices) {
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* The index buffer is too large for hardware.  Try to split
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * on whole-primitive boundaries, otherwise try to split the
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * individual primitives.
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 vbo_split_inplace(ctx, arrays, prim, nr_prims, ib,
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   min_index, max_index, draw, limits );
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Why were we called? */
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(0);
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (max_index - min_index >= limits->max_verts) {
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* The vertex buffer is too large for hardware (or the swtnl
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * module).  Try to split on whole-primitive boundaries,
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * otherwise try to split the individual primitives.
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 vbo_split_inplace(ctx, arrays, prim, nr_prims, ib,
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   min_index, max_index, draw, limits );
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Why were we called? */
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(0);
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
169