t_draw.c revision 28249bd260f4c52badf3eb61ade2744604b21bca
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
128a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace/**
129a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace * \brief Convert fixed-point to floating-point.
130a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace *
131a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace * In OpenGL, a fixed-point number is a "signed 2's complement 16.16 scaled
132a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace * integer" (Table 2.2 of the OpenGL ES 2.0 spec).
133a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace *
134a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace * If the buffer has the \c normalized flag set, the formula
135a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace *     \code normalize(x) := (2*x + 1) / (2^16 - 1) \endcode
136a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace * is used to map the fixed-point numbers into the range [-1, 1].
137a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace */
138a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versacestatic void
139a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versaceconvert_fixed_to_float(const struct gl_client_array *input,
140a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace                       const GLubyte *ptr, GLfloat *fptr,
141a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace                       GLuint count)
142a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace{
143a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace   GLuint i, j;
144a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace   const GLint size = input->Size;
145a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace
146a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace   if (input->Normalized) {
147a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace      for (i = 0; i < count; ++i) {
148a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         const GLfixed *in = (GLfixed *) ptr;
149a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         for (j = 0; j < size; ++j) {
150a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace            *fptr++ = (GLfloat) (2 * in[j] + 1) / (GLfloat) ((1 << 16) - 1);
151a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         }
152a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         ptr += input->StrideB;
153a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace      }
154a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace   } else {
155a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace      for (i = 0; i < count; ++i) {
156a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         const GLfixed *in = (GLfixed *) ptr;
157a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         for (j = 0; j < size; ++j) {
158a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace            *fptr++ = in[j] / (GLfloat) (1 << 16);
159a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         }
160a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         ptr += input->StrideB;
161a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace      }
162a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace   }
163a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace}
164a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace
165c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell/* Adjust pointer to point at first requested element, convert to
166c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * floating point, populate VB->AttribPtr[].
167c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell */
168f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void _tnl_import_array( struct gl_context *ctx,
169c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			       GLuint attrib,
170893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell			       GLuint count,
171c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			       const struct gl_client_array *input,
172188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell			       const GLubyte *ptr )
173c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
174c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
175c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   struct vertex_buffer *VB = &tnl->vb;
176c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   GLuint stride = input->StrideB;
177c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
178c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   if (input->Type != GL_FLOAT) {
179c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      const GLuint sz = input->Size;
180188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      GLubyte *buf = get_space(ctx, count * sz * sizeof(GLfloat));
1817e9c3684ef45e0df8426317f28c883d16f27c031Keith Whitwell      GLfloat *fptr = (GLfloat *)buf;
182c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
183c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      switch (input->Type) {
184c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_BYTE:
185c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLbyte, BYTE_TO_FLOAT);
186c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
187c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_UNSIGNED_BYTE:
1880791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul         if (input->Format == GL_BGRA) {
1890791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul            /* See GL_EXT_vertex_array_bgra */
1900791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul            convert_bgra_to_float(input, ptr, fptr, count);
1910791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul         }
1920791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul         else {
1930791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul            CONVERT(GLubyte, UBYTE_TO_FLOAT);
1940791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul         }
195c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
196c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_SHORT:
197c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLshort, SHORT_TO_FLOAT);
198c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
199c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_UNSIGNED_SHORT:
200c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLushort, USHORT_TO_FLOAT);
201c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
202c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_INT:
203c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLint, INT_TO_FLOAT);
204c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
205c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_UNSIGNED_INT:
206c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLuint, UINT_TO_FLOAT);
207c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
208c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_DOUBLE:
209c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLdouble, (GLfloat));
210c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
211cfe884e2030466df673881da8e830c300dda40dbDave Airlie      case GL_HALF_FLOAT:
212cfe884e2030466df673881da8e830c300dda40dbDave Airlie	 convert_half_to_float(input, ptr, fptr, count, sz);
213cfe884e2030466df673881da8e830c300dda40dbDave Airlie	 break;
214a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace      case GL_FIXED:
215a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         convert_fixed_to_float(input, ptr, fptr, count);
216a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         break;
217c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      default:
218c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 assert(0);
219c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
220c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      }
221c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
2227e9c3684ef45e0df8426317f28c883d16f27c031Keith Whitwell      ptr = buf;
223c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      stride = sz * sizeof(GLfloat);
224c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
225c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
226c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib] = &tnl->tmp_inputs[attrib];
227c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->data = (GLfloat (*)[4])ptr;
228c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->start = (GLfloat *)ptr;
229c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->count = count;
230c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->stride = stride;
231c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->size = input->Size;
232c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
233c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   /* This should die, but so should the whole GLvector4f concept:
234c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell    */
235c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->flags = (((1<<input->Size)-1) |
236c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell				   VEC_NOT_WRITEABLE |
237c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell				   (stride == 4*sizeof(GLfloat) ? 0 : VEC_BAD_STRIDE));
238c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
239c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->storage = NULL;
240c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
241c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
2429827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell#define CLIPVERTS  ((6 + MAX_CLIP_PLANES) * 2)
2439827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
2449827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
245f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic GLboolean *_tnl_import_edgeflag( struct gl_context *ctx,
2469827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell					const GLvector4f *input,
2479827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell					GLuint count)
2489827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell{
2499827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   const GLubyte *ptr = (const GLubyte *)input->data;
2509827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   const GLuint stride = input->stride;
2519827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   GLboolean *space = (GLboolean *)get_space(ctx, count + CLIPVERTS);
2529827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   GLboolean *bptr = space;
2539827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   GLuint i;
2549827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
2559827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   for (i = 0; i < count; i++) {
2569827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      *bptr++ = ((GLfloat *)ptr)[0] == 1.0;
2579827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      ptr += stride;
2589827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   }
2599827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
2609827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   return space;
2619827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell}
2629827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
263c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
264f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void bind_inputs( struct gl_context *ctx,
265c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			 const struct gl_client_array *inputs[],
266893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell			 GLint count,
267c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			 struct gl_buffer_object **bo,
268c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			 GLuint *nr_bo )
269c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
270c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
271c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   struct vertex_buffer *VB = &tnl->vb;
272c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   GLuint i;
273c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
274c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   /* Map all the VBOs
275c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell    */
276c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
277c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      const void *ptr;
278c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
279c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      if (inputs[i]->BufferObj->Name) {
280c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 if (!inputs[i]->BufferObj->Pointer) {
281c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	    bo[*nr_bo] = inputs[i]->BufferObj;
2827e9c3684ef45e0df8426317f28c883d16f27c031Keith Whitwell	    (*nr_bo)++;
28328249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick	    ctx->Driver.MapBufferRange(ctx, 0, inputs[i]->BufferObj->Size,
28428249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick				       GL_MAP_READ_BIT,
28528249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick				       inputs[i]->BufferObj);
286c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
287c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	    assert(inputs[i]->BufferObj->Pointer);
288c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 }
289c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
290c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 ptr = ADD_POINTERS(inputs[i]->BufferObj->Pointer,
291c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			    inputs[i]->Ptr);
292c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      }
293c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      else
294c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 ptr = inputs[i]->Ptr;
295c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
296c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      /* Just make sure the array is floating point, otherwise convert to
297893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       * temporary storage.
298c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       *
299c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       * XXX: remove the GLvector4f type at some stage and just use
300c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       * client arrays.
301c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       */
302893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      _tnl_import_array(ctx, i, count, inputs[i], ptr);
303c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
304c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
3055464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   /* We process only the vertices between min & max index:
3065464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell    */
307893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   VB->Count = count;
3085464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
30937c79d4d765b10a79e0cf217cc1e70d3fbb7a0c5Eric Anholt   /* These should perhaps be part of _TNL_ATTRIB_* */
3100a9187801505130738ae947c69cafa8a1dd118d1Eric Anholt   VB->BackfaceColorPtr = NULL;
311fc9a2970dc539b21b035ea0a770ec69822962145Eric Anholt   VB->BackfaceIndexPtr = NULL;
3120a9187801505130738ae947c69cafa8a1dd118d1Eric Anholt   VB->BackfaceSecondaryColorPtr = NULL;
313c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
3149827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   /* Clipping and drawing code still requires this to be a packed
3159827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell    * array of ubytes which can be written into.  TODO: Fix and
3169827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell    * remove.
317c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell    */
318c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   if (ctx->Polygon.FrontMode != GL_FILL ||
319c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       ctx->Polygon.BackMode != GL_FILL)
320c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   {
3219827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      VB->EdgeFlag = _tnl_import_edgeflag( ctx,
3229827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell					   VB->AttribPtr[_TNL_ATTRIB_EDGEFLAG],
3239827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell					   VB->Count );
324c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
325d2d86a3f0b38716196ea2b3ffa4cbbd0420de1b3Brian   else {
326d2d86a3f0b38716196ea2b3ffa4cbbd0420de1b3Brian      /* the data previously pointed to by EdgeFlag may have been freed */
327d2d86a3f0b38716196ea2b3ffa4cbbd0420de1b3Brian      VB->EdgeFlag = NULL;
328d2d86a3f0b38716196ea2b3ffa4cbbd0420de1b3Brian   }
329c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
330c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
331c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
332c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell/* Translate indices to GLuints and store in VB->Elts.
333c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell */
334f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void bind_indices( struct gl_context *ctx,
3355464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell			  const struct _mesa_index_buffer *ib,
3365464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell			  struct gl_buffer_object **bo,
3375464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell			  GLuint *nr_bo)
338c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
339c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
340c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   struct vertex_buffer *VB = &tnl->vb;
341188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   GLuint i;
342188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   void *ptr;
343c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
344893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   if (!ib) {
345893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      VB->Elts = NULL;
346c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      return;
347893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   }
348c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
349c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   if (ib->obj->Name && !ib->obj->Pointer) {
350c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      bo[*nr_bo] = ib->obj;
3517e9c3684ef45e0df8426317f28c883d16f27c031Keith Whitwell      (*nr_bo)++;
35228249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick      ctx->Driver.MapBufferRange(ctx, 0, ib->obj->Size, GL_MAP_READ_BIT,
35328249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick				 ib->obj);
354c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
355c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      assert(ib->obj->Pointer);
356c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
357c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
358188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr);
359c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
36092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   if (ib->type == GL_UNSIGNED_INT && VB->Primitive[0].basevertex == 0) {
361188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      VB->Elts = (GLuint *) ptr;
362188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   }
363188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   else {
364188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      GLuint *elts = (GLuint *)get_space(ctx, ib->count * sizeof(GLuint));
365188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      VB->Elts = elts;
366188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell
36792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      if (ib->type == GL_UNSIGNED_INT) {
36892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 const GLuint *in = (GLuint *)ptr;
36992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 for (i = 0; i < ib->count; i++)
37092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
37192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      }
37292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      else if (ib->type == GL_UNSIGNED_SHORT) {
373893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell	 const GLushort *in = (GLushort *)ptr;
374188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell	 for (i = 0; i < ib->count; i++)
37592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
376188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      }
377893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      else {
378893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell	 const GLubyte *in = (GLubyte *)ptr;
379188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell	 for (i = 0; i < ib->count; i++)
38092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
381188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      }
382c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
383c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
384c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
385f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void bind_prims( struct gl_context *ctx,
3865464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell			const struct _mesa_prim *prim,
387893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell			GLuint nr_prims )
3885464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell{
3895464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
3905464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   struct vertex_buffer *VB = &tnl->vb;
3915464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
392893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   VB->Primitive = prim;
3935464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   VB->PrimitiveCount = nr_prims;
3945464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell}
3955464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
396f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void unmap_vbos( struct gl_context *ctx,
397c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			struct gl_buffer_object **bo,
398c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			GLuint nr_bo )
399c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
400c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   GLuint i;
401c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   for (i = 0; i < nr_bo; i++) {
40256f0c00f125ee75caeadc1c9e8cab8a488635e5eIan Romanick      ctx->Driver.UnmapBuffer(ctx, bo[i]);
403c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
404c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
405c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
406c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
407f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvoid _tnl_vbo_draw_prims(struct gl_context *ctx,
4082708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 const struct gl_client_array *arrays[],
4092708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 const struct _mesa_prim *prim,
4102708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 GLuint nr_prims,
4112708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 const struct _mesa_index_buffer *ib,
4122708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 GLboolean index_bounds_valid,
4132708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 GLuint min_index,
4142708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 GLuint max_index)
4152708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt{
4162708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   if (!index_bounds_valid)
4172708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt      vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
4182708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt
4192708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
4202708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt}
421c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
422c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell/* This is the main entrypoint into the slimmed-down software tnl
423c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * module.  In a regular swtnl driver, this can be plugged straight
424c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * into the vbo->Driver.DrawPrims() callback.
425c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell */
426f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvoid _tnl_draw_prims( struct gl_context *ctx,
427c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      const struct gl_client_array *arrays[],
428c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      const struct _mesa_prim *prim,
429c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      GLuint nr_prims,
430c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      const struct _mesa_index_buffer *ib,
431c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      GLuint min_index,
432c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      GLuint max_index)
433c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
434c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
435893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   const GLuint TEST_SPLIT = 0;
436893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   const GLint max = TEST_SPLIT ? 8 : tnl->vb.Size - MAX_CLIPPED_VERTICES;
43728bd4a1d81c200d7eff4545de946dd943d853b08Brian Paul   GLint max_basevertex = prim->basevertex;
43892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GLuint i;
43992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
4406fea2be7959620fe0a1b28c275a7d960005c8b09Brian Paul   /* Mesa core state should have been validated already */
4416fea2be7959620fe0a1b28c275a7d960005c8b09Brian Paul   assert(ctx->NewState == 0x0);
4426fea2be7959620fe0a1b28c275a7d960005c8b09Brian Paul
443699cfaeb3cde2a329b2d79ae09c7783ed4edacfeBrian Paul   if (!_mesa_check_conditional_render(ctx))
444699cfaeb3cde2a329b2d79ae09c7783ed4edacfeBrian Paul      return; /* don't draw */
445699cfaeb3cde2a329b2d79ae09c7783ed4edacfeBrian Paul
44692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   for (i = 1; i < nr_prims; i++)
44792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      max_basevertex = MAX2(max_basevertex, prim[i].basevertex);
4485464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
449893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   if (0)
45082152a2a8e1afeb61710318e769b1379be6c02c6keithw   {
451298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
45282152a2a8e1afeb61710318e769b1379be6c02c6keithw      for (i = 0; i < nr_prims; i++)
453298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	 printf("prim %d: %s start %d count %d\n", i,
454298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg		_mesa_lookup_enum_by_nr(prim[i].mode),
455298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg		prim[i].start,
456298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg		prim[i].count);
45782152a2a8e1afeb61710318e769b1379be6c02c6keithw   }
4585464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
459893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   if (min_index) {
460893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      /* We always translate away calls with min_index != 0.
461893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       */
462893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib,
463893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell			min_index, max_index,
4642708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			_tnl_vbo_draw_prims );
465893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      return;
466893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   }
467b30898f4ab533085d97a33638ad0a1cf9ddb1d67Karl Schultz   else if ((GLint)max_index + max_basevertex > max) {
468893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      /* The software TNL pipeline has a fixed amount of storage for
469893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       * vertices and it is necessary to split incoming drawing commands
470893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       * if they exceed that limit.
471893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       */
4725464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      struct split_limits limits;
473893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      limits.max_verts = max;
4745464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      limits.max_vb_size = ~0;
4755464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      limits.max_indices = ~0;
4765464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
4775464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      /* This will split the buffers one way or another and
4785464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell       * recursively call back into this function.
4795464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell       */
4805464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      vbo_split_prims( ctx, arrays, prim, nr_prims, ib,
48192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt		       0, max_index + prim->basevertex,
4822708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt		       _tnl_vbo_draw_prims,
4835464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell		       &limits );
4845464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   }
4855464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   else {
4865464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      /* May need to map a vertex buffer object for every attribute plus
4875464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell       * one for the index buffer.
4885464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell       */
4895464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1];
4905464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      GLuint nr_bo = 0;
491a63486ac680acc0bfb895037aca130a457caa01aBrian Paul      GLuint inst;
492c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
49392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      for (i = 0; i < nr_prims;) {
49492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 GLuint this_nr_prims;
49592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
49692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 /* Our SW TNL pipeline doesn't handle basevertex yet, so bind_indices
49792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  * will rebase the elements to the basevertex, and we'll only
49892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  * emit strings of prims with the same basevertex in one draw call.
49992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  */
50092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 for (this_nr_prims = 1; i + this_nr_prims < nr_prims;
50192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	      this_nr_prims++) {
50292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    if (prim[i].basevertex != prim[i + this_nr_prims].basevertex)
50392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	       break;
50492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 }
50592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
5066179f7e38e78eea6fb06180fca3c8b1e78d25f2bBrian Paul         assert(prim[i].num_instances > 0);
5076179f7e38e78eea6fb06180fca3c8b1e78d25f2bBrian Paul
50892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 /* Binding inputs may imply mapping some vertex buffer objects.
50992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  * They will need to be unmapped below.
51092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  */
511a63486ac680acc0bfb895037aca130a457caa01aBrian Paul         for (inst = 0; inst < prim[i].num_instances; inst++) {
512c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
513a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            bind_prims(ctx, &prim[i], this_nr_prims);
514a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            bind_inputs(ctx, arrays, max_index + prim[i].basevertex + 1,
515a63486ac680acc0bfb895037aca130a457caa01aBrian Paul                        bo, &nr_bo);
516a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            bind_indices(ctx, ib, bo, &nr_bo);
517c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
518a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            tnl->CurInstance = inst;
519a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);
520a63486ac680acc0bfb895037aca130a457caa01aBrian Paul
521a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            unmap_vbos(ctx, bo, nr_bo);
522a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            free_space(ctx);
523a63486ac680acc0bfb895037aca130a457caa01aBrian Paul         }
52492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
52592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 i += this_nr_prims;
52692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      }
5275464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   }
528c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
529c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
530