2 * GLX Hardware Device Driver for Intel i810
3 * Copyright (C) 1999 Keith Whitwell
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
21 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.c,v 1.3 2002/10/30 12:52:01 alanh Exp $ */
27 #include "main/glheader.h"
28 #include "main/mtypes.h"
29 #include "main/imports.h"
30 #include "main/macros.h"
31 #include "main/colormac.h"
33 #include "math/m_translate.h"
34 #include "swrast_setup/swrast_setup.h"
36 #include "tdfx_context.h"
38 #include "tdfx_tris.h"
39 #include "tdfx_state.h"
40 #include "tdfx_render.h"
42 static void copy_pv( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
44 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
45 tdfxVertex
*dst
= fxMesa
->verts
+ edst
;
46 tdfxVertex
*src
= fxMesa
->verts
+ esrc
;
47 *(GLuint
*)&dst
->color
= *(GLuint
*)&src
->color
;
51 void (*emit
)( GLcontext
*, GLuint
, GLuint
, void * );
52 tnl_interp_func interp
;
53 tnl_copy_pv_func copy_pv
;
54 GLboolean (*check_tex_sizes
)( GLcontext
*ctx
);
56 } setup_tab
[TDFX_MAX_SETUP
];
61 #define GET_COLOR(ptr, idx) ((ptr)->data[idx])
64 static void interp_extras( GLcontext
*ctx
,
66 GLuint dst
, GLuint out
, GLuint in
,
67 GLboolean force_boundary
)
69 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
71 /*fprintf(stderr, "%s\n", __FUNCTION__);*/
73 if (VB
->ColorPtr
[1]) {
75 GET_COLOR(VB
->ColorPtr
[1], dst
),
76 GET_COLOR(VB
->ColorPtr
[1], out
),
77 GET_COLOR(VB
->ColorPtr
[1], in
) );
81 VB
->EdgeFlag
[dst
] = VB
->EdgeFlag
[out
] || force_boundary
;
84 setup_tab
[TDFX_CONTEXT(ctx
)->SetupIndex
].interp(ctx
, t
, dst
, out
, in
,
88 static void copy_pv_extras( GLcontext
*ctx
, GLuint dst
, GLuint src
)
90 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
92 if (VB
->ColorPtr
[1]) {
93 COPY_4FV( GET_COLOR(VB
->ColorPtr
[1], dst
),
94 GET_COLOR(VB
->ColorPtr
[1], src
) );
97 setup_tab
[TDFX_CONTEXT(ctx
)->SetupIndex
].copy_pv(ctx
, dst
, src
);
102 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT)
103 #define TAG(x) x##_wg
104 #include "tdfx_vbtmp.h"
106 /* Special for tdfx: fog requires w
108 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT)
109 #define TAG(x) x##_wg_fog
110 #include "tdfx_vbtmp.h"
112 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT)
113 #define TAG(x) x##_wgt0
114 #include "tdfx_vbtmp.h"
116 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)
117 #define TAG(x) x##_wgt0t1
118 #include "tdfx_vbtmp.h"
120 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_PTEX_BIT)
121 #define TAG(x) x##_wgpt0
122 #include "tdfx_vbtmp.h"
124 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT|\
126 #define TAG(x) x##_wgpt0t1
127 #include "tdfx_vbtmp.h"
129 #define IND (TDFX_RGBA_BIT)
131 #include "tdfx_vbtmp.h"
133 #define IND (TDFX_TEX0_BIT)
134 #define TAG(x) x##_t0
135 #include "tdfx_vbtmp.h"
137 #define IND (TDFX_TEX0_BIT|TDFX_TEX1_BIT)
138 #define TAG(x) x##_t0t1
139 #include "tdfx_vbtmp.h"
141 #define IND (TDFX_RGBA_BIT|TDFX_TEX0_BIT)
142 #define TAG(x) x##_gt0
143 #include "tdfx_vbtmp.h"
145 #define IND (TDFX_RGBA_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)
146 #define TAG(x) x##_gt0t1
147 #include "tdfx_vbtmp.h"
151 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_FOGC_BIT)
152 #define TAG(x) x##_wgf
153 #include "tdfx_vbtmp.h"
155 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_FOGC_BIT)
156 #define TAG(x) x##_wgt0f
157 #include "tdfx_vbtmp.h"
159 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT|TDFX_FOGC_BIT)
160 #define TAG(x) x##_wgt0t1f
161 #include "tdfx_vbtmp.h"
163 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_PTEX_BIT|TDFX_FOGC_BIT)
164 #define TAG(x) x##_wgpt0f
165 #include "tdfx_vbtmp.h"
167 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT|\
168 TDFX_PTEX_BIT|TDFX_FOGC_BIT)
169 #define TAG(x) x##_wgpt0t1f
170 #include "tdfx_vbtmp.h"
174 static void init_setup_tab( void )
198 void tdfxPrintSetupFlags(char *msg
, GLuint flags
)
200 fprintf(stderr
, "%s(%x): %s%s%s%s%s%s\n",
203 (flags
& TDFX_XYZ_BIT
) ? " xyz," : "",
204 (flags
& TDFX_W_BIT
) ? " w," : "",
205 (flags
& TDFX_RGBA_BIT
) ? " rgba," : "",
206 (flags
& TDFX_TEX0_BIT
) ? " tex-0," : "",
207 (flags
& TDFX_TEX1_BIT
) ? " tex-1," : "",
208 (flags
& TDFX_FOGC_BIT
) ? " fogc," : "");
213 void tdfxCheckTexSizes( GLcontext
*ctx
)
215 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
216 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
218 if (!setup_tab
[fxMesa
->SetupIndex
].check_tex_sizes(ctx
)) {
219 GLuint ind
= fxMesa
->SetupIndex
|= (TDFX_PTEX_BIT
|TDFX_RGBA_BIT
);
221 /* Tdfx handles projective textures nicely; just have to change
222 * up to the new vertex format.
224 if (setup_tab
[ind
].vertex_format
!= fxMesa
->vertexFormat
) {
226 fxMesa
->dirty
|= TDFX_UPLOAD_VERTEX_LAYOUT
;
227 fxMesa
->vertexFormat
= setup_tab
[ind
].vertex_format
;
229 /* This is required as we have just changed the vertex
230 * format, so the interp and copy routines must also change.
231 * In the unfilled and twosided cases we are using the
232 * swrast_setup ones anyway, so leave them in place.
234 if (!(ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
235 tnl
->Driver
.Render
.Interp
= setup_tab
[fxMesa
->SetupIndex
].interp
;
236 tnl
->Driver
.Render
.CopyPV
= setup_tab
[fxMesa
->SetupIndex
].copy_pv
;
243 void tdfxBuildVertices( GLcontext
*ctx
, GLuint start
, GLuint end
,
246 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
247 tdfxVertex
*v
= fxMesa
->verts
+ start
;
249 newinputs
|= fxMesa
->SetupNewInputs
;
250 fxMesa
->SetupNewInputs
= 0;
255 if (newinputs
& VERT_BIT_POS
) {
256 setup_tab
[fxMesa
->SetupIndex
].emit( ctx
, start
, end
, v
);
260 if (newinputs
& VERT_BIT_COLOR0
)
261 ind
|= TDFX_RGBA_BIT
;
263 if (newinputs
& VERT_BIT_FOG
)
264 ind
|= TDFX_FOGC_BIT
;
266 if (newinputs
& VERT_BIT_TEX0
)
267 ind
|= TDFX_TEX0_BIT
;
269 if (newinputs
& VERT_BIT_TEX1
)
270 ind
|= TDFX_TEX0_BIT
|TDFX_TEX1_BIT
;
272 if (fxMesa
->SetupIndex
& TDFX_PTEX_BIT
)
275 ind
&= fxMesa
->SetupIndex
;
278 setup_tab
[ind
].emit( ctx
, start
, end
, v
);
284 void tdfxChooseVertexState( GLcontext
*ctx
)
286 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
287 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
288 GLuint ind
= TDFX_XYZ_BIT
|TDFX_RGBA_BIT
;
290 fxMesa
->tmu_source
[0] = 0;
291 fxMesa
->tmu_source
[1] = 1;
293 if (ctx
->Texture
._EnabledUnits
& 0x2) {
294 if (ctx
->Texture
._EnabledUnits
& 0x1) {
295 ind
|= TDFX_TEX1_BIT
;
297 ind
|= TDFX_W_BIT
|TDFX_TEX0_BIT
;
298 fxMesa
->tmu_source
[0] = 1;
299 fxMesa
->tmu_source
[1] = 0;
300 } else if (ctx
->Texture
._EnabledUnits
& 0x1) {
302 ind
|= TDFX_W_BIT
|TDFX_TEX0_BIT
;
303 } else if (fxMesa
->Fog
.Mode
!= GR_FOG_DISABLE
) {
307 if (fxMesa
->Fog
.Mode
== GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT
) {
308 ind
|= TDFX_FOGC_BIT
;
311 fxMesa
->SetupIndex
= ind
;
313 if (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
)) {
314 tnl
->Driver
.Render
.Interp
= interp_extras
;
315 tnl
->Driver
.Render
.CopyPV
= copy_pv_extras
;
317 tnl
->Driver
.Render
.Interp
= setup_tab
[ind
].interp
;
318 tnl
->Driver
.Render
.CopyPV
= setup_tab
[ind
].copy_pv
;
321 if (setup_tab
[ind
].vertex_format
!= fxMesa
->vertexFormat
) {
323 fxMesa
->dirty
|= TDFX_UPLOAD_VERTEX_LAYOUT
;
324 fxMesa
->vertexFormat
= setup_tab
[ind
].vertex_format
;
330 void tdfxInitVB( GLcontext
*ctx
)
332 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
333 GLuint size
= TNL_CONTEXT(ctx
)->vb
.Size
;
334 static int firsttime
= 1;
340 fxMesa
->verts
= ALIGN_MALLOC(size
* sizeof(tdfxVertex
), 32);
341 fxMesa
->vertexFormat
= TDFX_LAYOUT_TINY
;
342 fxMesa
->SetupIndex
= TDFX_XYZ_BIT
|TDFX_RGBA_BIT
;
346 void tdfxFreeVB( GLcontext
*ctx
)
348 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
350 ALIGN_FREE(fxMesa
->verts
);