t_vb_texgen.c revision 22144ab7552f0799bcfca506bf4ffa7f70a06649
122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes/* $Id: t_vb_texgen.c,v 1.6 2001/03/12 00:48:44 gareth Exp $ */
2cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
3cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell/*
4cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * Mesa 3-D graphics library
5cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * Version:  3.5
6cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell *
722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
8cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell *
9cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
10cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * copy of this software and associated documentation files (the "Software"),
11cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * to deal in the Software without restriction, including without limitation
12cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * and/or sell copies of the Software, and to permit persons to whom the
14cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * Software is furnished to do so, subject to the following conditions:
15cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell *
16cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * The above copyright notice and this permission notice shall be included
17cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * in all copies or substantial portions of the Software.
18cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell *
19cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell *
26cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * Authors:
27cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell *    Brian Paul <brian@valinux.com>
28cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell *    Keith Whitwell <keithw@valinux.com>
29cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell */
30cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
31cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
32cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "glheader.h"
33cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "colormac.h"
34cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "context.h"
35cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "macros.h"
36cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "mmath.h"
37cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "mem.h"
38cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "mtypes.h"
39cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
40cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "math/m_xform.h"
41cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
42cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "t_context.h"
43cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "t_pipeline.h"
44cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
45cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
46cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell/***********************************************************************
47cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * Automatic texture coordinate generation (texgen) code.
48cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell */
49cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
50cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
51cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstruct texgen_stage_data;
52cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
53cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwelltypedef void (*texgen_func)( GLcontext *ctx,
54cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell			     struct texgen_stage_data *store,
55cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell			     GLuint unit);
56cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
57cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
58cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstruct texgen_stage_data {
59cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
60cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   /* Per-texunit derived state.
61cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell    */
62cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint TexgenSize[MAX_TEXTURE_UNITS];
63cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint TexgenHoles[MAX_TEXTURE_UNITS];
64cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   texgen_func TexgenFunc[MAX_TEXTURE_UNITS];
65cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
66cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   /* Temporary values used in texgen.
67cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell    */
68cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat (*tmp_f)[3];
69cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *tmp_m;
70cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
71cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   /* Buffered outputs of the stage.
72cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell    */
73cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLvector4f texcoord[MAX_TEXTURE_UNITS];
74cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell};
75cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
76cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
77b51b0a847d7e7daaea69f77ab569086ef81c24a2Brian Paul#define TEXGEN_STAGE_DATA(stage) ((struct texgen_stage_data *)stage->privatePtr)
78cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
79cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
80cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
81cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
82cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstatic GLuint all_bits[5] = {
83cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   0,
84cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   VEC_SIZE_1,
85cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   VEC_SIZE_2,
86cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   VEC_SIZE_3,
87cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   VEC_SIZE_4,
88cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell};
89cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
90cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#define VEC_SIZE_FLAGS (VEC_SIZE_1|VEC_SIZE_2|VEC_SIZE_3|VEC_SIZE_4)
91cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
9222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes/*
93cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell */
94cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstatic void build_m3(GLfloat f[][3], GLfloat m[],
9522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes		     const GLvector3f *normal,
96cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		     const GLvector4f *eye )
97cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
98cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint stride = eye->stride;
99cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *coord = (GLfloat *)eye->start;
100cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint count = eye->count;
101cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   const GLfloat *norm = normal->start;
102cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
103cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
104cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
105cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   /* KW: Had to rearrange this loop to avoid a compiler bug with gcc
106cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell    *     2.7.3.1 at -O3 optimization.  Using -fno-strength-reduce
10722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes    *     also fixed the bug - is this generally necessary?
108cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell    */
109cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   for (i=0;i<count;i++,STRIDE_F(coord,stride)) {
110cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLfloat u[3], two_nu, fx, fy, fz;
11122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      COPY_3V( u, coord );
112cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      NORMALIZE_3FV( u );
113cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      two_nu = 2.0F * DOT3(norm,u);
114cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      fx = f[i][0] = u[0] - norm[0] * two_nu;
115cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      fy = f[i][1] = u[1] - norm[1] * two_nu;
116cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      fz = f[i][2] = u[2] - norm[2] * two_nu;
117cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      m[i] = fx * fx + fy * fy + (fz + 1.0F) * (fz + 1.0F);
118cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      if (m[i] != 0.0F) {
119cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 m[i] = 0.5F / (GLfloat) GL_SQRT(m[i]);
120cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
121cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
122cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      STRIDE_F(norm, normal->stride);
123cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
124cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
125cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
126cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
127cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
128cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstatic void build_m2(GLfloat f[][3], GLfloat m[],
12922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes		     const GLvector3f *normal,
130cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		     const GLvector4f *eye )
131cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
132cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint stride = eye->stride;
133cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *coord = eye->start;
134cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint count = eye->count;
135cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
136cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *norm = normal->start;
137cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
138cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
139cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   for (i=0;i<count;i++,STRIDE_F(coord,stride)) {
140cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
141cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLfloat u[3], two_nu, fx, fy, fz;
14222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      COPY_2V( u, coord );
143cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      u[2] = 0;
144cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      NORMALIZE_3FV( u );
145cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      two_nu = 2.0F * DOT3(norm,u);
146cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      fx = f[i][0] = u[0] - norm[0] * two_nu;
147cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      fy = f[i][1] = u[1] - norm[1] * two_nu;
148cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      fz = f[i][2] = u[2] - norm[2] * two_nu;
149cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      m[i] = fx * fx + fy * fy + (fz + 1.0F) * (fz + 1.0F);
150cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      if (m[i] != 0.0F) {
151cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 m[i] = 0.5F / (GLfloat) GL_SQRT(m[i]);
152cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
153cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
154cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      STRIDE_F(norm, normal->stride);
155cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
156cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
157cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
158cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
159cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
160cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwelltypedef void (*build_m_func)(GLfloat f[][3],
161cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell			     GLfloat m[],
162cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell			     const GLvector3f *normal,
163cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell			     const GLvector4f *eye );
164cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
165cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
166cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
167cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstatic build_m_func build_m_tab[5] = {
168cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   0,
169cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   0,
170cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   build_m2,
171cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   build_m3,
172cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   build_m3
173cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell};
174cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
175cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
176cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell/* This is unusual in that we respect the stride of the output vector
177cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * (f).  This allows us to pass in either a texcoord vector4f, or a
17822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * temporary vector3f.
179cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell */
18022144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughesstatic void build_f3( GLfloat *f,
181cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		      GLuint fstride,
182cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		      const GLvector3f *normal,
183cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		      const GLvector4f *eye )
184cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
185cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint stride = eye->stride;
186cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *coord = eye->start;
187cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint count = eye->count;
188cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
189cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *norm = normal->start;
190cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
191cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
192cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   for (i=0;i<count;i++) {
193cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLfloat u[3], two_nu;
19422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      COPY_3V( u, coord );
195cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      NORMALIZE_3FV( u );
196cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      two_nu = 2.0F * DOT3(norm,u);
197cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      f[0] = u[0] - norm[0] * two_nu;
198cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      f[1] = u[1] - norm[1] * two_nu;
199cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      f[2] = u[2] - norm[2] * two_nu;
200cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      STRIDE_F(coord,stride);
20122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      STRIDE_F(f,fstride);
202cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      STRIDE_F(norm, normal->stride);
203cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
204cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
205cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
206cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
20722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughesstatic void build_f2( GLfloat *f,
208cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		      GLuint fstride,
209cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		      const GLvector3f *normal,
210cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		      const GLvector4f *eye )
211cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
212cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint stride = eye->stride;
213cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *coord = eye->start;
214cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint count = eye->count;
215cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *norm = normal->start;
216cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
217cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
218cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   for (i=0;i<count;i++) {
219cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
220cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLfloat u[3], two_nu;
22122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      COPY_2V( u, coord );
222cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      u[2] = 0;
223cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      NORMALIZE_3FV( u );
224cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      two_nu = 2.0F * DOT3(norm,u);
225cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      f[0] = u[0] - norm[0] * two_nu;
226cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      f[1] = u[1] - norm[1] * two_nu;
227cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      f[2] = u[2] - norm[2] * two_nu;
228cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
229cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      STRIDE_F(coord,stride);
230cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      STRIDE_F(f,fstride);
231cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      STRIDE_F(norm, normal->stride);
232cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
233cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
234cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
235cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwelltypedef void (*build_f_func)( GLfloat *f,
236cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell			      GLuint fstride,
237cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell			      const GLvector3f *normal_vec,
238cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell			      const GLvector4f *eye );
239cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
240cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
241cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
24222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes/* Just treat 4-vectors as 3-vectors.
243cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell */
244cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstatic build_f_func build_f_tab[5] = {
245cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   0,
246cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   0,
247cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   build_f2,
248cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   build_f3,
24922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes   build_f3
250cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell};
251cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
252cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
253cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell/* Special case texgen functions.
254cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell */
255cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstatic void texgen_reflection_map_nv( GLcontext *ctx,
256cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell				      struct texgen_stage_data *store,
257cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell				      GLuint unit )
258cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
259cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
260cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLvector4f *in = VB->TexCoordPtr[unit];
261cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLvector4f *out = &store->texcoord[unit];
262cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
263cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   build_f_tab[VB->EyePtr->size]( out->start,
264cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell				  out->stride,
26522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes				  VB->NormalPtr,
26622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes				  VB->EyePtr );
26722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
268cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (in) {
269cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->flags |= (in->flags & VEC_SIZE_FLAGS) | VEC_SIZE_3;
270cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->count = in->count;
271cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->size = MAX2(in->size, 3);
27222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      if (in->size == 4)
27308836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul	 _mesa_copy_tab[0][0x8](out, in, 0);
27422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes   }
275cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   else {
276cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->flags |= VEC_SIZE_3;
277cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->size = 3;
278cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->count = in->count;
279cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
28022144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
281cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
282cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
283cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
284cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
285cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstatic void texgen_normal_map_nv( GLcontext *ctx,
286cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell				  struct texgen_stage_data *store,
287cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell				  GLuint unit )
288cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
289cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
290cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLvector4f *in = VB->TexCoordPtr[unit];
291cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLvector4f *out = &store->texcoord[unit];
29222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes   GLvector3f *normal = VB->NormalPtr;
293cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat (*texcoord)[4] = (GLfloat (*)[4])out->start;
294cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint count = VB->Count;
295cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
296cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   const GLfloat *norm = normal->start;
297cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
298cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   for (i=0;i<count;i++, STRIDE_F(norm, normal->stride)) {
299cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      texcoord[i][0] = norm[0];
300cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      texcoord[i][1] = norm[1];
301cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      texcoord[i][2] = norm[2];
302cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
303cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
304cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
305cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (in) {
306cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->flags |= (in->flags & VEC_SIZE_FLAGS) | VEC_SIZE_3;
307cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->count = in->count;
308cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->size = MAX2(in->size, 3);
30922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      if (in->size == 4)
31008836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul	 _mesa_copy_tab[0][0x8](out, in, 0);
31122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes   }
312cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   else {
313cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->flags |= VEC_SIZE_3;
314cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->size = 3;
315cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->count = in->count;
316cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
317cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
318cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
319cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
320cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstatic void texgen_sphere_map( GLcontext *ctx,
321cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell			       struct texgen_stage_data *store,
322cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell			       GLuint unit )
323cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
324cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
325cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLvector4f *in = VB->TexCoordPtr[unit];
326cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLvector4f *out = &store->texcoord[unit];
327cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat (*texcoord)[4] = (GLfloat (*)[4]) out->start;
328cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint count = VB->Count;
329cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
330cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat (*f)[3] = store->tmp_f;
331cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *m = store->tmp_m;
332cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
33322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes   (build_m_tab[VB->EyePtr->size])( store->tmp_f,
33422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes				    store->tmp_m,
33522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes				    VB->NormalPtr,
33622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes				    VB->EyePtr );
337cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
338cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   for (i=0;i<count;i++) {
339cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      texcoord[i][0] = f[i][0] * m[i] + 0.5F;
340cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      texcoord[i][1] = f[i][1] * m[i] + 0.5F;
341cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
342cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
343cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (in) {
344cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->size = MAX2(in->size,2);
345cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->count = in->count;
346cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->flags |= (in->flags & VEC_SIZE_FLAGS) | VEC_SIZE_2;
34722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      if (in->size > 2)
34808836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul	 _mesa_copy_tab[0][all_bits[in->size] & ~0x3](out, in, 0);
349cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   } else {
350cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->size = 2;
351cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->flags |= VEC_SIZE_2;
352cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->count = in->count;
353cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
354cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
355cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
356cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
357cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
35822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughesstatic void texgen( GLcontext *ctx,
359cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		    struct texgen_stage_data *store,
360cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		    GLuint unit )
361cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
362cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
363cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   struct vertex_buffer *VB = &tnl->vb;
364cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLvector4f *in = VB->TexCoordPtr[unit];
365cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLvector4f *out = &store->texcoord[unit];
366cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
367cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   const GLvector4f *obj = VB->ObjPtr;
368cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   const GLvector4f *eye = VB->EyePtr;
369cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   const GLvector3f *normal = VB->NormalPtr;
370cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat (*texcoord)[4] = (GLfloat (*)[4])out->data;
371cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *indata;
372cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint count = VB->Count;
373cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat (*f)[3] = store->tmp_f;
374cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *m = store->tmp_m;
3755c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell	 GLuint holes = 0;
376cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
377cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
378cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (texUnit->_GenFlags & TEXGEN_NEED_M) {
37922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      build_m_tab[in->size]( store->tmp_f, store->tmp_m, normal, eye );
380cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   } else if (texUnit->_GenFlags & TEXGEN_NEED_F) {
38122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      build_f_tab[in->size]( (GLfloat *)store->tmp_f, 3, normal, eye );
382cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
383cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
3845c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell   if (!in) {
3855c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      ASSERT(0);
3865c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      in = out;
3875c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      in->count = VB->Count;
3885c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell
3895c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      out->size = store->TexgenSize[unit];
3905c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      out->flags |= texUnit->TexGenEnabled;
3915c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      out->count = VB->Count;
3925c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      holes = store->TexgenHoles[unit];
3935c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell   }
3945c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell   else {
395cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLuint copy = (all_bits[in->size] & ~texUnit->TexGenEnabled);
396cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      if (copy)
39708836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul	 _mesa_copy_tab[0][copy](out, in, 0);
398cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
3995c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      out->size = MAX2(in->size, store->TexgenSize[unit]);
4005c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      out->flags |= (in->flags & VEC_SIZE_FLAGS) | texUnit->TexGenEnabled;
4015c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      out->count = in->count;
40222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
4035c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      holes = ~all_bits[in->size] & store->TexgenHoles[unit];
404cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
405cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
4065c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell   if (holes) {
40708836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      if (holes & VEC_DIRTY_2) _mesa_vector4f_clean_elem(out, count, 2);
40808836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      if (holes & VEC_DIRTY_1) _mesa_vector4f_clean_elem(out, count, 1);
40908836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      if (holes & VEC_DIRTY_0) _mesa_vector4f_clean_elem(out, count, 0);
4105c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell   }
411cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
412cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (texUnit->TexGenEnabled & S_BIT) {
413cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLuint i;
414cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      switch (texUnit->GenModeS) {
415cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_OBJECT_LINEAR:
416188f2949eaf181f4aab041a6dad26fa76e746eeeBrian Paul	 (_mesa_dotprod_tab[0][obj->size])((GLfloat *)out->data,
41722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes					sizeof(out->data[0]), obj,
418cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell					texUnit->ObjectPlaneS, 0);
419cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
420cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_EYE_LINEAR:
42122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 (_mesa_dotprod_tab[0][eye->size])((GLfloat *)out->data,
422cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell					sizeof(out->data[0]), eye,
423cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell					texUnit->EyePlaneS, 0);
424cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
42522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      case GL_SPHERE_MAP:
4265c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell	 for (indata=in->start,i=0 ; i<count ;i++, STRIDE_F(indata,in->stride))
427cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    texcoord[i][0] = indata[0] * m[i] + 0.5F;
428cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
42922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      case GL_REFLECTION_MAP_NV:
43022144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 for (i=0;i<count;i++)
431cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	     texcoord[i][0] = f[i][0];
432cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
433cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_NORMAL_MAP_NV: {
434cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 const GLfloat *norm = normal->start;
435cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 for (i=0;i<count;i++, STRIDE_F(norm, normal->stride)) {
436cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	     texcoord[i][0] = norm[0];
437cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 }
438cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
439cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
440cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      default:
44108836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul	 _mesa_problem(ctx, "Bad S texgen");
442cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
44322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes   }
444cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
445cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (texUnit->TexGenEnabled & T_BIT) {
446cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLuint i;
447cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      switch (texUnit->GenModeT) {
448cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_OBJECT_LINEAR:
44922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 (_mesa_dotprod_tab[0][obj->size])(&(out->data[0][1]),
45022144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes					sizeof(out->data[0]), obj,
451cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell					texUnit->ObjectPlaneT, 0);
452cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
453cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_EYE_LINEAR:
45422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 (_mesa_dotprod_tab[0][eye->size])(&(out->data[0][1]),
45522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes					sizeof(out->data[0]), eye,
456cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell					texUnit->EyePlaneT, 0);
45722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 break;
45822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      case GL_SPHERE_MAP:
45922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 for (indata=in->start,i=0; i<count ;i++,STRIDE_F(indata,in->stride))
460cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	     texcoord[i][1] = indata[1] * m[i] + 0.5F;
46122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 break;
46222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      case GL_REFLECTION_MAP_NV:
46322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 for (i=0;i<count;i++)
464cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	     texcoord[i][0] = f[i][0];
465cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
466cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_NORMAL_MAP_NV: {
467cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 const GLfloat *norm = normal->start;
468cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 for (i=0;i<count;i++, STRIDE_F(norm, normal->stride)) {
469cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	     texcoord[i][1] = norm[1];
470cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 }
471cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
472cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
473cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      default:
47408836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul	 _mesa_problem(ctx, "Bad T texgen");
475cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
476cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
477cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
478cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (texUnit->TexGenEnabled & R_BIT) {
479cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLuint i;
480cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      switch (texUnit->GenModeR) {
481cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_OBJECT_LINEAR:
48222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 (_mesa_dotprod_tab[0][obj->size])(&(out->data[0][2]),
48322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes					sizeof(out->data[0]), obj,
484cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell					texUnit->ObjectPlaneR, 0);
485cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
486cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_EYE_LINEAR:
48722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 (_mesa_dotprod_tab[0][eye->size])(&(out->data[0][2]),
488cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell					sizeof(out->data[0]), eye,
489cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell					texUnit->EyePlaneR, 0);
490cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
49122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      case GL_REFLECTION_MAP_NV:
49222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 for (i=0;i<count;i++)
493cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	     texcoord[i][2] = f[i][2];
494cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
495cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_NORMAL_MAP_NV: {
496cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 const GLfloat *norm = normal->start;
497cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 for (i=0;i<count;i++,STRIDE_F(norm, normal->stride)) {
498cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	     texcoord[i][2] = norm[2];
499cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 }
500cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
501cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
502cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      default:
50308836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul	 _mesa_problem(ctx, "Bad R texgen");
504cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
505cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
506cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
507cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (texUnit->TexGenEnabled & Q_BIT) {
508cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      switch (texUnit->GenModeQ) {
509cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_OBJECT_LINEAR:
51022144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 (_mesa_dotprod_tab[0][obj->size])(&(out->data[0][3]),
51122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes					sizeof(out->data[0]), obj,
512cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell					texUnit->ObjectPlaneQ, 0);
513cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
514cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_EYE_LINEAR:
51522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 (_mesa_dotprod_tab[0][eye->size])(&(out->data[0][3]),
516cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell					sizeof(out->data[0]), eye,
517cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell					texUnit->EyePlaneQ, 0);
518cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
519cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      default:
52008836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul	 _mesa_problem(ctx, "Bad Q texgen");
521cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
522cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
523cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
524cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
525cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
526cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
52722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughesstatic GLboolean run_texgen_stage( GLcontext *ctx,
528cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell				   struct gl_pipeline_stage *stage )
529cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
53022144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
531cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   struct texgen_stage_data *store = TEXGEN_STAGE_DATA( stage );
532cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
533cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
53422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes   for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
535cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      if (ctx->_Enabled & ENABLE_TEXGEN(i)) {
536cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 if (stage->changed_inputs & (VERT_EYE | VERT_NORM | VERT_TEX(i)))
537cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    store->TexgenFunc[i]( ctx, store, i );
538cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
539cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 VB->TexCoordPtr[i] = &store->texcoord[i];
540cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
541cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
542cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   return GL_TRUE;
543cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
544cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
545cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
546cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
547cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
54822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughesstatic GLboolean run_validate_texgen_stage( GLcontext *ctx,
549cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell					    struct gl_pipeline_stage *stage )
550cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
551cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage);
552cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
553cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
554cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
555cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
556cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
557cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      if (texUnit->TexGenEnabled) {
558cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 GLuint sz;
559cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
560cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 if (texUnit->TexGenEnabled & R_BIT)
561cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    sz = 4;
562cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 else if (texUnit->TexGenEnabled & Q_BIT)
563cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    sz = 3;
564cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 else if (texUnit->TexGenEnabled & T_BIT)
565cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    sz = 2;
566cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 else
567cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    sz = 1;
56822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
569cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 store->TexgenSize[i] = sz;
570cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 store->TexgenHoles[i] = (all_bits[sz] & ~texUnit->TexGenEnabled);
571cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 store->TexgenFunc[i] = texgen;
57222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
573cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 if (texUnit->TexGenEnabled == (S_BIT|T_BIT|R_BIT)) {
574cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    if (texUnit->_GenFlags == TEXGEN_REFLECTION_MAP_NV) {
575cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	       store->TexgenFunc[i] = texgen_reflection_map_nv;
576cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    }
577cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    else if (texUnit->_GenFlags == TEXGEN_NORMAL_MAP_NV) {
578cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	       store->TexgenFunc[i] = texgen_normal_map_nv;
579cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    }
580cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 }
581cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 else if (texUnit->TexGenEnabled == (S_BIT|T_BIT) &&
582cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		  texUnit->_GenFlags == TEXGEN_SPHERE_MAP) {
583cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    store->TexgenFunc[i] = texgen_sphere_map;
584cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 }
585cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
586cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
587cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
588cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   stage->run = run_texgen_stage;
589cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   return stage->run( ctx, stage );
590cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
591cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
592cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
593cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstatic void check_texgen( GLcontext *ctx, struct gl_pipeline_stage *stage )
594cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
595cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
596cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   stage->active = 0;
597cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
598cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (ctx->_Enabled & ENABLE_TEXGEN_ANY) {
599cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLuint inputs = 0;
600cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLuint outputs = 0;
601cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
602cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      if (ctx->Texture._GenFlags & TEXGEN_NEED_VERTICES)
603cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 inputs |= VERT_EYE;
604cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
605cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      if (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS)
606cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 inputs |= VERT_NORM;
607cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
60822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
60922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 if (ctx->_Enabled & ENABLE_TEXGEN(i))
610cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 {
611cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    outputs |= VERT_TEX(i);
612cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
613cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    /* Need the original input in case it contains a Q coord:
614cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	     * (sigh)
615cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	     */
6165c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell/*  	    if ((ctx->Texture.Unit[i]._ReallyEnabled|Q_BIT) & */
6175c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell/*  		~ctx->Texture.Unit[i].TexGenEnabled) */
618cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	       inputs |= VERT_TEX(i);
619cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
620cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    /* Something for Feedback? */
621cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 }
622cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
623b51b0a847d7e7daaea69f77ab569086ef81c24a2Brian Paul      if (stage->privatePtr)
624cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 stage->run = run_validate_texgen_stage;
625cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      stage->active = 1;
626cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      stage->inputs = inputs;
627cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      stage->outputs = outputs;
628cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
629cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
63022144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
631cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
632cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
633cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
634cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell/* Called the first time stage->run() is invoked.
635cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell */
63622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughesstatic GLboolean alloc_texgen_data( GLcontext *ctx,
637cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell				    struct gl_pipeline_stage *stage )
638cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
63922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
640cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   struct texgen_stage_data *store;
641cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
642cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
643b51b0a847d7e7daaea69f77ab569086ef81c24a2Brian Paul   stage->privatePtr = CALLOC(sizeof(*store));
644cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   store = TEXGEN_STAGE_DATA(stage);
645cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (!store)
646cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      return GL_FALSE;
647cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
648cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
64908836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      _mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 );
650cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
651cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   store->tmp_f = (GLfloat (*)[3]) MALLOC(VB->Size * sizeof(GLfloat) * 3);
652cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   store->tmp_m = (GLfloat *) MALLOC(VB->Size * sizeof(GLfloat));
653cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
654cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   /* Now validate and run the stage.
655cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell    */
656cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   stage->run = run_validate_texgen_stage;
657cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   return stage->run( ctx, stage );
658cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
659cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
660cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
661cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstatic void free_texgen_data( struct gl_pipeline_stage *stage )
662cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
663cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
664cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage);
665cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
666cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
667cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (store) {
668cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
66922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 if (store->texcoord[i].data)
67008836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul	    _mesa_vector4f_free( &store->texcoord[i] );
671cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
67222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
673cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      if (store->tmp_f) FREE( store->tmp_f );
674cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      if (store->tmp_m) FREE( store->tmp_m );
675cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      FREE( store );
676b51b0a847d7e7daaea69f77ab569086ef81c24a2Brian Paul      stage->privatePtr = NULL;
677cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
678cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
679cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
680cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
68122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
68222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughesconst struct gl_pipeline_stage _tnl_texgen_stage =
68322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes{
684cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   "texgen",
685cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   _NEW_TEXTURE,		/* when to call check() */
686cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   _NEW_TEXTURE,		/* when to invalidate stored data */
687cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   0,0,0,			/* active, inputs, outputs */
688cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   0,0,				/* changed_inputs, private */
689cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   free_texgen_data,		/* destructor */
690cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   check_texgen,		/* check */
691cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   alloc_texgen_data		/* run -- initially set to alloc data */
692cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell};
693