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.
42 #include "math/m_translate.h"
43 #include "swrast_setup/swrast_setup.h"
46 #include "tnl/t_context.h"
51 static void copy_pv( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
53 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
54 GrVertex
*dst
= fxMesa
->verts
+ edst
;
55 GrVertex
*src
= fxMesa
->verts
+ esrc
;
57 *(GLuint
*)&dst
->pargb
= *(GLuint
*)&src
->pargb
;
60 typedef void (*emit_func
)( GLcontext
*, GLuint
, GLuint
, void * );
65 GLboolean (*check_tex_sizes
)( GLcontext
*ctx
);
67 } setup_tab
[MAX_SETUP
];
70 static void import_float_colors( GLcontext
*ctx
)
72 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
73 struct gl_client_array
*from
= VB
->ColorPtr
[0];
74 struct gl_client_array
*to
= &FX_CONTEXT(ctx
)->UbyteColor
;
75 GLuint count
= VB
->Count
;
78 to
->Ptr
= ALIGN_MALLOC( VB
->Size
* 4 * sizeof(GLubyte
), 32 );
79 to
->Type
= GL_UNSIGNED_BYTE
;
82 /* No need to transform the same value 3000 times.
89 to
->StrideB
= 4 * sizeof(GLubyte
);
91 _math_trans_4ub( (GLubyte (*)[4]) to
->Ptr
,
103 /* Hack alert: assume chan is 8 bits */
104 #define GET_COLOR(ptr, idx) (((GLchan (*)[4])((ptr)->Ptr))[idx])
107 static void interp_extras( GLcontext
*ctx
,
109 GLuint dst
, GLuint out
, GLuint in
,
110 GLboolean force_boundary
)
112 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
114 if (VB
->ColorPtr
[1]) {
116 GET_COLOR(VB
->ColorPtr
[1], dst
),
117 GET_COLOR(VB
->ColorPtr
[1], out
),
118 GET_COLOR(VB
->ColorPtr
[1], in
) );
119 #if 1 /* [dBorca] GL_EXT_separate_specular_color */
120 if (VB
->SecondaryColorPtr
[1]) {
122 GET_COLOR(VB
->SecondaryColorPtr
[1], dst
),
123 GET_COLOR(VB
->SecondaryColorPtr
[1], out
),
124 GET_COLOR(VB
->SecondaryColorPtr
[1], in
) );
130 VB
->EdgeFlag
[dst
] = VB
->EdgeFlag
[out
] || force_boundary
;
133 setup_tab
[FX_CONTEXT(ctx
)->SetupIndex
].interp(ctx
, t
, dst
, out
, in
,
137 static void copy_pv_extras( GLcontext
*ctx
, GLuint dst
, GLuint src
)
139 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
141 if (VB
->ColorPtr
[1]) {
142 COPY_CHAN4( GET_COLOR(VB
->ColorPtr
[1], dst
),
143 GET_COLOR(VB
->ColorPtr
[1], src
) );
144 #if 1 /* [dBorca] GL_EXT_separate_specular_color */
145 if (VB
->SecondaryColorPtr
[1]) {
146 COPY_CHAN4( GET_COLOR(VB
->SecondaryColorPtr
[1], dst
),
147 GET_COLOR(VB
->SecondaryColorPtr
[1], src
) );
152 copy_pv(ctx
, dst
, src
);
156 #define IND (SETUP_XYZW|SETUP_RGBA)
157 #define TAG(x) x##_wg
160 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0)
161 #define TAG(x) x##_wgt0
164 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1)
165 #define TAG(x) x##_wgt0t1
168 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_PTEX)
169 #define TAG(x) x##_wgpt0
172 #define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1|\
174 #define TAG(x) x##_wgpt0t1
178 /* Snapping for voodoo-1
180 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA)
181 #define TAG(x) x##_wsg
184 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0)
185 #define TAG(x) x##_wsgt0
188 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
190 #define TAG(x) x##_wsgt0t1
193 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
195 #define TAG(x) x##_wsgpt0
198 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
199 SETUP_TMU1|SETUP_PTEX)
200 #define TAG(x) x##_wsgpt0t1
204 /* Vertex repair (multipass rendering)
206 #define IND (SETUP_RGBA)
210 #define IND (SETUP_TMU0)
211 #define TAG(x) x##_t0
214 #define IND (SETUP_TMU0|SETUP_TMU1)
215 #define TAG(x) x##_t0t1
218 #define IND (SETUP_RGBA|SETUP_TMU0)
219 #define TAG(x) x##_gt0
222 #define IND (SETUP_RGBA|SETUP_TMU0|SETUP_TMU1)
223 #define TAG(x) x##_gt0t1
228 static void init_setup_tab( void )
250 void fxPrintSetupFlags(char *msg
, GLuint flags
)
252 fprintf(stderr
, "%s(%x): %s%s%s%s%s\n",
255 (flags
& SETUP_XYZW
) ? " xyzw," : "",
256 (flags
& SETUP_SNAP
) ? " snap," : "",
257 (flags
& SETUP_RGBA
) ? " rgba," : "",
258 (flags
& SETUP_TMU0
) ? " tex-0," : "",
259 (flags
& SETUP_TMU1
) ? " tex-1," : "");
264 void fxCheckTexSizes( GLcontext
*ctx
)
266 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
267 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
269 if (!setup_tab
[fxMesa
->SetupIndex
].check_tex_sizes(ctx
)) {
270 GLuint ind
= fxMesa
->SetupIndex
|= (SETUP_PTEX
|SETUP_RGBA
);
272 /* Tdfx handles projective textures nicely; just have to change
273 * up to the new vertex format.
275 if (setup_tab
[ind
].vertex_format
!= fxMesa
->stw_hint_state
) {
277 fxMesa
->stw_hint_state
= setup_tab
[ind
].vertex_format
;
278 FX_grHints(GR_HINT_STWHINT
, fxMesa
->stw_hint_state
);
280 /* This is required as we have just changed the vertex
281 * format, so the interp routines must also change.
282 * In the unfilled and twosided cases we are using the
283 * Extras ones anyway, so leave them in place.
285 if (!(ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
286 tnl
->Driver
.Render
.Interp
= setup_tab
[fxMesa
->SetupIndex
].interp
;
293 void fxBuildVertices( GLcontext
*ctx
, GLuint start
, GLuint count
,
296 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
297 GrVertex
*v
= (fxMesa
->verts
+ start
);
302 if (newinputs
& VERT_BIT_CLIP
) {
303 setup_tab
[fxMesa
->SetupIndex
].emit( ctx
, start
, count
, v
);
307 if (newinputs
& VERT_BIT_COLOR0
)
310 if (newinputs
& VERT_BIT_TEX0
)
313 if (newinputs
& VERT_BIT_TEX1
)
314 ind
|= SETUP_TMU0
|SETUP_TMU1
;
316 if (fxMesa
->SetupIndex
& SETUP_PTEX
)
319 ind
&= fxMesa
->SetupIndex
;
322 setup_tab
[ind
].emit( ctx
, start
, count
, v
);
328 void fxChooseVertexState( GLcontext
*ctx
)
330 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
331 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
332 GLuint ind
= SETUP_XYZW
|SETUP_RGBA
;
334 if (fxMesa
->snapVertices
)
337 fxMesa
->tmu_source
[0] = 0;
338 fxMesa
->tmu_source
[1] = 1;
340 if (ctx
->Texture
._EnabledUnits
& 0x2) {
341 if (ctx
->Texture
._EnabledUnits
& 0x1) {
342 ind
|= SETUP_TMU1
|SETUP_TMU0
;
345 fxMesa
->tmu_source
[0] = 1;
346 fxMesa
->tmu_source
[1] = 0;
350 else if (ctx
->Texture
._EnabledUnits
& 0x1) {
354 fxMesa
->SetupIndex
= ind
;
356 if (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
)) {
357 tnl
->Driver
.Render
.Interp
= interp_extras
;
358 tnl
->Driver
.Render
.CopyPV
= copy_pv_extras
;
360 tnl
->Driver
.Render
.Interp
= setup_tab
[ind
].interp
;
361 tnl
->Driver
.Render
.CopyPV
= copy_pv
;
364 if (setup_tab
[ind
].vertex_format
!= fxMesa
->stw_hint_state
) {
365 fxMesa
->stw_hint_state
= setup_tab
[ind
].vertex_format
;
366 FX_grHints(GR_HINT_STWHINT
, fxMesa
->stw_hint_state
);
372 void fxAllocVB( GLcontext
*ctx
)
374 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
375 GLuint size
= TNL_CONTEXT(ctx
)->vb
.Size
;
376 static int firsttime
= 1;
382 fxMesa
->verts
= (GrVertex
*)ALIGN_MALLOC(size
* sizeof(GrVertex
), 32);
383 fxMesa
->SetupIndex
= SETUP_XYZW
|SETUP_RGBA
;
387 void fxFreeVB( GLcontext
*ctx
)
389 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
391 ALIGN_FREE(fxMesa
->verts
);
395 if (fxMesa
->UbyteColor
.Ptr
) {
396 ALIGN_FREE((void *)fxMesa
->UbyteColor
.Ptr
);
397 fxMesa
->UbyteColor
.Ptr
= 0;
404 * Need this to provide at least one external definition.
407 extern int gl_fx_dummy_function_vb(void);
409 gl_fx_dummy_function_vb(void)