1 /* -*- mode: c; c-basic-offset: 3 -*-
3 * Copyright 2000 VA Linux Systems Inc., Fremont, California.
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:
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
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
26 /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c,v 1.4 2002/02/22 21:45:03 dawes Exp $ */
30 * Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004
33 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
36 * Gareth Hughes <gareth@valinux.com>
37 * Brian Paul <brianp@valinux.com>
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"
47 /* Clear the color and/or depth buffers.
49 static void tdfxClear( GLcontext
*ctx
,
50 GLbitfield mask
, GLboolean all
,
51 GLint x
, GLint y
, GLint width
, GLint height
)
53 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
54 GLbitfield softwareMask
= mask
& (DD_ACCUM_BIT
);
55 const GLuint stencil_size
=
56 fxMesa
->haveHwStencil
? fxMesa
->glCtx
->Visual
.stencilBits
: 0;
58 if ( TDFX_DEBUG
& DEBUG_VERBOSE_API
) {
59 fprintf( stderr
, "%s( %d, %d, %d, %d )\n",
60 __FUNCTION__
, (int) x
, (int) y
, (int) width
, (int) height
);
63 /* Need this check to respond to glScissor and clipping updates */
64 if ((fxMesa
->new_state
& (TDFX_NEW_CLIP
| TDFX_NEW_DEPTH
)) ||
65 (fxMesa
->dirty
& TDFX_UPLOAD_COLOR_MASK
)) {
66 tdfxDDUpdateHwState(ctx
);
69 /* we can't clear accum buffers */
70 mask
&= ~(DD_ACCUM_BIT
);
72 if (mask
& DD_STENCIL_BIT
) {
73 if (!fxMesa
->haveHwStencil
|| ctx
->Stencil
.WriteMask
[0] != 0xff) {
74 /* Napalm seems to have trouble with stencil write masks != 0xff */
75 /* do stencil clear in software */
76 mask
&= ~(DD_STENCIL_BIT
);
77 softwareMask
|= DD_STENCIL_BIT
;
81 if (fxMesa
->glCtx
->Visual
.redBits
!= 8) {
82 /* can only do color masking if running in 24/32bpp on Napalm */
83 if (ctx
->Color
.ColorMask
[RCOMP
] != ctx
->Color
.ColorMask
[GCOMP
] ||
84 ctx
->Color
.ColorMask
[GCOMP
] != ctx
->Color
.ColorMask
[BCOMP
]) {
85 softwareMask
|= (mask
& (DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
));
86 mask
&= ~(DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
);
90 if (fxMesa
->haveHwStencil
) {
92 * If we want to clear stencil, it must be enabled
93 * in the HW, even if the stencil test is not enabled
96 LOCK_HARDWARE(fxMesa
);
97 if (mask
& DD_STENCIL_BIT
) {
98 fxMesa
->Glide
.grStencilMask(/*ctx->Stencil.WriteMask*/ 0xff);
99 /* set stencil ref value = desired clear value */
100 fxMesa
->Glide
.grStencilFunc(GR_CMP_ALWAYS
,
101 fxMesa
->Stencil
.Clear
, 0xff);
102 fxMesa
->Glide
.grStencilOp(GR_STENCILOP_REPLACE
,
103 GR_STENCILOP_REPLACE
, GR_STENCILOP_REPLACE
);
104 fxMesa
->Glide
.grEnable(GR_STENCIL_MODE_EXT
);
107 fxMesa
->Glide
.grDisable(GR_STENCIL_MODE_EXT
);
109 UNLOCK_HARDWARE(fxMesa
);
113 * This may be ugly, but it's needed in order to work around a number
116 BEGIN_CLIP_LOOP(fxMesa
);
119 * This could probably be done fancier but doing each possible case
120 * explicitly is less error prone.
122 switch (mask
& ~DD_STENCIL_BIT
) {
123 case DD_BACK_LEFT_BIT
| DD_DEPTH_BIT
:
124 /* back buffer & depth */
125 FX_grColorMaskv_NoLock(ctx
, true4
); /* work around Voodoo3 bug */
126 fxMesa
->Glide
.grDepthMask(FXTRUE
);
127 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
128 if (stencil_size
> 0) {
129 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
130 fxMesa
->Color
.ClearAlpha
,
132 (FxU32
) ctx
->Stencil
.Clear
);
135 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
136 fxMesa
->Color
.ClearAlpha
,
137 fxMesa
->Depth
.Clear
);
138 if (!ctx
->Depth
.Mask
|| !ctx
->Depth
.Test
) {
139 fxMesa
->Glide
.grDepthMask(FXFALSE
);
142 case DD_FRONT_LEFT_BIT
| DD_DEPTH_BIT
:
143 /* XXX it appears that the depth buffer isn't cleared when
144 * glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set.
145 * This is a work-around/
148 fxMesa
->Glide
.grDepthMask(FXTRUE
);
149 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
150 FX_grColorMaskv_NoLock(ctx
, false4
);
151 if (stencil_size
> 0)
152 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
153 fxMesa
->Color
.ClearAlpha
,
155 (FxU32
) ctx
->Stencil
.Clear
);
157 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
158 fxMesa
->Color
.ClearAlpha
,
159 fxMesa
->Depth
.Clear
);
161 FX_grColorMaskv_NoLock(ctx
, true4
);
162 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
163 if (stencil_size
> 0)
164 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
165 fxMesa
->Color
.ClearAlpha
,
167 (FxU32
) ctx
->Stencil
.Clear
);
169 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
170 fxMesa
->Color
.ClearAlpha
,
171 fxMesa
->Depth
.Clear
);
172 if (!ctx
->Depth
.Mask
|| !ctx
->Depth
.Test
) {
173 fxMesa
->Glide
.grDepthMask(FXFALSE
);
176 case DD_BACK_LEFT_BIT
:
177 /* back buffer only */
178 fxMesa
->Glide
.grDepthMask(FXFALSE
);
179 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
180 if (stencil_size
> 0)
181 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
182 fxMesa
->Color
.ClearAlpha
,
184 (FxU32
) ctx
->Stencil
.Clear
);
186 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
187 fxMesa
->Color
.ClearAlpha
,
188 fxMesa
->Depth
.Clear
);
189 if (ctx
->Depth
.Mask
&& ctx
->Depth
.Test
) {
190 fxMesa
->Glide
.grDepthMask(FXTRUE
);
193 case DD_FRONT_LEFT_BIT
:
194 /* front buffer only */
195 fxMesa
->Glide
.grDepthMask(FXFALSE
);
196 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
197 if (stencil_size
> 0)
198 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
199 fxMesa
->Color
.ClearAlpha
,
201 (FxU32
) ctx
->Stencil
.Clear
);
203 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
204 fxMesa
->Color
.ClearAlpha
,
205 fxMesa
->Depth
.Clear
);
206 if (ctx
->Depth
.Mask
&& ctx
->Depth
.Test
) {
207 fxMesa
->Glide
.grDepthMask(FXTRUE
);
210 case DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
:
212 fxMesa
->Glide
.grDepthMask(FXFALSE
);
213 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
214 if (stencil_size
> 0)
215 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
216 fxMesa
->Color
.ClearAlpha
,
218 (FxU32
) ctx
->Stencil
.Clear
);
220 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
221 fxMesa
->Color
.ClearAlpha
,
222 fxMesa
->Depth
.Clear
);
223 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
224 if (stencil_size
> 0)
225 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
226 fxMesa
->Color
.ClearAlpha
,
228 (FxU32
) ctx
->Stencil
.Clear
);
230 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
231 fxMesa
->Color
.ClearAlpha
,
232 fxMesa
->Depth
.Clear
);
233 if (ctx
->Depth
.Mask
&& ctx
->Depth
.Test
) {
234 fxMesa
->Glide
.grDepthMask(FXTRUE
);
237 case DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
| DD_DEPTH_BIT
:
239 fxMesa
->Glide
.grDepthMask(FXFALSE
);
240 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
241 if (stencil_size
> 0)
242 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
243 fxMesa
->Color
.ClearAlpha
,
245 (FxU32
) ctx
->Stencil
.Clear
);
247 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
248 fxMesa
->Color
.ClearAlpha
,
249 fxMesa
->Depth
.Clear
);
250 /* clear back and depth */
251 fxMesa
->Glide
.grDepthMask(FXTRUE
);
252 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
253 if (stencil_size
> 0)
254 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
255 fxMesa
->Color
.ClearAlpha
,
257 (FxU32
) ctx
->Stencil
.Clear
);
259 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
260 fxMesa
->Color
.ClearAlpha
,
261 fxMesa
->Depth
.Clear
);
262 if (!ctx
->Depth
.Mask
|| !ctx
->Depth
.Mask
) {
263 fxMesa
->Glide
.grDepthMask(FXFALSE
);
267 /* just the depth buffer */
268 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
269 FX_grColorMaskv_NoLock(ctx
, false4
);
270 fxMesa
->Glide
.grDepthMask(FXTRUE
);
271 if (stencil_size
> 0)
272 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
273 fxMesa
->Color
.ClearAlpha
,
275 (FxU32
) ctx
->Stencil
.Clear
);
277 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
278 fxMesa
->Color
.ClearAlpha
,
279 fxMesa
->Depth
.Clear
);
280 FX_grColorMaskv_NoLock(ctx
, true4
);
281 if (ctx
->Color
._DrawDestMask
[0] & DD_FRONT_LEFT_BIT
)
282 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
283 if (!ctx
->Depth
.Test
|| !ctx
->Depth
.Mask
)
284 fxMesa
->Glide
.grDepthMask(FXFALSE
);
287 /* clear no color buffers or depth buffer but might clear stencil */
288 if (stencil_size
> 0 && (mask
& DD_STENCIL_BIT
)) {
289 /* XXX need this RenderBuffer call to work around Glide bug */
290 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
291 fxMesa
->Glide
.grDepthMask(FXFALSE
);
292 FX_grColorMaskv_NoLock(ctx
, false4
);
293 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
294 fxMesa
->Color
.ClearAlpha
,
296 (FxU32
) ctx
->Stencil
.Clear
);
297 if (ctx
->Depth
.Mask
&& ctx
->Depth
.Test
) {
298 fxMesa
->Glide
.grDepthMask(FXTRUE
);
300 FX_grColorMaskv_NoLock(ctx
, true4
);
301 if (ctx
->Color
._DrawDestMask
[0] & DD_FRONT_LEFT_BIT
)
302 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
306 END_CLIP_LOOP(fxMesa
);
308 if (fxMesa
->haveHwStencil
&& (mask
& DD_STENCIL_BIT
)) {
309 /* We changed the stencil state above. Signal that we need to
312 fxMesa
->dirty
|= TDFX_UPLOAD_STENCIL
;
316 _swrast_Clear( ctx
, softwareMask
, all
, x
, y
, width
, height
);
321 static void tdfxFinish( GLcontext
*ctx
)
323 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
325 FLUSH_BATCH( fxMesa
);
327 LOCK_HARDWARE( fxMesa
);
328 fxMesa
->Glide
.grFinish();
329 UNLOCK_HARDWARE( fxMesa
);
332 static void tdfxFlush( GLcontext
*ctx
)
334 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
336 FLUSH_BATCH( fxMesa
);
338 LOCK_HARDWARE( fxMesa
);
339 fxMesa
->Glide
.grFlush();
340 UNLOCK_HARDWARE( fxMesa
);
345 static const char *texSource(int k
)
349 return "GR_CMBX_ZERO";
350 case GR_CMBX_TEXTURE_ALPHA
:
351 return "GR_CMBX_TEXTURE_ALPHA";
353 return "GR_CMBX_ALOCAL";
355 return "GR_CMBX_AOTHER";
358 case GR_CMBX_CONSTANT_ALPHA
:
359 return "GR_CMBX_CONSTANT_ALPHA";
360 case GR_CMBX_CONSTANT_COLOR
:
361 return "GR_CMBX_CONSTANT_COLOR";
362 case GR_CMBX_DETAIL_FACTOR
:
363 return "GR_CMBX_DETAIL_FACTOR";
364 case GR_CMBX_ITALPHA
:
365 return "GR_CMBX_ITALPHA";
367 return "GR_CMBX_ITRGB";
368 case GR_CMBX_LOCAL_TEXTURE_ALPHA
:
369 return "GR_CMBX_LOCAL_TEXTURE_ALPHA";
370 case GR_CMBX_LOCAL_TEXTURE_RGB
:
371 return "GR_CMBX_LOCAL_TEXTURE_RGB";
372 case GR_CMBX_LOD_FRAC
:
373 return "GR_CMBX_LOD_FRAC";
374 case GR_CMBX_OTHER_TEXTURE_ALPHA
:
375 return "GR_CMBX_OTHER_TEXTURE_ALPHA";
376 case GR_CMBX_OTHER_TEXTURE_RGB
:
377 return "GR_CMBX_OTHER_TEXTURE_RGB";
378 case GR_CMBX_TEXTURE_RGB
:
379 return "GR_CMBX_TEXTURE_RGB";
380 case GR_CMBX_TMU_CALPHA
:
381 return "GR_CMBX_TMU_CALPHA";
382 case GR_CMBX_TMU_CCOLOR
:
383 return "GR_CMBX_TMU_CCOLOR";
391 static const char *texMode(int k
)
394 case GR_FUNC_MODE_ZERO
:
395 return "GR_FUNC_MODE_ZERO";
397 return "GR_FUNC_MODE_X";
398 case GR_FUNC_MODE_ONE_MINUS_X
:
399 return "GR_FUNC_MODE_ONE_MINUS_X";
400 case GR_FUNC_MODE_NEGATIVE_X
:
401 return "GR_FUNC_MODE_NEGATIVE_X";
402 case GR_FUNC_MODE_X_MINUS_HALF
:
403 return "GR_FUNC_MODE_X_MINUS_HALF";
411 static const char *texInvert(int k
)
413 return k
? "FXTRUE" : "FXFALSE";
417 static void uploadTextureEnv( tdfxContextPtr fxMesa
)
419 if (TDFX_IS_NAPALM(fxMesa
)) {
421 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
423 printf("upload env %d\n", unit
);
424 printf(" cSourceA = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Color
.SourceA
));
425 printf(" cModeA = %s\n", texMode(fxMesa
->TexCombineExt
[unit
].Color
.ModeA
));
426 printf(" cSourceB = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Color
.SourceB
));
427 printf(" cModeB = %s\n", texMode(fxMesa
->TexCombineExt
[unit
].Color
.ModeB
));
428 printf(" cSourceC = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Color
.SourceC
));
429 printf(" cInvertC = %s\n", texInvert(fxMesa
->TexCombineExt
[unit
].Color
.InvertC
));
430 printf(" cSourceD = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Color
.SourceD
));
431 printf(" cInvertD = %s\n", texInvert(fxMesa
->TexCombineExt
[unit
].Color
.InvertD
));
432 printf(" cShift = %d\t", fxMesa
->TexCombineExt
[unit
].Color
.Shift
);
433 printf(" cInvert = %d\n", fxMesa
->TexCombineExt
[unit
].Color
.Invert
);
434 printf(" aSourceA = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Alpha
.SourceA
));
435 printf(" aModeA = %s\n", texMode(fxMesa
->TexCombineExt
[unit
].Alpha
.ModeA
));
436 printf(" aSourceB = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Alpha
.SourceB
));
437 printf(" aModeB = %s\n", texMode(fxMesa
->TexCombineExt
[unit
].Alpha
.ModeB
));
438 printf(" aSourceC = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Alpha
.SourceC
));
439 printf(" aInvertC = %s\n", texInvert(fxMesa
->TexCombineExt
[unit
].Alpha
.InvertC
));
440 printf(" aSourceD = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Alpha
.SourceD
));
441 printf(" aInvertD = %s\n", texInvert(fxMesa
->TexCombineExt
[unit
].Alpha
.InvertD
));
442 printf(" aShift = %d\t", fxMesa
->TexCombineExt
[unit
].Alpha
.Shift
);
443 printf(" aInvert = %d\n", fxMesa
->TexCombineExt
[unit
].Alpha
.Invert
);
444 printf(" Color = 0x%08x\n", fxMesa
->TexCombineExt
[unit
].EnvColor
);
446 fxMesa
->Glide
.grTexColorCombineExt(TDFX_TMU0
+ unit
,
447 fxMesa
->TexCombineExt
[unit
].Color
.SourceA
,
448 fxMesa
->TexCombineExt
[unit
].Color
.ModeA
,
449 fxMesa
->TexCombineExt
[unit
].Color
.SourceB
,
450 fxMesa
->TexCombineExt
[unit
].Color
.ModeB
,
451 fxMesa
->TexCombineExt
[unit
].Color
.SourceC
,
452 fxMesa
->TexCombineExt
[unit
].Color
.InvertC
,
453 fxMesa
->TexCombineExt
[unit
].Color
.SourceD
,
454 fxMesa
->TexCombineExt
[unit
].Color
.InvertD
,
455 fxMesa
->TexCombineExt
[unit
].Color
.Shift
,
456 fxMesa
->TexCombineExt
[unit
].Color
.Invert
);
457 fxMesa
->Glide
.grTexAlphaCombineExt(TDFX_TMU0
+ unit
,
458 fxMesa
->TexCombineExt
[unit
].Alpha
.SourceA
,
459 fxMesa
->TexCombineExt
[unit
].Alpha
.ModeA
,
460 fxMesa
->TexCombineExt
[unit
].Alpha
.SourceB
,
461 fxMesa
->TexCombineExt
[unit
].Alpha
.ModeB
,
462 fxMesa
->TexCombineExt
[unit
].Alpha
.SourceC
,
463 fxMesa
->TexCombineExt
[unit
].Alpha
.InvertC
,
464 fxMesa
->TexCombineExt
[unit
].Alpha
.SourceD
,
465 fxMesa
->TexCombineExt
[unit
].Alpha
.InvertD
,
466 fxMesa
->TexCombineExt
[unit
].Alpha
.Shift
,
467 fxMesa
->TexCombineExt
[unit
].Alpha
.Invert
);
468 fxMesa
->Glide
.grConstantColorValueExt(TDFX_TMU0
+ unit
,
469 fxMesa
->TexCombineExt
[unit
].EnvColor
);
475 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
476 struct tdfx_texcombine
*comb
= &fxMesa
->TexCombine
[unit
];
477 fxMesa
->Glide
.grTexCombine(TDFX_TMU0
+ unit
,
489 static void uploadTextureParams( tdfxContextPtr fxMesa
)
492 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
493 const struct tdfx_texparams
*p
= &fxMesa
->TexParams
[unit
];
495 printf("upload params %d\n", unit);
496 printf(" clamp %x %x\n", env->sClamp, env->tClamp);
497 printf(" filter %x %x\n", env->minFilt, env->magFilt);
498 printf(" mipmap %x %x\n", env->mmMode, env->LODblend);
499 printf(" lod bias %f\n", env->LodBias);
501 fxMesa
->Glide
.grTexClampMode(GR_TMU0
+ unit
, p
->sClamp
, p
->tClamp
);
502 fxMesa
->Glide
.grTexFilterMode(GR_TMU0
+ unit
, p
->minFilt
, p
->magFilt
);
503 fxMesa
->Glide
.grTexMipMapMode(GR_TMU0
+ unit
, p
->mmMode
, p
->LODblend
);
504 fxMesa
->Glide
.grTexLodBiasValue(GR_TMU0
+ unit
, CLAMP(p
->LodBias
, -8, 7.75));
509 static void uploadTextureSource( tdfxContextPtr fxMesa
)
512 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
513 const struct tdfx_texsource
*src
= &fxMesa
->TexSource
[unit
];
515 printf("upload source %d @ %d %p\n", unit, src->StartAddress, src->Info);
519 printf(" smallLodLog2=%d largeLodLog2=%d ar=%d format=%d data=%p\n",
520 src->Info->smallLodLog2, src->Info->largeLodLog2,
521 src->Info->aspectRatioLog2, src->Info->format,
524 fxMesa
->Glide
.grTexSource(GR_TMU0
+ unit
,
533 static void uploadTextureImages( tdfxContextPtr fxMesa
)
535 GLcontext
*ctx
= fxMesa
->glCtx
;
537 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
538 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
539 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[unit
]._Current
;
540 tdfxTexInfo
*ti
= TDFX_TEXTURE_DATA(tObj
);
541 if (ti
&& ti
->reloadImages
&& ti
->whichTMU
!= TDFX_TMU_NONE
) {
543 printf("download texture image on unit %d\n", unit);
545 tdfxTMDownloadTexture(fxMesa
, tObj
);
546 ti
->reloadImages
= GL_FALSE
;
555 * If scissoring is enabled, compute intersection of scissor region
556 * with all X clip rects, resulting in new cliprect list.
557 * If number of cliprects is zero or one, call grClipWindow to setup
558 * the clip region. Otherwise we'll call grClipWindow inside the
559 * BEGIN_CLIP_LOOP macro.
561 void tdfxUploadClipping( tdfxContextPtr fxMesa
)
563 __DRIdrawablePrivate
*dPriv
= fxMesa
->driDrawable
;
567 if (fxMesa
->numClipRects
== 0) {
568 /* all drawing clipped away */
569 fxMesa
->Glide
.grClipWindow(0, 0, 0, 0);
571 else if (fxMesa
->numClipRects
== 1) {
572 fxMesa
->Glide
.grClipWindow(fxMesa
->pClipRects
[0].x1
,
573 fxMesa
->screen_height
- fxMesa
->pClipRects
[0].y2
,
574 fxMesa
->pClipRects
[0].x2
,
575 fxMesa
->screen_height
- fxMesa
->pClipRects
[0].y1
);
577 /* else, we'll do a cliprect loop around all drawing */
579 fxMesa
->Glide
.grDRIPosition( dPriv
->x
, dPriv
->y
, dPriv
->w
, dPriv
->h
,
580 fxMesa
->numClipRects
, fxMesa
->pClipRects
);
584 void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa
)
586 if ( !fxMesa
->dirty
)
589 if ( fxMesa
->dirty
& TDFX_UPLOAD_COLOR_COMBINE
) {
590 if (TDFX_IS_NAPALM(fxMesa
)) {
591 fxMesa
->Glide
.grColorCombineExt(fxMesa
->ColorCombineExt
.SourceA
,
592 fxMesa
->ColorCombineExt
.ModeA
,
593 fxMesa
->ColorCombineExt
.SourceB
,
594 fxMesa
->ColorCombineExt
.ModeB
,
595 fxMesa
->ColorCombineExt
.SourceC
,
596 fxMesa
->ColorCombineExt
.InvertC
,
597 fxMesa
->ColorCombineExt
.SourceD
,
598 fxMesa
->ColorCombineExt
.InvertD
,
599 fxMesa
->ColorCombineExt
.Shift
,
600 fxMesa
->ColorCombineExt
.Invert
);
604 fxMesa
->Glide
.grColorCombine( fxMesa
->ColorCombine
.Function
,
605 fxMesa
->ColorCombine
.Factor
,
606 fxMesa
->ColorCombine
.Local
,
607 fxMesa
->ColorCombine
.Other
,
608 fxMesa
->ColorCombine
.Invert
);
610 fxMesa
->dirty
&= ~TDFX_UPLOAD_COLOR_COMBINE
;
612 if ( fxMesa
->dirty
& TDFX_UPLOAD_ALPHA_COMBINE
) {
613 if (TDFX_IS_NAPALM(fxMesa
)) {
614 fxMesa
->Glide
.grAlphaCombineExt(fxMesa
->AlphaCombineExt
.SourceA
,
615 fxMesa
->AlphaCombineExt
.ModeA
,
616 fxMesa
->AlphaCombineExt
.SourceB
,
617 fxMesa
->AlphaCombineExt
.ModeB
,
618 fxMesa
->AlphaCombineExt
.SourceC
,
619 fxMesa
->AlphaCombineExt
.InvertC
,
620 fxMesa
->AlphaCombineExt
.SourceD
,
621 fxMesa
->AlphaCombineExt
.InvertD
,
622 fxMesa
->AlphaCombineExt
.Shift
,
623 fxMesa
->AlphaCombineExt
.Invert
);
627 fxMesa
->Glide
.grAlphaCombine( fxMesa
->AlphaCombine
.Function
,
628 fxMesa
->AlphaCombine
.Factor
,
629 fxMesa
->AlphaCombine
.Local
,
630 fxMesa
->AlphaCombine
.Other
,
631 fxMesa
->AlphaCombine
.Invert
);
633 fxMesa
->dirty
&= ~TDFX_UPLOAD_ALPHA_COMBINE
;
636 if ( fxMesa
->dirty
& TDFX_UPLOAD_RENDER_BUFFER
) {
637 fxMesa
->Glide
.grRenderBuffer( fxMesa
->DrawBuffer
);
638 fxMesa
->dirty
&= ~TDFX_UPLOAD_RENDER_BUFFER
;
641 if ( fxMesa
->dirty
& TDFX_UPLOAD_STIPPLE
) {
642 fxMesa
->Glide
.grStipplePattern( fxMesa
->Stipple
.Pattern
);
643 fxMesa
->Glide
.grStippleMode( fxMesa
->Stipple
.Mode
);
644 fxMesa
->dirty
&= ~TDFX_UPLOAD_STIPPLE
;
647 if ( fxMesa
->dirty
& TDFX_UPLOAD_ALPHA_TEST
) {
648 fxMesa
->Glide
.grAlphaTestFunction( fxMesa
->Color
.AlphaFunc
);
649 fxMesa
->dirty
&= ~TDFX_UPLOAD_ALPHA_TEST
;
651 if ( fxMesa
->dirty
& TDFX_UPLOAD_ALPHA_REF
) {
652 fxMesa
->Glide
.grAlphaTestReferenceValue( fxMesa
->Color
.AlphaRef
);
653 fxMesa
->dirty
&= ~TDFX_UPLOAD_ALPHA_REF
;
655 if ( fxMesa
->dirty
& TDFX_UPLOAD_BLEND_FUNC
) {
656 if (fxMesa
->Glide
.grAlphaBlendFunctionExt
) {
657 fxMesa
->Glide
.grAlphaBlendFunctionExt( fxMesa
->Color
.BlendSrcRGB
,
658 fxMesa
->Color
.BlendDstRGB
,
659 fxMesa
->Color
.BlendEqRGB
,
660 fxMesa
->Color
.BlendSrcA
,
661 fxMesa
->Color
.BlendDstA
,
662 fxMesa
->Color
.BlendEqA
);
665 fxMesa
->Glide
.grAlphaBlendFunction( fxMesa
->Color
.BlendSrcRGB
,
666 fxMesa
->Color
.BlendDstRGB
,
667 fxMesa
->Color
.BlendSrcA
,
668 fxMesa
->Color
.BlendDstA
);
670 fxMesa
->dirty
&= ~TDFX_UPLOAD_BLEND_FUNC
;
673 if ( fxMesa
->dirty
& TDFX_UPLOAD_DEPTH_MODE
) {
674 fxMesa
->Glide
.grDepthBufferMode( fxMesa
->Depth
.Mode
);
675 fxMesa
->dirty
&= ~TDFX_UPLOAD_DEPTH_MODE
;
677 if ( fxMesa
->dirty
& TDFX_UPLOAD_DEPTH_BIAS
) {
678 fxMesa
->Glide
.grDepthBiasLevel( fxMesa
->Depth
.Bias
);
679 fxMesa
->dirty
&= ~TDFX_UPLOAD_DEPTH_BIAS
;
681 if ( fxMesa
->dirty
& TDFX_UPLOAD_DEPTH_FUNC
) {
682 fxMesa
->Glide
.grDepthBufferFunction( fxMesa
->Depth
.Func
);
683 fxMesa
->dirty
&= ~TDFX_UPLOAD_DEPTH_FUNC
;
685 if ( fxMesa
->dirty
& TDFX_UPLOAD_DEPTH_MASK
) {
686 fxMesa
->Glide
.grDepthMask( fxMesa
->Depth
.Mask
);
687 fxMesa
->dirty
&= ~TDFX_UPLOAD_DEPTH_MASK
;
690 if ( fxMesa
->dirty
& TDFX_UPLOAD_DITHER
) {
691 fxMesa
->Glide
.grDitherMode( fxMesa
->Color
.Dither
);
694 if ( fxMesa
->dirty
& TDFX_UPLOAD_FOG_MODE
) {
695 fxMesa
->Glide
.grFogMode( fxMesa
->Fog
.Mode
);
696 fxMesa
->dirty
&= ~TDFX_UPLOAD_FOG_MODE
;
698 if ( fxMesa
->dirty
& TDFX_UPLOAD_FOG_COLOR
) {
699 fxMesa
->Glide
.grFogColorValue( fxMesa
->Fog
.Color
);
700 fxMesa
->dirty
&= ~TDFX_UPLOAD_FOG_COLOR
;
702 if ( fxMesa
->dirty
& TDFX_UPLOAD_FOG_TABLE
) {
703 fxMesa
->Glide
.grFogTable( fxMesa
->Fog
.Table
);
704 fxMesa
->dirty
&= ~TDFX_UPLOAD_FOG_TABLE
;
707 if ( fxMesa
->dirty
& TDFX_UPLOAD_CULL
) {
708 fxMesa
->Glide
.grCullMode( fxMesa
->CullMode
);
709 fxMesa
->dirty
&= ~TDFX_UPLOAD_CULL
;
712 if ( fxMesa
->dirty
& TDFX_UPLOAD_CLIP
) {
713 tdfxUploadClipping( fxMesa
);
714 fxMesa
->dirty
&= ~TDFX_UPLOAD_CLIP
;
717 if ( fxMesa
->dirty
& TDFX_UPLOAD_COLOR_MASK
) {
718 if ( fxMesa
->Glide
.grColorMaskExt
719 && fxMesa
->glCtx
->Visual
.redBits
== 8) {
720 fxMesa
->Glide
.grColorMaskExt( fxMesa
->Color
.ColorMask
[RCOMP
],
721 fxMesa
->Color
.ColorMask
[GCOMP
],
722 fxMesa
->Color
.ColorMask
[BCOMP
],
723 fxMesa
->Color
.ColorMask
[ACOMP
] );
725 fxMesa
->Glide
.grColorMask( fxMesa
->Color
.ColorMask
[RCOMP
] ||
726 fxMesa
->Color
.ColorMask
[GCOMP
] ||
727 fxMesa
->Color
.ColorMask
[BCOMP
],
728 /*fxMesa->Color.ColorMask[ACOMP]*/GL_FALSE
/*[dBorca] no-no*/ );
730 fxMesa
->dirty
&= ~TDFX_UPLOAD_COLOR_MASK
;
733 if ( fxMesa
->dirty
& TDFX_UPLOAD_CONSTANT_COLOR
) {
734 fxMesa
->Glide
.grConstantColorValue( fxMesa
->Color
.MonoColor
);
735 fxMesa
->dirty
&= ~TDFX_UPLOAD_CONSTANT_COLOR
;
738 if ( fxMesa
->dirty
& TDFX_UPLOAD_LINE
) {
739 if (fxMesa
->glCtx
->Line
.SmoothFlag
&& fxMesa
->glCtx
->Line
.Width
== 1.0)
740 fxMesa
->Glide
.grEnable(GR_AA_ORDERED
);
742 fxMesa
->Glide
.grDisable(GR_AA_ORDERED
);
743 fxMesa
->dirty
&= ~TDFX_UPLOAD_LINE
;
746 if ( fxMesa
->dirty
& TDFX_UPLOAD_STENCIL
) {
747 if (fxMesa
->glCtx
->Stencil
.Enabled
) {
748 fxMesa
->Glide
.grEnable(GR_STENCIL_MODE_EXT
);
749 fxMesa
->Glide
.grStencilOp(fxMesa
->Stencil
.FailFunc
,
750 fxMesa
->Stencil
.ZFailFunc
,
751 fxMesa
->Stencil
.ZPassFunc
);
752 fxMesa
->Glide
.grStencilFunc(fxMesa
->Stencil
.Function
,
753 fxMesa
->Stencil
.RefValue
,
754 fxMesa
->Stencil
.ValueMask
);
755 fxMesa
->Glide
.grStencilMask(fxMesa
->Stencil
.WriteMask
);
758 fxMesa
->Glide
.grDisable(GR_STENCIL_MODE_EXT
);
760 fxMesa
->dirty
&= ~TDFX_UPLOAD_STENCIL
;
763 if ( fxMesa
->dirty
& TDFX_UPLOAD_VERTEX_LAYOUT
) {
764 fxMesa
->Glide
.grGlideSetVertexLayout( fxMesa
->layout
[fxMesa
->vertexFormat
] );
765 /* [dborca] enable fogcoord */
766 fxMesa
->Glide
.grVertexLayout(GR_PARAM_FOG_EXT
, TDFX_FOG_OFFSET
,
767 fxMesa
->Fog
.Mode
== GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT
);
768 fxMesa
->dirty
&= ~TDFX_UPLOAD_VERTEX_LAYOUT
;
771 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_ENV
) {
772 uploadTextureEnv(fxMesa
);
773 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_ENV
;
776 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_PARAMS
) {
777 uploadTextureParams(fxMesa
);
778 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_PARAMS
;
781 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_PALETTE
) {
782 if (fxMesa
->TexPalette
.Data
) {
783 fxMesa
->Glide
.grTexDownloadTable(fxMesa
->TexPalette
.Type
, fxMesa
->TexPalette
.Data
);
785 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_PALETTE
;
788 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_SOURCE
) {
789 uploadTextureSource(fxMesa
);
790 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_SOURCE
;
793 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_IMAGES
) {
794 uploadTextureImages(fxMesa
);
795 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_IMAGES
;
803 void tdfxInitRenderFuncs( struct dd_function_table
*functions
)
805 functions
->Clear
= tdfxClear
;
806 functions
->Finish
= tdfxFinish
;
807 functions
->Flush
= tdfxFlush
;