1 /* $Id: fxvb.c,v 1.20 2003/10/09 15:12:21 dborca Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
23 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
25 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
44 #include "math/m_translate.h"
45 #include "swrast_setup/swrast_setup.h"
48 #include "tnl/t_context.h"
53 static void copy_pv( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
55 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
56 GrVertex
*dst
= fxMesa
->verts
+ edst
;
57 GrVertex
*src
= fxMesa
->verts
+ esrc
;
59 *(GLuint
*)&dst
->pargb
= *(GLuint
*)&src
->pargb
;
62 typedef void (*emit_func
)( GLcontext
*, GLuint
, GLuint
, void * );
67 GLboolean (*check_tex_sizes
)( GLcontext
*ctx
);
69 } setup_tab
[MAX_SETUP
];
72 static void import_float_colors( GLcontext
*ctx
)
74 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
75 struct gl_client_array
*from
= VB
->ColorPtr
[0];
76 struct gl_client_array
*to
= &FX_CONTEXT(ctx
)->UbyteColor
;
77 GLuint count
= VB
->Count
;
80 to
->Ptr
= ALIGN_MALLOC( VB
->Size
* 4 * sizeof(GLubyte
), 32 );
81 to
->Type
= GL_UNSIGNED_BYTE
;
84 /* No need to transform the same value 3000 times.
91 to
->StrideB
= 4 * sizeof(GLubyte
);
93 _math_trans_4ub( (GLubyte (*)[4]) to
->Ptr
,
101 VB
->ColorPtr
[0] = to
;
105 /* Hack alert: assume chan is 8 bits */
106 #define GET_COLOR(ptr, idx) (((GLchan (*)[4])((ptr)->Ptr))[idx])
109 static void interp_extras( GLcontext
*ctx
,
111 GLuint dst
, GLuint out
, GLuint in
,
112 GLboolean force_boundary
)
114 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
116 if (VB
->ColorPtr
[1]) {
118 GET_COLOR(VB
->ColorPtr
[1], dst
),
119 GET_COLOR(VB
->ColorPtr
[1], out
),
120 GET_COLOR(VB
->ColorPtr
[1], in
) );
121 #if 1 /* [dBorca] GL_EXT_separate_specular_color */
122 if (VB
->SecondaryColorPtr
[1]) {
124 GET_COLOR(VB
->SecondaryColorPtr
[1], dst
),
125 GET_COLOR(VB
->SecondaryColorPtr
[1], out
),
126 GET_COLOR(VB
->SecondaryColorPtr
[1], in
) );
132 VB
->EdgeFlag
[dst
] = VB
->EdgeFlag
[out
] || force_boundary
;
135 setup_tab
[FX_CONTEXT(ctx
)->SetupIndex
].interp(ctx
, t
, dst
, out
, in
,
139 static void copy_pv_extras( GLcontext
*ctx
, GLuint dst
, GLuint src
)
141 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
143 if (VB
->ColorPtr
[1]) {
144 COPY_CHAN4( GET_COLOR(VB
->ColorPtr
[1], dst
),
145 GET_COLOR(VB
->ColorPtr
[1], src
) );
146 #if 1 /* [dBorca] GL_EXT_separate_specular_color */
147 if (VB
->SecondaryColorPtr
[1]) {
148 COPY_CHAN4( GET_COLOR(VB
->SecondaryColorPtr
[1], dst
),
149 GET_COLOR(VB
->SecondaryColorPtr
[1], src
) );
154 copy_pv(ctx
, dst
, src
);
158 #define IND (SETUP_XYZW|SETUP_RGBA)
159 #define TAG(x) x##_wg
162 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0)
163 #define TAG(x) x##_wgt0
166 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1)
167 #define TAG(x) x##_wgt0t1
170 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_PTEX)
171 #define TAG(x) x##_wgpt0
174 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1|\
176 #define TAG(x) x##_wgpt0t1
180 /* Snapping for voodoo-1
182 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA)
183 #define TAG(x) x##_wsg
186 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0)
187 #define TAG(x) x##_wsgt0
190 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
192 #define TAG(x) x##_wsgt0t1
195 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
197 #define TAG(x) x##_wsgpt0
200 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
201 SETUP_TMU1|SETUP_PTEX)
202 #define TAG(x) x##_wsgpt0t1
206 /* Vertex repair (multipass rendering)
208 #define IND (SETUP_RGBA)
212 #define IND (SETUP_TMU0)
213 #define TAG(x) x##_t0
216 #define IND (SETUP_TMU0|SETUP_TMU1)
217 #define TAG(x) x##_t0t1
220 #define IND (SETUP_RGBA|SETUP_TMU0)
221 #define TAG(x) x##_gt0
224 #define IND (SETUP_RGBA|SETUP_TMU0|SETUP_TMU1)
225 #define TAG(x) x##_gt0t1
230 static void init_setup_tab( void )
252 void fxPrintSetupFlags(char *msg
, GLuint flags
)
254 fprintf(stderr
, "%s(%x): %s%s%s%s%s\n",
257 (flags
& SETUP_XYZW
) ? " xyzw," : "",
258 (flags
& SETUP_SNAP
) ? " snap," : "",
259 (flags
& SETUP_RGBA
) ? " rgba," : "",
260 (flags
& SETUP_TMU0
) ? " tex-0," : "",
261 (flags
& SETUP_TMU1
) ? " tex-1," : "");
266 void fxCheckTexSizes( GLcontext
*ctx
)
268 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
269 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
271 if (!setup_tab
[fxMesa
->SetupIndex
].check_tex_sizes(ctx
)) {
272 GLuint ind
= fxMesa
->SetupIndex
|= (SETUP_PTEX
|SETUP_RGBA
);
274 /* Tdfx handles projective textures nicely; just have to change
275 * up to the new vertex format.
277 if (setup_tab
[ind
].vertex_format
!= fxMesa
->stw_hint_state
) {
279 fxMesa
->stw_hint_state
= setup_tab
[ind
].vertex_format
;
280 FX_grHints(GR_HINT_STWHINT
, fxMesa
->stw_hint_state
);
282 /* This is required as we have just changed the vertex
283 * format, so the interp routines must also change.
284 * In the unfilled and twosided cases we are using the
285 * Extras ones anyway, so leave them in place.
287 if (!(ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
288 tnl
->Driver
.Render
.Interp
= setup_tab
[fxMesa
->SetupIndex
].interp
;
295 void fxBuildVertices( GLcontext
*ctx
, GLuint start
, GLuint count
,
298 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
299 GrVertex
*v
= (fxMesa
->verts
+ start
);
304 if (newinputs
& VERT_BIT_CLIP
) {
305 setup_tab
[fxMesa
->SetupIndex
].emit( ctx
, start
, count
, v
);
309 if (newinputs
& VERT_BIT_COLOR0
)
312 if (newinputs
& VERT_BIT_TEX0
)
315 if (newinputs
& VERT_BIT_TEX1
)
316 ind
|= SETUP_TMU0
|SETUP_TMU1
;
318 if (fxMesa
->SetupIndex
& SETUP_PTEX
)
321 ind
&= fxMesa
->SetupIndex
;
324 setup_tab
[ind
].emit( ctx
, start
, count
, v
);
330 void fxChooseVertexState( GLcontext
*ctx
)
332 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
333 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
334 GLuint ind
= SETUP_XYZW
|SETUP_RGBA
;
336 if (fxMesa
->snapVertices
)
339 fxMesa
->tmu_source
[0] = 0;
340 fxMesa
->tmu_source
[1] = 1;
342 if (ctx
->Texture
._EnabledUnits
& 0x2) {
343 if (ctx
->Texture
._EnabledUnits
& 0x1) {
344 ind
|= SETUP_TMU1
|SETUP_TMU0
;
347 fxMesa
->tmu_source
[0] = 1;
348 fxMesa
->tmu_source
[1] = 0;
352 else if (ctx
->Texture
._EnabledUnits
& 0x1) {
356 fxMesa
->SetupIndex
= ind
;
358 if (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
)) {
359 tnl
->Driver
.Render
.Interp
= interp_extras
;
360 tnl
->Driver
.Render
.CopyPV
= copy_pv_extras
;
362 tnl
->Driver
.Render
.Interp
= setup_tab
[ind
].interp
;
363 tnl
->Driver
.Render
.CopyPV
= copy_pv
;
366 if (setup_tab
[ind
].vertex_format
!= fxMesa
->stw_hint_state
) {
367 fxMesa
->stw_hint_state
= setup_tab
[ind
].vertex_format
;
368 FX_grHints(GR_HINT_STWHINT
, fxMesa
->stw_hint_state
);
374 void fxAllocVB( GLcontext
*ctx
)
376 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
377 GLuint size
= TNL_CONTEXT(ctx
)->vb
.Size
;
378 static int firsttime
= 1;
384 fxMesa
->verts
= (GrVertex
*)ALIGN_MALLOC(size
* sizeof(GrVertex
), 32);
385 fxMesa
->SetupIndex
= SETUP_XYZW
|SETUP_RGBA
;
389 void fxFreeVB( GLcontext
*ctx
)
391 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
393 ALIGN_FREE(fxMesa
->verts
);
397 if (fxMesa
->UbyteColor
.Ptr
) {
398 ALIGN_FREE(fxMesa
->UbyteColor
.Ptr
);
399 fxMesa
->UbyteColor
.Ptr
= 0;
406 * Need this to provide at least one external definition.
409 extern int gl_fx_dummy_function_vb(void);
411 gl_fx_dummy_function_vb(void)