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.
26 #include "main/glheader.h"
27 #include "main/mtypes.h"
28 #include "main/imports.h"
29 #include "main/macros.h"
30 #include "main/colormac.h"
32 #include "math/m_translate.h"
33 #include "swrast_setup/swrast_setup.h"
35 #include "tdfx_context.h"
37 #include "tdfx_tris.h"
38 #include "tdfx_state.h"
39 #include "tdfx_render.h"
41 static void copy_pv( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
43 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
44 tdfxVertex
*dst
= fxMesa
->verts
+ edst
;
45 tdfxVertex
*src
= fxMesa
->verts
+ esrc
;
46 *(GLuint
*)&dst
->color
= *(GLuint
*)&src
->color
;
50 void (*emit
)( GLcontext
*, GLuint
, GLuint
, void * );
51 tnl_interp_func interp
;
52 tnl_copy_pv_func copy_pv
;
53 GLboolean (*check_tex_sizes
)( GLcontext
*ctx
);
55 } setup_tab
[TDFX_MAX_SETUP
];
60 #define GET_COLOR(ptr, idx) ((ptr)->data[idx])
63 static void interp_extras( GLcontext
*ctx
,
65 GLuint dst
, GLuint out
, GLuint in
,
66 GLboolean force_boundary
)
68 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
70 /*fprintf(stderr, "%s\n", __FUNCTION__);*/
72 if (VB
->ColorPtr
[1]) {
74 GET_COLOR(VB
->ColorPtr
[1], dst
),
75 GET_COLOR(VB
->ColorPtr
[1], out
),
76 GET_COLOR(VB
->ColorPtr
[1], in
) );
80 VB
->EdgeFlag
[dst
] = VB
->EdgeFlag
[out
] || force_boundary
;
83 setup_tab
[TDFX_CONTEXT(ctx
)->SetupIndex
].interp(ctx
, t
, dst
, out
, in
,
87 static void copy_pv_extras( GLcontext
*ctx
, GLuint dst
, GLuint src
)
89 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
91 if (VB
->ColorPtr
[1]) {
92 COPY_4FV( GET_COLOR(VB
->ColorPtr
[1], dst
),
93 GET_COLOR(VB
->ColorPtr
[1], src
) );
96 setup_tab
[TDFX_CONTEXT(ctx
)->SetupIndex
].copy_pv(ctx
, dst
, src
);
101 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT)
102 #define TAG(x) x##_wg
103 #include "tdfx_vbtmp.h"
105 /* Special for tdfx: fog requires w
107 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT)
108 #define TAG(x) x##_wg_fog
109 #include "tdfx_vbtmp.h"
111 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT)
112 #define TAG(x) x##_wgt0
113 #include "tdfx_vbtmp.h"
115 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)
116 #define TAG(x) x##_wgt0t1
117 #include "tdfx_vbtmp.h"
119 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_PTEX_BIT)
120 #define TAG(x) x##_wgpt0
121 #include "tdfx_vbtmp.h"
123 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT|\
125 #define TAG(x) x##_wgpt0t1
126 #include "tdfx_vbtmp.h"
128 #define IND (TDFX_RGBA_BIT)
130 #include "tdfx_vbtmp.h"
132 #define IND (TDFX_TEX0_BIT)
133 #define TAG(x) x##_t0
134 #include "tdfx_vbtmp.h"
136 #define IND (TDFX_TEX0_BIT|TDFX_TEX1_BIT)
137 #define TAG(x) x##_t0t1
138 #include "tdfx_vbtmp.h"
140 #define IND (TDFX_RGBA_BIT|TDFX_TEX0_BIT)
141 #define TAG(x) x##_gt0
142 #include "tdfx_vbtmp.h"
144 #define IND (TDFX_RGBA_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)
145 #define TAG(x) x##_gt0t1
146 #include "tdfx_vbtmp.h"
150 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_FOGC_BIT)
151 #define TAG(x) x##_wgf
152 #include "tdfx_vbtmp.h"
154 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_FOGC_BIT)
155 #define TAG(x) x##_wgt0f
156 #include "tdfx_vbtmp.h"
158 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT|TDFX_FOGC_BIT)
159 #define TAG(x) x##_wgt0t1f
160 #include "tdfx_vbtmp.h"
162 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_PTEX_BIT|TDFX_FOGC_BIT)
163 #define TAG(x) x##_wgpt0f
164 #include "tdfx_vbtmp.h"
166 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT|\
167 TDFX_PTEX_BIT|TDFX_FOGC_BIT)
168 #define TAG(x) x##_wgpt0t1f
169 #include "tdfx_vbtmp.h"
173 static void init_setup_tab( void )
197 void tdfxPrintSetupFlags(char *msg
, GLuint flags
)
199 fprintf(stderr
, "%s(%x): %s%s%s%s%s%s\n",
202 (flags
& TDFX_XYZ_BIT
) ? " xyz," : "",
203 (flags
& TDFX_W_BIT
) ? " w," : "",
204 (flags
& TDFX_RGBA_BIT
) ? " rgba," : "",
205 (flags
& TDFX_TEX0_BIT
) ? " tex-0," : "",
206 (flags
& TDFX_TEX1_BIT
) ? " tex-1," : "",
207 (flags
& TDFX_FOGC_BIT
) ? " fogc," : "");
212 void tdfxCheckTexSizes( GLcontext
*ctx
)
214 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
215 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
217 if (!setup_tab
[fxMesa
->SetupIndex
].check_tex_sizes(ctx
)) {
218 GLuint ind
= fxMesa
->SetupIndex
|= (TDFX_PTEX_BIT
|TDFX_RGBA_BIT
);
220 /* Tdfx handles projective textures nicely; just have to change
221 * up to the new vertex format.
223 if (setup_tab
[ind
].vertex_format
!= fxMesa
->vertexFormat
) {
225 fxMesa
->dirty
|= TDFX_UPLOAD_VERTEX_LAYOUT
;
226 fxMesa
->vertexFormat
= setup_tab
[ind
].vertex_format
;
228 /* This is required as we have just changed the vertex
229 * format, so the interp and copy routines must also change.
230 * In the unfilled and twosided cases we are using the
231 * swrast_setup ones anyway, so leave them in place.
233 if (!(ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
234 tnl
->Driver
.Render
.Interp
= setup_tab
[fxMesa
->SetupIndex
].interp
;
235 tnl
->Driver
.Render
.CopyPV
= setup_tab
[fxMesa
->SetupIndex
].copy_pv
;
242 void tdfxBuildVertices( GLcontext
*ctx
, GLuint start
, GLuint end
,
245 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
246 tdfxVertex
*v
= fxMesa
->verts
+ start
;
248 newinputs
|= fxMesa
->SetupNewInputs
;
249 fxMesa
->SetupNewInputs
= 0;
254 if (newinputs
& VERT_BIT_POS
) {
255 setup_tab
[fxMesa
->SetupIndex
].emit( ctx
, start
, end
, v
);
259 if (newinputs
& VERT_BIT_COLOR0
)
260 ind
|= TDFX_RGBA_BIT
;
262 if (newinputs
& VERT_BIT_FOG
)
263 ind
|= TDFX_FOGC_BIT
;
265 if (newinputs
& VERT_BIT_TEX0
)
266 ind
|= TDFX_TEX0_BIT
;
268 if (newinputs
& VERT_BIT_TEX1
)
269 ind
|= TDFX_TEX0_BIT
|TDFX_TEX1_BIT
;
271 if (fxMesa
->SetupIndex
& TDFX_PTEX_BIT
)
274 ind
&= fxMesa
->SetupIndex
;
277 setup_tab
[ind
].emit( ctx
, start
, end
, v
);
283 void tdfxChooseVertexState( GLcontext
*ctx
)
285 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
286 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
287 GLuint ind
= TDFX_XYZ_BIT
|TDFX_RGBA_BIT
;
289 fxMesa
->tmu_source
[0] = 0;
290 fxMesa
->tmu_source
[1] = 1;
292 if (ctx
->Texture
._EnabledUnits
& 0x2) {
293 if (ctx
->Texture
._EnabledUnits
& 0x1) {
294 ind
|= TDFX_TEX1_BIT
;
296 ind
|= TDFX_W_BIT
|TDFX_TEX0_BIT
;
297 fxMesa
->tmu_source
[0] = 1;
298 fxMesa
->tmu_source
[1] = 0;
299 } else if (ctx
->Texture
._EnabledUnits
& 0x1) {
301 ind
|= TDFX_W_BIT
|TDFX_TEX0_BIT
;
302 } else if (fxMesa
->Fog
.Mode
!= GR_FOG_DISABLE
) {
306 if (fxMesa
->Fog
.Mode
== GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT
) {
307 ind
|= TDFX_FOGC_BIT
;
310 fxMesa
->SetupIndex
= ind
;
312 if (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
)) {
313 tnl
->Driver
.Render
.Interp
= interp_extras
;
314 tnl
->Driver
.Render
.CopyPV
= copy_pv_extras
;
316 tnl
->Driver
.Render
.Interp
= setup_tab
[ind
].interp
;
317 tnl
->Driver
.Render
.CopyPV
= setup_tab
[ind
].copy_pv
;
320 if (setup_tab
[ind
].vertex_format
!= fxMesa
->vertexFormat
) {
322 fxMesa
->dirty
|= TDFX_UPLOAD_VERTEX_LAYOUT
;
323 fxMesa
->vertexFormat
= setup_tab
[ind
].vertex_format
;
329 void tdfxInitVB( GLcontext
*ctx
)
331 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
332 GLuint size
= TNL_CONTEXT(ctx
)->vb
.Size
;
333 static int firsttime
= 1;
339 fxMesa
->verts
= ALIGN_MALLOC(size
* sizeof(tdfxVertex
), 32);
340 fxMesa
->vertexFormat
= TDFX_LAYOUT_TINY
;
341 fxMesa
->SetupIndex
= TDFX_XYZ_BIT
|TDFX_RGBA_BIT
;
345 void tdfxFreeVB( GLcontext
*ctx
)
347 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
349 ALIGN_FREE(fxMesa
->verts
);