t_draw.c revision 699cfaeb3cde2a329b2d79ae09c7783ed4edacfe
1c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell/*
2c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * Mesa 3-D graphics library
3f8ee72d98f2d23e034e90870ff6a760659a462a5Brian * Version:  7.1
4c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell *
5f8ee72d98f2d23e034e90870ff6a760659a462a5Brian * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
6c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell *
7c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
8c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * copy of this software and associated documentation files (the "Software"),
9c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * to deal in the Software without restriction, including without limitation
10c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the
12c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * Software is furnished to do so, subject to the following conditions:
13c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell *
14c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * The above copyright notice and this permission notice shall be included
15c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * in all copies or substantial portions of the Software.
16c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell *
17c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell *
24c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * Authors:
25c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell *    Keith Whitwell <keith@tungstengraphics.com>
26c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell */
27c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
28bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h"
29699cfaeb3cde2a329b2d79ae09c7783ed4edacfeBrian Paul#include "main/condrender.h"
30bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/context.h"
31bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/imports.h"
32bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/state.h"
33bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/mtypes.h"
34bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h"
35bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/enums.h"
36c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
37c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell#include "t_context.h"
38c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell#include "t_pipeline.h"
39c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell#include "t_vp_build.h"
40c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell#include "t_vertex.h"
41c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell#include "tnl.h"
42c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
43c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
44c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
45188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwellstatic GLubyte *get_space(GLcontext *ctx, GLuint bytes)
46c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
47c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
48c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   GLubyte *space = _mesa_malloc(bytes);
49c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
50c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   tnl->block[tnl->nr_blocks++] = space;
51188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   return space;
52c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
53c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
54c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
55c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwellstatic void free_space(GLcontext *ctx)
56c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
57c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
58c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   GLuint i;
59c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   for (i = 0; i < tnl->nr_blocks; i++)
60c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      _mesa_free(tnl->block[i]);
61c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   tnl->nr_blocks = 0;
62c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
63c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
64c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
659827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell/* Convert the incoming array to GLfloats.  Understands the
669827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell * array->Normalized flag and selects the correct conversion method.
679827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell */
689827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell#define CONVERT( TYPE, MACRO ) do {		\
699827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   GLuint i, j;					\
709827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   if (input->Normalized) {			\
719827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      for (i = 0; i < count; i++) {		\
729827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 const TYPE *in = (TYPE *)ptr;		\
739827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 for (j = 0; j < sz; j++) {		\
749827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	    *fptr++ = MACRO(*in);		\
759827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	    in++;				\
769827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 }					\
779827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 ptr += input->StrideB;			\
789827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      }						\
799827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   } else {					\
809827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      for (i = 0; i < count; i++) {		\
819827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 const TYPE *in = (TYPE *)ptr;		\
829827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 for (j = 0; j < sz; j++) {		\
839827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	    *fptr++ = (GLfloat)(*in);		\
849827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	    in++;				\
859827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 }					\
869827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 ptr += input->StrideB;			\
879827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      }						\
889827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   }						\
899827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell} while (0)
909827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
919827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
920791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul/**
930791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul * Convert array of BGRA/GLubyte[4] values to RGBA/float[4]
940791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul * \param ptr  input/ubyte array
950791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul * \param fptr  output/float array
960791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul */
970791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paulstatic void
980791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paulconvert_bgra_to_float(const struct gl_client_array *input,
990791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul                      const GLubyte *ptr, GLfloat *fptr,
1000791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul                      GLuint count )
1010791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul{
1020791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul   GLuint i;
1030791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul   assert(input->Normalized);
1040791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul   assert(input->Size == 4);
1050791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul   for (i = 0; i < count; i++) {
1060791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      const GLubyte *in = (GLubyte *) ptr;  /* in is in BGRA order */
1070791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      *fptr++ = UBYTE_TO_FLOAT(in[2]);  /* red */
1080791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      *fptr++ = UBYTE_TO_FLOAT(in[1]);  /* green */
1090791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      *fptr++ = UBYTE_TO_FLOAT(in[0]);  /* blue */
1100791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      *fptr++ = UBYTE_TO_FLOAT(in[3]);  /* alpha */
1110791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      ptr += input->StrideB;
1120791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul   }
1130791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul}
1140791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul
1159827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
116c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell/* Adjust pointer to point at first requested element, convert to
117c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * floating point, populate VB->AttribPtr[].
118c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell */
119c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwellstatic void _tnl_import_array( GLcontext *ctx,
120c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			       GLuint attrib,
121893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell			       GLuint count,
122c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			       const struct gl_client_array *input,
123188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell			       const GLubyte *ptr )
124c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
125c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
126c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   struct vertex_buffer *VB = &tnl->vb;
127c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   GLuint stride = input->StrideB;
128c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
129c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   if (input->Type != GL_FLOAT) {
130c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      const GLuint sz = input->Size;
131188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      GLubyte *buf = get_space(ctx, count * sz * sizeof(GLfloat));
1327e9c3684ef45e0df8426317f28c883d16f27c031Keith Whitwell      GLfloat *fptr = (GLfloat *)buf;
133c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
134c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      switch (input->Type) {
135c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_BYTE:
136c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLbyte, BYTE_TO_FLOAT);
137c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
138c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_UNSIGNED_BYTE:
1390791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul         if (input->Format == GL_BGRA) {
1400791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul            /* See GL_EXT_vertex_array_bgra */
1410791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul            convert_bgra_to_float(input, ptr, fptr, count);
1420791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul         }
1430791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul         else {
1440791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul            CONVERT(GLubyte, UBYTE_TO_FLOAT);
1450791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul         }
146c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
147c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_SHORT:
148c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLshort, SHORT_TO_FLOAT);
149c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
150c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_UNSIGNED_SHORT:
151c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLushort, USHORT_TO_FLOAT);
152c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
153c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_INT:
154c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLint, INT_TO_FLOAT);
155c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
156c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_UNSIGNED_INT:
157c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLuint, UINT_TO_FLOAT);
158c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
159c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_DOUBLE:
160c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLdouble, (GLfloat));
161c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
162c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      default:
163c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 assert(0);
164c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
165c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      }
166c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
1677e9c3684ef45e0df8426317f28c883d16f27c031Keith Whitwell      ptr = buf;
168c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      stride = sz * sizeof(GLfloat);
169c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
170c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
171c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib] = &tnl->tmp_inputs[attrib];
172c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->data = (GLfloat (*)[4])ptr;
173c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->start = (GLfloat *)ptr;
174c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->count = count;
175c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->stride = stride;
176c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->size = input->Size;
177c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
178c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   /* This should die, but so should the whole GLvector4f concept:
179c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell    */
180c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->flags = (((1<<input->Size)-1) |
181c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell				   VEC_NOT_WRITEABLE |
182c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell				   (stride == 4*sizeof(GLfloat) ? 0 : VEC_BAD_STRIDE));
183c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
184c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->storage = NULL;
185c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
186c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
1879827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell#define CLIPVERTS  ((6 + MAX_CLIP_PLANES) * 2)
1889827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
1899827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
1909827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwellstatic GLboolean *_tnl_import_edgeflag( GLcontext *ctx,
1919827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell					const GLvector4f *input,
1929827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell					GLuint count)
1939827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell{
1949827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   const GLubyte *ptr = (const GLubyte *)input->data;
1959827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   const GLuint stride = input->stride;
1969827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   GLboolean *space = (GLboolean *)get_space(ctx, count + CLIPVERTS);
1979827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   GLboolean *bptr = space;
1989827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   GLuint i;
1999827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
2009827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   for (i = 0; i < count; i++) {
2019827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      *bptr++ = ((GLfloat *)ptr)[0] == 1.0;
2029827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      ptr += stride;
2039827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   }
2049827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
2059827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   return space;
2069827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell}
2079827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
208c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
209c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwellstatic void bind_inputs( GLcontext *ctx,
210c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			 const struct gl_client_array *inputs[],
211893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell			 GLint count,
212c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			 struct gl_buffer_object **bo,
213c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			 GLuint *nr_bo )
214c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
215c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
216c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   struct vertex_buffer *VB = &tnl->vb;
217c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   GLuint i;
218c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
219c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   /* Map all the VBOs
220c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell    */
221c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
222c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      const void *ptr;
223c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
224c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      if (inputs[i]->BufferObj->Name) {
225c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 if (!inputs[i]->BufferObj->Pointer) {
226c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	    bo[*nr_bo] = inputs[i]->BufferObj;
2277e9c3684ef45e0df8426317f28c883d16f27c031Keith Whitwell	    (*nr_bo)++;
228c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	    ctx->Driver.MapBuffer(ctx,
229c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell				  GL_ARRAY_BUFFER,
230c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell				  GL_READ_ONLY_ARB,
231c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell				  inputs[i]->BufferObj);
232c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
233c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	    assert(inputs[i]->BufferObj->Pointer);
234c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 }
235c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
236c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 ptr = ADD_POINTERS(inputs[i]->BufferObj->Pointer,
237c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			    inputs[i]->Ptr);
238c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      }
239c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      else
240c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 ptr = inputs[i]->Ptr;
241c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
242c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      /* Just make sure the array is floating point, otherwise convert to
243893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       * temporary storage.
244c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       *
245c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       * XXX: remove the GLvector4f type at some stage and just use
246c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       * client arrays.
247c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       */
248893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      _tnl_import_array(ctx, i, count, inputs[i], ptr);
249c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
250c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
2515464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   /* We process only the vertices between min & max index:
2525464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell    */
253893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   VB->Count = count;
2545464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
25537c79d4d765b10a79e0cf217cc1e70d3fbb7a0c5Eric Anholt   /* These should perhaps be part of _TNL_ATTRIB_* */
2560a9187801505130738ae947c69cafa8a1dd118d1Eric Anholt   VB->BackfaceColorPtr = NULL;
257fc9a2970dc539b21b035ea0a770ec69822962145Eric Anholt   VB->BackfaceIndexPtr = NULL;
2580a9187801505130738ae947c69cafa8a1dd118d1Eric Anholt   VB->BackfaceSecondaryColorPtr = NULL;
259c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
2609827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   /* Clipping and drawing code still requires this to be a packed
2619827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell    * array of ubytes which can be written into.  TODO: Fix and
2629827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell    * remove.
263c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell    */
264c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   if (ctx->Polygon.FrontMode != GL_FILL ||
265c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       ctx->Polygon.BackMode != GL_FILL)
266c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   {
2679827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      VB->EdgeFlag = _tnl_import_edgeflag( ctx,
2689827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell					   VB->AttribPtr[_TNL_ATTRIB_EDGEFLAG],
2699827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell					   VB->Count );
270c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
271d2d86a3f0b38716196ea2b3ffa4cbbd0420de1b3Brian   else {
272d2d86a3f0b38716196ea2b3ffa4cbbd0420de1b3Brian      /* the data previously pointed to by EdgeFlag may have been freed */
273d2d86a3f0b38716196ea2b3ffa4cbbd0420de1b3Brian      VB->EdgeFlag = NULL;
274d2d86a3f0b38716196ea2b3ffa4cbbd0420de1b3Brian   }
275c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
276c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
277c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
278c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell/* Translate indices to GLuints and store in VB->Elts.
279c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell */
2805464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwellstatic void bind_indices( GLcontext *ctx,
2815464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell			  const struct _mesa_index_buffer *ib,
2825464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell			  struct gl_buffer_object **bo,
2835464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell			  GLuint *nr_bo)
284c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
285c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
286c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   struct vertex_buffer *VB = &tnl->vb;
287188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   GLuint i;
288188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   void *ptr;
289c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
290893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   if (!ib) {
291893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      VB->Elts = NULL;
292c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      return;
293893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   }
294c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
295c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   if (ib->obj->Name && !ib->obj->Pointer) {
296c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      bo[*nr_bo] = ib->obj;
2977e9c3684ef45e0df8426317f28c883d16f27c031Keith Whitwell      (*nr_bo)++;
298c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      ctx->Driver.MapBuffer(ctx,
299c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			    GL_ELEMENT_ARRAY_BUFFER,
300c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			    GL_READ_ONLY_ARB,
301c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			    ib->obj);
302c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
303c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      assert(ib->obj->Pointer);
304c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
305c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
306188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr);
307c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
30892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   if (ib->type == GL_UNSIGNED_INT && VB->Primitive[0].basevertex == 0) {
309188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      VB->Elts = (GLuint *) ptr;
310188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   }
311188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   else {
312188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      GLuint *elts = (GLuint *)get_space(ctx, ib->count * sizeof(GLuint));
313188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      VB->Elts = elts;
314188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell
31592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      if (ib->type == GL_UNSIGNED_INT) {
31692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 const GLuint *in = (GLuint *)ptr;
31792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 for (i = 0; i < ib->count; i++)
31892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
31992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      }
32092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      else if (ib->type == GL_UNSIGNED_SHORT) {
321893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell	 const GLushort *in = (GLushort *)ptr;
322188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell	 for (i = 0; i < ib->count; i++)
32392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
324188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      }
325893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      else {
326893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell	 const GLubyte *in = (GLubyte *)ptr;
327188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell	 for (i = 0; i < ib->count; i++)
32892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
329188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      }
330c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
331c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
332c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
3335464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwellstatic void bind_prims( GLcontext *ctx,
3345464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell			const struct _mesa_prim *prim,
335893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell			GLuint nr_prims )
3365464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell{
3375464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
3385464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   struct vertex_buffer *VB = &tnl->vb;
3395464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
340893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   VB->Primitive = prim;
3415464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   VB->PrimitiveCount = nr_prims;
3425464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell}
3435464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
344c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwellstatic void unmap_vbos( GLcontext *ctx,
345c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			struct gl_buffer_object **bo,
346c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			GLuint nr_bo )
347c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
348c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   GLuint i;
349c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   for (i = 0; i < nr_bo; i++) {
350c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      ctx->Driver.UnmapBuffer(ctx,
351c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			      0, /* target -- I don't see why this would be needed */
352c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			      bo[i]);
353c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
354c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
355c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
356c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
3572708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholtvoid _tnl_vbo_draw_prims(GLcontext *ctx,
3582708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 const struct gl_client_array *arrays[],
3592708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 const struct _mesa_prim *prim,
3602708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 GLuint nr_prims,
3612708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 const struct _mesa_index_buffer *ib,
3622708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 GLboolean index_bounds_valid,
3632708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 GLuint min_index,
3642708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 GLuint max_index)
3652708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt{
3662708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   if (!index_bounds_valid)
3672708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt      vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
3682708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt
3692708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
3702708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt}
371c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
372c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell/* This is the main entrypoint into the slimmed-down software tnl
373c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * module.  In a regular swtnl driver, this can be plugged straight
374c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * into the vbo->Driver.DrawPrims() callback.
375c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell */
376c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwellvoid _tnl_draw_prims( GLcontext *ctx,
377c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      const struct gl_client_array *arrays[],
378c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      const struct _mesa_prim *prim,
379c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      GLuint nr_prims,
380c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      const struct _mesa_index_buffer *ib,
381c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      GLuint min_index,
382c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      GLuint max_index)
383c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
384c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
385893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   const GLuint TEST_SPLIT = 0;
386893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   const GLint max = TEST_SPLIT ? 8 : tnl->vb.Size - MAX_CLIPPED_VERTICES;
38792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GLuint max_basevertex = prim->basevertex;
38892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GLuint i;
38992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
390699cfaeb3cde2a329b2d79ae09c7783ed4edacfeBrian Paul   if (!_mesa_check_conditional_render(ctx))
391699cfaeb3cde2a329b2d79ae09c7783ed4edacfeBrian Paul      return; /* don't draw */
392699cfaeb3cde2a329b2d79ae09c7783ed4edacfeBrian Paul
39392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   for (i = 1; i < nr_prims; i++)
39492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      max_basevertex = MAX2(max_basevertex, prim[i].basevertex);
3955464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
396893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   if (0)
39782152a2a8e1afeb61710318e769b1379be6c02c6keithw   {
39882152a2a8e1afeb61710318e769b1379be6c02c6keithw      _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
39982152a2a8e1afeb61710318e769b1379be6c02c6keithw      for (i = 0; i < nr_prims; i++)
40082152a2a8e1afeb61710318e769b1379be6c02c6keithw	 _mesa_printf("prim %d: %s start %d count %d\n", i,
40182152a2a8e1afeb61710318e769b1379be6c02c6keithw		      _mesa_lookup_enum_by_nr(prim[i].mode),
40282152a2a8e1afeb61710318e769b1379be6c02c6keithw		      prim[i].start,
40382152a2a8e1afeb61710318e769b1379be6c02c6keithw		      prim[i].count);
40482152a2a8e1afeb61710318e769b1379be6c02c6keithw   }
4055464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
406893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   if (min_index) {
407893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      /* We always translate away calls with min_index != 0.
408893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       */
409893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib,
410893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell			min_index, max_index,
4112708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			_tnl_vbo_draw_prims );
412893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      return;
413893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   }
41492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   else if (max_index + max_basevertex > max) {
415893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      /* The software TNL pipeline has a fixed amount of storage for
416893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       * vertices and it is necessary to split incoming drawing commands
417893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       * if they exceed that limit.
418893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       */
4195464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      struct split_limits limits;
420893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      limits.max_verts = max;
4215464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      limits.max_vb_size = ~0;
4225464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      limits.max_indices = ~0;
4235464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
4245464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      /* This will split the buffers one way or another and
4255464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell       * recursively call back into this function.
4265464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell       */
4275464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      vbo_split_prims( ctx, arrays, prim, nr_prims, ib,
42892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt		       0, max_index + prim->basevertex,
4292708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt		       _tnl_vbo_draw_prims,
4305464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell		       &limits );
4315464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   }
4325464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   else {
4335464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      /* May need to map a vertex buffer object for every attribute plus
4345464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell       * one for the index buffer.
4355464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell       */
4365464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1];
4375464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      GLuint nr_bo = 0;
438c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
43992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      for (i = 0; i < nr_prims;) {
44092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 GLuint this_nr_prims;
44192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
44292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 /* Our SW TNL pipeline doesn't handle basevertex yet, so bind_indices
44392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  * will rebase the elements to the basevertex, and we'll only
44492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  * emit strings of prims with the same basevertex in one draw call.
44592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  */
44692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 for (this_nr_prims = 1; i + this_nr_prims < nr_prims;
44792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	      this_nr_prims++) {
44892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    if (prim[i].basevertex != prim[i + this_nr_prims].basevertex)
44992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	       break;
45092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 }
45192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
45292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 /* Binding inputs may imply mapping some vertex buffer objects.
45392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  * They will need to be unmapped below.
45492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  */
45592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 bind_prims(ctx, &prim[i], this_nr_prims);
45692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 bind_inputs(ctx, arrays, max_index + prim[i].basevertex + 1,
45792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt		     bo, &nr_bo);
45892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 bind_indices(ctx, ib, bo, &nr_bo);
459c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
46092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);
461c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
46292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 unmap_vbos(ctx, bo, nr_bo);
46392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 free_space(ctx);
46492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
46592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 i += this_nr_prims;
46692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      }
4675464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   }
468c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
469c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
470