Remove x/y/width/height parameters from Clear functions.
[mesa.git] / src / mesa / drivers / dri / tdfx / tdfx_render.c
1 /* -*- mode: c; c-basic-offset: 3 -*-
2 *
3 * Copyright 2000 VA Linux Systems Inc., Fremont, California.
4 *
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * VA LINUX SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
23 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 */
26 /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c,v 1.4 2002/02/22 21:45:03 dawes Exp $ */
27
28 /*
29 * New fixes:
30 * Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004
31 *
32 * Original rewrite:
33 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
34 *
35 * Authors:
36 * Gareth Hughes <gareth@valinux.com>
37 * Brian Paul <brianp@valinux.com>
38 *
39 */
40
41 #include "tdfx_context.h"
42 #include "tdfx_render.h"
43 #include "tdfx_state.h"
44 #include "tdfx_texman.h"
45 #include "swrast/swrast.h"
46
47 /* Clear the color and/or depth buffers.
48 */
49 static void tdfxClear( GLcontext *ctx, GLbitfield mask )
50 {
51 tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx;
52 GLbitfield softwareMask = mask & (BUFFER_BIT_ACCUM);
53 const GLuint stencil_size =
54 fxMesa->haveHwStencil ? fxMesa->glCtx->Visual.stencilBits : 0;
55
56 if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
57 fprintf( stderr, "tdfxClear(0x%x)\n", mask);
58 }
59
60 /* Need this check to respond to glScissor and clipping updates */
61 if ((fxMesa->new_state & (TDFX_NEW_CLIP | TDFX_NEW_DEPTH)) ||
62 (fxMesa->dirty & TDFX_UPLOAD_COLOR_MASK)) {
63 tdfxDDUpdateHwState(ctx);
64 }
65
66 /* we can't clear accum buffers */
67 mask &= ~(BUFFER_BIT_ACCUM);
68
69 if (mask & BUFFER_BIT_STENCIL) {
70 if (!fxMesa->haveHwStencil || (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
71 /* Napalm seems to have trouble with stencil write masks != 0xff */
72 /* do stencil clear in software */
73 mask &= ~(BUFFER_BIT_STENCIL);
74 softwareMask |= BUFFER_BIT_STENCIL;
75 }
76 }
77
78 if (fxMesa->glCtx->Visual.redBits != 8) {
79 /* can only do color masking if running in 24/32bpp on Napalm */
80 if (ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP] ||
81 ctx->Color.ColorMask[GCOMP] != ctx->Color.ColorMask[BCOMP]) {
82 softwareMask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT));
83 mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT);
84 }
85 }
86
87 if (fxMesa->haveHwStencil) {
88 /*
89 * If we want to clear stencil, it must be enabled
90 * in the HW, even if the stencil test is not enabled
91 * in the OGL state.
92 */
93 LOCK_HARDWARE(fxMesa);
94 if (mask & BUFFER_BIT_STENCIL) {
95 fxMesa->Glide.grStencilMask(/*ctx->Stencil.WriteMask*/ 0xff);
96 /* set stencil ref value = desired clear value */
97 fxMesa->Glide.grStencilFunc(GR_CMP_ALWAYS,
98 (fxMesa->Stencil.Clear & 0xff), 0xff);
99 fxMesa->Glide.grStencilOp(GR_STENCILOP_REPLACE,
100 GR_STENCILOP_REPLACE, GR_STENCILOP_REPLACE);
101 fxMesa->Glide.grEnable(GR_STENCIL_MODE_EXT);
102 }
103 else {
104 fxMesa->Glide.grDisable(GR_STENCIL_MODE_EXT);
105 }
106 UNLOCK_HARDWARE(fxMesa);
107 }
108
109 /*
110 * This may be ugly, but it's needed in order to work around a number
111 * of Glide bugs.
112 */
113 BEGIN_CLIP_LOOP(fxMesa);
114 {
115 /*
116 * This could probably be done fancier but doing each possible case
117 * explicitly is less error prone.
118 */
119 switch (mask & ~BUFFER_BIT_STENCIL) {
120 case BUFFER_BIT_BACK_LEFT | BUFFER_BIT_DEPTH:
121 /* back buffer & depth */
122 FX_grColorMaskv_NoLock(ctx, true4); /* work around Voodoo3 bug */
123 fxMesa->Glide.grDepthMask(FXTRUE);
124 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
125 if (stencil_size > 0) {
126 fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
127 fxMesa->Color.ClearAlpha,
128 fxMesa->Depth.Clear,
129 (FxU32) (ctx->Stencil.Clear & 0xff));
130 }
131 else
132 fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
133 fxMesa->Color.ClearAlpha,
134 fxMesa->Depth.Clear);
135 if (!ctx->Depth.Mask || !ctx->Depth.Test) {
136 fxMesa->Glide.grDepthMask(FXFALSE);
137 }
138 break;
139 case BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_DEPTH:
140 /* XXX it appears that the depth buffer isn't cleared when
141 * glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set.
142 * This is a work-around/
143 */
144 /* clear depth */
145 fxMesa->Glide.grDepthMask(FXTRUE);
146 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
147 FX_grColorMaskv_NoLock(ctx, false4);
148 if (stencil_size > 0)
149 fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
150 fxMesa->Color.ClearAlpha,
151 fxMesa->Depth.Clear,
152 (FxU32) (ctx->Stencil.Clear & 0xff));
153 else
154 fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
155 fxMesa->Color.ClearAlpha,
156 fxMesa->Depth.Clear & 0xff);
157 /* clear front */
158 FX_grColorMaskv_NoLock(ctx, true4);
159 fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
160 if (stencil_size > 0)
161 fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
162 fxMesa->Color.ClearAlpha,
163 fxMesa->Depth.Clear,
164 (FxU32) (ctx->Stencil.Clear & 0xff));
165 else
166 fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
167 fxMesa->Color.ClearAlpha,
168 fxMesa->Depth.Clear);
169 if (!ctx->Depth.Mask || !ctx->Depth.Test) {
170 fxMesa->Glide.grDepthMask(FXFALSE);
171 }
172 break;
173 case BUFFER_BIT_BACK_LEFT:
174 /* back buffer only */
175 fxMesa->Glide.grDepthMask(FXFALSE);
176 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
177 if (stencil_size > 0)
178 fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
179 fxMesa->Color.ClearAlpha,
180 fxMesa->Depth.Clear,
181 (FxU32) (ctx->Stencil.Clear & 0xff));
182 else
183 fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
184 fxMesa->Color.ClearAlpha,
185 fxMesa->Depth.Clear);
186 if (ctx->Depth.Mask && ctx->Depth.Test) {
187 fxMesa->Glide.grDepthMask(FXTRUE);
188 }
189 break;
190 case BUFFER_BIT_FRONT_LEFT:
191 /* front buffer only */
192 fxMesa->Glide.grDepthMask(FXFALSE);
193 fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
194 if (stencil_size > 0)
195 fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
196 fxMesa->Color.ClearAlpha,
197 fxMesa->Depth.Clear,
198 (FxU32) (ctx->Stencil.Clear & 0xff));
199 else
200 fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
201 fxMesa->Color.ClearAlpha,
202 fxMesa->Depth.Clear);
203 if (ctx->Depth.Mask && ctx->Depth.Test) {
204 fxMesa->Glide.grDepthMask(FXTRUE);
205 }
206 break;
207 case BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT:
208 /* front and back */
209 fxMesa->Glide.grDepthMask(FXFALSE);
210 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
211 if (stencil_size > 0)
212 fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
213 fxMesa->Color.ClearAlpha,
214 fxMesa->Depth.Clear,
215 (FxU32) (ctx->Stencil.Clear & 0xff));
216 else
217 fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
218 fxMesa->Color.ClearAlpha,
219 fxMesa->Depth.Clear);
220 fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
221 if (stencil_size > 0)
222 fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
223 fxMesa->Color.ClearAlpha,
224 fxMesa->Depth.Clear,
225 (FxU32) (ctx->Stencil.Clear & 0xff));
226 else
227 fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
228 fxMesa->Color.ClearAlpha,
229 fxMesa->Depth.Clear);
230 if (ctx->Depth.Mask && ctx->Depth.Test) {
231 fxMesa->Glide.grDepthMask(FXTRUE);
232 }
233 break;
234 case BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT | BUFFER_BIT_DEPTH:
235 /* clear front */
236 fxMesa->Glide.grDepthMask(FXFALSE);
237 fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
238 if (stencil_size > 0)
239 fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
240 fxMesa->Color.ClearAlpha,
241 fxMesa->Depth.Clear,
242 (FxU32) (ctx->Stencil.Clear & 0xff));
243 else
244 fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
245 fxMesa->Color.ClearAlpha,
246 fxMesa->Depth.Clear);
247 /* clear back and depth */
248 fxMesa->Glide.grDepthMask(FXTRUE);
249 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
250 if (stencil_size > 0)
251 fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
252 fxMesa->Color.ClearAlpha,
253 fxMesa->Depth.Clear,
254 (FxU32) (ctx->Stencil.Clear & 0xff));
255 else
256 fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
257 fxMesa->Color.ClearAlpha,
258 fxMesa->Depth.Clear);
259 if (!ctx->Depth.Mask || !ctx->Depth.Mask) {
260 fxMesa->Glide.grDepthMask(FXFALSE);
261 }
262 break;
263 case BUFFER_BIT_DEPTH:
264 /* just the depth buffer */
265 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
266 FX_grColorMaskv_NoLock(ctx, false4);
267 fxMesa->Glide.grDepthMask(FXTRUE);
268 if (stencil_size > 0)
269 fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
270 fxMesa->Color.ClearAlpha,
271 fxMesa->Depth.Clear,
272 (FxU32) (ctx->Stencil.Clear & 0xff));
273 else
274 fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
275 fxMesa->Color.ClearAlpha,
276 fxMesa->Depth.Clear);
277 FX_grColorMaskv_NoLock(ctx, true4);
278 if (ctx->DrawBuffer->_ColorDrawBufferMask[0] & BUFFER_BIT_FRONT_LEFT)
279 fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
280 if (!ctx->Depth.Test || !ctx->Depth.Mask)
281 fxMesa->Glide.grDepthMask(FXFALSE);
282 break;
283 default:
284 /* clear no color buffers or depth buffer but might clear stencil */
285 if (stencil_size > 0 && (mask & BUFFER_BIT_STENCIL)) {
286 /* XXX need this RenderBuffer call to work around Glide bug */
287 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
288 fxMesa->Glide.grDepthMask(FXFALSE);
289 FX_grColorMaskv_NoLock(ctx, false4);
290 fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
291 fxMesa->Color.ClearAlpha,
292 fxMesa->Depth.Clear,
293 (FxU32) (ctx->Stencil.Clear & 0xff));
294 if (ctx->Depth.Mask && ctx->Depth.Test) {
295 fxMesa->Glide.grDepthMask(FXTRUE);
296 }
297 FX_grColorMaskv_NoLock(ctx, true4);
298 if (ctx->DrawBuffer->_ColorDrawBufferMask[0] & BUFFER_BIT_FRONT_LEFT)
299 fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
300 }
301 }
302 }
303 END_CLIP_LOOP(fxMesa);
304
305 if (fxMesa->haveHwStencil && (mask & BUFFER_BIT_STENCIL)) {
306 /* We changed the stencil state above. Signal that we need to
307 * upload it again.
308 */
309 fxMesa->dirty |= TDFX_UPLOAD_STENCIL;
310 }
311
312 if (softwareMask)
313 _swrast_Clear(ctx, softwareMask);
314 }
315
316
317
318 static void tdfxFinish( GLcontext *ctx )
319 {
320 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
321
322 FLUSH_BATCH( fxMesa );
323
324 LOCK_HARDWARE( fxMesa );
325 fxMesa->Glide.grFinish();
326 UNLOCK_HARDWARE( fxMesa );
327 }
328
329 static void tdfxFlush( GLcontext *ctx )
330 {
331 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
332
333 FLUSH_BATCH( fxMesa );
334
335 LOCK_HARDWARE( fxMesa );
336 fxMesa->Glide.grFlush();
337 UNLOCK_HARDWARE( fxMesa );
338 }
339
340
341 #if 0
342 static const char *texSource(int k)
343 {
344 switch (k) {
345 case GR_CMBX_ZERO:
346 return "GR_CMBX_ZERO";
347 case GR_CMBX_TEXTURE_ALPHA:
348 return "GR_CMBX_TEXTURE_ALPHA";
349 case GR_CMBX_ALOCAL:
350 return "GR_CMBX_ALOCAL";
351 case GR_CMBX_AOTHER:
352 return "GR_CMBX_AOTHER";
353 case GR_CMBX_B:
354 return "GR_CMBX_B";
355 case GR_CMBX_CONSTANT_ALPHA:
356 return "GR_CMBX_CONSTANT_ALPHA";
357 case GR_CMBX_CONSTANT_COLOR:
358 return "GR_CMBX_CONSTANT_COLOR";
359 case GR_CMBX_DETAIL_FACTOR:
360 return "GR_CMBX_DETAIL_FACTOR";
361 case GR_CMBX_ITALPHA:
362 return "GR_CMBX_ITALPHA";
363 case GR_CMBX_ITRGB:
364 return "GR_CMBX_ITRGB";
365 case GR_CMBX_LOCAL_TEXTURE_ALPHA:
366 return "GR_CMBX_LOCAL_TEXTURE_ALPHA";
367 case GR_CMBX_LOCAL_TEXTURE_RGB:
368 return "GR_CMBX_LOCAL_TEXTURE_RGB";
369 case GR_CMBX_LOD_FRAC:
370 return "GR_CMBX_LOD_FRAC";
371 case GR_CMBX_OTHER_TEXTURE_ALPHA:
372 return "GR_CMBX_OTHER_TEXTURE_ALPHA";
373 case GR_CMBX_OTHER_TEXTURE_RGB:
374 return "GR_CMBX_OTHER_TEXTURE_RGB";
375 case GR_CMBX_TEXTURE_RGB:
376 return "GR_CMBX_TEXTURE_RGB";
377 case GR_CMBX_TMU_CALPHA:
378 return "GR_CMBX_TMU_CALPHA";
379 case GR_CMBX_TMU_CCOLOR:
380 return "GR_CMBX_TMU_CCOLOR";
381 default:
382 return "";
383 }
384 }
385 #endif
386
387 #if 0
388 static const char *texMode(int k)
389 {
390 switch (k) {
391 case GR_FUNC_MODE_ZERO:
392 return "GR_FUNC_MODE_ZERO";
393 case GR_FUNC_MODE_X:
394 return "GR_FUNC_MODE_X";
395 case GR_FUNC_MODE_ONE_MINUS_X:
396 return "GR_FUNC_MODE_ONE_MINUS_X";
397 case GR_FUNC_MODE_NEGATIVE_X:
398 return "GR_FUNC_MODE_NEGATIVE_X";
399 case GR_FUNC_MODE_X_MINUS_HALF:
400 return "GR_FUNC_MODE_X_MINUS_HALF";
401 default:
402 return "";
403 }
404 }
405 #endif
406
407 #if 0
408 static const char *texInvert(int k)
409 {
410 return k ? "FXTRUE" : "FXFALSE";
411 }
412 #endif
413
414 static void uploadTextureEnv( tdfxContextPtr fxMesa )
415 {
416 if (TDFX_IS_NAPALM(fxMesa)) {
417 int unit;
418 for (unit = 0; unit < TDFX_NUM_TMU; unit++) {
419 #if 0
420 printf("upload env %d\n", unit);
421 printf(" cSourceA = %s\t", texSource(fxMesa->TexCombineExt[unit].Color.SourceA));
422 printf(" cModeA = %s\n", texMode(fxMesa->TexCombineExt[unit].Color.ModeA));
423 printf(" cSourceB = %s\t", texSource(fxMesa->TexCombineExt[unit].Color.SourceB));
424 printf(" cModeB = %s\n", texMode(fxMesa->TexCombineExt[unit].Color.ModeB));
425 printf(" cSourceC = %s\t", texSource(fxMesa->TexCombineExt[unit].Color.SourceC));
426 printf(" cInvertC = %s\n", texInvert(fxMesa->TexCombineExt[unit].Color.InvertC));
427 printf(" cSourceD = %s\t", texSource(fxMesa->TexCombineExt[unit].Color.SourceD));
428 printf(" cInvertD = %s\n", texInvert(fxMesa->TexCombineExt[unit].Color.InvertD));
429 printf(" cShift = %d\t", fxMesa->TexCombineExt[unit].Color.Shift);
430 printf(" cInvert = %d\n", fxMesa->TexCombineExt[unit].Color.Invert);
431 printf(" aSourceA = %s\t", texSource(fxMesa->TexCombineExt[unit].Alpha.SourceA));
432 printf(" aModeA = %s\n", texMode(fxMesa->TexCombineExt[unit].Alpha.ModeA));
433 printf(" aSourceB = %s\t", texSource(fxMesa->TexCombineExt[unit].Alpha.SourceB));
434 printf(" aModeB = %s\n", texMode(fxMesa->TexCombineExt[unit].Alpha.ModeB));
435 printf(" aSourceC = %s\t", texSource(fxMesa->TexCombineExt[unit].Alpha.SourceC));
436 printf(" aInvertC = %s\n", texInvert(fxMesa->TexCombineExt[unit].Alpha.InvertC));
437 printf(" aSourceD = %s\t", texSource(fxMesa->TexCombineExt[unit].Alpha.SourceD));
438 printf(" aInvertD = %s\n", texInvert(fxMesa->TexCombineExt[unit].Alpha.InvertD));
439 printf(" aShift = %d\t", fxMesa->TexCombineExt[unit].Alpha.Shift);
440 printf(" aInvert = %d\n", fxMesa->TexCombineExt[unit].Alpha.Invert);
441 printf(" Color = 0x%08x\n", fxMesa->TexCombineExt[unit].EnvColor);
442 #endif
443 fxMesa->Glide.grTexColorCombineExt(TDFX_TMU0 + unit,
444 fxMesa->TexCombineExt[unit].Color.SourceA,
445 fxMesa->TexCombineExt[unit].Color.ModeA,
446 fxMesa->TexCombineExt[unit].Color.SourceB,
447 fxMesa->TexCombineExt[unit].Color.ModeB,
448 fxMesa->TexCombineExt[unit].Color.SourceC,
449 fxMesa->TexCombineExt[unit].Color.InvertC,
450 fxMesa->TexCombineExt[unit].Color.SourceD,
451 fxMesa->TexCombineExt[unit].Color.InvertD,
452 fxMesa->TexCombineExt[unit].Color.Shift,
453 fxMesa->TexCombineExt[unit].Color.Invert);
454 fxMesa->Glide.grTexAlphaCombineExt(TDFX_TMU0 + unit,
455 fxMesa->TexCombineExt[unit].Alpha.SourceA,
456 fxMesa->TexCombineExt[unit].Alpha.ModeA,
457 fxMesa->TexCombineExt[unit].Alpha.SourceB,
458 fxMesa->TexCombineExt[unit].Alpha.ModeB,
459 fxMesa->TexCombineExt[unit].Alpha.SourceC,
460 fxMesa->TexCombineExt[unit].Alpha.InvertC,
461 fxMesa->TexCombineExt[unit].Alpha.SourceD,
462 fxMesa->TexCombineExt[unit].Alpha.InvertD,
463 fxMesa->TexCombineExt[unit].Alpha.Shift,
464 fxMesa->TexCombineExt[unit].Alpha.Invert);
465 fxMesa->Glide.grConstantColorValueExt(TDFX_TMU0 + unit,
466 fxMesa->TexCombineExt[unit].EnvColor);
467 }
468 }
469 else {
470 /* Voodoo3 */
471 int unit;
472 for (unit = 0; unit < TDFX_NUM_TMU; unit++) {
473 struct tdfx_texcombine *comb = &fxMesa->TexCombine[unit];
474 fxMesa->Glide.grTexCombine(TDFX_TMU0 + unit,
475 comb->FunctionRGB,
476 comb->FactorRGB,
477 comb->FunctionAlpha,
478 comb->FactorAlpha,
479 comb->InvertRGB,
480 comb->InvertAlpha);
481 }
482 }
483 }
484
485
486 static void uploadTextureParams( tdfxContextPtr fxMesa )
487 {
488 int unit;
489 for (unit = 0; unit < TDFX_NUM_TMU; unit++) {
490 const struct tdfx_texparams *p = &fxMesa->TexParams[unit];
491 /*
492 printf("upload params %d\n", unit);
493 printf(" clamp %x %x\n", env->sClamp, env->tClamp);
494 printf(" filter %x %x\n", env->minFilt, env->magFilt);
495 printf(" mipmap %x %x\n", env->mmMode, env->LODblend);
496 printf(" lod bias %f\n", env->LodBias);
497 */
498 fxMesa->Glide.grTexClampMode(GR_TMU0 + unit, p->sClamp, p->tClamp);
499 fxMesa->Glide.grTexFilterMode(GR_TMU0 + unit, p->minFilt, p->magFilt);
500 fxMesa->Glide.grTexMipMapMode(GR_TMU0 + unit, p->mmMode, p->LODblend);
501 fxMesa->Glide.grTexLodBiasValue(GR_TMU0 + unit, CLAMP(p->LodBias, -8, 7.75));
502 }
503 }
504
505
506 static void uploadTextureSource( tdfxContextPtr fxMesa )
507 {
508 int unit;
509 for (unit = 0; unit < TDFX_NUM_TMU; unit++) {
510 const struct tdfx_texsource *src = &fxMesa->TexSource[unit];
511 /*
512 printf("upload source %d @ %d %p\n", unit, src->StartAddress, src->Info);
513 */
514 if (src->Info) {
515 /*
516 printf(" smallLodLog2=%d largeLodLog2=%d ar=%d format=%d data=%p\n",
517 src->Info->smallLodLog2, src->Info->largeLodLog2,
518 src->Info->aspectRatioLog2, src->Info->format,
519 src->Info->data);
520 */
521 fxMesa->Glide.grTexSource(GR_TMU0 + unit,
522 src->StartAddress,
523 src->EvenOdd,
524 src->Info);
525 }
526 }
527 }
528
529
530 static void uploadTextureImages( tdfxContextPtr fxMesa )
531 {
532 GLcontext *ctx = fxMesa->glCtx;
533 int unit;
534 for (unit = 0; unit < TDFX_NUM_TMU; unit++) {
535 if (ctx->Texture.Unit[unit]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
536 struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
537 tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
538 if (ti && ti->reloadImages && ti->whichTMU != TDFX_TMU_NONE) {
539 /*
540 printf("download texture image on unit %d\n", unit);
541 */
542 tdfxTMDownloadTexture(fxMesa, tObj);
543 ti->reloadImages = GL_FALSE;
544 }
545 }
546 }
547 }
548
549
550
551 /*
552 * If scissoring is enabled, compute intersection of scissor region
553 * with all X clip rects, resulting in new cliprect list.
554 * If number of cliprects is zero or one, call grClipWindow to setup
555 * the clip region. Otherwise we'll call grClipWindow inside the
556 * BEGIN_CLIP_LOOP macro.
557 */
558 void tdfxUploadClipping( tdfxContextPtr fxMesa )
559 {
560 __DRIdrawablePrivate *dPriv = fxMesa->driDrawable;
561
562 assert(dPriv);
563
564 if (fxMesa->numClipRects == 0) {
565 /* all drawing clipped away */
566 fxMesa->Glide.grClipWindow(0, 0, 0, 0);
567 }
568 else if (fxMesa->numClipRects == 1) {
569 fxMesa->Glide.grClipWindow(fxMesa->pClipRects[0].x1,
570 fxMesa->screen_height - fxMesa->pClipRects[0].y2,
571 fxMesa->pClipRects[0].x2,
572 fxMesa->screen_height - fxMesa->pClipRects[0].y1);
573 }
574 /* else, we'll do a cliprect loop around all drawing */
575
576 fxMesa->Glide.grDRIPosition( dPriv->x, dPriv->y, dPriv->w, dPriv->h,
577 fxMesa->numClipRects, fxMesa->pClipRects );
578 }
579
580
581 void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa )
582 {
583 if ( !fxMesa->dirty )
584 return;
585
586 if ( fxMesa->dirty & TDFX_UPLOAD_COLOR_COMBINE ) {
587 if (TDFX_IS_NAPALM(fxMesa)) {
588 fxMesa->Glide.grColorCombineExt(fxMesa->ColorCombineExt.SourceA,
589 fxMesa->ColorCombineExt.ModeA,
590 fxMesa->ColorCombineExt.SourceB,
591 fxMesa->ColorCombineExt.ModeB,
592 fxMesa->ColorCombineExt.SourceC,
593 fxMesa->ColorCombineExt.InvertC,
594 fxMesa->ColorCombineExt.SourceD,
595 fxMesa->ColorCombineExt.InvertD,
596 fxMesa->ColorCombineExt.Shift,
597 fxMesa->ColorCombineExt.Invert);
598 }
599 else {
600 /* Voodoo 3 */
601 fxMesa->Glide.grColorCombine( fxMesa->ColorCombine.Function,
602 fxMesa->ColorCombine.Factor,
603 fxMesa->ColorCombine.Local,
604 fxMesa->ColorCombine.Other,
605 fxMesa->ColorCombine.Invert );
606 }
607 fxMesa->dirty &= ~TDFX_UPLOAD_COLOR_COMBINE;
608 }
609 if ( fxMesa->dirty & TDFX_UPLOAD_ALPHA_COMBINE ) {
610 if (TDFX_IS_NAPALM(fxMesa)) {
611 fxMesa->Glide.grAlphaCombineExt(fxMesa->AlphaCombineExt.SourceA,
612 fxMesa->AlphaCombineExt.ModeA,
613 fxMesa->AlphaCombineExt.SourceB,
614 fxMesa->AlphaCombineExt.ModeB,
615 fxMesa->AlphaCombineExt.SourceC,
616 fxMesa->AlphaCombineExt.InvertC,
617 fxMesa->AlphaCombineExt.SourceD,
618 fxMesa->AlphaCombineExt.InvertD,
619 fxMesa->AlphaCombineExt.Shift,
620 fxMesa->AlphaCombineExt.Invert);
621 }
622 else {
623 /* Voodoo 3 */
624 fxMesa->Glide.grAlphaCombine( fxMesa->AlphaCombine.Function,
625 fxMesa->AlphaCombine.Factor,
626 fxMesa->AlphaCombine.Local,
627 fxMesa->AlphaCombine.Other,
628 fxMesa->AlphaCombine.Invert );
629 }
630 fxMesa->dirty &= ~TDFX_UPLOAD_ALPHA_COMBINE;
631 }
632
633 if ( fxMesa->dirty & TDFX_UPLOAD_RENDER_BUFFER ) {
634 fxMesa->Glide.grRenderBuffer( fxMesa->DrawBuffer );
635 fxMesa->dirty &= ~TDFX_UPLOAD_RENDER_BUFFER;
636 }
637
638 if ( fxMesa->dirty & TDFX_UPLOAD_STIPPLE) {
639 fxMesa->Glide.grStipplePattern( fxMesa->Stipple.Pattern );
640 fxMesa->Glide.grStippleMode( fxMesa->Stipple.Mode );
641 fxMesa->dirty &= ~TDFX_UPLOAD_STIPPLE;
642 }
643
644 if ( fxMesa->dirty & TDFX_UPLOAD_ALPHA_TEST ) {
645 fxMesa->Glide.grAlphaTestFunction( fxMesa->Color.AlphaFunc );
646 fxMesa->dirty &= ~TDFX_UPLOAD_ALPHA_TEST;
647 }
648 if ( fxMesa->dirty & TDFX_UPLOAD_ALPHA_REF ) {
649 fxMesa->Glide.grAlphaTestReferenceValue( fxMesa->Color.AlphaRef );
650 fxMesa->dirty &= ~TDFX_UPLOAD_ALPHA_REF;
651 }
652 if ( fxMesa->dirty & TDFX_UPLOAD_BLEND_FUNC ) {
653 if (fxMesa->Glide.grAlphaBlendFunctionExt) {
654 fxMesa->Glide.grAlphaBlendFunctionExt( fxMesa->Color.BlendSrcRGB,
655 fxMesa->Color.BlendDstRGB,
656 fxMesa->Color.BlendEqRGB,
657 fxMesa->Color.BlendSrcA,
658 fxMesa->Color.BlendDstA,
659 fxMesa->Color.BlendEqA );
660 }
661 else {
662 fxMesa->Glide.grAlphaBlendFunction( fxMesa->Color.BlendSrcRGB,
663 fxMesa->Color.BlendDstRGB,
664 fxMesa->Color.BlendSrcA,
665 fxMesa->Color.BlendDstA );
666 }
667 fxMesa->dirty &= ~TDFX_UPLOAD_BLEND_FUNC;
668 }
669
670 if ( fxMesa->dirty & TDFX_UPLOAD_DEPTH_MODE ) {
671 fxMesa->Glide.grDepthBufferMode( fxMesa->Depth.Mode );
672 fxMesa->dirty &= ~TDFX_UPLOAD_DEPTH_MODE;
673 }
674 if ( fxMesa->dirty & TDFX_UPLOAD_DEPTH_BIAS ) {
675 fxMesa->Glide.grDepthBiasLevel( fxMesa->Depth.Bias );
676 fxMesa->dirty &= ~TDFX_UPLOAD_DEPTH_BIAS;
677 }
678 if ( fxMesa->dirty & TDFX_UPLOAD_DEPTH_FUNC ) {
679 fxMesa->Glide.grDepthBufferFunction( fxMesa->Depth.Func );
680 fxMesa->dirty &= ~TDFX_UPLOAD_DEPTH_FUNC;
681 }
682 if ( fxMesa->dirty & TDFX_UPLOAD_DEPTH_MASK ) {
683 fxMesa->Glide.grDepthMask( fxMesa->Depth.Mask );
684 fxMesa->dirty &= ~TDFX_UPLOAD_DEPTH_MASK;
685 }
686
687 if ( fxMesa->dirty & TDFX_UPLOAD_DITHER) {
688 fxMesa->Glide.grDitherMode( fxMesa->Color.Dither );
689 }
690
691 if ( fxMesa->dirty & TDFX_UPLOAD_FOG_MODE ) {
692 fxMesa->Glide.grFogMode( fxMesa->Fog.Mode );
693 fxMesa->dirty &= ~TDFX_UPLOAD_FOG_MODE;
694 }
695 if ( fxMesa->dirty & TDFX_UPLOAD_FOG_COLOR ) {
696 fxMesa->Glide.grFogColorValue( fxMesa->Fog.Color );
697 fxMesa->dirty &= ~TDFX_UPLOAD_FOG_COLOR;
698 }
699 if ( fxMesa->dirty & TDFX_UPLOAD_FOG_TABLE ) {
700 fxMesa->Glide.grFogTable( fxMesa->Fog.Table );
701 fxMesa->dirty &= ~TDFX_UPLOAD_FOG_TABLE;
702 }
703
704 if ( fxMesa->dirty & TDFX_UPLOAD_CULL ) {
705 fxMesa->Glide.grCullMode( fxMesa->CullMode );
706 fxMesa->dirty &= ~TDFX_UPLOAD_CULL;
707 }
708
709 if ( fxMesa->dirty & TDFX_UPLOAD_CLIP ) {
710 tdfxUploadClipping( fxMesa );
711 fxMesa->dirty &= ~TDFX_UPLOAD_CLIP;
712 }
713
714 if ( fxMesa->dirty & TDFX_UPLOAD_COLOR_MASK ) {
715 if ( fxMesa->Glide.grColorMaskExt
716 && fxMesa->glCtx->Visual.redBits == 8) {
717 fxMesa->Glide.grColorMaskExt( fxMesa->Color.ColorMask[RCOMP],
718 fxMesa->Color.ColorMask[GCOMP],
719 fxMesa->Color.ColorMask[BCOMP],
720 fxMesa->Color.ColorMask[ACOMP] );
721 } else {
722 fxMesa->Glide.grColorMask( fxMesa->Color.ColorMask[RCOMP] ||
723 fxMesa->Color.ColorMask[GCOMP] ||
724 fxMesa->Color.ColorMask[BCOMP],
725 /*fxMesa->Color.ColorMask[ACOMP]*/GL_FALSE/*[dBorca] no-no*/ );
726 }
727 fxMesa->dirty &= ~TDFX_UPLOAD_COLOR_MASK;
728 }
729
730 if ( fxMesa->dirty & TDFX_UPLOAD_CONSTANT_COLOR ) {
731 fxMesa->Glide.grConstantColorValue( fxMesa->Color.MonoColor );
732 fxMesa->dirty &= ~TDFX_UPLOAD_CONSTANT_COLOR;
733 }
734
735 if ( fxMesa->dirty & TDFX_UPLOAD_LINE ) {
736 if (fxMesa->glCtx->Line.SmoothFlag && fxMesa->glCtx->Line.Width == 1.0)
737 fxMesa->Glide.grEnable(GR_AA_ORDERED);
738 else
739 fxMesa->Glide.grDisable(GR_AA_ORDERED);
740 fxMesa->dirty &= ~TDFX_UPLOAD_LINE;
741 }
742
743 if ( fxMesa->dirty & TDFX_UPLOAD_STENCIL ) {
744 if (fxMesa->glCtx->Stencil.Enabled) {
745 fxMesa->Glide.grEnable(GR_STENCIL_MODE_EXT);
746 fxMesa->Glide.grStencilOp(fxMesa->Stencil.FailFunc,
747 fxMesa->Stencil.ZFailFunc,
748 fxMesa->Stencil.ZPassFunc);
749 fxMesa->Glide.grStencilFunc(fxMesa->Stencil.Function,
750 fxMesa->Stencil.RefValue,
751 fxMesa->Stencil.ValueMask);
752 fxMesa->Glide.grStencilMask(fxMesa->Stencil.WriteMask);
753 }
754 else {
755 fxMesa->Glide.grDisable(GR_STENCIL_MODE_EXT);
756 }
757 fxMesa->dirty &= ~TDFX_UPLOAD_STENCIL;
758 }
759
760 if ( fxMesa->dirty & TDFX_UPLOAD_VERTEX_LAYOUT ) {
761 fxMesa->Glide.grGlideSetVertexLayout( fxMesa->layout[fxMesa->vertexFormat] );
762 /* [dborca] enable fogcoord */
763 fxMesa->Glide.grVertexLayout(GR_PARAM_FOG_EXT, TDFX_FOG_OFFSET,
764 fxMesa->Fog.Mode == GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);
765 fxMesa->dirty &= ~TDFX_UPLOAD_VERTEX_LAYOUT;
766 }
767
768 if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_ENV ) {
769 uploadTextureEnv(fxMesa);
770 fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_ENV;
771 }
772
773 if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_PARAMS ) {
774 uploadTextureParams(fxMesa);
775 fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_PARAMS;
776 }
777
778 if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_PALETTE ) {
779 if (fxMesa->TexPalette.Data) {
780 fxMesa->Glide.grTexDownloadTable(fxMesa->TexPalette.Type, fxMesa->TexPalette.Data);
781 }
782 fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_PALETTE;
783 }
784
785 if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_SOURCE ) {
786 uploadTextureSource(fxMesa);
787 fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_SOURCE;
788 }
789
790 if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_IMAGES ) {
791 uploadTextureImages(fxMesa);
792 fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_IMAGES;
793 }
794
795 fxMesa->dirty = 0;
796 }
797
798
799
800 void tdfxInitRenderFuncs( struct dd_function_table *functions )
801 {
802 functions->Clear = tdfxClear;
803 functions->Finish = tdfxFinish;
804 functions->Flush = tdfxFlush;
805 }