fix build problem
[mesa.git] / src / mesa / drivers / dri / tdfx / tdfx_vb.c
1 /*
2 * GLX Hardware Device Driver for Intel i810
3 * Copyright (C) 1999 Keith Whitwell
4 *
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:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
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.
22 *
23 *
24 */
25 /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_vb.c,v 1.3 2002/10/30 12:52:01 alanh Exp $ */
26
27 #include "glheader.h"
28 #include "mtypes.h"
29 #include "imports.h"
30 #include "macros.h"
31 #include "colormac.h"
32
33 #include "math/m_translate.h"
34 #include "swrast_setup/swrast_setup.h"
35
36 #include "tdfx_context.h"
37 #include "tdfx_vb.h"
38 #include "tdfx_tris.h"
39 #include "tdfx_state.h"
40 #include "tdfx_render.h"
41
42 static void copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc )
43 {
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;
48 }
49
50 static struct {
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 );
55 GLuint vertex_format;
56 } setup_tab[TDFX_MAX_SETUP];
57
58
59
60
61 #define GET_COLOR(ptr, idx) ((ptr)->data[idx])
62
63
64 static void interp_extras( GLcontext *ctx,
65 GLfloat t,
66 GLuint dst, GLuint out, GLuint in,
67 GLboolean force_boundary )
68 {
69 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
70
71 /*fprintf(stderr, "%s\n", __FUNCTION__);*/
72
73 if (VB->ColorPtr[1]) {
74 INTERP_4F( t,
75 GET_COLOR(VB->ColorPtr[1], dst),
76 GET_COLOR(VB->ColorPtr[1], out),
77 GET_COLOR(VB->ColorPtr[1], in) );
78 }
79
80 if (VB->EdgeFlag) {
81 VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
82 }
83
84 setup_tab[TDFX_CONTEXT(ctx)->SetupIndex].interp(ctx, t, dst, out, in,
85 force_boundary);
86 }
87
88 static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src )
89 {
90 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
91
92 if (VB->ColorPtr[1]) {
93 COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst),
94 GET_COLOR(VB->ColorPtr[1], src) );
95 }
96
97 setup_tab[TDFX_CONTEXT(ctx)->SetupIndex].copy_pv(ctx, dst, src);
98 }
99
100
101
102 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT)
103 #define TAG(x) x##_wg
104 #include "tdfx_vbtmp.h"
105
106 /* Special for tdfx: fog requires w
107 */
108 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT)
109 #define TAG(x) x##_wg_fog
110 #include "tdfx_vbtmp.h"
111
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"
115
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"
119
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"
123
124 #define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT|\
125 TDFX_PTEX_BIT)
126 #define TAG(x) x##_wgpt0t1
127 #include "tdfx_vbtmp.h"
128
129 #define IND (TDFX_RGBA_BIT)
130 #define TAG(x) x##_g
131 #include "tdfx_vbtmp.h"
132
133 #define IND (TDFX_TEX0_BIT)
134 #define TAG(x) x##_t0
135 #include "tdfx_vbtmp.h"
136
137 #define IND (TDFX_TEX0_BIT|TDFX_TEX1_BIT)
138 #define TAG(x) x##_t0t1
139 #include "tdfx_vbtmp.h"
140
141 #define IND (TDFX_RGBA_BIT|TDFX_TEX0_BIT)
142 #define TAG(x) x##_gt0
143 #include "tdfx_vbtmp.h"
144
145 #define IND (TDFX_RGBA_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)
146 #define TAG(x) x##_gt0t1
147 #include "tdfx_vbtmp.h"
148
149
150 /* fogc { */
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"
154
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"
158
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"
162
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"
166
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"
171 /* fogc } */
172
173
174 static void init_setup_tab( void )
175 {
176 init_wg();
177 init_wg_fog();
178 init_wgt0();
179 init_wgt0t1();
180 init_wgpt0();
181 init_wgpt0t1();
182
183 init_g();
184 init_t0();
185 init_t0t1();
186 init_gt0();
187 init_gt0t1();
188
189 /* fogcoord */
190 init_wgf();
191 init_wgt0f();
192 init_wgt0t1f();
193 init_wgpt0f();
194 init_wgpt0t1f();
195 }
196
197
198 void tdfxPrintSetupFlags(char *msg, GLuint flags )
199 {
200 fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n",
201 msg,
202 (int)flags,
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," : "");
209 }
210
211
212
213 void tdfxCheckTexSizes( GLcontext *ctx )
214 {
215 TNLcontext *tnl = TNL_CONTEXT(ctx);
216 tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
217
218 if (!setup_tab[fxMesa->SetupIndex].check_tex_sizes(ctx)) {
219 GLuint ind = fxMesa->SetupIndex |= (TDFX_PTEX_BIT|TDFX_RGBA_BIT);
220
221 /* Tdfx handles projective textures nicely; just have to change
222 * up to the new vertex format.
223 */
224 if (setup_tab[ind].vertex_format != fxMesa->vertexFormat) {
225 FLUSH_BATCH(fxMesa);
226 fxMesa->dirty |= TDFX_UPLOAD_VERTEX_LAYOUT;
227 fxMesa->vertexFormat = setup_tab[ind].vertex_format;
228
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.
233 */
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;
237 }
238 }
239 }
240 }
241
242
243 void tdfxBuildVertices( GLcontext *ctx, GLuint start, GLuint count,
244 GLuint newinputs )
245 {
246 tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
247 tdfxVertex *v = fxMesa->verts + start;
248
249 newinputs |= fxMesa->SetupNewInputs;
250 fxMesa->SetupNewInputs = 0;
251
252 if (!newinputs)
253 return;
254
255 if (newinputs & VERT_BIT_POS) {
256 setup_tab[fxMesa->SetupIndex].emit( ctx, start, count, v );
257 } else {
258 GLuint ind = 0;
259
260 if (newinputs & VERT_BIT_COLOR0)
261 ind |= TDFX_RGBA_BIT;
262
263 if (newinputs & VERT_BIT_FOG)
264 ind |= TDFX_FOGC_BIT;
265
266 if (newinputs & VERT_BIT_TEX0)
267 ind |= TDFX_TEX0_BIT;
268
269 if (newinputs & VERT_BIT_TEX1)
270 ind |= TDFX_TEX0_BIT|TDFX_TEX1_BIT;
271
272 if (fxMesa->SetupIndex & TDFX_PTEX_BIT)
273 ind = ~0;
274
275 ind &= fxMesa->SetupIndex;
276
277 if (ind) {
278 setup_tab[ind].emit( ctx, start, count, v );
279 }
280 }
281 }
282
283
284 void tdfxChooseVertexState( GLcontext *ctx )
285 {
286 TNLcontext *tnl = TNL_CONTEXT(ctx);
287 tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
288 GLuint ind = TDFX_XYZ_BIT|TDFX_RGBA_BIT;
289
290 fxMesa->tmu_source[0] = 0;
291 fxMesa->tmu_source[1] = 1;
292
293 if (ctx->Texture._EnabledUnits & 0x2) {
294 if (ctx->Texture._EnabledUnits & 0x1) {
295 ind |= TDFX_TEX1_BIT;
296 }
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) {
301 /* unit 0 enabled */
302 ind |= TDFX_W_BIT|TDFX_TEX0_BIT;
303 } else if (fxMesa->Fog.Mode != GR_FOG_DISABLE) {
304 ind |= TDFX_W_BIT;
305 }
306
307 if (fxMesa->Fog.Mode == GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT) {
308 ind |= TDFX_FOGC_BIT;
309 }
310
311 fxMesa->SetupIndex = ind;
312
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;
316 } else {
317 tnl->Driver.Render.Interp = setup_tab[ind].interp;
318 tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
319 }
320
321 if (setup_tab[ind].vertex_format != fxMesa->vertexFormat) {
322 FLUSH_BATCH(fxMesa);
323 fxMesa->dirty |= TDFX_UPLOAD_VERTEX_LAYOUT;
324 fxMesa->vertexFormat = setup_tab[ind].vertex_format;
325 }
326 }
327
328
329
330 void tdfxInitVB( GLcontext *ctx )
331 {
332 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
333 GLuint size = TNL_CONTEXT(ctx)->vb.Size;
334 static int firsttime = 1;
335 if (firsttime) {
336 init_setup_tab();
337 firsttime = 0;
338 }
339
340 fxMesa->verts = ALIGN_MALLOC(size * sizeof(tdfxVertex), 32);
341 fxMesa->vertexFormat = TDFX_LAYOUT_TINY;
342 fxMesa->SetupIndex = TDFX_XYZ_BIT|TDFX_RGBA_BIT;
343 }
344
345
346 void tdfxFreeVB( GLcontext *ctx )
347 {
348 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
349 if (fxMesa->verts) {
350 ALIGN_FREE(fxMesa->verts);
351 fxMesa->verts = 0;
352 }
353 }