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