2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
23 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * Keith Whitwell <keith@tungstengraphics.com>
28 * Daniel Borca <dborca@users.sourceforge.net>
43 #include "math/m_translate.h"
44 #include "swrast_setup/swrast_setup.h"
47 #include "tnl/t_context.h"
52 static void copy_pv( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
54 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
55 GrVertex
*dst
= fxMesa
->verts
+ edst
;
56 GrVertex
*src
= fxMesa
->verts
+ esrc
;
58 *(GLuint
*)&dst
->pargb
= *(GLuint
*)&src
->pargb
;
61 static void copy_pv2( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
63 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
64 GrVertex
*dst
= fxMesa
->verts
+ edst
;
65 GrVertex
*src
= fxMesa
->verts
+ esrc
;
67 *(GLuint
*)&dst
->pargb
= *(GLuint
*)&src
->pargb
;
68 *(GLuint
*)&dst
->pspec
= *(GLuint
*)&src
->pspec
;
71 typedef void (*emit_func
)( GLcontext
*, GLuint
, GLuint
, void * );
75 tnl_copy_pv_func copy_pv
;
76 tnl_interp_func interp
;
77 GLboolean (*check_tex_sizes
)( GLcontext
*ctx
);
79 } setup_tab
[MAX_SETUP
];
82 #define GET_COLOR(ptr, idx) ((ptr)->data[idx])
85 static void interp_extras( GLcontext
*ctx
,
87 GLuint dst
, GLuint out
, GLuint in
,
88 GLboolean force_boundary
)
90 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
92 if (VB
->ColorPtr
[1]) {
93 assert(VB
->ColorPtr
[1]->stride
== 4 * sizeof(GLfloat
));
96 GET_COLOR(VB
->ColorPtr
[1], dst
),
97 GET_COLOR(VB
->ColorPtr
[1], out
),
98 GET_COLOR(VB
->ColorPtr
[1], in
) );
100 if (VB
->SecondaryColorPtr
[1]) {
102 GET_COLOR(VB
->SecondaryColorPtr
[1], dst
),
103 GET_COLOR(VB
->SecondaryColorPtr
[1], out
),
104 GET_COLOR(VB
->SecondaryColorPtr
[1], in
) );
109 VB
->EdgeFlag
[dst
] = VB
->EdgeFlag
[out
] || force_boundary
;
112 setup_tab
[FX_CONTEXT(ctx
)->SetupIndex
].interp(ctx
, t
, dst
, out
, in
,
116 static void copy_pv_extras( GLcontext
*ctx
, GLuint dst
, GLuint src
)
118 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
120 if (VB
->ColorPtr
[1]) {
121 COPY_4FV( GET_COLOR(VB
->ColorPtr
[1], dst
),
122 GET_COLOR(VB
->ColorPtr
[1], src
) );
124 if (VB
->SecondaryColorPtr
[1]) {
125 COPY_3FV( GET_COLOR(VB
->SecondaryColorPtr
[1], dst
),
126 GET_COLOR(VB
->SecondaryColorPtr
[1], src
) );
130 setup_tab
[FX_CONTEXT(ctx
)->SetupIndex
].copy_pv(ctx
, dst
, src
);
134 #define IND (SETUP_XYZW|SETUP_RGBA)
135 #define TAG(x) x##_wg
138 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0)
139 #define TAG(x) x##_wgt0
142 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1)
143 #define TAG(x) x##_wgt0t1
146 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_PTEX)
147 #define TAG(x) x##_wgpt0
150 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1|\
152 #define TAG(x) x##_wgpt0t1
155 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_PSIZ)
156 #define TAG(x) x##_wga
159 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_PSIZ)
160 #define TAG(x) x##_wgt0a
163 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1|SETUP_PSIZ)
164 #define TAG(x) x##_wgt0t1a
167 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_PTEX|SETUP_PSIZ)
168 #define TAG(x) x##_wgpt0a
171 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1|\
172 SETUP_PTEX|SETUP_PSIZ)
173 #define TAG(x) x##_wgpt0t1a
177 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC)
178 #define TAG(x) x##_2wg
181 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0)
182 #define TAG(x) x##_2wgt0
185 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1)
186 #define TAG(x) x##_2wgt0t1
189 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_PTEX)
190 #define TAG(x) x##_2wgpt0
193 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1|\
195 #define TAG(x) x##_2wgpt0t1
198 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_PSIZ)
199 #define TAG(x) x##_2wga
202 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_PSIZ)
203 #define TAG(x) x##_2wgt0a
206 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1|SETUP_PSIZ)
207 #define TAG(x) x##_2wgt0t1a
210 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_PTEX|SETUP_PSIZ)
211 #define TAG(x) x##_2wgpt0a
214 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1|\
215 SETUP_PTEX|SETUP_PSIZ)
216 #define TAG(x) x##_2wgpt0t1a
220 /* Snapping for voodoo-1
222 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA)
223 #define TAG(x) x##_wsg
226 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0)
227 #define TAG(x) x##_wsgt0
230 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
232 #define TAG(x) x##_wsgt0t1
235 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
237 #define TAG(x) x##_wsgpt0
240 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
241 SETUP_TMU1|SETUP_PTEX)
242 #define TAG(x) x##_wsgpt0t1
245 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_PSIZ)
246 #define TAG(x) x##_wsga
249 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|SETUP_PSIZ)
250 #define TAG(x) x##_wsgt0a
253 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
254 SETUP_TMU1|SETUP_PSIZ)
255 #define TAG(x) x##_wsgt0t1a
258 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
259 SETUP_PTEX|SETUP_PSIZ)
260 #define TAG(x) x##_wsgpt0a
263 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
264 SETUP_TMU1|SETUP_PTEX|SETUP_PSIZ)
265 #define TAG(x) x##_wsgpt0t1a
269 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC)
270 #define TAG(x) x##_2wsg
273 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0)
274 #define TAG(x) x##_2wsgt0
277 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\
279 #define TAG(x) x##_2wsgt0t1
282 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\
284 #define TAG(x) x##_2wsgpt0
287 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\
288 SETUP_TMU1|SETUP_PTEX)
289 #define TAG(x) x##_2wsgpt0t1
292 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_PSIZ)
293 #define TAG(x) x##_2wsga
296 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_PSIZ)
297 #define TAG(x) x##_2wsgt0a
300 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\
301 SETUP_TMU1|SETUP_PSIZ)
302 #define TAG(x) x##_2wsgt0t1a
305 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\
306 SETUP_PTEX|SETUP_PSIZ)
307 #define TAG(x) x##_2wsgpt0a
310 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\
311 SETUP_TMU1|SETUP_PTEX|SETUP_PSIZ)
312 #define TAG(x) x##_2wsgpt0t1a
316 /* Vertex repair (multipass rendering)
318 #define IND (SETUP_RGBA)
322 #define IND (SETUP_TMU0)
323 #define TAG(x) x##_t0
326 #define IND (SETUP_TMU0|SETUP_TMU1)
327 #define TAG(x) x##_t0t1
330 #define IND (SETUP_RGBA|SETUP_TMU0)
331 #define TAG(x) x##_gt0
334 #define IND (SETUP_RGBA|SETUP_TMU0|SETUP_TMU1)
335 #define TAG(x) x##_gt0t1
339 #define IND (SETUP_RGBA|SETUP_SPEC)
340 #define TAG(x) x##_2g
343 #define IND (SETUP_TMU0|SETUP_SPEC)
344 #define TAG(x) x##_2t0
347 #define IND (SETUP_TMU0|SETUP_SPEC|SETUP_TMU1)
348 #define TAG(x) x##_2t0t1
351 #define IND (SETUP_RGBA|SETUP_SPEC|SETUP_TMU0)
352 #define TAG(x) x##_2gt0
355 #define IND (SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1)
356 #define TAG(x) x##_2gt0t1
361 static void init_setup_tab( void )
418 void fxPrintSetupFlags(char *msg
, GLuint flags
)
420 fprintf(stderr
, "%s(%x): %s%s%s%s%s%s%s\n",
423 (flags
& SETUP_XYZW
) ? " xyzw," : "",
424 (flags
& SETUP_SNAP
) ? " snap," : "",
425 (flags
& SETUP_RGBA
) ? " rgba," : "",
426 (flags
& SETUP_TMU0
) ? " tex-0," : "",
427 (flags
& SETUP_TMU1
) ? " tex-1," : "",
428 (flags
& SETUP_PSIZ
) ? " psiz," : "",
429 (flags
& SETUP_SPEC
) ? " spec," : "");
434 void fxCheckTexSizes( GLcontext
*ctx
)
436 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
437 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
439 if (!setup_tab
[fxMesa
->SetupIndex
].check_tex_sizes(ctx
)) {
440 GLuint ind
= fxMesa
->SetupIndex
|= (SETUP_PTEX
|SETUP_RGBA
);
442 /* Tdfx handles projective textures nicely; just have to change
443 * up to the new vertex format.
445 if (setup_tab
[ind
].vertex_format
!= fxMesa
->stw_hint_state
) {
447 fxMesa
->stw_hint_state
= setup_tab
[ind
].vertex_format
;
448 FX_grHints(GR_HINT_STWHINT
, fxMesa
->stw_hint_state
);
450 /* This is required as we have just changed the vertex
451 * format, so the interp routines must also change.
452 * In the unfilled and twosided cases we are using the
453 * Extras ones anyway, so leave them in place.
455 if (!(ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
456 tnl
->Driver
.Render
.Interp
= setup_tab
[fxMesa
->SetupIndex
].interp
;
463 void fxBuildVertices( GLcontext
*ctx
, GLuint start
, GLuint count
,
466 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
467 GrVertex
*v
= (fxMesa
->verts
+ start
);
472 if (newinputs
& VERT_BIT_POS
) {
473 setup_tab
[fxMesa
->SetupIndex
].emit( ctx
, start
, count
, v
);
477 /* [dBorca] masked by VERT_BIT_POS ?!?
478 if (newinputs & VERT_BIT_POINT_SIZE)
481 if (newinputs
& VERT_BIT_COLOR0
)
484 if (newinputs
& VERT_BIT_COLOR1
)
487 if (newinputs
& VERT_BIT_TEX0
)
490 if (newinputs
& VERT_BIT_TEX1
)
491 ind
|= SETUP_TMU0
|SETUP_TMU1
;
493 if (fxMesa
->SetupIndex
& SETUP_PTEX
)
496 ind
&= fxMesa
->SetupIndex
;
499 setup_tab
[ind
].emit( ctx
, start
, count
, v
);
505 void fxChooseVertexState( GLcontext
*ctx
)
507 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
508 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
509 GLuint ind
= SETUP_XYZW
|SETUP_RGBA
;
511 if (fxMesa
->snapVertices
)
514 fxMesa
->tmu_source
[0] = 0;
515 fxMesa
->tmu_source
[1] = 1;
517 if (ctx
->Texture
._EnabledUnits
& 0x2) {
518 if (ctx
->Texture
._EnabledUnits
& 0x1) {
522 fxMesa
->tmu_source
[0] = 1;
523 fxMesa
->tmu_source
[1] = 0;
525 else if (ctx
->Texture
._EnabledUnits
& 0x1) {
529 if (ctx
->_TriangleCaps
& DD_POINT_ATTEN
) {
533 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
) {
537 fxMesa
->SetupIndex
= ind
;
539 if (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
)) {
540 tnl
->Driver
.Render
.Interp
= interp_extras
;
541 tnl
->Driver
.Render
.CopyPV
= copy_pv_extras
;
543 tnl
->Driver
.Render
.Interp
= setup_tab
[ind
].interp
;
544 tnl
->Driver
.Render
.CopyPV
= setup_tab
[ind
].copy_pv
;
547 if (setup_tab
[ind
].vertex_format
!= fxMesa
->stw_hint_state
) {
548 fxMesa
->stw_hint_state
= setup_tab
[ind
].vertex_format
;
549 FX_grHints(GR_HINT_STWHINT
, fxMesa
->stw_hint_state
);
555 void fxAllocVB( GLcontext
*ctx
)
557 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
558 GLuint size
= TNL_CONTEXT(ctx
)->vb
.Size
;
559 static int firsttime
= 1;
565 fxMesa
->verts
= (GrVertex
*)ALIGN_MALLOC(size
* sizeof(GrVertex
), 32);
566 fxMesa
->SetupIndex
= SETUP_XYZW
|SETUP_RGBA
;
570 void fxFreeVB( GLcontext
*ctx
)
572 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
574 ALIGN_FREE(fxMesa
->verts
);
582 * Need this to provide at least one external definition.
585 extern int gl_fx_dummy_function_vb(void);
587 gl_fx_dummy_function_vb(void)