t_draw.c revision 6179f7e38e78eea6fb06180fca3c8b1e78d25f2b
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/mtypes.h"
33bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h"
34bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/enums.h"
35c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
36c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell#include "t_context.h"
37c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell#include "tnl.h"
38c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
39c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
40c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
41f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic GLubyte *get_space(struct gl_context *ctx, GLuint bytes)
42c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
43c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
4432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg   GLubyte *space = malloc(bytes);
45c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
46c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   tnl->block[tnl->nr_blocks++] = space;
47188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   return space;
48c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
49c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
50c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
51f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void free_space(struct gl_context *ctx)
52c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
53c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
54c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   GLuint i;
55c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   for (i = 0; i < tnl->nr_blocks; i++)
5632f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      free(tnl->block[i]);
57c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   tnl->nr_blocks = 0;
58c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
59c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
60c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
619827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell/* Convert the incoming array to GLfloats.  Understands the
629827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell * array->Normalized flag and selects the correct conversion method.
639827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell */
649827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell#define CONVERT( TYPE, MACRO ) do {		\
659827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   GLuint i, j;					\
669827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   if (input->Normalized) {			\
679827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      for (i = 0; i < count; i++) {		\
689827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 const TYPE *in = (TYPE *)ptr;		\
699827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 for (j = 0; j < sz; j++) {		\
709827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	    *fptr++ = MACRO(*in);		\
719827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	    in++;				\
729827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 }					\
739827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 ptr += input->StrideB;			\
749827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      }						\
759827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   } else {					\
769827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      for (i = 0; i < count; i++) {		\
779827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 const TYPE *in = (TYPE *)ptr;		\
789827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 for (j = 0; j < sz; j++) {		\
799827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	    *fptr++ = (GLfloat)(*in);		\
809827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	    in++;				\
819827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 }					\
829827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 ptr += input->StrideB;			\
839827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      }						\
849827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   }						\
859827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell} while (0)
869827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
879827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
880791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul/**
890791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul * Convert array of BGRA/GLubyte[4] values to RGBA/float[4]
900791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul * \param ptr  input/ubyte array
910791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul * \param fptr  output/float array
920791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul */
930791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paulstatic void
940791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paulconvert_bgra_to_float(const struct gl_client_array *input,
950791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul                      const GLubyte *ptr, GLfloat *fptr,
960791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul                      GLuint count )
970791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul{
980791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul   GLuint i;
990791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul   assert(input->Normalized);
1000791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul   assert(input->Size == 4);
1010791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul   for (i = 0; i < count; i++) {
1020791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      const GLubyte *in = (GLubyte *) ptr;  /* in is in BGRA order */
1030791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      *fptr++ = UBYTE_TO_FLOAT(in[2]);  /* red */
1040791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      *fptr++ = UBYTE_TO_FLOAT(in[1]);  /* green */
1050791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      *fptr++ = UBYTE_TO_FLOAT(in[0]);  /* blue */
1060791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      *fptr++ = UBYTE_TO_FLOAT(in[3]);  /* alpha */
1070791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      ptr += input->StrideB;
1080791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul   }
1090791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul}
1100791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul
111cfe884e2030466df673881da8e830c300dda40dbDave Airliestatic void
112cfe884e2030466df673881da8e830c300dda40dbDave Airlieconvert_half_to_float(const struct gl_client_array *input,
113cfe884e2030466df673881da8e830c300dda40dbDave Airlie		      const GLubyte *ptr, GLfloat *fptr,
114cfe884e2030466df673881da8e830c300dda40dbDave Airlie		      GLuint count, GLuint sz)
115cfe884e2030466df673881da8e830c300dda40dbDave Airlie{
116cfe884e2030466df673881da8e830c300dda40dbDave Airlie   GLuint i, j;
117cfe884e2030466df673881da8e830c300dda40dbDave Airlie
118cfe884e2030466df673881da8e830c300dda40dbDave Airlie   for (i = 0; i < count; i++) {
119cfe884e2030466df673881da8e830c300dda40dbDave Airlie      GLhalfARB *in = (GLhalfARB *)ptr;
120cfe884e2030466df673881da8e830c300dda40dbDave Airlie
121cfe884e2030466df673881da8e830c300dda40dbDave Airlie      for (j = 0; j < sz; j++) {
122cfe884e2030466df673881da8e830c300dda40dbDave Airlie	 *fptr++ = _mesa_half_to_float(in[j]);
123cfe884e2030466df673881da8e830c300dda40dbDave Airlie      }
124cfe884e2030466df673881da8e830c300dda40dbDave Airlie      ptr += input->StrideB;
125cfe884e2030466df673881da8e830c300dda40dbDave Airlie   }
126cfe884e2030466df673881da8e830c300dda40dbDave Airlie}
1279827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
128c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell/* Adjust pointer to point at first requested element, convert to
129c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * floating point, populate VB->AttribPtr[].
130c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell */
131f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void _tnl_import_array( struct gl_context *ctx,
132c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			       GLuint attrib,
133893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell			       GLuint count,
134c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			       const struct gl_client_array *input,
135188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell			       const GLubyte *ptr )
136c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
137c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
138c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   struct vertex_buffer *VB = &tnl->vb;
139c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   GLuint stride = input->StrideB;
140c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
141c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   if (input->Type != GL_FLOAT) {
142c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      const GLuint sz = input->Size;
143188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      GLubyte *buf = get_space(ctx, count * sz * sizeof(GLfloat));
1447e9c3684ef45e0df8426317f28c883d16f27c031Keith Whitwell      GLfloat *fptr = (GLfloat *)buf;
145c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
146c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      switch (input->Type) {
147c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_BYTE:
148c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLbyte, BYTE_TO_FLOAT);
149c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
150c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_UNSIGNED_BYTE:
1510791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul         if (input->Format == GL_BGRA) {
1520791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul            /* See GL_EXT_vertex_array_bgra */
1530791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul            convert_bgra_to_float(input, ptr, fptr, count);
1540791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul         }
1550791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul         else {
1560791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul            CONVERT(GLubyte, UBYTE_TO_FLOAT);
1570791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul         }
158c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
159c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_SHORT:
160c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLshort, SHORT_TO_FLOAT);
161c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
162c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_UNSIGNED_SHORT:
163c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLushort, USHORT_TO_FLOAT);
164c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
165c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_INT:
166c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLint, INT_TO_FLOAT);
167c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
168c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_UNSIGNED_INT:
169c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLuint, UINT_TO_FLOAT);
170c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
171c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_DOUBLE:
172c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLdouble, (GLfloat));
173c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
174cfe884e2030466df673881da8e830c300dda40dbDave Airlie      case GL_HALF_FLOAT:
175cfe884e2030466df673881da8e830c300dda40dbDave Airlie	 convert_half_to_float(input, ptr, fptr, count, sz);
176cfe884e2030466df673881da8e830c300dda40dbDave Airlie	 break;
177c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      default:
178c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 assert(0);
179c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
180c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      }
181c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
1827e9c3684ef45e0df8426317f28c883d16f27c031Keith Whitwell      ptr = buf;
183c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      stride = sz * sizeof(GLfloat);
184c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
185c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
186c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib] = &tnl->tmp_inputs[attrib];
187c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->data = (GLfloat (*)[4])ptr;
188c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->start = (GLfloat *)ptr;
189c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->count = count;
190c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->stride = stride;
191c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->size = input->Size;
192c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
193c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   /* This should die, but so should the whole GLvector4f concept:
194c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell    */
195c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->flags = (((1<<input->Size)-1) |
196c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell				   VEC_NOT_WRITEABLE |
197c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell				   (stride == 4*sizeof(GLfloat) ? 0 : VEC_BAD_STRIDE));
198c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
199c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->storage = NULL;
200c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
201c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
2029827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell#define CLIPVERTS  ((6 + MAX_CLIP_PLANES) * 2)
2039827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
2049827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
205f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic GLboolean *_tnl_import_edgeflag( struct gl_context *ctx,
2069827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell					const GLvector4f *input,
2079827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell					GLuint count)
2089827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell{
2099827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   const GLubyte *ptr = (const GLubyte *)input->data;
2109827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   const GLuint stride = input->stride;
2119827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   GLboolean *space = (GLboolean *)get_space(ctx, count + CLIPVERTS);
2129827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   GLboolean *bptr = space;
2139827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   GLuint i;
2149827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
2159827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   for (i = 0; i < count; i++) {
2169827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      *bptr++ = ((GLfloat *)ptr)[0] == 1.0;
2179827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      ptr += stride;
2189827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   }
2199827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
2209827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   return space;
2219827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell}
2229827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
223c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
224f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void bind_inputs( struct gl_context *ctx,
225c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			 const struct gl_client_array *inputs[],
226893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell			 GLint count,
227c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			 struct gl_buffer_object **bo,
228c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			 GLuint *nr_bo )
229c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
230c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
231c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   struct vertex_buffer *VB = &tnl->vb;
232c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   GLuint i;
233c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
234c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   /* Map all the VBOs
235c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell    */
236c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
237c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      const void *ptr;
238c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
239c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      if (inputs[i]->BufferObj->Name) {
240c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 if (!inputs[i]->BufferObj->Pointer) {
241c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	    bo[*nr_bo] = inputs[i]->BufferObj;
2427e9c3684ef45e0df8426317f28c883d16f27c031Keith Whitwell	    (*nr_bo)++;
243c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	    ctx->Driver.MapBuffer(ctx,
244c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell				  GL_ARRAY_BUFFER,
245c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell				  GL_READ_ONLY_ARB,
246c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell				  inputs[i]->BufferObj);
247c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
248c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	    assert(inputs[i]->BufferObj->Pointer);
249c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 }
250c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
251c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 ptr = ADD_POINTERS(inputs[i]->BufferObj->Pointer,
252c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			    inputs[i]->Ptr);
253c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      }
254c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      else
255c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 ptr = inputs[i]->Ptr;
256c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
257c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      /* Just make sure the array is floating point, otherwise convert to
258893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       * temporary storage.
259c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       *
260c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       * XXX: remove the GLvector4f type at some stage and just use
261c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       * client arrays.
262c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       */
263893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      _tnl_import_array(ctx, i, count, inputs[i], ptr);
264c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
265c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
2665464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   /* We process only the vertices between min & max index:
2675464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell    */
268893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   VB->Count = count;
2695464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
27037c79d4d765b10a79e0cf217cc1e70d3fbb7a0c5Eric Anholt   /* These should perhaps be part of _TNL_ATTRIB_* */
2710a9187801505130738ae947c69cafa8a1dd118d1Eric Anholt   VB->BackfaceColorPtr = NULL;
272fc9a2970dc539b21b035ea0a770ec69822962145Eric Anholt   VB->BackfaceIndexPtr = NULL;
2730a9187801505130738ae947c69cafa8a1dd118d1Eric Anholt   VB->BackfaceSecondaryColorPtr = NULL;
274c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
2759827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   /* Clipping and drawing code still requires this to be a packed
2769827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell    * array of ubytes which can be written into.  TODO: Fix and
2779827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell    * remove.
278c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell    */
279c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   if (ctx->Polygon.FrontMode != GL_FILL ||
280c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       ctx->Polygon.BackMode != GL_FILL)
281c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   {
2829827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      VB->EdgeFlag = _tnl_import_edgeflag( ctx,
2839827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell					   VB->AttribPtr[_TNL_ATTRIB_EDGEFLAG],
2849827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell					   VB->Count );
285c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
286d2d86a3f0b38716196ea2b3ffa4cbbd0420de1b3Brian   else {
287d2d86a3f0b38716196ea2b3ffa4cbbd0420de1b3Brian      /* the data previously pointed to by EdgeFlag may have been freed */
288d2d86a3f0b38716196ea2b3ffa4cbbd0420de1b3Brian      VB->EdgeFlag = NULL;
289d2d86a3f0b38716196ea2b3ffa4cbbd0420de1b3Brian   }
290c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
291c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
292c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
293c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell/* Translate indices to GLuints and store in VB->Elts.
294c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell */
295f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void bind_indices( struct gl_context *ctx,
2965464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell			  const struct _mesa_index_buffer *ib,
2975464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell			  struct gl_buffer_object **bo,
2985464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell			  GLuint *nr_bo)
299c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
300c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
301c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   struct vertex_buffer *VB = &tnl->vb;
302188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   GLuint i;
303188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   void *ptr;
304c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
305893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   if (!ib) {
306893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      VB->Elts = NULL;
307c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      return;
308893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   }
309c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
310c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   if (ib->obj->Name && !ib->obj->Pointer) {
311c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      bo[*nr_bo] = ib->obj;
3127e9c3684ef45e0df8426317f28c883d16f27c031Keith Whitwell      (*nr_bo)++;
313c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      ctx->Driver.MapBuffer(ctx,
314c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			    GL_ELEMENT_ARRAY_BUFFER,
315c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			    GL_READ_ONLY_ARB,
316c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			    ib->obj);
317c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
318c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      assert(ib->obj->Pointer);
319c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
320c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
321188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr);
322c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
32392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   if (ib->type == GL_UNSIGNED_INT && VB->Primitive[0].basevertex == 0) {
324188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      VB->Elts = (GLuint *) ptr;
325188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   }
326188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   else {
327188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      GLuint *elts = (GLuint *)get_space(ctx, ib->count * sizeof(GLuint));
328188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      VB->Elts = elts;
329188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell
33092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      if (ib->type == GL_UNSIGNED_INT) {
33192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 const GLuint *in = (GLuint *)ptr;
33292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 for (i = 0; i < ib->count; i++)
33392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
33492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      }
33592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      else if (ib->type == GL_UNSIGNED_SHORT) {
336893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell	 const GLushort *in = (GLushort *)ptr;
337188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell	 for (i = 0; i < ib->count; i++)
33892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
339188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      }
340893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      else {
341893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell	 const GLubyte *in = (GLubyte *)ptr;
342188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell	 for (i = 0; i < ib->count; i++)
34392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
344188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      }
345c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
346c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
347c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
348f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void bind_prims( struct gl_context *ctx,
3495464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell			const struct _mesa_prim *prim,
350893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell			GLuint nr_prims )
3515464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell{
3525464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
3535464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   struct vertex_buffer *VB = &tnl->vb;
3545464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
355893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   VB->Primitive = prim;
3565464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   VB->PrimitiveCount = nr_prims;
3575464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell}
3585464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
359f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void unmap_vbos( struct gl_context *ctx,
360c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			struct gl_buffer_object **bo,
361c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			GLuint nr_bo )
362c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
363c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   GLuint i;
364c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   for (i = 0; i < nr_bo; i++) {
365c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      ctx->Driver.UnmapBuffer(ctx,
366c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			      0, /* target -- I don't see why this would be needed */
367c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			      bo[i]);
368c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
369c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
370c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
371c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
372f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvoid _tnl_vbo_draw_prims(struct gl_context *ctx,
3732708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 const struct gl_client_array *arrays[],
3742708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 const struct _mesa_prim *prim,
3752708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 GLuint nr_prims,
3762708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 const struct _mesa_index_buffer *ib,
3772708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 GLboolean index_bounds_valid,
3782708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 GLuint min_index,
3792708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 GLuint max_index)
3802708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt{
3812708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   if (!index_bounds_valid)
3822708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt      vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
3832708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt
3842708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
3852708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt}
386c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
387c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell/* This is the main entrypoint into the slimmed-down software tnl
388c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * module.  In a regular swtnl driver, this can be plugged straight
389c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * into the vbo->Driver.DrawPrims() callback.
390c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell */
391f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvoid _tnl_draw_prims( struct gl_context *ctx,
392c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      const struct gl_client_array *arrays[],
393c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      const struct _mesa_prim *prim,
394c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      GLuint nr_prims,
395c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      const struct _mesa_index_buffer *ib,
396c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      GLuint min_index,
397c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      GLuint max_index)
398c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
399c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
400893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   const GLuint TEST_SPLIT = 0;
401893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   const GLint max = TEST_SPLIT ? 8 : tnl->vb.Size - MAX_CLIPPED_VERTICES;
40228bd4a1d81c200d7eff4545de946dd943d853b08Brian Paul   GLint max_basevertex = prim->basevertex;
40392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GLuint i;
40492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
4056fea2be7959620fe0a1b28c275a7d960005c8b09Brian Paul   /* Mesa core state should have been validated already */
4066fea2be7959620fe0a1b28c275a7d960005c8b09Brian Paul   assert(ctx->NewState == 0x0);
4076fea2be7959620fe0a1b28c275a7d960005c8b09Brian Paul
408699cfaeb3cde2a329b2d79ae09c7783ed4edacfeBrian Paul   if (!_mesa_check_conditional_render(ctx))
409699cfaeb3cde2a329b2d79ae09c7783ed4edacfeBrian Paul      return; /* don't draw */
410699cfaeb3cde2a329b2d79ae09c7783ed4edacfeBrian Paul
41192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   for (i = 1; i < nr_prims; i++)
41292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      max_basevertex = MAX2(max_basevertex, prim[i].basevertex);
4135464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
414893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   if (0)
41582152a2a8e1afeb61710318e769b1379be6c02c6keithw   {
416298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
41782152a2a8e1afeb61710318e769b1379be6c02c6keithw      for (i = 0; i < nr_prims; i++)
418298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	 printf("prim %d: %s start %d count %d\n", i,
419298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg		_mesa_lookup_enum_by_nr(prim[i].mode),
420298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg		prim[i].start,
421298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg		prim[i].count);
42282152a2a8e1afeb61710318e769b1379be6c02c6keithw   }
4235464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
424893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   if (min_index) {
425893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      /* We always translate away calls with min_index != 0.
426893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       */
427893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib,
428893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell			min_index, max_index,
4292708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			_tnl_vbo_draw_prims );
430893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      return;
431893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   }
432b30898f4ab533085d97a33638ad0a1cf9ddb1d67Karl Schultz   else if ((GLint)max_index + max_basevertex > max) {
433893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      /* The software TNL pipeline has a fixed amount of storage for
434893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       * vertices and it is necessary to split incoming drawing commands
435893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       * if they exceed that limit.
436893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       */
4375464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      struct split_limits limits;
438893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      limits.max_verts = max;
4395464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      limits.max_vb_size = ~0;
4405464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      limits.max_indices = ~0;
4415464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
4425464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      /* This will split the buffers one way or another and
4435464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell       * recursively call back into this function.
4445464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell       */
4455464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      vbo_split_prims( ctx, arrays, prim, nr_prims, ib,
44692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt		       0, max_index + prim->basevertex,
4472708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt		       _tnl_vbo_draw_prims,
4485464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell		       &limits );
4495464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   }
4505464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   else {
4515464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      /* May need to map a vertex buffer object for every attribute plus
4525464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell       * one for the index buffer.
4535464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell       */
4545464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1];
4555464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      GLuint nr_bo = 0;
456a63486ac680acc0bfb895037aca130a457caa01aBrian Paul      GLuint inst;
457c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
45892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      for (i = 0; i < nr_prims;) {
45992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 GLuint this_nr_prims;
46092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
46192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 /* Our SW TNL pipeline doesn't handle basevertex yet, so bind_indices
46292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  * will rebase the elements to the basevertex, and we'll only
46392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  * emit strings of prims with the same basevertex in one draw call.
46492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  */
46592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 for (this_nr_prims = 1; i + this_nr_prims < nr_prims;
46692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	      this_nr_prims++) {
46792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    if (prim[i].basevertex != prim[i + this_nr_prims].basevertex)
46892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	       break;
46992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 }
47092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
4716179f7e38e78eea6fb06180fca3c8b1e78d25f2bBrian Paul         assert(prim[i].num_instances > 0);
4726179f7e38e78eea6fb06180fca3c8b1e78d25f2bBrian Paul
47392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 /* Binding inputs may imply mapping some vertex buffer objects.
47492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  * They will need to be unmapped below.
47592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  */
476a63486ac680acc0bfb895037aca130a457caa01aBrian Paul         for (inst = 0; inst < prim[i].num_instances; inst++) {
477c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
478a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            bind_prims(ctx, &prim[i], this_nr_prims);
479a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            bind_inputs(ctx, arrays, max_index + prim[i].basevertex + 1,
480a63486ac680acc0bfb895037aca130a457caa01aBrian Paul                        bo, &nr_bo);
481a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            bind_indices(ctx, ib, bo, &nr_bo);
482c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
483a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            tnl->CurInstance = inst;
484a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);
485a63486ac680acc0bfb895037aca130a457caa01aBrian Paul
486a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            unmap_vbos(ctx, bo, nr_bo);
487a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            free_space(ctx);
488a63486ac680acc0bfb895037aca130a457caa01aBrian Paul         }
48992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
49092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 i += this_nr_prims;
49192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      }
4925464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   }
493c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
494c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
495