Major rework of tnl module
[mesa.git] / src / mesa / drivers / glide / fxvb.c
1
2 /*
3 * Mesa 3-D graphics library
4 * Version: 3.3
5 *
6 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 *
26 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
27 * terms stated above.
28 *
29 * Author:
30 * Keith Whitwell <keith@precisioninsight.com>
31 */
32
33
34 /* fxvsetup.c - 3Dfx VooDoo vertices setup functions */
35
36
37 #ifdef HAVE_CONFIG_H
38 #include "conf.h"
39 #endif
40
41 #if defined(FX)
42
43 #include "fxdrv.h"
44 #include "mmath.h"
45 #include "swrast_setup/swrast_setup.h"
46
47 #include "tnl/t_context.h"
48 #include "tnl/t_pipeline.h"
49
50
51 void fxPrintSetupFlags( const char *msg, GLuint flags )
52 {
53 fprintf(stderr, "%s: %d %s%s%s%s%s\n",
54 msg,
55 flags,
56 (flags & SETUP_XYZW) ? " xyzw," : "",
57 (flags & SETUP_SNAP) ? " snap," : "",
58 (flags & SETUP_RGBA) ? " rgba," : "",
59 (flags & SETUP_TMU0) ? " tmu0," : "",
60 (flags & SETUP_TMU1) ? " tmu1," : "");
61 }
62
63 static void project_texcoords( fxVertex *v,
64 struct vertex_buffer *VB,
65 GLuint tmu_nr, GLuint tc_nr,
66 GLuint start, GLuint count )
67 {
68 GrTmuVertex *tmu = &(v->v.tmuvtx[tmu_nr]);
69 GLvector4f *vec = VB->TexCoordPtr[tc_nr];
70
71 GLuint i;
72 GLuint stride = vec->stride;
73 GLfloat *data = VEC_ELT(vec, GLfloat, start);
74
75 for (i = start ; i < count ; i++, STRIDE_F(data, stride), v++) {
76 tmu->oow = v->v.oow * data[3];
77 tmu = (GrTmuVertex *)((char *)tmu + sizeof(fxVertex));
78 }
79 }
80
81
82 static void copy_w( fxVertex *v,
83 struct vertex_buffer *VB,
84 GLuint tmu_nr,
85 GLuint start, GLuint count )
86 {
87 GrTmuVertex *tmu = &(v->v.tmuvtx[tmu_nr]);
88 GLuint i;
89
90 for (i = start ; i < count ; i++, v++) {
91 tmu->oow = v->v.oow;
92 tmu = (GrTmuVertex *)((char *)tmu + sizeof(fxVertex));
93 }
94 }
95
96 /* need to compute W values for fogging purposes
97 */
98 static void fx_fake_fog_w( GLcontext *ctx,
99 fxVertex *verts,
100 struct vertex_buffer *VB,
101 GLuint start, GLuint end )
102 {
103 const GLfloat m10 = ctx->ProjectionMatrix.m[10];
104 const GLfloat m14 = ctx->ProjectionMatrix.m[14];
105 GLfloat (*clip)[4] = VB->ClipPtr->data;
106 GLubyte *clipmask = VB->ClipMask;
107 GLuint i;
108
109 for ( i = start ; i < end ; i++) {
110 if (clipmask[i] == 0) {
111 verts[i].v.oow = - m10 / (clip[i][2] - m14); /* -1/zEye */
112 }
113 }
114 }
115
116
117
118 static tfxSetupFunc setupfuncs[MAX_SETUP];
119
120
121 #define IND (SETUP_XYZW)
122 #define INPUTS (VERT_CLIP)
123 #define NAME fxsetupXYZW
124 #include "fxvbtmp.h"
125
126 #define IND (SETUP_XYZW|SETUP_RGBA)
127 #define INPUTS (VERT_CLIP|VERT_RGBA)
128 #define NAME fxsetupXYZWRGBA
129 #include "fxvbtmp.h"
130
131 #define IND (SETUP_XYZW|SETUP_TMU0)
132 #define INPUTS (VERT_CLIP|VERT_TEX_ANY)
133 #define NAME fxsetupXYZWT0
134 #include "fxvbtmp.h"
135
136 #define IND (SETUP_XYZW|SETUP_TMU1)
137 #define INPUTS (VERT_CLIP|VERT_TEX_ANY)
138 #define NAME fxsetupXYZWT1
139 #include "fxvbtmp.h"
140
141 #define IND (SETUP_XYZW|SETUP_TMU1|SETUP_TMU0)
142 #define INPUTS (VERT_CLIP|VERT_TEX_ANY)
143 #define NAME fxsetupXYZWT0T1
144 #include "fxvbtmp.h"
145
146 #define IND (SETUP_XYZW|SETUP_TMU0|SETUP_RGBA)
147 #define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
148 #define NAME fxsetupXYZWRGBAT0
149 #include "fxvbtmp.h"
150
151 #define IND (SETUP_XYZW|SETUP_TMU1|SETUP_RGBA)
152 #define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
153 #define NAME fxsetupXYZWRGBAT1
154 #include "fxvbtmp.h"
155
156 #define IND (SETUP_XYZW|SETUP_TMU1|SETUP_TMU0|SETUP_RGBA)
157 #define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
158 #define NAME fxsetupXYZWRGBAT0T1
159 #include "fxvbtmp.h"
160
161
162 #define IND (SETUP_XYZW|SETUP_SNAP)
163 #define INPUTS (VERT_CLIP)
164 #define NAME fxsetupXYZW_SNAP
165 #include "fxvbtmp.h"
166
167 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA)
168 #define INPUTS (VERT_CLIP|VERT_RGBA)
169 #define NAME fxsetupXYZW_SNAP_RGBA
170 #include "fxvbtmp.h"
171
172 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU0)
173 #define INPUTS (VERT_CLIP|VERT_TEX_ANY)
174 #define NAME fxsetupXYZW_SNAP_T0
175 #include "fxvbtmp.h"
176
177 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1)
178 #define INPUTS (VERT_CLIP|VERT_TEX_ANY)
179 #define NAME fxsetupXYZW_SNAP_T1
180 #include "fxvbtmp.h"
181
182 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_TMU0)
183 #define INPUTS (VERT_CLIP|VERT_TEX_ANY)
184 #define NAME fxsetupXYZW_SNAP_T0T1
185 #include "fxvbtmp.h"
186
187 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU0|SETUP_RGBA)
188 #define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
189 #define NAME fxsetupXYZW_SNAP_RGBAT0
190 #include "fxvbtmp.h"
191
192 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_RGBA)
193 #define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
194 #define NAME fxsetupXYZW_SNAP_RGBAT1
195 #include "fxvbtmp.h"
196
197 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_TMU0|SETUP_RGBA)
198 #define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
199 #define NAME fxsetupXYZW_SNAP_RGBAT0T1
200 #include "fxvbtmp.h"
201
202
203
204 #define IND (SETUP_RGBA)
205 #define INPUTS (VERT_RGBA)
206 #define NAME fxsetupRGBA
207 #include "fxvbtmp.h"
208
209 #define IND (SETUP_TMU0)
210 #define INPUTS (VERT_TEX_ANY)
211 #define NAME fxsetupT0
212 #include "fxvbtmp.h"
213
214 #define IND (SETUP_TMU1)
215 #define INPUTS (VERT_TEX_ANY)
216 #define NAME fxsetupT1
217 #include "fxvbtmp.h"
218
219 #define IND (SETUP_TMU1|SETUP_TMU0)
220 #define INPUTS (VERT_TEX_ANY)
221 #define NAME fxsetupT0T1
222 #include "fxvbtmp.h"
223
224 #define IND (SETUP_TMU0|SETUP_RGBA)
225 #define INPUTS (VERT_RGBA|VERT_TEX_ANY)
226 #define NAME fxsetupRGBAT0
227 #include "fxvbtmp.h"
228
229 #define IND (SETUP_TMU1|SETUP_RGBA)
230 #define INPUTS (VERT_RGBA|VERT_TEX_ANY)
231 #define NAME fxsetupRGBAT1
232 #include "fxvbtmp.h"
233
234 #define IND (SETUP_TMU1|SETUP_TMU0|SETUP_RGBA)
235 #define INPUTS (VERT_RGBA|VERT_TEX_ANY)
236 #define NAME fxsetupRGBAT0T1
237 #include "fxvbtmp.h"
238
239
240 static void
241 fxsetup_invalid( GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs )
242 {
243 fprintf(stderr, "fxMesa: invalid setup function\n");
244 (void) (ctx && start && end && newinputs);
245 }
246
247
248 void fxDDSetupInit( void )
249 {
250 GLuint i;
251 for (i = 0 ; i < Elements(setupfuncs) ; i++)
252 setupfuncs[i] = fxsetup_invalid;
253
254 setupfuncs[SETUP_XYZW] = fxsetupXYZW;
255 setupfuncs[SETUP_XYZW|SETUP_RGBA] = fxsetupXYZWRGBA;
256 setupfuncs[SETUP_XYZW|SETUP_TMU0] = fxsetupXYZWT0;
257 setupfuncs[SETUP_XYZW|SETUP_TMU1] = fxsetupXYZWT1;
258 setupfuncs[SETUP_XYZW|SETUP_TMU0|SETUP_RGBA] = fxsetupXYZWRGBAT0;
259 setupfuncs[SETUP_XYZW|SETUP_TMU1|SETUP_RGBA] = fxsetupXYZWRGBAT1;
260 setupfuncs[SETUP_XYZW|SETUP_TMU1|SETUP_TMU0] = fxsetupXYZWT0T1;
261 setupfuncs[SETUP_XYZW|SETUP_TMU1|SETUP_TMU0|SETUP_RGBA] =
262 fxsetupXYZWRGBAT0T1;
263
264 setupfuncs[SETUP_XYZW|SETUP_SNAP] = fxsetupXYZW_SNAP;
265 setupfuncs[SETUP_XYZW|SETUP_SNAP|SETUP_RGBA] = fxsetupXYZW_SNAP_RGBA;
266 setupfuncs[SETUP_XYZW|SETUP_SNAP|SETUP_TMU0] = fxsetupXYZW_SNAP_T0;
267 setupfuncs[SETUP_XYZW|SETUP_SNAP|SETUP_TMU1] = fxsetupXYZW_SNAP_T1;
268 setupfuncs[SETUP_XYZW|SETUP_SNAP|SETUP_TMU0|SETUP_RGBA] =
269 fxsetupXYZW_SNAP_RGBAT0;
270 setupfuncs[SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_RGBA] =
271 fxsetupXYZW_SNAP_RGBAT1;
272 setupfuncs[SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_TMU0] =
273 fxsetupXYZW_SNAP_T0T1;
274 setupfuncs[SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_TMU0|SETUP_RGBA] =
275 fxsetupXYZW_SNAP_RGBAT0T1;
276
277 setupfuncs[SETUP_RGBA] = fxsetupRGBA;
278 setupfuncs[SETUP_TMU0] = fxsetupT0;
279 setupfuncs[SETUP_TMU1] = fxsetupT1;
280 setupfuncs[SETUP_TMU1|SETUP_TMU0] = fxsetupT0T1;
281 setupfuncs[SETUP_TMU0|SETUP_RGBA] = fxsetupRGBAT0;
282 setupfuncs[SETUP_TMU1|SETUP_RGBA] = fxsetupRGBAT1;
283 setupfuncs[SETUP_TMU1|SETUP_TMU0|SETUP_RGBA] = fxsetupRGBAT0T1;
284 }
285
286
287
288 void fx_validate_BuildProjVerts(GLcontext *ctx, GLuint start, GLuint count,
289 GLuint newinputs )
290 {
291 GLuint setupindex = SETUP_XYZW;
292 fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
293
294 if (!fxMesa->is_in_hardware)
295 ctx->Driver.BuildProjectedVertices = _swsetup_BuildProjectedVertices;
296 else {
297 fxMesa->tmu_source[0] = 0;
298 fxMesa->tmu_source[1] = 1;
299 fxMesa->tex_dest[0] = SETUP_TMU0;
300 fxMesa->tex_dest[1] = SETUP_TMU1;
301
302 /* For flat and two-side-lit triangles, colors will always be added
303 * to vertices in the triangle functions. Vertices will *always*
304 * have rbga values, but only sometimes will they come from here.
305 */
306 if ((ctx->_TriangleCaps & (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE)) == 0)
307 setupindex |= SETUP_RGBA;
308
309 if (ctx->Texture._ReallyEnabled & TEXTURE0_2D)
310 setupindex |= SETUP_TMU0;
311
312 if (ctx->Texture._ReallyEnabled & TEXTURE1_2D) {
313 if ((ctx->Texture._ReallyEnabled & TEXTURE0_2D) == 0) {
314 fxMesa->tmu_source[0] = 1; fxMesa->tex_dest[0] = SETUP_TMU1;
315 fxMesa->tmu_source[1] = 0; fxMesa->tex_dest[1] = SETUP_TMU0;
316 setupindex |= SETUP_TMU0;
317 } else {
318 setupindex |= SETUP_TMU1;
319 }
320 }
321
322 if (MESA_VERBOSE & (VERBOSE_DRIVER|VERBOSE_PIPELINE|VERBOSE_STATE))
323 fxPrintSetupFlags("fxmesa: vertex setup function", setupindex);
324
325 fxMesa->setupindex = setupindex;
326 ctx->Driver.BuildProjectedVertices = fx_BuildProjVerts;
327 }
328 ctx->Driver.BuildProjectedVertices( ctx, start, count, newinputs );
329 }
330
331
332 void fx_BuildProjVerts( GLcontext *ctx, GLuint start, GLuint count,
333 GLuint newinputs )
334 {
335 fxMesaContext fxMesa = FX_CONTEXT(ctx);
336 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
337 GLuint ind = fxMesa->setup_gone;
338
339 fxMesa->setup_gone = 0;
340
341 if (newinputs & VERT_CLIP)
342 ind = fxMesa->setupindex; /* clipmask has changed - invalidated all */
343 else {
344 if (newinputs & VERT_TEX0)
345 ind |= fxMesa->tex_dest[0];
346
347 if (newinputs & VERT_TEX1)
348 ind |= fxMesa->tex_dest[1];
349
350 if (newinputs & VERT_RGBA)
351 ind |= SETUP_RGBA;
352
353 ind &= fxMesa->setupindex;
354 }
355
356 if (0) {
357 _tnl_print_vert_flags("newinputs", newinputs);
358 fxPrintSetupFlags("setup function", ind);
359 }
360
361 if (fxMesa->new_state)
362 fxSetupFXUnits( ctx );
363
364 if (VB->importable_data)
365 VB->import_data( ctx, VB->importable_data & newinputs,
366 (VB->ClipOrMask
367 ? VEC_NOT_WRITEABLE|VEC_BAD_STRIDE
368 : VEC_BAD_STRIDE));
369
370 setupfuncs[ind]( ctx, start, count, newinputs );
371 }
372
373
374 void fxAllocVB( GLcontext *ctx )
375 {
376 fxMesaContext fxMesa = FX_CONTEXT(ctx);
377 TNLcontext *tnl = TNL_CONTEXT(ctx);
378 fxMesa->verts = ALIGN_MALLOC( tnl->vb.Size * sizeof(fxMesa->verts[0]), 32 );
379 }
380
381 void fxFreeVB( GLcontext *ctx )
382 {
383 fxMesaContext fxMesa = FX_CONTEXT(ctx);
384 if (fxMesa->verts)
385 ALIGN_FREE( fxMesa->verts );
386 fxMesa->verts = 0;
387 }
388
389
390 #else
391
392
393 /*
394 * Need this to provide at least one external definition.
395 */
396
397 extern int gl_fx_dummy_function_vsetup(void);
398 int gl_fx_dummy_function_vsetup(void)
399 {
400 return 0;
401 }
402
403 #endif /* FX */