t_vb_texgen.c revision 790734045b69c47b1525fbf9106a7ca5a8eb7416
1cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell/*
2cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * Mesa 3-D graphics library
3610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul * Version:  5.1
4cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell *
527558a160a9fe91745728d7626995cd88f8fe339Brian Paul * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
6cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell *
7cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
8cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * copy of this software and associated documentation files (the "Software"),
9cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * to deal in the Software without restriction, including without limitation
10cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * and/or sell copies of the Software, and to permit persons to whom the
12cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * Software is furnished to do so, subject to the following conditions:
13cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell *
14cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * The above copyright notice and this permission notice shall be included
15cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * in all copies or substantial portions of the Software.
16cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell *
17cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell *
24cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * Authors:
2505a4b37707d2c598ea68c05d07a3d65bcbf5a076Brian Paul *    Brian Paul
2605a4b37707d2c598ea68c05d07a3d65bcbf5a076Brian Paul *    Keith Whitwell <keith@tungstengraphics.com>
27cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell */
28cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
29cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
30cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "glheader.h"
31cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "colormac.h"
32cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "context.h"
33cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "macros.h"
343c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "imports.h"
35cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "mtypes.h"
36cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
37cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "math/m_xform.h"
38cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
39cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "t_context.h"
40cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#include "t_pipeline.h"
41cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
42cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
43cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell/***********************************************************************
44cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * Automatic texture coordinate generation (texgen) code.
45cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell */
46cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
47cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
48cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstruct texgen_stage_data;
49cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
50cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwelltypedef void (*texgen_func)( GLcontext *ctx,
51cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell			     struct texgen_stage_data *store,
52cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell			     GLuint unit);
53cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
54cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
55cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstruct texgen_stage_data {
56cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
57cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   /* Per-texunit derived state.
58cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell    */
59610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul   GLuint TexgenSize[MAX_TEXTURE_COORD_UNITS];
60610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul   GLuint TexgenHoles[MAX_TEXTURE_COORD_UNITS];
61610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul   texgen_func TexgenFunc[MAX_TEXTURE_COORD_UNITS];
62cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
63cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   /* Temporary values used in texgen.
64cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell    */
65cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat (*tmp_f)[3];
66cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *tmp_m;
67cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
68cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   /* Buffered outputs of the stage.
69cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell    */
70610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul   GLvector4f texcoord[MAX_TEXTURE_COORD_UNITS];
71cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell};
72cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
73cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
74b51b0a847d7e7daaea69f77ab569086ef81c24a2Brian Paul#define TEXGEN_STAGE_DATA(stage) ((struct texgen_stage_data *)stage->privatePtr)
75cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
76cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
77cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
78cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstatic GLuint all_bits[5] = {
79cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   0,
80cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   VEC_SIZE_1,
81cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   VEC_SIZE_2,
82cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   VEC_SIZE_3,
83cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   VEC_SIZE_4,
84cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell};
85cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
86cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell#define VEC_SIZE_FLAGS (VEC_SIZE_1|VEC_SIZE_2|VEC_SIZE_3|VEC_SIZE_4)
87cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
88ed39a43b8cb2e1cf69b097fc89365cde470ebf51Keith Whitwell#define TEXGEN_NEED_M            (TEXGEN_SPHERE_MAP)
89ed39a43b8cb2e1cf69b097fc89365cde470ebf51Keith Whitwell#define TEXGEN_NEED_F            (TEXGEN_SPHERE_MAP        | \
90ed39a43b8cb2e1cf69b097fc89365cde470ebf51Keith Whitwell				  TEXGEN_REFLECTION_MAP_NV)
91ed39a43b8cb2e1cf69b097fc89365cde470ebf51Keith Whitwell
92ed39a43b8cb2e1cf69b097fc89365cde470ebf51Keith Whitwell
93ed39a43b8cb2e1cf69b097fc89365cde470ebf51Keith Whitwell
945e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughesstatic void build_m3( GLfloat f[][3], GLfloat m[],
95bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul		      const GLvector4f *normal,
965e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes		      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
104908be619fdba608b057ae512834dcc7a76aa3224Keith Whitwell   for (i=0;i<count;i++,STRIDE_F(coord,stride),STRIDE_F(norm,normal->stride)) {
105cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLfloat u[3], two_nu, fx, fy, fz;
10622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      COPY_3V( u, coord );
107cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      NORMALIZE_3FV( u );
108cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      two_nu = 2.0F * DOT3(norm,u);
109cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      fx = f[i][0] = u[0] - norm[0] * two_nu;
110cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      fy = f[i][1] = u[1] - norm[1] * two_nu;
111cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      fz = f[i][2] = u[2] - norm[2] * two_nu;
112cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      m[i] = fx * fx + fy * fy + (fz + 1.0F) * (fz + 1.0F);
113cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      if (m[i] != 0.0F) {
114f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul	 m[i] = 0.5F * _mesa_inv_sqrtf(m[i]);
115cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
116cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
117cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
118cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
119cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
120cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
1215e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughesstatic void build_m2( GLfloat f[][3], GLfloat m[],
122bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul		      const GLvector4f *normal,
1235e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes		      const GLvector4f *eye )
124cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
125cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint stride = eye->stride;
126cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *coord = eye->start;
127cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint count = eye->count;
128cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
129cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *norm = normal->start;
130cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
131cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
132908be619fdba608b057ae512834dcc7a76aa3224Keith Whitwell   for (i=0;i<count;i++,STRIDE_F(coord,stride),STRIDE_F(norm,normal->stride)) {
133cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLfloat u[3], two_nu, fx, fy, fz;
13422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      COPY_2V( u, coord );
135cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      u[2] = 0;
136cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      NORMALIZE_3FV( u );
137cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      two_nu = 2.0F * DOT3(norm,u);
138cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      fx = f[i][0] = u[0] - norm[0] * two_nu;
139cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      fy = f[i][1] = u[1] - norm[1] * two_nu;
140cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      fz = f[i][2] = u[2] - norm[2] * two_nu;
141cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      m[i] = fx * fx + fy * fy + (fz + 1.0F) * (fz + 1.0F);
142cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      if (m[i] != 0.0F) {
143f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul	 m[i] = 0.5F * _mesa_inv_sqrtf(m[i]);
144cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
145cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
146cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
147cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
148cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
149cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
1505e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughestypedef void (*build_m_func)( GLfloat f[][3],
1515e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes			      GLfloat m[],
152bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul			      const GLvector4f *normal,
1535e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes			      const GLvector4f *eye );
154cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
155cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
156cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstatic build_m_func build_m_tab[5] = {
157cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   0,
158cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   0,
159cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   build_m2,
160cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   build_m3,
161cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   build_m3
162cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell};
163cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
164cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
165cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell/* This is unusual in that we respect the stride of the output vector
166cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell * (f).  This allows us to pass in either a texcoord vector4f, or a
16722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * temporary vector3f.
168cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell */
16922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughesstatic void build_f3( GLfloat *f,
170cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		      GLuint fstride,
171bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul		      const GLvector4f *normal,
172cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		      const GLvector4f *eye )
173cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
174cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint stride = eye->stride;
175cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *coord = eye->start;
176cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint count = eye->count;
177cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
178cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *norm = normal->start;
179cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
180cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
181cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   for (i=0;i<count;i++) {
182cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLfloat u[3], two_nu;
18322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      COPY_3V( u, coord );
184cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      NORMALIZE_3FV( u );
185cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      two_nu = 2.0F * DOT3(norm,u);
186cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      f[0] = u[0] - norm[0] * two_nu;
187cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      f[1] = u[1] - norm[1] * two_nu;
188cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      f[2] = u[2] - norm[2] * two_nu;
189cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      STRIDE_F(coord,stride);
19022144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      STRIDE_F(f,fstride);
191cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      STRIDE_F(norm, normal->stride);
192cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
193cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
194cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
195cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
19622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughesstatic void build_f2( GLfloat *f,
197cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		      GLuint fstride,
198bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul		      const GLvector4f *normal,
199cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		      const GLvector4f *eye )
200cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
201cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint stride = eye->stride;
202cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *coord = eye->start;
203cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint count = eye->count;
204cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *norm = normal->start;
205cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
206cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
207cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   for (i=0;i<count;i++) {
208cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
209cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLfloat u[3], two_nu;
21022144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      COPY_2V( u, coord );
211cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      u[2] = 0;
212cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      NORMALIZE_3FV( u );
213cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      two_nu = 2.0F * DOT3(norm,u);
214cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      f[0] = u[0] - norm[0] * two_nu;
215cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      f[1] = u[1] - norm[1] * two_nu;
216cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      f[2] = u[2] - norm[2] * two_nu;
217cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
218cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      STRIDE_F(coord,stride);
219cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      STRIDE_F(f,fstride);
220cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      STRIDE_F(norm, normal->stride);
221cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
222cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
223cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
224cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwelltypedef void (*build_f_func)( GLfloat *f,
225cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell			      GLuint fstride,
226bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul			      const GLvector4f *normal_vec,
227cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell			      const GLvector4f *eye );
228cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
229cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
230cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
23122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes/* Just treat 4-vectors as 3-vectors.
232cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell */
233cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstatic build_f_func build_f_tab[5] = {
234cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   0,
235cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   0,
236cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   build_f2,
237cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   build_f3,
23822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes   build_f3
239cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell};
240cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
241cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
242cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell/* Special case texgen functions.
243cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell */
244cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstatic void texgen_reflection_map_nv( GLcontext *ctx,
245cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell				      struct texgen_stage_data *store,
246cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell				      GLuint unit )
247cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
248cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
249cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLvector4f *in = VB->TexCoordPtr[unit];
250cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLvector4f *out = &store->texcoord[unit];
251cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
252cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   build_f_tab[VB->EyePtr->size]( out->start,
253cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell				  out->stride,
25422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes				  VB->NormalPtr,
25522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes				  VB->EyePtr );
25622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
257cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (in) {
258cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->flags |= (in->flags & VEC_SIZE_FLAGS) | VEC_SIZE_3;
259cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->count = in->count;
260cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->size = MAX2(in->size, 3);
26122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      if (in->size == 4)
2625e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes	 _mesa_copy_tab[0x8]( out, in );
26322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes   }
264cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   else {
265cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->flags |= VEC_SIZE_3;
266cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->size = 3;
267cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->count = in->count;
268cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
26922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
270cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
271cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
272cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
273cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
274cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstatic void texgen_normal_map_nv( GLcontext *ctx,
275cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell				  struct texgen_stage_data *store,
276cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell				  GLuint unit )
277cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
278cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
279cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLvector4f *in = VB->TexCoordPtr[unit];
280cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLvector4f *out = &store->texcoord[unit];
281bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   GLvector4f *normal = VB->NormalPtr;
282cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat (*texcoord)[4] = (GLfloat (*)[4])out->start;
283cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint count = VB->Count;
284cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
285cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   const GLfloat *norm = normal->start;
286cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
287cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   for (i=0;i<count;i++, STRIDE_F(norm, normal->stride)) {
288cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      texcoord[i][0] = norm[0];
289cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      texcoord[i][1] = norm[1];
290cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      texcoord[i][2] = norm[2];
291cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
292cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
293cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
294cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (in) {
295cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->flags |= (in->flags & VEC_SIZE_FLAGS) | VEC_SIZE_3;
296cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->count = in->count;
297cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->size = MAX2(in->size, 3);
29822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      if (in->size == 4)
2995e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes	 _mesa_copy_tab[0x8]( out, in );
30022144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes   }
301cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   else {
302cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->flags |= VEC_SIZE_3;
303cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->size = 3;
304cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->count = in->count;
305cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
306cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
307cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
308cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
309cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwellstatic void texgen_sphere_map( GLcontext *ctx,
310cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell			       struct texgen_stage_data *store,
311cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell			       GLuint unit )
312cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
313cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
314cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLvector4f *in = VB->TexCoordPtr[unit];
315cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLvector4f *out = &store->texcoord[unit];
316cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat (*texcoord)[4] = (GLfloat (*)[4]) out->start;
317cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint count = VB->Count;
318cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
319cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat (*f)[3] = store->tmp_f;
320cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat *m = store->tmp_m;
321cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
32222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes   (build_m_tab[VB->EyePtr->size])( store->tmp_f,
32322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes				    store->tmp_m,
32422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes				    VB->NormalPtr,
32522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes				    VB->EyePtr );
326cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
327cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   for (i=0;i<count;i++) {
328cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      texcoord[i][0] = f[i][0] * m[i] + 0.5F;
329cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      texcoord[i][1] = f[i][1] * m[i] + 0.5F;
330cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
331cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
332cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (in) {
333cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->size = MAX2(in->size,2);
334cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->count = in->count;
335cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->flags |= (in->flags & VEC_SIZE_FLAGS) | VEC_SIZE_2;
33622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      if (in->size > 2)
3375e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes	 _mesa_copy_tab[all_bits[in->size] & ~0x3]( out, in );
338cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   } else {
339cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->size = 2;
340cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->flags |= VEC_SIZE_2;
341cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      out->count = in->count;
342cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
343cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
344cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
345cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
346cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
34722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughesstatic void texgen( GLcontext *ctx,
348cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		    struct texgen_stage_data *store,
349cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		    GLuint unit )
350cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
351cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   TNLcontext *tnl = TNL_CONTEXT(ctx);
352cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   struct vertex_buffer *VB = &tnl->vb;
353cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLvector4f *in = VB->TexCoordPtr[unit];
354cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLvector4f *out = &store->texcoord[unit];
3552655e68504786b62a8463d04eaa74a953e5d2871Brian Paul   const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
356cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   const GLvector4f *obj = VB->ObjPtr;
357cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   const GLvector4f *eye = VB->EyePtr;
358bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   const GLvector4f *normal = VB->NormalPtr;
3592655e68504786b62a8463d04eaa74a953e5d2871Brian Paul   const GLfloat *m = store->tmp_m;
3602655e68504786b62a8463d04eaa74a953e5d2871Brian Paul   const GLuint count = VB->Count;
361cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat (*texcoord)[4] = (GLfloat (*)[4])out->data;
362cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLfloat (*f)[3] = store->tmp_f;
363c765d446507b25f3531be3a116d1b5de598bb9adBrian Paul   GLuint holes = 0;
364cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
365cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (texUnit->_GenFlags & TEXGEN_NEED_M) {
3662655e68504786b62a8463d04eaa74a953e5d2871Brian Paul      build_m_tab[eye->size]( store->tmp_f, store->tmp_m, normal, eye );
367cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   } else if (texUnit->_GenFlags & TEXGEN_NEED_F) {
3682655e68504786b62a8463d04eaa74a953e5d2871Brian Paul      build_f_tab[eye->size]( (GLfloat *)store->tmp_f, 3, normal, eye );
369cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
370cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
3715c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell   if (!in) {
3725c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      ASSERT(0);
3735c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      in = out;
3745c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      in->count = VB->Count;
3755c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell
3765c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      out->size = store->TexgenSize[unit];
3775c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      out->flags |= texUnit->TexGenEnabled;
3785c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      out->count = VB->Count;
3795c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      holes = store->TexgenHoles[unit];
3805c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell   }
3815c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell   else {
382cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLuint copy = (all_bits[in->size] & ~texUnit->TexGenEnabled);
383cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      if (copy)
3845e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes	 _mesa_copy_tab[copy]( out, in );
385cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
3865c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      out->size = MAX2(in->size, store->TexgenSize[unit]);
3875c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      out->flags |= (in->flags & VEC_SIZE_FLAGS) | texUnit->TexGenEnabled;
3885c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      out->count = in->count;
38922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
3905c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell      holes = ~all_bits[in->size] & store->TexgenHoles[unit];
391cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
392cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
3935c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell   if (holes) {
394c765d446507b25f3531be3a116d1b5de598bb9adBrian Paul      if (holes & VEC_DIRTY_3) _mesa_vector4f_clean_elem(out, count, 3);
39508836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      if (holes & VEC_DIRTY_2) _mesa_vector4f_clean_elem(out, count, 2);
39608836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      if (holes & VEC_DIRTY_1) _mesa_vector4f_clean_elem(out, count, 1);
39708836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      if (holes & VEC_DIRTY_0) _mesa_vector4f_clean_elem(out, count, 0);
3985c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell   }
399cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
400cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (texUnit->TexGenEnabled & S_BIT) {
401cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLuint i;
402cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      switch (texUnit->GenModeS) {
403cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_OBJECT_LINEAR:
4045e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes	 _mesa_dotprod_tab[obj->size]( (GLfloat *)out->data,
4055e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes				       sizeof(out->data[0]), obj,
4065e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes				       texUnit->ObjectPlaneS );
407cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
408cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_EYE_LINEAR:
4095e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes	 _mesa_dotprod_tab[eye->size]( (GLfloat *)out->data,
4105e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes				       sizeof(out->data[0]), eye,
4115e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes				       texUnit->EyePlaneS );
412cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
41322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      case GL_SPHERE_MAP:
4142655e68504786b62a8463d04eaa74a953e5d2871Brian Paul         for (i = 0; i < count; i++)
4152655e68504786b62a8463d04eaa74a953e5d2871Brian Paul            texcoord[i][0] = f[i][0] * m[i] + 0.5F;
416cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
41722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      case GL_REFLECTION_MAP_NV:
41822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 for (i=0;i<count;i++)
419cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	     texcoord[i][0] = f[i][0];
420cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
421cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_NORMAL_MAP_NV: {
422cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 const GLfloat *norm = normal->start;
423cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 for (i=0;i<count;i++, STRIDE_F(norm, normal->stride)) {
424cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	     texcoord[i][0] = norm[0];
425cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 }
426cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
427cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
428cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      default:
42908836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul	 _mesa_problem(ctx, "Bad S texgen");
430cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
43122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes   }
432cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
433cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (texUnit->TexGenEnabled & T_BIT) {
434cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLuint i;
435cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      switch (texUnit->GenModeT) {
436cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_OBJECT_LINEAR:
4375e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes	 _mesa_dotprod_tab[obj->size]( &(out->data[0][1]),
4385e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes				       sizeof(out->data[0]), obj,
4395e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes				       texUnit->ObjectPlaneT );
440cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
441cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_EYE_LINEAR:
4425e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes	 _mesa_dotprod_tab[eye->size]( &(out->data[0][1]),
4435e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes				       sizeof(out->data[0]), eye,
4445e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes				       texUnit->EyePlaneT );
44522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 break;
44622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      case GL_SPHERE_MAP:
4472655e68504786b62a8463d04eaa74a953e5d2871Brian Paul         for (i = 0; i < count; i++)
4482655e68504786b62a8463d04eaa74a953e5d2871Brian Paul            texcoord[i][1] = f[i][1] * m[i] + 0.5F;
44922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 break;
45022144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      case GL_REFLECTION_MAP_NV:
45122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 for (i=0;i<count;i++)
4528fee8dfcaaf2dae5a8a022077f2d888b9943b5a2Daniel Borca	     texcoord[i][1] = f[i][1];
453cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
454cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_NORMAL_MAP_NV: {
455cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 const GLfloat *norm = normal->start;
456cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 for (i=0;i<count;i++, STRIDE_F(norm, normal->stride)) {
457cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	     texcoord[i][1] = norm[1];
458cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 }
459cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
460cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
461cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      default:
46208836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul	 _mesa_problem(ctx, "Bad T texgen");
463cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
464cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
465cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
466cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (texUnit->TexGenEnabled & R_BIT) {
467cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLuint i;
468cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      switch (texUnit->GenModeR) {
469cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_OBJECT_LINEAR:
4705e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes	 _mesa_dotprod_tab[obj->size]( &(out->data[0][2]),
4715e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes				       sizeof(out->data[0]), obj,
4725e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes				       texUnit->ObjectPlaneR );
473cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
474cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_EYE_LINEAR:
4755e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes	 _mesa_dotprod_tab[eye->size]( &(out->data[0][2]),
4765e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes				       sizeof(out->data[0]), eye,
4775e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes				       texUnit->EyePlaneR );
478cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
47922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes      case GL_REFLECTION_MAP_NV:
48022144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 for (i=0;i<count;i++)
481cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	     texcoord[i][2] = f[i][2];
482cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
483cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_NORMAL_MAP_NV: {
484cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 const GLfloat *norm = normal->start;
485cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 for (i=0;i<count;i++,STRIDE_F(norm, normal->stride)) {
486cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	     texcoord[i][2] = norm[2];
487cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 }
488cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
489cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
490cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      default:
49108836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul	 _mesa_problem(ctx, "Bad R texgen");
492cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
493cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
494cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
495cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (texUnit->TexGenEnabled & Q_BIT) {
496cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      switch (texUnit->GenModeQ) {
497cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_OBJECT_LINEAR:
4985e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes	 _mesa_dotprod_tab[obj->size]( &(out->data[0][3]),
4995e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes				       sizeof(out->data[0]), obj,
5005e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes				       texUnit->ObjectPlaneQ );
501cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
502cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      case GL_EYE_LINEAR:
5035e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes	 _mesa_dotprod_tab[eye->size]( &(out->data[0][3]),
5045e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes				       sizeof(out->data[0]), eye,
5055e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes				       texUnit->EyePlaneQ );
506cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 break;
507cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      default:
50808836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul	 _mesa_problem(ctx, "Bad Q texgen");
509cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
510cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
511cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
512cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
513cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
514cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
51522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughesstatic GLboolean run_texgen_stage( GLcontext *ctx,
516ae0eaf93e092ac8e8b1c98f3e986de96940663faKeith Whitwell				   struct tnl_pipeline_stage *stage )
517cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
51822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
519cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   struct texgen_stage_data *store = TEXGEN_STAGE_DATA( stage );
520cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
521cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
52292f9785c727ea10ff5f8dc9770f0e8f388fcea70Brian Paul   for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
523ed39a43b8cb2e1cf69b097fc89365cde470ebf51Keith Whitwell      if (ctx->Texture._TexGenEnabled & ENABLE_TEXGEN(i)) {
524ae0eaf93e092ac8e8b1c98f3e986de96940663faKeith Whitwell	 if (stage->changed_inputs & (_TNL_BIT_POS | _TNL_BIT_NORMAL | _TNL_BIT_TEX(i)))
525cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    store->TexgenFunc[i]( ctx, store, i );
526cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
527790734045b69c47b1525fbf9106a7ca5a8eb7416Keith Whitwell	 VB->AttribPtr[VERT_ATTRIB_TEX0+i] =
528790734045b69c47b1525fbf9106a7ca5a8eb7416Keith Whitwell	    VB->TexCoordPtr[i] = &store->texcoord[i];
529cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
530cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
531cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   return GL_TRUE;
532cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
533cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
534cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
535cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
536cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
53722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughesstatic GLboolean run_validate_texgen_stage( GLcontext *ctx,
538ae0eaf93e092ac8e8b1c98f3e986de96940663faKeith Whitwell					    struct tnl_pipeline_stage *stage )
539cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
540cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage);
541cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
542cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
54392f9785c727ea10ff5f8dc9770f0e8f388fcea70Brian Paul   for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) {
544cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
545cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
546cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      if (texUnit->TexGenEnabled) {
547cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 GLuint sz;
548cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
549a4e65d69dc745a78fb3dbcbb0ee194e1b6877c5dBrian Paul	 if (texUnit->TexGenEnabled & Q_BIT)
550cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    sz = 4;
551a4e65d69dc745a78fb3dbcbb0ee194e1b6877c5dBrian Paul	 else if (texUnit->TexGenEnabled & R_BIT)
552cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    sz = 3;
553cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 else if (texUnit->TexGenEnabled & T_BIT)
554cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    sz = 2;
555cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 else
556cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    sz = 1;
55722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
558cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 store->TexgenSize[i] = sz;
559cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 store->TexgenHoles[i] = (all_bits[sz] & ~texUnit->TexGenEnabled);
5602655e68504786b62a8463d04eaa74a953e5d2871Brian Paul	 store->TexgenFunc[i] = texgen; /* general solution */
56122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
5622655e68504786b62a8463d04eaa74a953e5d2871Brian Paul         /* look for special texgen cases */
563cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 if (texUnit->TexGenEnabled == (S_BIT|T_BIT|R_BIT)) {
564cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    if (texUnit->_GenFlags == TEXGEN_REFLECTION_MAP_NV) {
565cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	       store->TexgenFunc[i] = texgen_reflection_map_nv;
566cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    }
567cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    else if (texUnit->_GenFlags == TEXGEN_NORMAL_MAP_NV) {
568cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	       store->TexgenFunc[i] = texgen_normal_map_nv;
569cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    }
570cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 }
571cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 else if (texUnit->TexGenEnabled == (S_BIT|T_BIT) &&
572cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell		  texUnit->_GenFlags == TEXGEN_SPHERE_MAP) {
573cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    store->TexgenFunc[i] = texgen_sphere_map;
574cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 }
575cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      }
576cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
577cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
578cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   stage->run = run_texgen_stage;
579cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   return stage->run( ctx, stage );
580cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
581cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
582cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
583ae0eaf93e092ac8e8b1c98f3e986de96940663faKeith Whitwellstatic void check_texgen( GLcontext *ctx, struct tnl_pipeline_stage *stage )
584cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
585cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
586cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   stage->active = 0;
587cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
58886b842790b720cd6b1499ce8edca8a4e9c8dc029Brian Paul   if (ctx->Texture._TexGenEnabled && !ctx->VertexProgram.Enabled) {
589cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLuint inputs = 0;
590cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      GLuint outputs = 0;
591cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
592ae0eaf93e092ac8e8b1c98f3e986de96940663faKeith Whitwell      if (ctx->Texture._GenFlags & (TEXGEN_OBJ_LINEAR | TEXGEN_NEED_EYE_COORD))
593ae0eaf93e092ac8e8b1c98f3e986de96940663faKeith Whitwell	 inputs |= _TNL_BIT_POS;
594cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
595cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      if (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS)
596ae0eaf93e092ac8e8b1c98f3e986de96940663faKeith Whitwell	 inputs |= _TNL_BIT_NORMAL;
597cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
59892f9785c727ea10ff5f8dc9770f0e8f388fcea70Brian Paul      for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
599ed39a43b8cb2e1cf69b097fc89365cde470ebf51Keith Whitwell	 if (ctx->Texture._TexGenEnabled & ENABLE_TEXGEN(i))
600cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 {
601ae0eaf93e092ac8e8b1c98f3e986de96940663faKeith Whitwell	    outputs |= _TNL_BIT_TEX(i);
602cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
603cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    /* Need the original input in case it contains a Q coord:
604cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	     * (sigh)
605cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	     */
606ae0eaf93e092ac8e8b1c98f3e986de96940663faKeith Whitwell	    inputs |= _TNL_BIT_TEX(i);
607cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
608cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	    /* Something for Feedback? */
609cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 }
610cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
611b51b0a847d7e7daaea69f77ab569086ef81c24a2Brian Paul      if (stage->privatePtr)
612cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell	 stage->run = run_validate_texgen_stage;
613cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      stage->active = 1;
614cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      stage->inputs = inputs;
615cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      stage->outputs = outputs;
616cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
617cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
61822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
619cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
620cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
621cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
622cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell/* Called the first time stage->run() is invoked.
623cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell */
62422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughesstatic GLboolean alloc_texgen_data( GLcontext *ctx,
625ae0eaf93e092ac8e8b1c98f3e986de96940663faKeith Whitwell				    struct tnl_pipeline_stage *stage )
626cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
62722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
628cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   struct texgen_stage_data *store;
629cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
630cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
631b51b0a847d7e7daaea69f77ab569086ef81c24a2Brian Paul   stage->privatePtr = CALLOC(sizeof(*store));
632cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   store = TEXGEN_STAGE_DATA(stage);
633cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (!store)
634cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      return GL_FALSE;
635cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
63692f9785c727ea10ff5f8dc9770f0e8f388fcea70Brian Paul   for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
63708836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      _mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 );
638cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
639cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   store->tmp_f = (GLfloat (*)[3]) MALLOC(VB->Size * sizeof(GLfloat) * 3);
640cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   store->tmp_m = (GLfloat *) MALLOC(VB->Size * sizeof(GLfloat));
641cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
642cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   /* Now validate and run the stage.
643cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell    */
644cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   stage->run = run_validate_texgen_stage;
645cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   return stage->run( ctx, stage );
646cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
647cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
648cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
649ae0eaf93e092ac8e8b1c98f3e986de96940663faKeith Whitwellstatic void free_texgen_data( struct tnl_pipeline_stage *stage )
650cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
651cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell{
652cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage);
653cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   GLuint i;
654cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
655cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   if (store) {
656610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul      for (i = 0 ; i < MAX_TEXTURE_COORD_UNITS ; i++)
65722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes	 if (store->texcoord[i].data)
65808836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul	    _mesa_vector4f_free( &store->texcoord[i] );
659cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
66022144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
661cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      if (store->tmp_f) FREE( store->tmp_f );
662cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      if (store->tmp_m) FREE( store->tmp_m );
663cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell      FREE( store );
664b51b0a847d7e7daaea69f77ab569086ef81c24a2Brian Paul      stage->privatePtr = NULL;
665cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   }
666cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell}
667cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
668cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
66922144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
670ae0eaf93e092ac8e8b1c98f3e986de96940663faKeith Whitwellconst struct tnl_pipeline_stage _tnl_texgen_stage =
67122144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes{
67286b842790b720cd6b1499ce8edca8a4e9c8dc029Brian Paul   "texgen",			/* name */
673cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   _NEW_TEXTURE,		/* when to call check() */
674cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   _NEW_TEXTURE,		/* when to invalidate stored data */
67586b842790b720cd6b1499ce8edca8a4e9c8dc029Brian Paul   GL_FALSE,			/* active? */
67686b842790b720cd6b1499ce8edca8a4e9c8dc029Brian Paul   0,				/* inputs */
67786b842790b720cd6b1499ce8edca8a4e9c8dc029Brian Paul   0,				/* outputs */
67886b842790b720cd6b1499ce8edca8a4e9c8dc029Brian Paul   0,				/* changed_inputs */
67986b842790b720cd6b1499ce8edca8a4e9c8dc029Brian Paul   NULL,			/* private data */
680cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   free_texgen_data,		/* destructor */
681cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   check_texgen,		/* check */
682cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   alloc_texgen_data		/* run -- initially set to alloc data */
683cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell};
684