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"
29642bbc6f596722492470c4322a9c011e1705a951Brian Paul#include "main/bufferobj.h"
30699cfaeb3cde2a329b2d79ae09c7783ed4edacfeBrian Paul#include "main/condrender.h"
31bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/context.h"
32bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/imports.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 "tnl.h"
39c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
40c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
41c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
42f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic GLubyte *get_space(struct gl_context *ctx, GLuint bytes)
43c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
44c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
4532f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg   GLubyte *space = malloc(bytes);
46c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
47c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   tnl->block[tnl->nr_blocks++] = space;
48188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   return space;
49c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
50c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
51c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
52f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void free_space(struct gl_context *ctx)
53c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
54c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
55c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   GLuint i;
56c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   for (i = 0; i < tnl->nr_blocks; i++)
5732f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      free(tnl->block[i]);
58c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   tnl->nr_blocks = 0;
59c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
60c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
61c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
629827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell/* Convert the incoming array to GLfloats.  Understands the
639827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell * array->Normalized flag and selects the correct conversion method.
649827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell */
659827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell#define CONVERT( TYPE, MACRO ) do {		\
669827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   GLuint i, j;					\
679827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   if (input->Normalized) {			\
689827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      for (i = 0; i < count; i++) {		\
699827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 const TYPE *in = (TYPE *)ptr;		\
709827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 for (j = 0; j < sz; j++) {		\
719827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	    *fptr++ = MACRO(*in);		\
729827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	    in++;				\
739827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 }					\
749827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 ptr += input->StrideB;			\
759827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      }						\
769827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   } else {					\
779827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      for (i = 0; i < count; i++) {		\
789827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 const TYPE *in = (TYPE *)ptr;		\
799827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 for (j = 0; j < sz; j++) {		\
809827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	    *fptr++ = (GLfloat)(*in);		\
819827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	    in++;				\
829827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 }					\
839827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell	 ptr += input->StrideB;			\
849827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      }						\
859827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   }						\
869827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell} while (0)
879827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
889827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
890791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul/**
900791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul * Convert array of BGRA/GLubyte[4] values to RGBA/float[4]
910791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul * \param ptr  input/ubyte array
920791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul * \param fptr  output/float array
930791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul */
940791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paulstatic void
950791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paulconvert_bgra_to_float(const struct gl_client_array *input,
960791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul                      const GLubyte *ptr, GLfloat *fptr,
970791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul                      GLuint count )
980791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul{
990791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul   GLuint i;
1000791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul   assert(input->Normalized);
1010791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul   assert(input->Size == 4);
1020791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul   for (i = 0; i < count; i++) {
1030791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      const GLubyte *in = (GLubyte *) ptr;  /* in is in BGRA order */
1040791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      *fptr++ = UBYTE_TO_FLOAT(in[2]);  /* red */
1050791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      *fptr++ = UBYTE_TO_FLOAT(in[1]);  /* green */
1060791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      *fptr++ = UBYTE_TO_FLOAT(in[0]);  /* blue */
1070791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      *fptr++ = UBYTE_TO_FLOAT(in[3]);  /* alpha */
1080791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul      ptr += input->StrideB;
1090791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul   }
1100791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul}
1110791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul
112cfe884e2030466df673881da8e830c300dda40dbDave Airliestatic void
113cfe884e2030466df673881da8e830c300dda40dbDave Airlieconvert_half_to_float(const struct gl_client_array *input,
114cfe884e2030466df673881da8e830c300dda40dbDave Airlie		      const GLubyte *ptr, GLfloat *fptr,
115cfe884e2030466df673881da8e830c300dda40dbDave Airlie		      GLuint count, GLuint sz)
116cfe884e2030466df673881da8e830c300dda40dbDave Airlie{
117cfe884e2030466df673881da8e830c300dda40dbDave Airlie   GLuint i, j;
118cfe884e2030466df673881da8e830c300dda40dbDave Airlie
119cfe884e2030466df673881da8e830c300dda40dbDave Airlie   for (i = 0; i < count; i++) {
120cfe884e2030466df673881da8e830c300dda40dbDave Airlie      GLhalfARB *in = (GLhalfARB *)ptr;
121cfe884e2030466df673881da8e830c300dda40dbDave Airlie
122cfe884e2030466df673881da8e830c300dda40dbDave Airlie      for (j = 0; j < sz; j++) {
123cfe884e2030466df673881da8e830c300dda40dbDave Airlie	 *fptr++ = _mesa_half_to_float(in[j]);
124cfe884e2030466df673881da8e830c300dda40dbDave Airlie      }
125cfe884e2030466df673881da8e830c300dda40dbDave Airlie      ptr += input->StrideB;
126cfe884e2030466df673881da8e830c300dda40dbDave Airlie   }
127cfe884e2030466df673881da8e830c300dda40dbDave Airlie}
1289827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
129a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace/**
130a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace * \brief Convert fixed-point to floating-point.
131a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace *
132a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace * In OpenGL, a fixed-point number is a "signed 2's complement 16.16 scaled
133a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace * integer" (Table 2.2 of the OpenGL ES 2.0 spec).
134a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace *
135a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace * If the buffer has the \c normalized flag set, the formula
136a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace *     \code normalize(x) := (2*x + 1) / (2^16 - 1) \endcode
137a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace * is used to map the fixed-point numbers into the range [-1, 1].
138a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace */
139a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versacestatic void
140a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versaceconvert_fixed_to_float(const struct gl_client_array *input,
141a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace                       const GLubyte *ptr, GLfloat *fptr,
142a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace                       GLuint count)
143a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace{
144a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace   GLuint i, j;
145a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace   const GLint size = input->Size;
146a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace
147a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace   if (input->Normalized) {
148a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace      for (i = 0; i < count; ++i) {
149a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         const GLfixed *in = (GLfixed *) ptr;
150a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         for (j = 0; j < size; ++j) {
151a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace            *fptr++ = (GLfloat) (2 * in[j] + 1) / (GLfloat) ((1 << 16) - 1);
152a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         }
153a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         ptr += input->StrideB;
154a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace      }
155a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace   } else {
156a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace      for (i = 0; i < count; ++i) {
157a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         const GLfixed *in = (GLfixed *) ptr;
158a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         for (j = 0; j < size; ++j) {
159a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace            *fptr++ = in[j] / (GLfloat) (1 << 16);
160a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         }
161a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         ptr += input->StrideB;
162a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace      }
163a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace   }
164a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace}
165a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace
166c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell/* Adjust pointer to point at first requested element, convert to
167c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * floating point, populate VB->AttribPtr[].
168c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell */
169f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void _tnl_import_array( struct gl_context *ctx,
170c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			       GLuint attrib,
171893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell			       GLuint count,
172c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			       const struct gl_client_array *input,
173188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell			       const GLubyte *ptr )
174c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
175c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
176c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   struct vertex_buffer *VB = &tnl->vb;
177c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   GLuint stride = input->StrideB;
178c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
179c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   if (input->Type != GL_FLOAT) {
180c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      const GLuint sz = input->Size;
181188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      GLubyte *buf = get_space(ctx, count * sz * sizeof(GLfloat));
1827e9c3684ef45e0df8426317f28c883d16f27c031Keith Whitwell      GLfloat *fptr = (GLfloat *)buf;
183c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
184c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      switch (input->Type) {
185c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_BYTE:
186c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLbyte, BYTE_TO_FLOAT);
187c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
188c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_UNSIGNED_BYTE:
1890791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul         if (input->Format == GL_BGRA) {
1900791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul            /* See GL_EXT_vertex_array_bgra */
1910791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul            convert_bgra_to_float(input, ptr, fptr, count);
1920791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul         }
1930791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul         else {
1940791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul            CONVERT(GLubyte, UBYTE_TO_FLOAT);
1950791fdff6fe87cf9a29ddf4a716f1881c367c7deBrian Paul         }
196c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
197c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_SHORT:
198c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLshort, SHORT_TO_FLOAT);
199c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
200c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_UNSIGNED_SHORT:
201c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLushort, USHORT_TO_FLOAT);
202c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
203c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_INT:
204c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLint, INT_TO_FLOAT);
205c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
206c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_UNSIGNED_INT:
207c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLuint, UINT_TO_FLOAT);
208c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
209c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      case GL_DOUBLE:
210c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 CONVERT(GLdouble, (GLfloat));
211c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
212cfe884e2030466df673881da8e830c300dda40dbDave Airlie      case GL_HALF_FLOAT:
213cfe884e2030466df673881da8e830c300dda40dbDave Airlie	 convert_half_to_float(input, ptr, fptr, count, sz);
214cfe884e2030466df673881da8e830c300dda40dbDave Airlie	 break;
215a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace      case GL_FIXED:
216a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         convert_fixed_to_float(input, ptr, fptr, count);
217a231ac23f41a38cf9bde80bab4cb6aa8821d4895Chad Versace         break;
218c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      default:
219c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 assert(0);
220c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 break;
221c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      }
222c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
2237e9c3684ef45e0df8426317f28c883d16f27c031Keith Whitwell      ptr = buf;
224c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      stride = sz * sizeof(GLfloat);
225c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
226c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
227c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib] = &tnl->tmp_inputs[attrib];
228c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->data = (GLfloat (*)[4])ptr;
229c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->start = (GLfloat *)ptr;
230c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->count = count;
231c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->stride = stride;
232c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->size = input->Size;
233c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
234c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   /* This should die, but so should the whole GLvector4f concept:
235c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell    */
236c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->flags = (((1<<input->Size)-1) |
237c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell				   VEC_NOT_WRITEABLE |
238c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell				   (stride == 4*sizeof(GLfloat) ? 0 : VEC_BAD_STRIDE));
239c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
240c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   VB->AttribPtr[attrib]->storage = NULL;
241c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
242c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
2439827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell#define CLIPVERTS  ((6 + MAX_CLIP_PLANES) * 2)
2449827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
2459827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
246f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic GLboolean *_tnl_import_edgeflag( struct gl_context *ctx,
2479827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell					const GLvector4f *input,
2489827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell					GLuint count)
2499827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell{
2509827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   const GLubyte *ptr = (const GLubyte *)input->data;
2519827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   const GLuint stride = input->stride;
2529827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   GLboolean *space = (GLboolean *)get_space(ctx, count + CLIPVERTS);
2539827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   GLboolean *bptr = space;
2549827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   GLuint i;
2559827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
2569827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   for (i = 0; i < count; i++) {
2579827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      *bptr++ = ((GLfloat *)ptr)[0] == 1.0;
2589827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      ptr += stride;
2599827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   }
2609827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
2619827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   return space;
2629827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell}
2639827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell
264c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
265f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void bind_inputs( struct gl_context *ctx,
266c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			 const struct gl_client_array *inputs[],
267893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell			 GLint count,
268c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			 struct gl_buffer_object **bo,
269c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			 GLuint *nr_bo )
270c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
271c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
272c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   struct vertex_buffer *VB = &tnl->vb;
273c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   GLuint i;
274c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
275c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   /* Map all the VBOs
276c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell    */
277c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
278c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      const void *ptr;
279c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
280c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      if (inputs[i]->BufferObj->Name) {
281c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 if (!inputs[i]->BufferObj->Pointer) {
282c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	    bo[*nr_bo] = inputs[i]->BufferObj;
2837e9c3684ef45e0df8426317f28c883d16f27c031Keith Whitwell	    (*nr_bo)++;
28428249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick	    ctx->Driver.MapBufferRange(ctx, 0, inputs[i]->BufferObj->Size,
28528249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick				       GL_MAP_READ_BIT,
28628249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick				       inputs[i]->BufferObj);
287c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
288c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	    assert(inputs[i]->BufferObj->Pointer);
289c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 }
290c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
291c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 ptr = ADD_POINTERS(inputs[i]->BufferObj->Pointer,
292c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			    inputs[i]->Ptr);
293c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      }
294c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      else
295c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell	 ptr = inputs[i]->Ptr;
296c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
297c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      /* Just make sure the array is floating point, otherwise convert to
298893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       * temporary storage.
299c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       *
300c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       * XXX: remove the GLvector4f type at some stage and just use
301c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       * client arrays.
302c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       */
303893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      _tnl_import_array(ctx, i, count, inputs[i], ptr);
304c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
305c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
3065464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   /* We process only the vertices between min & max index:
3075464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell    */
308893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   VB->Count = count;
3095464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
31037c79d4d765b10a79e0cf217cc1e70d3fbb7a0c5Eric Anholt   /* These should perhaps be part of _TNL_ATTRIB_* */
3110a9187801505130738ae947c69cafa8a1dd118d1Eric Anholt   VB->BackfaceColorPtr = NULL;
312fc9a2970dc539b21b035ea0a770ec69822962145Eric Anholt   VB->BackfaceIndexPtr = NULL;
3130a9187801505130738ae947c69cafa8a1dd118d1Eric Anholt   VB->BackfaceSecondaryColorPtr = NULL;
314c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
3159827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell   /* Clipping and drawing code still requires this to be a packed
3169827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell    * array of ubytes which can be written into.  TODO: Fix and
3179827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell    * remove.
318c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell    */
319c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   if (ctx->Polygon.FrontMode != GL_FILL ||
320c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell       ctx->Polygon.BackMode != GL_FILL)
321c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   {
3229827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell      VB->EdgeFlag = _tnl_import_edgeflag( ctx,
3239827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell					   VB->AttribPtr[_TNL_ATTRIB_EDGEFLAG],
3249827dc8bea422b940f1efcfbd1c0d76f8bbca844Keith Whitwell					   VB->Count );
325c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
326d2d86a3f0b38716196ea2b3ffa4cbbd0420de1b3Brian   else {
327d2d86a3f0b38716196ea2b3ffa4cbbd0420de1b3Brian      /* the data previously pointed to by EdgeFlag may have been freed */
328d2d86a3f0b38716196ea2b3ffa4cbbd0420de1b3Brian      VB->EdgeFlag = NULL;
329d2d86a3f0b38716196ea2b3ffa4cbbd0420de1b3Brian   }
330c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
331c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
332c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
333c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell/* Translate indices to GLuints and store in VB->Elts.
334c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell */
335f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void bind_indices( struct gl_context *ctx,
3365464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell			  const struct _mesa_index_buffer *ib,
3375464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell			  struct gl_buffer_object **bo,
3385464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell			  GLuint *nr_bo)
339c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
340c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
341c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   struct vertex_buffer *VB = &tnl->vb;
342188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   GLuint i;
343788d9bf12174ce59584f4ed768a24a9626f5d9b7Brian Paul   const void *ptr;
344c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
345893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   if (!ib) {
346893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      VB->Elts = NULL;
347c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      return;
348893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   }
349c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
350642bbc6f596722492470c4322a9c011e1705a951Brian Paul   if (_mesa_is_bufferobj(ib->obj) && !_mesa_bufferobj_mapped(ib->obj)) {
351642bbc6f596722492470c4322a9c011e1705a951Brian Paul      /* if the buffer object isn't mapped yet, map it now */
352c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      bo[*nr_bo] = ib->obj;
3537e9c3684ef45e0df8426317f28c883d16f27c031Keith Whitwell      (*nr_bo)++;
354efa1fac2158c9146b87f0d4340a864661721de21Yuanhan Liu      ptr = ctx->Driver.MapBufferRange(ctx, (GLsizeiptr) ib->ptr,
355efa1fac2158c9146b87f0d4340a864661721de21Yuanhan Liu                                       ib->count * vbo_sizeof_ib_type(ib->type),
3562ea1ff38164d95f8291ef2e5dfe2cb13936a60f2Ian Romanick				       GL_MAP_READ_BIT, ib->obj);
357c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell      assert(ib->obj->Pointer);
3582ea1ff38164d95f8291ef2e5dfe2cb13936a60f2Ian Romanick   } else {
3595d9e242c3e28046e9c8ae1760533f92841d0cfafBrian Paul      /* user-space elements, or buffer already mapped */
3605d9e242c3e28046e9c8ae1760533f92841d0cfafBrian Paul      ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr);
361c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
362c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
36392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   if (ib->type == GL_UNSIGNED_INT && VB->Primitive[0].basevertex == 0) {
364188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      VB->Elts = (GLuint *) ptr;
365188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   }
366188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell   else {
367188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      GLuint *elts = (GLuint *)get_space(ctx, ib->count * sizeof(GLuint));
368188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      VB->Elts = elts;
369188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell
37092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      if (ib->type == GL_UNSIGNED_INT) {
37192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 const GLuint *in = (GLuint *)ptr;
37292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 for (i = 0; i < ib->count; i++)
37392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
37492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      }
37592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      else if (ib->type == GL_UNSIGNED_SHORT) {
376893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell	 const GLushort *in = (GLushort *)ptr;
377188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell	 for (i = 0; i < ib->count; i++)
37892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
379188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      }
380893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      else {
381893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell	 const GLubyte *in = (GLubyte *)ptr;
382188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell	 for (i = 0; i < ib->count; i++)
38392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
384188a4db49c4c22429bfa7ae87d4b1a0c35bf0285Keith Whitwell      }
385c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
386c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
387c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
388f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void bind_prims( struct gl_context *ctx,
3895464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell			const struct _mesa_prim *prim,
390893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell			GLuint nr_prims )
3915464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell{
3925464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
3935464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   struct vertex_buffer *VB = &tnl->vb;
3945464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
395893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   VB->Primitive = prim;
3965464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   VB->PrimitiveCount = nr_prims;
3975464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell}
3985464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
399f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void unmap_vbos( struct gl_context *ctx,
400c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			struct gl_buffer_object **bo,
401c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell			GLuint nr_bo )
402c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
403c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   GLuint i;
404c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   for (i = 0; i < nr_bo; i++) {
40556f0c00f125ee75caeadc1c9e8cab8a488635e5eIan Romanick      ctx->Driver.UnmapBuffer(ctx, bo[i]);
406c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   }
407c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
408c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
409c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
410f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvoid _tnl_vbo_draw_prims(struct gl_context *ctx,
4112708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 const struct _mesa_prim *prim,
4122708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 GLuint nr_prims,
4132708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 const struct _mesa_index_buffer *ib,
4142708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 GLboolean index_bounds_valid,
4152708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			 GLuint min_index,
41614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák			 GLuint max_index,
41714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák			 struct gl_transform_feedback_object *tfb_vertcount)
4182708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt{
41950f7e75f9e945cfbb2ae868cc961a2205a0b6e73Marek Olšák   const struct gl_client_array **arrays = ctx->Array._DrawArrays;
42050f7e75f9e945cfbb2ae868cc961a2205a0b6e73Marek Olšák
4212708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   if (!index_bounds_valid)
42242d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu      vbo_get_minmax_indices(ctx, prim, ib, &min_index, &max_index, nr_prims);
4232708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt
4242708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
4252708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt}
426c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
427c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell/* This is the main entrypoint into the slimmed-down software tnl
428c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * module.  In a regular swtnl driver, this can be plugged straight
429c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell * into the vbo->Driver.DrawPrims() callback.
430c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell */
431f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvoid _tnl_draw_prims( struct gl_context *ctx,
432c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      const struct gl_client_array *arrays[],
433c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      const struct _mesa_prim *prim,
434c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      GLuint nr_prims,
435c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      const struct _mesa_index_buffer *ib,
436c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      GLuint min_index,
437c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell		      GLuint max_index)
438c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell{
439c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
440893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   const GLuint TEST_SPLIT = 0;
441893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   const GLint max = TEST_SPLIT ? 8 : tnl->vb.Size - MAX_CLIPPED_VERTICES;
44228bd4a1d81c200d7eff4545de946dd943d853b08Brian Paul   GLint max_basevertex = prim->basevertex;
44392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GLuint i;
44492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
4456fea2be7959620fe0a1b28c275a7d960005c8b09Brian Paul   /* Mesa core state should have been validated already */
4466fea2be7959620fe0a1b28c275a7d960005c8b09Brian Paul   assert(ctx->NewState == 0x0);
4476fea2be7959620fe0a1b28c275a7d960005c8b09Brian Paul
448699cfaeb3cde2a329b2d79ae09c7783ed4edacfeBrian Paul   if (!_mesa_check_conditional_render(ctx))
449699cfaeb3cde2a329b2d79ae09c7783ed4edacfeBrian Paul      return; /* don't draw */
450699cfaeb3cde2a329b2d79ae09c7783ed4edacfeBrian Paul
45192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   for (i = 1; i < nr_prims; i++)
45292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      max_basevertex = MAX2(max_basevertex, prim[i].basevertex);
4535464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
454893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   if (0)
45582152a2a8e1afeb61710318e769b1379be6c02c6keithw   {
456298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
45782152a2a8e1afeb61710318e769b1379be6c02c6keithw      for (i = 0; i < nr_prims; i++)
458298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	 printf("prim %d: %s start %d count %d\n", i,
459298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg		_mesa_lookup_enum_by_nr(prim[i].mode),
460298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg		prim[i].start,
461298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg		prim[i].count);
46282152a2a8e1afeb61710318e769b1379be6c02c6keithw   }
4635464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
464893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   if (min_index) {
465893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      /* We always translate away calls with min_index != 0.
466893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       */
467893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib,
468893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell			min_index, max_index,
4692708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			_tnl_vbo_draw_prims );
470893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      return;
471893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   }
472b30898f4ab533085d97a33638ad0a1cf9ddb1d67Karl Schultz   else if ((GLint)max_index + max_basevertex > max) {
473893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      /* The software TNL pipeline has a fixed amount of storage for
474893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       * vertices and it is necessary to split incoming drawing commands
475893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       * if they exceed that limit.
476893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell       */
4775464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      struct split_limits limits;
478893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      limits.max_verts = max;
4795464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      limits.max_vb_size = ~0;
4805464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      limits.max_indices = ~0;
4815464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell
4825464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      /* This will split the buffers one way or another and
4835464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell       * recursively call back into this function.
4845464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell       */
4855464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      vbo_split_prims( ctx, arrays, prim, nr_prims, ib,
48692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt		       0, max_index + prim->basevertex,
4872708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt		       _tnl_vbo_draw_prims,
4885464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell		       &limits );
4895464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   }
4905464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   else {
4915464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      /* May need to map a vertex buffer object for every attribute plus
4925464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell       * one for the index buffer.
4935464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell       */
4945464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1];
4955464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell      GLuint nr_bo = 0;
496a63486ac680acc0bfb895037aca130a457caa01aBrian Paul      GLuint inst;
497c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
49892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      for (i = 0; i < nr_prims;) {
49992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 GLuint this_nr_prims;
50092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
50192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 /* Our SW TNL pipeline doesn't handle basevertex yet, so bind_indices
50292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  * will rebase the elements to the basevertex, and we'll only
50392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  * emit strings of prims with the same basevertex in one draw call.
50492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  */
50592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 for (this_nr_prims = 1; i + this_nr_prims < nr_prims;
50692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	      this_nr_prims++) {
50792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    if (prim[i].basevertex != prim[i + this_nr_prims].basevertex)
50892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	       break;
50992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 }
51092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
5116179f7e38e78eea6fb06180fca3c8b1e78d25f2bBrian Paul         assert(prim[i].num_instances > 0);
5126179f7e38e78eea6fb06180fca3c8b1e78d25f2bBrian Paul
51392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 /* Binding inputs may imply mapping some vertex buffer objects.
51492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  * They will need to be unmapped below.
51592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	  */
516a63486ac680acc0bfb895037aca130a457caa01aBrian Paul         for (inst = 0; inst < prim[i].num_instances; inst++) {
517c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
518a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            bind_prims(ctx, &prim[i], this_nr_prims);
519a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            bind_inputs(ctx, arrays, max_index + prim[i].basevertex + 1,
520a63486ac680acc0bfb895037aca130a457caa01aBrian Paul                        bo, &nr_bo);
521a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            bind_indices(ctx, ib, bo, &nr_bo);
522c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
523a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            tnl->CurInstance = inst;
524a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);
525a63486ac680acc0bfb895037aca130a457caa01aBrian Paul
526a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            unmap_vbos(ctx, bo, nr_bo);
527a63486ac680acc0bfb895037aca130a457caa01aBrian Paul            free_space(ctx);
528a63486ac680acc0bfb895037aca130a457caa01aBrian Paul         }
52992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
53092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 i += this_nr_prims;
53192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      }
5325464cd0a60f474753abc6af047fd21b0e29b8ac4Keith Whitwell   }
533c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell}
534c22f8a7787bd5260135a20a0c2ae8b743228497bKeith Whitwell
535