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 $ */
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_rgba4( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
44 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
45 GLubyte
*tdfxverts
= (GLubyte
*)fxMesa
->verts
;
46 GLuint shift
= fxMesa
->vertex_stride_shift
;
47 tdfxVertex
*dst
= (tdfxVertex
*)(tdfxverts
+ (edst
<< shift
));
48 tdfxVertex
*src
= (tdfxVertex
*)(tdfxverts
+ (esrc
<< shift
));
49 dst
->ui
[4] = src
->ui
[4];
52 static void copy_pv_rgba3( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
54 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
55 GLubyte
*tdfxverts
= (GLubyte
*)fxMesa
->verts
;
56 GLuint shift
= fxMesa
->vertex_stride_shift
;
57 tdfxVertex
*dst
= (tdfxVertex
*)(tdfxverts
+ (edst
<< shift
));
58 tdfxVertex
*src
= (tdfxVertex
*)(tdfxverts
+ (esrc
<< shift
));
59 dst
->ui
[3] = src
->ui
[3];
62 typedef void (*tdfx_emit_func
)( GLcontext
*, GLuint
, GLuint
, void *, GLuint
);
66 tnl_interp_func interp
;
67 tnl_copy_pv_func copy_pv
;
68 GLboolean (*check_tex_sizes
)( GLcontext
*ctx
);
70 GLuint vertex_stride_shift
;
72 } setup_tab
[TDFX_MAX_SETUP
];
77 #define GET_COLOR(ptr, idx) ((ptr)->data[idx])
80 static void interp_extras( GLcontext
*ctx
,
82 GLuint dst
, GLuint out
, GLuint in
,
83 GLboolean force_boundary
)
85 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
87 /*fprintf(stderr, "%s\n", __FUNCTION__);*/
89 if (VB
->ColorPtr
[1]) {
91 GET_COLOR(VB
->ColorPtr
[1], dst
),
92 GET_COLOR(VB
->ColorPtr
[1], out
),
93 GET_COLOR(VB
->ColorPtr
[1], in
) );
97 VB
->EdgeFlag
[dst
] = VB
->EdgeFlag
[out
] || force_boundary
;
100 setup_tab
[TDFX_CONTEXT(ctx
)->SetupIndex
].interp(ctx
, t
, dst
, out
, in
,
104 static void copy_pv_extras( GLcontext
*ctx
, GLuint dst
, GLuint src
)
106 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
108 if (VB
->ColorPtr
[1]) {
109 COPY_CHAN4( GET_COLOR(VB
->ColorPtr
[1], dst
),
110 GET_COLOR(VB
->ColorPtr
[1], src
) );
113 setup_tab
[TDFX_CONTEXT(ctx
)->SetupIndex
].copy_pv(ctx
, dst
, src
);
118 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT)
119 #define TAG(x) x##_wg
120 #include "tdfx_vbtmp.h"
122 /* Special for tdfx: fog requires w
124 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT)
125 #define TAG(x) x##_wg_fog
126 #include "tdfx_vbtmp.h"
128 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT)
129 #define TAG(x) x##_wgt0
130 #include "tdfx_vbtmp.h"
132 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)
133 #define TAG(x) x##_wgt0t1
134 #include "tdfx_vbtmp.h"
136 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_PTEX_BIT)
137 #define TAG(x) x##_wgpt0
138 #include "tdfx_vbtmp.h"
140 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT|\
142 #define TAG(x) x##_wgpt0t1
143 #include "tdfx_vbtmp.h"
145 #define IND (TDFX_RGBA_BIT)
147 #include "tdfx_vbtmp.h"
149 #define IND (TDFX_TEX0_BIT)
150 #define TAG(x) x##_t0
151 #include "tdfx_vbtmp.h"
153 #define IND (TDFX_TEX0_BIT|TDFX_TEX1_BIT)
154 #define TAG(x) x##_t0t1
155 #include "tdfx_vbtmp.h"
157 #define IND (TDFX_RGBA_BIT|TDFX_TEX0_BIT)
158 #define TAG(x) x##_gt0
159 #include "tdfx_vbtmp.h"
161 #define IND (TDFX_RGBA_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)
162 #define TAG(x) x##_gt0t1
163 #include "tdfx_vbtmp.h"
167 static void init_setup_tab( void )
184 void tdfxPrintSetupFlags(char *msg
, GLuint flags
)
186 fprintf(stderr
, "%s(%x): %s%s%s%s%s\n",
189 (flags
& TDFX_XYZ_BIT
) ? " xyz," : "",
190 (flags
& TDFX_W_BIT
) ? " w," : "",
191 (flags
& TDFX_RGBA_BIT
) ? " rgba," : "",
192 (flags
& TDFX_TEX0_BIT
) ? " tex-0," : "",
193 (flags
& TDFX_TEX1_BIT
) ? " tex-1," : "");
198 void tdfxCheckTexSizes( GLcontext
*ctx
)
200 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
201 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
203 if (!setup_tab
[fxMesa
->SetupIndex
].check_tex_sizes(ctx
)) {
204 GLuint ind
= fxMesa
->SetupIndex
|= (TDFX_PTEX_BIT
|TDFX_RGBA_BIT
);
206 /* Tdfx handles projective textures nicely; just have to change
207 * up to the new vertex format.
209 if (setup_tab
[ind
].vertex_format
!= fxMesa
->vertexFormat
) {
211 fxMesa
->dirty
|= TDFX_UPLOAD_VERTEX_LAYOUT
;
212 fxMesa
->vertexFormat
= setup_tab
[ind
].vertex_format
;
213 fxMesa
->vertex_stride_shift
= setup_tab
[ind
].vertex_stride_shift
;
215 /* This is required as we have just changed the vertex
216 * format, so the interp and copy routines must also change.
217 * In the unfilled and twosided cases we are using the
218 * swrast_setup ones anyway, so leave them in place.
220 if (!(ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
221 tnl
->Driver
.Render
.Interp
= setup_tab
[fxMesa
->SetupIndex
].interp
;
222 tnl
->Driver
.Render
.CopyPV
= setup_tab
[fxMesa
->SetupIndex
].copy_pv
;
229 void tdfxBuildVertices( GLcontext
*ctx
, GLuint start
, GLuint count
,
232 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
233 GLubyte
*v
= (fxMesa
->verts
+ (start
<<fxMesa
->vertex_stride_shift
));
234 GLuint stride
= 1<<fxMesa
->vertex_stride_shift
;
236 newinputs
|= fxMesa
->SetupNewInputs
;
237 fxMesa
->SetupNewInputs
= 0;
242 if (newinputs
& VERT_BIT_POS
) {
243 setup_tab
[fxMesa
->SetupIndex
].emit( ctx
, start
, count
, v
, stride
);
247 if (newinputs
& VERT_BIT_COLOR0
)
248 ind
|= TDFX_RGBA_BIT
;
250 if (newinputs
& VERT_BIT_TEX0
)
251 ind
|= TDFX_TEX0_BIT
;
253 if (newinputs
& VERT_BIT_TEX1
)
254 ind
|= TDFX_TEX0_BIT
|TDFX_TEX1_BIT
;
256 if (fxMesa
->SetupIndex
& TDFX_PTEX_BIT
)
259 ind
&= fxMesa
->SetupIndex
;
262 setup_tab
[ind
].emit( ctx
, start
, count
, v
, stride
);
268 void tdfxChooseVertexState( GLcontext
*ctx
)
270 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
271 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
272 GLuint ind
= TDFX_XYZ_BIT
|TDFX_RGBA_BIT
;
274 if (ctx
->Texture
._EnabledUnits
& 0x2)
276 ind
|= TDFX_W_BIT
|TDFX_TEX1_BIT
|TDFX_TEX0_BIT
;
277 else if (ctx
->Texture
._EnabledUnits
& 0x1)
279 ind
|= TDFX_W_BIT
|TDFX_TEX0_BIT
;
280 else if (ctx
->Fog
.Enabled
)
283 fxMesa
->SetupIndex
= ind
;
285 if (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
)) {
286 tnl
->Driver
.Render
.Interp
= interp_extras
;
287 tnl
->Driver
.Render
.CopyPV
= copy_pv_extras
;
289 tnl
->Driver
.Render
.Interp
= setup_tab
[ind
].interp
;
290 tnl
->Driver
.Render
.CopyPV
= setup_tab
[ind
].copy_pv
;
293 if (setup_tab
[ind
].vertex_format
!= fxMesa
->vertexFormat
) {
295 fxMesa
->dirty
|= TDFX_UPLOAD_VERTEX_LAYOUT
;
296 fxMesa
->vertexFormat
= setup_tab
[ind
].vertex_format
;
297 fxMesa
->vertex_stride_shift
= setup_tab
[ind
].vertex_stride_shift
;
303 void tdfxInitVB( GLcontext
*ctx
)
305 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
306 GLuint size
= TNL_CONTEXT(ctx
)->vb
.Size
;
307 static int firsttime
= 1;
313 fxMesa
->verts
= (GLubyte
*)ALIGN_MALLOC(size
* sizeof(tdfxVertex
), 32);
314 fxMesa
->vertexFormat
= setup_tab
[TDFX_XYZ_BIT
|TDFX_RGBA_BIT
].vertex_format
;
315 fxMesa
->vertex_stride_shift
= setup_tab
[(TDFX_XYZ_BIT
|
316 TDFX_RGBA_BIT
)].vertex_stride_shift
;
317 fxMesa
->SetupIndex
= TDFX_XYZ_BIT
|TDFX_RGBA_BIT
;
321 void tdfxFreeVB( GLcontext
*ctx
)
323 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
325 ALIGN_FREE(fxMesa
->verts
);