3 * Mesa 3-D graphics library
6 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
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:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
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.
26 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
30 * Keith Whitwell <keith@precisioninsight.com>
34 /* fxvsetup.c - 3Dfx VooDoo vertices setup functions */
45 #include "swrast_setup/swrast_setup.h"
47 #include "tnl/t_context.h"
48 #include "tnl/t_pipeline.h"
51 void fxPrintSetupFlags( const char *msg
, GLuint flags
)
53 fprintf(stderr
, "%s: %d %s%s%s%s%s\n",
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," : "");
63 static void project_texcoords( fxVertex
*v
,
64 struct vertex_buffer
*VB
,
65 GLuint tmu_nr
, GLuint tc_nr
,
66 GLuint start
, GLuint count
)
68 GrTmuVertex
*tmu
= &(v
->v
.tmuvtx
[tmu_nr
]);
69 GLvector4f
*vec
= VB
->TexCoordPtr
[tc_nr
];
72 GLuint stride
= vec
->stride
;
73 GLfloat
*data
= VEC_ELT(vec
, GLfloat
, start
);
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
));
82 static void copy_w( fxVertex
*v
,
83 struct vertex_buffer
*VB
,
85 GLuint start
, GLuint count
)
87 GrTmuVertex
*tmu
= &(v
->v
.tmuvtx
[tmu_nr
]);
90 for (i
= start
; i
< count
; i
++, v
++) {
92 tmu
= (GrTmuVertex
*)((char *)tmu
+ sizeof(fxVertex
));
96 /* need to compute W values for fogging purposes
98 static void fx_fake_fog_w( GLcontext
*ctx
,
100 struct vertex_buffer
*VB
,
101 GLuint start
, GLuint end
)
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
;
109 for ( i
= start
; i
< end
; i
++) {
110 if (clipmask
[i
] == 0) {
111 verts
[i
].v
.oow
= - m10
/ (clip
[i
][2] - m14
); /* -1/zEye */
118 static tfxSetupFunc setupfuncs
[MAX_SETUP
];
121 #define IND (SETUP_XYZW)
122 #define INPUTS (VERT_CLIP)
123 #define NAME fxsetupXYZW
126 #define IND (SETUP_XYZW|SETUP_RGBA)
127 #define INPUTS (VERT_CLIP|VERT_RGBA)
128 #define NAME fxsetupXYZWRGBA
131 #define IND (SETUP_XYZW|SETUP_TMU0)
132 #define INPUTS (VERT_CLIP|VERT_TEX_ANY)
133 #define NAME fxsetupXYZWT0
136 #define IND (SETUP_XYZW|SETUP_TMU1)
137 #define INPUTS (VERT_CLIP|VERT_TEX_ANY)
138 #define NAME fxsetupXYZWT1
141 #define IND (SETUP_XYZW|SETUP_TMU1|SETUP_TMU0)
142 #define INPUTS (VERT_CLIP|VERT_TEX_ANY)
143 #define NAME fxsetupXYZWT0T1
146 #define IND (SETUP_XYZW|SETUP_TMU0|SETUP_RGBA)
147 #define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
148 #define NAME fxsetupXYZWRGBAT0
151 #define IND (SETUP_XYZW|SETUP_TMU1|SETUP_RGBA)
152 #define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
153 #define NAME fxsetupXYZWRGBAT1
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
162 #define IND (SETUP_XYZW|SETUP_SNAP)
163 #define INPUTS (VERT_CLIP)
164 #define NAME fxsetupXYZW_SNAP
167 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA)
168 #define INPUTS (VERT_CLIP|VERT_RGBA)
169 #define NAME fxsetupXYZW_SNAP_RGBA
172 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU0)
173 #define INPUTS (VERT_CLIP|VERT_TEX_ANY)
174 #define NAME fxsetupXYZW_SNAP_T0
177 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1)
178 #define INPUTS (VERT_CLIP|VERT_TEX_ANY)
179 #define NAME fxsetupXYZW_SNAP_T1
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
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
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
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
204 #define IND (SETUP_RGBA)
205 #define INPUTS (VERT_RGBA)
206 #define NAME fxsetupRGBA
209 #define IND (SETUP_TMU0)
210 #define INPUTS (VERT_TEX_ANY)
211 #define NAME fxsetupT0
214 #define IND (SETUP_TMU1)
215 #define INPUTS (VERT_TEX_ANY)
216 #define NAME fxsetupT1
219 #define IND (SETUP_TMU1|SETUP_TMU0)
220 #define INPUTS (VERT_TEX_ANY)
221 #define NAME fxsetupT0T1
224 #define IND (SETUP_TMU0|SETUP_RGBA)
225 #define INPUTS (VERT_RGBA|VERT_TEX_ANY)
226 #define NAME fxsetupRGBAT0
229 #define IND (SETUP_TMU1|SETUP_RGBA)
230 #define INPUTS (VERT_RGBA|VERT_TEX_ANY)
231 #define NAME fxsetupRGBAT1
234 #define IND (SETUP_TMU1|SETUP_TMU0|SETUP_RGBA)
235 #define INPUTS (VERT_RGBA|VERT_TEX_ANY)
236 #define NAME fxsetupRGBAT0T1
241 fxsetup_invalid( GLcontext
*ctx
, GLuint start
, GLuint end
, GLuint newinputs
)
243 fprintf(stderr
, "fxMesa: invalid setup function\n");
244 (void) (ctx
&& start
&& end
&& newinputs
);
248 void fxDDSetupInit( void )
251 for (i
= 0 ; i
< Elements(setupfuncs
) ; i
++)
252 setupfuncs
[i
] = fxsetup_invalid
;
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
] =
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
;
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
;
288 void fx_validate_BuildProjVerts(GLcontext
*ctx
, GLuint start
, GLuint count
,
291 GLuint setupindex
= SETUP_XYZW
;
292 fxMesaContext fxMesa
= (fxMesaContext
)ctx
->DriverCtx
;
294 if (!fxMesa
->is_in_hardware
)
295 ctx
->Driver
.BuildProjectedVertices
= _swsetup_BuildProjectedVertices
;
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
;
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.
306 if ((ctx
->_TriangleCaps
& (DD_FLATSHADE
|DD_TRI_LIGHT_TWOSIDE
)) == 0)
307 setupindex
|= SETUP_RGBA
;
309 if (ctx
->Texture
._ReallyEnabled
& TEXTURE0_2D
)
310 setupindex
|= SETUP_TMU0
;
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
;
318 setupindex
|= SETUP_TMU1
;
322 if (MESA_VERBOSE
& (VERBOSE_DRIVER
|VERBOSE_PIPELINE
|VERBOSE_STATE
))
323 fxPrintSetupFlags("fxmesa: vertex setup function", setupindex
);
325 fxMesa
->setupindex
= setupindex
;
326 ctx
->Driver
.BuildProjectedVertices
= fx_BuildProjVerts
;
328 ctx
->Driver
.BuildProjectedVertices( ctx
, start
, count
, newinputs
);
332 void fx_BuildProjVerts( GLcontext
*ctx
, GLuint start
, GLuint count
,
335 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
336 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
337 GLuint ind
= fxMesa
->setup_gone
;
339 fxMesa
->setup_gone
= 0;
341 if (newinputs
& VERT_CLIP
)
342 ind
= fxMesa
->setupindex
; /* clipmask has changed - invalidated all */
344 if (newinputs
& VERT_TEX0
)
345 ind
|= fxMesa
->tex_dest
[0];
347 if (newinputs
& VERT_TEX1
)
348 ind
|= fxMesa
->tex_dest
[1];
350 if (newinputs
& VERT_RGBA
)
353 ind
&= fxMesa
->setupindex
;
357 _tnl_print_vert_flags("newinputs", newinputs
);
358 fxPrintSetupFlags("setup function", ind
);
361 if (fxMesa
->new_state
)
362 fxSetupFXUnits( ctx
);
364 if (VB
->importable_data
)
365 VB
->import_data( ctx
, VB
->importable_data
& newinputs
,
367 ? VEC_NOT_WRITEABLE
|VEC_BAD_STRIDE
370 setupfuncs
[ind
]( ctx
, start
, count
, newinputs
);
374 void fxAllocVB( GLcontext
*ctx
)
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 );
381 void fxFreeVB( GLcontext
*ctx
)
383 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
385 ALIGN_FREE( fxMesa
->verts
);
394 * Need this to provide at least one external definition.
397 extern int gl_fx_dummy_function_vsetup(void);
398 int gl_fx_dummy_function_vsetup(void)