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 "tdfx_context.h"
34 #include "tdfx_render.h"
36 static void copy_pv( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
38 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
39 tdfxVertex
*dst
= fxMesa
->verts
+ edst
;
40 tdfxVertex
*src
= fxMesa
->verts
+ esrc
;
41 *(GLuint
*)&dst
->color
= *(GLuint
*)&src
->color
;
45 void (*emit
)( GLcontext
*, GLuint
, GLuint
, void * );
46 tnl_interp_func interp
;
47 tnl_copy_pv_func copy_pv
;
48 GLboolean (*check_tex_sizes
)( GLcontext
*ctx
);
50 } setup_tab
[TDFX_MAX_SETUP
];
55 #define GET_COLOR(ptr, idx) ((ptr)->data[idx])
58 static void interp_extras( GLcontext
*ctx
,
60 GLuint dst
, GLuint out
, GLuint in
,
61 GLboolean force_boundary
)
63 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
65 /*fprintf(stderr, "%s\n", __FUNCTION__);*/
67 if (VB
->BackfaceColorPtr
) {
69 GET_COLOR(VB
->BackfaceColorPtr
, dst
),
70 GET_COLOR(VB
->BackfaceColorPtr
, out
),
71 GET_COLOR(VB
->BackfaceColorPtr
, in
) );
75 VB
->EdgeFlag
[dst
] = VB
->EdgeFlag
[out
] || force_boundary
;
78 setup_tab
[TDFX_CONTEXT(ctx
)->SetupIndex
].interp(ctx
, t
, dst
, out
, in
,
82 static void copy_pv_extras( GLcontext
*ctx
, GLuint dst
, GLuint src
)
84 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
86 if (VB
->BackfaceColorPtr
) {
87 COPY_4FV( GET_COLOR(VB
->BackfaceColorPtr
, dst
),
88 GET_COLOR(VB
->BackfaceColorPtr
, src
) );
91 setup_tab
[TDFX_CONTEXT(ctx
)->SetupIndex
].copy_pv(ctx
, dst
, src
);
96 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT)
98 #include "tdfx_vbtmp.h"
100 /* Special for tdfx: fog requires w
102 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT)
103 #define TAG(x) x##_wg_fog
104 #include "tdfx_vbtmp.h"
106 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT)
107 #define TAG(x) x##_wgt0
108 #include "tdfx_vbtmp.h"
110 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)
111 #define TAG(x) x##_wgt0t1
112 #include "tdfx_vbtmp.h"
114 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_PTEX_BIT)
115 #define TAG(x) x##_wgpt0
116 #include "tdfx_vbtmp.h"
118 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT|\
120 #define TAG(x) x##_wgpt0t1
121 #include "tdfx_vbtmp.h"
123 #define IND (TDFX_RGBA_BIT)
125 #include "tdfx_vbtmp.h"
127 #define IND (TDFX_TEX0_BIT)
128 #define TAG(x) x##_t0
129 #include "tdfx_vbtmp.h"
131 #define IND (TDFX_TEX0_BIT|TDFX_TEX1_BIT)
132 #define TAG(x) x##_t0t1
133 #include "tdfx_vbtmp.h"
135 #define IND (TDFX_RGBA_BIT|TDFX_TEX0_BIT)
136 #define TAG(x) x##_gt0
137 #include "tdfx_vbtmp.h"
139 #define IND (TDFX_RGBA_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)
140 #define TAG(x) x##_gt0t1
141 #include "tdfx_vbtmp.h"
145 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_FOGC_BIT)
146 #define TAG(x) x##_wgf
147 #include "tdfx_vbtmp.h"
149 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_FOGC_BIT)
150 #define TAG(x) x##_wgt0f
151 #include "tdfx_vbtmp.h"
153 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT|TDFX_FOGC_BIT)
154 #define TAG(x) x##_wgt0t1f
155 #include "tdfx_vbtmp.h"
157 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_PTEX_BIT|TDFX_FOGC_BIT)
158 #define TAG(x) x##_wgpt0f
159 #include "tdfx_vbtmp.h"
161 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT|\
162 TDFX_PTEX_BIT|TDFX_FOGC_BIT)
163 #define TAG(x) x##_wgpt0t1f
164 #include "tdfx_vbtmp.h"
168 static void init_setup_tab( void )
192 void tdfxPrintSetupFlags(char *msg
, GLuint flags
)
194 fprintf(stderr
, "%s(%x): %s%s%s%s%s%s\n",
197 (flags
& TDFX_XYZ_BIT
) ? " xyz," : "",
198 (flags
& TDFX_W_BIT
) ? " w," : "",
199 (flags
& TDFX_RGBA_BIT
) ? " rgba," : "",
200 (flags
& TDFX_TEX0_BIT
) ? " tex-0," : "",
201 (flags
& TDFX_TEX1_BIT
) ? " tex-1," : "",
202 (flags
& TDFX_FOGC_BIT
) ? " fogc," : "");
207 void tdfxCheckTexSizes( GLcontext
*ctx
)
209 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
210 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
212 if (!setup_tab
[fxMesa
->SetupIndex
].check_tex_sizes(ctx
)) {
213 GLuint ind
= fxMesa
->SetupIndex
|= (TDFX_PTEX_BIT
|TDFX_RGBA_BIT
);
215 /* Tdfx handles projective textures nicely; just have to change
216 * up to the new vertex format.
218 if (setup_tab
[ind
].vertex_format
!= fxMesa
->vertexFormat
) {
220 fxMesa
->dirty
|= TDFX_UPLOAD_VERTEX_LAYOUT
;
221 fxMesa
->vertexFormat
= setup_tab
[ind
].vertex_format
;
223 /* This is required as we have just changed the vertex
224 * format, so the interp and copy routines must also change.
225 * In the unfilled and twosided cases we are using the
226 * swrast_setup ones anyway, so leave them in place.
228 if (!(ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
229 tnl
->Driver
.Render
.Interp
= setup_tab
[fxMesa
->SetupIndex
].interp
;
230 tnl
->Driver
.Render
.CopyPV
= setup_tab
[fxMesa
->SetupIndex
].copy_pv
;
237 void tdfxBuildVertices( GLcontext
*ctx
, GLuint start
, GLuint end
,
240 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
241 tdfxVertex
*v
= fxMesa
->verts
+ start
;
243 newinputs
|= fxMesa
->SetupNewInputs
;
244 fxMesa
->SetupNewInputs
= 0;
249 if (newinputs
& VERT_BIT_POS
) {
250 setup_tab
[fxMesa
->SetupIndex
].emit( ctx
, start
, end
, v
);
254 if (newinputs
& VERT_BIT_COLOR0
)
255 ind
|= TDFX_RGBA_BIT
;
257 if (newinputs
& VERT_BIT_FOG
)
258 ind
|= TDFX_FOGC_BIT
;
260 if (newinputs
& VERT_BIT_TEX0
)
261 ind
|= TDFX_TEX0_BIT
;
263 if (newinputs
& VERT_BIT_TEX1
)
264 ind
|= TDFX_TEX0_BIT
|TDFX_TEX1_BIT
;
266 if (fxMesa
->SetupIndex
& TDFX_PTEX_BIT
)
269 ind
&= fxMesa
->SetupIndex
;
272 setup_tab
[ind
].emit( ctx
, start
, end
, v
);
278 void tdfxChooseVertexState( GLcontext
*ctx
)
280 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
281 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
282 GLuint ind
= TDFX_XYZ_BIT
|TDFX_RGBA_BIT
;
284 fxMesa
->tmu_source
[0] = 0;
285 fxMesa
->tmu_source
[1] = 1;
287 if (ctx
->Texture
._EnabledUnits
& 0x2) {
288 if (ctx
->Texture
._EnabledUnits
& 0x1) {
289 ind
|= TDFX_TEX1_BIT
;
291 ind
|= TDFX_W_BIT
|TDFX_TEX0_BIT
;
292 fxMesa
->tmu_source
[0] = 1;
293 fxMesa
->tmu_source
[1] = 0;
294 } else if (ctx
->Texture
._EnabledUnits
& 0x1) {
296 ind
|= TDFX_W_BIT
|TDFX_TEX0_BIT
;
297 } else if (fxMesa
->Fog
.Mode
!= GR_FOG_DISABLE
) {
301 if (fxMesa
->Fog
.Mode
== GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT
) {
302 ind
|= TDFX_FOGC_BIT
;
305 fxMesa
->SetupIndex
= ind
;
307 if (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
)) {
308 tnl
->Driver
.Render
.Interp
= interp_extras
;
309 tnl
->Driver
.Render
.CopyPV
= copy_pv_extras
;
311 tnl
->Driver
.Render
.Interp
= setup_tab
[ind
].interp
;
312 tnl
->Driver
.Render
.CopyPV
= setup_tab
[ind
].copy_pv
;
315 if (setup_tab
[ind
].vertex_format
!= fxMesa
->vertexFormat
) {
317 fxMesa
->dirty
|= TDFX_UPLOAD_VERTEX_LAYOUT
;
318 fxMesa
->vertexFormat
= setup_tab
[ind
].vertex_format
;
324 void tdfxInitVB( GLcontext
*ctx
)
326 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
327 GLuint size
= TNL_CONTEXT(ctx
)->vb
.Size
;
328 static int firsttime
= 1;
334 fxMesa
->verts
= _mesa_align_malloc(size
* sizeof(tdfxVertex
), 32);
335 fxMesa
->vertexFormat
= TDFX_LAYOUT_TINY
;
336 fxMesa
->SetupIndex
= TDFX_XYZ_BIT
|TDFX_RGBA_BIT
;
340 void tdfxFreeVB( GLcontext
*ctx
)
342 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
344 _mesa_align_free(fxMesa
->verts
);