1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version:  7.1
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software.
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Authors:
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    Keith Whitwell <keith@tungstengraphics.com>
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/glheader.h"
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/bufferobj.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/condrender.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/context.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/imports.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/mtypes.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/macros.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/enums.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "t_context.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tnl.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLubyte *get_space(struct gl_context *ctx, GLuint bytes)
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TNLcontext *tnl = TNL_CONTEXT(ctx);
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLubyte *space = malloc(bytes);
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tnl->block[tnl->nr_blocks++] = space;
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return space;
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void free_space(struct gl_context *ctx)
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TNLcontext *tnl = TNL_CONTEXT(ctx);
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < tnl->nr_blocks; i++)
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      free(tnl->block[i]);
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tnl->nr_blocks = 0;
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Convert the incoming array to GLfloats.  Understands the
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * array->Normalized flag and selects the correct conversion method.
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define CONVERT( TYPE, MACRO ) do {		\
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i, j;					\
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (input->Normalized) {			\
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < count; i++) {		\
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const TYPE *in = (TYPE *)ptr;		\
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 for (j = 0; j < sz; j++) {		\
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    *fptr++ = MACRO(*in);		\
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    in++;				\
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }					\
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ptr += input->StrideB;			\
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }						\
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {					\
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < count; i++) {		\
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const TYPE *in = (TYPE *)ptr;		\
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 for (j = 0; j < sz; j++) {		\
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    *fptr++ = (GLfloat)(*in);		\
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    in++;				\
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }					\
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ptr += input->StrideB;			\
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }						\
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }						\
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} while (0)
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convert array of BGRA/GLubyte[4] values to RGBA/float[4]
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param ptr  input/ubyte array
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param fptr  output/float array
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconvert_bgra_to_float(const struct gl_client_array *input,
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      const GLubyte *ptr, GLfloat *fptr,
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      GLuint count )
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(input->Normalized);
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(input->Size == 4);
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < count; i++) {
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLubyte *in = (GLubyte *) ptr;  /* in is in BGRA order */
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *fptr++ = UBYTE_TO_FLOAT(in[2]);  /* red */
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *fptr++ = UBYTE_TO_FLOAT(in[1]);  /* green */
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *fptr++ = UBYTE_TO_FLOAT(in[0]);  /* blue */
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *fptr++ = UBYTE_TO_FLOAT(in[3]);  /* alpha */
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ptr += input->StrideB;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconvert_half_to_float(const struct gl_client_array *input,
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const GLubyte *ptr, GLfloat *fptr,
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      GLuint count, GLuint sz)
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i, j;
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < count; i++) {
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLhalfARB *in = (GLhalfARB *)ptr;
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (j = 0; j < sz; j++) {
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 *fptr++ = _mesa_half_to_float(in[j]);
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ptr += input->StrideB;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \brief Convert fixed-point to floating-point.
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In OpenGL, a fixed-point number is a "signed 2's complement 16.16 scaled
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * integer" (Table 2.2 of the OpenGL ES 2.0 spec).
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If the buffer has the \c normalized flag set, the formula
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *     \code normalize(x) := (2*x + 1) / (2^16 - 1) \endcode
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is used to map the fixed-point numbers into the range [-1, 1].
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconvert_fixed_to_float(const struct gl_client_array *input,
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const GLubyte *ptr, GLfloat *fptr,
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       GLuint count)
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i, j;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint size = input->Size;
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (input->Normalized) {
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < count; ++i) {
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfixed *in = (GLfixed *) ptr;
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (j = 0; j < size; ++j) {
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            *fptr++ = (GLfloat) (2 * in[j] + 1) / (GLfloat) ((1 << 16) - 1);
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ptr += input->StrideB;
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < count; ++i) {
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         const GLfixed *in = (GLfixed *) ptr;
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (j = 0; j < size; ++j) {
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            *fptr++ = in[j] / (GLfloat) (1 << 16);
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ptr += input->StrideB;
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Adjust pointer to point at first requested element, convert to
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * floating point, populate VB->AttribPtr[].
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void _tnl_import_array( struct gl_context *ctx,
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       GLuint attrib,
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       GLuint count,
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       const struct gl_client_array *input,
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			       const GLubyte *ptr )
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TNLcontext *tnl = TNL_CONTEXT(ctx);
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vertex_buffer *VB = &tnl->vb;
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint stride = input->StrideB;
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (input->Type != GL_FLOAT) {
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLuint sz = input->Size;
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLubyte *buf = get_space(ctx, count * sz * sizeof(GLfloat));
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat *fptr = (GLfloat *)buf;
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (input->Type) {
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_BYTE:
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 CONVERT(GLbyte, BYTE_TO_FLOAT);
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_UNSIGNED_BYTE:
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (input->Format == GL_BGRA) {
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* See GL_EXT_vertex_array_bgra */
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            convert_bgra_to_float(input, ptr, fptr, count);
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            CONVERT(GLubyte, UBYTE_TO_FLOAT);
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_SHORT:
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 CONVERT(GLshort, SHORT_TO_FLOAT);
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_UNSIGNED_SHORT:
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 CONVERT(GLushort, USHORT_TO_FLOAT);
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_INT:
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 CONVERT(GLint, INT_TO_FLOAT);
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_UNSIGNED_INT:
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 CONVERT(GLuint, UINT_TO_FLOAT);
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_DOUBLE:
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 CONVERT(GLdouble, (GLfloat));
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_HALF_FLOAT:
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 convert_half_to_float(input, ptr, fptr, count, sz);
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case GL_FIXED:
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         convert_fixed_to_float(input, ptr, fptr, count);
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(0);
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ptr = buf;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      stride = sz * sizeof(GLfloat);
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VB->AttribPtr[attrib] = &tnl->tmp_inputs[attrib];
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VB->AttribPtr[attrib]->data = (GLfloat (*)[4])ptr;
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VB->AttribPtr[attrib]->start = (GLfloat *)ptr;
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VB->AttribPtr[attrib]->count = count;
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VB->AttribPtr[attrib]->stride = stride;
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VB->AttribPtr[attrib]->size = input->Size;
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* This should die, but so should the whole GLvector4f concept:
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VB->AttribPtr[attrib]->flags = (((1<<input->Size)-1) |
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				   VEC_NOT_WRITEABLE |
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				   (stride == 4*sizeof(GLfloat) ? 0 : VEC_BAD_STRIDE));
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VB->AttribPtr[attrib]->storage = NULL;
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define CLIPVERTS  ((6 + MAX_CLIP_PLANES) * 2)
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean *_tnl_import_edgeflag( struct gl_context *ctx,
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					const GLvector4f *input,
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					GLuint count)
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLubyte *ptr = (const GLubyte *)input->data;
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint stride = input->stride;
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLboolean *space = (GLboolean *)get_space(ctx, count + CLIPVERTS);
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLboolean *bptr = space;
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < count; i++) {
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *bptr++ = ((GLfloat *)ptr)[0] == 1.0;
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ptr += stride;
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return space;
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void bind_inputs( struct gl_context *ctx,
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 const struct gl_client_array *inputs[],
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 GLint count,
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 struct gl_buffer_object **bo,
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 GLuint *nr_bo )
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TNLcontext *tnl = TNL_CONTEXT(ctx);
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vertex_buffer *VB = &tnl->vb;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Map all the VBOs
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const void *ptr;
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (inputs[i]->BufferObj->Name) {
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (!inputs[i]->BufferObj->Pointer) {
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    bo[*nr_bo] = inputs[i]->BufferObj;
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    (*nr_bo)++;
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ctx->Driver.MapBufferRange(ctx, 0, inputs[i]->BufferObj->Size,
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       GL_MAP_READ_BIT,
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       inputs[i]->BufferObj);
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(inputs[i]->BufferObj->Pointer);
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ptr = ADD_POINTERS(inputs[i]->BufferObj->Pointer,
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			    inputs[i]->Ptr);
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ptr = inputs[i]->Ptr;
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Just make sure the array is floating point, otherwise convert to
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * temporary storage.
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * XXX: remove the GLvector4f type at some stage and just use
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * client arrays.
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _tnl_import_array(ctx, i, count, inputs[i], ptr);
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* We process only the vertices between min & max index:
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VB->Count = count;
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* These should perhaps be part of _TNL_ATTRIB_* */
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VB->BackfaceColorPtr = NULL;
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VB->BackfaceIndexPtr = NULL;
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VB->BackfaceSecondaryColorPtr = NULL;
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Clipping and drawing code still requires this to be a packed
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * array of ubytes which can be written into.  TODO: Fix and
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * remove.
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->Polygon.FrontMode != GL_FILL ||
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       ctx->Polygon.BackMode != GL_FILL)
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      VB->EdgeFlag = _tnl_import_edgeflag( ctx,
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   VB->AttribPtr[_TNL_ATTRIB_EDGEFLAG],
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   VB->Count );
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* the data previously pointed to by EdgeFlag may have been freed */
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      VB->EdgeFlag = NULL;
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Translate indices to GLuints and store in VB->Elts.
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void bind_indices( struct gl_context *ctx,
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  const struct _mesa_index_buffer *ib,
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  struct gl_buffer_object **bo,
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  GLuint *nr_bo)
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TNLcontext *tnl = TNL_CONTEXT(ctx);
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vertex_buffer *VB = &tnl->vb;
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const void *ptr;
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!ib) {
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      VB->Elts = NULL;
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (_mesa_is_bufferobj(ib->obj) && !_mesa_bufferobj_mapped(ib->obj)) {
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* if the buffer object isn't mapped yet, map it now */
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bo[*nr_bo] = ib->obj;
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (*nr_bo)++;
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ptr = ctx->Driver.MapBufferRange(ctx, (GLsizeiptr) ib->ptr,
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       ib->count * vbo_sizeof_ib_type(ib->type),
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       GL_MAP_READ_BIT, ib->obj);
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ib->obj->Pointer);
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* user-space elements, or buffer already mapped */
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr);
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ib->type == GL_UNSIGNED_INT && VB->Primitive[0].basevertex == 0) {
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      VB->Elts = (GLuint *) ptr;
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint *elts = (GLuint *)get_space(ctx, ib->count * sizeof(GLuint));
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      VB->Elts = elts;
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ib->type == GL_UNSIGNED_INT) {
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const GLuint *in = (GLuint *)ptr;
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 for (i = 0; i < ib->count; i++)
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (ib->type == GL_UNSIGNED_SHORT) {
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const GLushort *in = (GLushort *)ptr;
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 for (i = 0; i < ib->count; i++)
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const GLubyte *in = (GLubyte *)ptr;
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 for (i = 0; i < ib->count; i++)
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void bind_prims( struct gl_context *ctx,
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			const struct _mesa_prim *prim,
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			GLuint nr_prims )
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TNLcontext *tnl = TNL_CONTEXT(ctx);
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vertex_buffer *VB = &tnl->vb;
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VB->Primitive = prim;
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   VB->PrimitiveCount = nr_prims;
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void unmap_vbos( struct gl_context *ctx,
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			struct gl_buffer_object **bo,
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			GLuint nr_bo )
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < nr_bo; i++) {
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx->Driver.UnmapBuffer(ctx, bo[i]);
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid _tnl_vbo_draw_prims(struct gl_context *ctx,
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 const struct _mesa_prim *prim,
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 GLuint nr_prims,
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 const struct _mesa_index_buffer *ib,
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 GLboolean index_bounds_valid,
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 GLuint min_index,
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 GLuint max_index,
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 struct gl_transform_feedback_object *tfb_vertcount)
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct gl_client_array **arrays = ctx->Array._DrawArrays;
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!index_bounds_valid)
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      vbo_get_minmax_indices(ctx, prim, ib, &min_index, &max_index, nr_prims);
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* This is the main entrypoint into the slimmed-down software tnl
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * module.  In a regular swtnl driver, this can be plugged straight
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * into the vbo->Driver.DrawPrims() callback.
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid _tnl_draw_prims( struct gl_context *ctx,
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct gl_client_array *arrays[],
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct _mesa_prim *prim,
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      GLuint nr_prims,
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      const struct _mesa_index_buffer *ib,
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      GLuint min_index,
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      GLuint max_index)
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   TNLcontext *tnl = TNL_CONTEXT(ctx);
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint TEST_SPLIT = 0;
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLint max = TEST_SPLIT ? 8 : tnl->vb.Size - MAX_CLIPPED_VERTICES;
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint max_basevertex = prim->basevertex;
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Mesa core state should have been validated already */
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(ctx->NewState == 0x0);
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!_mesa_check_conditional_render(ctx))
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return; /* don't draw */
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 1; i < nr_prims; i++)
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      max_basevertex = MAX2(max_basevertex, prim[i].basevertex);
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (0)
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < nr_prims; i++)
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 printf("prim %d: %s start %d count %d\n", i,
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		_mesa_lookup_enum_by_nr(prim[i].mode),
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		prim[i].start,
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		prim[i].count);
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (min_index) {
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* We always translate away calls with min_index != 0.
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib,
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			min_index, max_index,
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			_tnl_vbo_draw_prims );
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if ((GLint)max_index + max_basevertex > max) {
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* The software TNL pipeline has a fixed amount of storage for
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * vertices and it is necessary to split incoming drawing commands
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * if they exceed that limit.
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct split_limits limits;
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      limits.max_verts = max;
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      limits.max_vb_size = ~0;
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      limits.max_indices = ~0;
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* This will split the buffers one way or another and
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * recursively call back into this function.
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      vbo_split_prims( ctx, arrays, prim, nr_prims, ib,
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       0, max_index + prim->basevertex,
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       _tnl_vbo_draw_prims,
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       &limits );
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* May need to map a vertex buffer object for every attribute plus
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * one for the index buffer.
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1];
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint nr_bo = 0;
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLuint inst;
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < nr_prims;) {
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 GLuint this_nr_prims;
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Our SW TNL pipeline doesn't handle basevertex yet, so bind_indices
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * will rebase the elements to the basevertex, and we'll only
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * emit strings of prims with the same basevertex in one draw call.
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 for (this_nr_prims = 1; i + this_nr_prims < nr_prims;
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      this_nr_prims++) {
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (prim[i].basevertex != prim[i + this_nr_prims].basevertex)
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       break;
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(prim[i].num_instances > 0);
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Binding inputs may imply mapping some vertex buffer objects.
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * They will need to be unmapped below.
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (inst = 0; inst < prim[i].num_instances; inst++) {
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            bind_prims(ctx, &prim[i], this_nr_prims);
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            bind_inputs(ctx, arrays, max_index + prim[i].basevertex + 1,
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        bo, &nr_bo);
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            bind_indices(ctx, ib, bo, &nr_bo);
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            tnl->CurInstance = inst;
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            unmap_vbos(ctx, bo, nr_bo);
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            free_space(ctx);
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 i += this_nr_prims;
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
535