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
29 * Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004
32 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
35 * Gareth Hughes <gareth@valinux.com>
36 * Brian Paul <brianp@valinux.com>
40 #include "tdfx_context.h"
41 #include "tdfx_render.h"
42 #include "tdfx_state.h"
43 #include "tdfx_texman.h"
44 #include "swrast/swrast.h"
46 /* Clear the color and/or depth buffers.
48 static void tdfxClear( GLcontext
*ctx
, GLbitfield mask
)
50 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
51 GLbitfield softwareMask
= mask
& (BUFFER_BIT_ACCUM
);
52 const GLuint stencil_size
=
53 fxMesa
->haveHwStencil
? fxMesa
->glCtx
->Visual
.stencilBits
: 0;
55 if ( TDFX_DEBUG
& DEBUG_VERBOSE_API
) {
56 fprintf( stderr
, "tdfxClear(0x%x)\n", mask
);
59 /* Need this check to respond to glScissor and clipping updates */
60 if ((fxMesa
->new_state
& (TDFX_NEW_CLIP
| TDFX_NEW_DEPTH
)) ||
61 (fxMesa
->dirty
& TDFX_UPLOAD_COLOR_MASK
)) {
62 tdfxDDUpdateHwState(ctx
);
65 /* we can't clear accum buffers */
66 mask
&= ~(BUFFER_BIT_ACCUM
);
68 if (mask
& BUFFER_BIT_STENCIL
) {
69 if (!fxMesa
->haveHwStencil
|| (ctx
->Stencil
.WriteMask
[0] & 0xff) != 0xff) {
70 /* Napalm seems to have trouble with stencil write masks != 0xff */
71 /* do stencil clear in software */
72 mask
&= ~(BUFFER_BIT_STENCIL
);
73 softwareMask
|= BUFFER_BIT_STENCIL
;
77 if (fxMesa
->glCtx
->Visual
.redBits
!= 8) {
78 /* can only do color masking if running in 24/32bpp on Napalm */
79 if (ctx
->Color
.ColorMask
[RCOMP
] != ctx
->Color
.ColorMask
[GCOMP
] ||
80 ctx
->Color
.ColorMask
[GCOMP
] != ctx
->Color
.ColorMask
[BCOMP
]) {
81 softwareMask
|= (mask
& (BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
));
82 mask
&= ~(BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
);
86 if (fxMesa
->haveHwStencil
) {
88 * If we want to clear stencil, it must be enabled
89 * in the HW, even if the stencil test is not enabled
92 LOCK_HARDWARE(fxMesa
);
93 if (mask
& BUFFER_BIT_STENCIL
) {
94 fxMesa
->Glide
.grStencilMask(/*ctx->Stencil.WriteMask*/ 0xff);
95 /* set stencil ref value = desired clear value */
96 fxMesa
->Glide
.grStencilFunc(GR_CMP_ALWAYS
,
97 (fxMesa
->Stencil
.Clear
& 0xff), 0xff);
98 fxMesa
->Glide
.grStencilOp(GR_STENCILOP_REPLACE
,
99 GR_STENCILOP_REPLACE
, GR_STENCILOP_REPLACE
);
100 fxMesa
->Glide
.grEnable(GR_STENCIL_MODE_EXT
);
103 fxMesa
->Glide
.grDisable(GR_STENCIL_MODE_EXT
);
105 UNLOCK_HARDWARE(fxMesa
);
109 * This may be ugly, but it's needed in order to work around a number
112 BEGIN_CLIP_LOOP(fxMesa
);
115 * This could probably be done fancier but doing each possible case
116 * explicitly is less error prone.
118 switch (mask
& ~BUFFER_BIT_STENCIL
) {
119 case BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_DEPTH
:
120 /* back buffer & depth */
121 FX_grColorMaskv_NoLock(ctx
, true4
); /* work around Voodoo3 bug */
122 fxMesa
->Glide
.grDepthMask(FXTRUE
);
123 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
124 if (stencil_size
> 0) {
125 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
126 fxMesa
->Color
.ClearAlpha
,
128 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
131 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
132 fxMesa
->Color
.ClearAlpha
,
133 fxMesa
->Depth
.Clear
);
134 if (!ctx
->Depth
.Mask
|| !ctx
->Depth
.Test
) {
135 fxMesa
->Glide
.grDepthMask(FXFALSE
);
138 case BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_DEPTH
:
139 /* XXX it appears that the depth buffer isn't cleared when
140 * glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set.
141 * This is a work-around/
144 fxMesa
->Glide
.grDepthMask(FXTRUE
);
145 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
146 FX_grColorMaskv_NoLock(ctx
, false4
);
147 if (stencil_size
> 0)
148 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
149 fxMesa
->Color
.ClearAlpha
,
151 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
153 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
154 fxMesa
->Color
.ClearAlpha
,
155 fxMesa
->Depth
.Clear
& 0xff);
157 FX_grColorMaskv_NoLock(ctx
, true4
);
158 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
159 if (stencil_size
> 0)
160 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
161 fxMesa
->Color
.ClearAlpha
,
163 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
165 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
166 fxMesa
->Color
.ClearAlpha
,
167 fxMesa
->Depth
.Clear
);
168 if (!ctx
->Depth
.Mask
|| !ctx
->Depth
.Test
) {
169 fxMesa
->Glide
.grDepthMask(FXFALSE
);
172 case BUFFER_BIT_BACK_LEFT
:
173 /* back buffer only */
174 fxMesa
->Glide
.grDepthMask(FXFALSE
);
175 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
176 if (stencil_size
> 0)
177 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
178 fxMesa
->Color
.ClearAlpha
,
180 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
182 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
183 fxMesa
->Color
.ClearAlpha
,
184 fxMesa
->Depth
.Clear
);
185 if (ctx
->Depth
.Mask
&& ctx
->Depth
.Test
) {
186 fxMesa
->Glide
.grDepthMask(FXTRUE
);
189 case BUFFER_BIT_FRONT_LEFT
:
190 /* front buffer only */
191 fxMesa
->Glide
.grDepthMask(FXFALSE
);
192 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
193 if (stencil_size
> 0)
194 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
195 fxMesa
->Color
.ClearAlpha
,
197 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
199 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
200 fxMesa
->Color
.ClearAlpha
,
201 fxMesa
->Depth
.Clear
);
202 if (ctx
->Depth
.Mask
&& ctx
->Depth
.Test
) {
203 fxMesa
->Glide
.grDepthMask(FXTRUE
);
206 case BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
:
208 fxMesa
->Glide
.grDepthMask(FXFALSE
);
209 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
210 if (stencil_size
> 0)
211 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
212 fxMesa
->Color
.ClearAlpha
,
214 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
216 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
217 fxMesa
->Color
.ClearAlpha
,
218 fxMesa
->Depth
.Clear
);
219 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
220 if (stencil_size
> 0)
221 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
222 fxMesa
->Color
.ClearAlpha
,
224 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
226 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
227 fxMesa
->Color
.ClearAlpha
,
228 fxMesa
->Depth
.Clear
);
229 if (ctx
->Depth
.Mask
&& ctx
->Depth
.Test
) {
230 fxMesa
->Glide
.grDepthMask(FXTRUE
);
233 case BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_DEPTH
:
235 fxMesa
->Glide
.grDepthMask(FXFALSE
);
236 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
237 if (stencil_size
> 0)
238 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
239 fxMesa
->Color
.ClearAlpha
,
241 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
243 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
244 fxMesa
->Color
.ClearAlpha
,
245 fxMesa
->Depth
.Clear
);
246 /* clear back and depth */
247 fxMesa
->Glide
.grDepthMask(FXTRUE
);
248 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
249 if (stencil_size
> 0)
250 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
251 fxMesa
->Color
.ClearAlpha
,
253 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
255 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
256 fxMesa
->Color
.ClearAlpha
,
257 fxMesa
->Depth
.Clear
);
258 if (!ctx
->Depth
.Mask
|| !ctx
->Depth
.Mask
) {
259 fxMesa
->Glide
.grDepthMask(FXFALSE
);
262 case BUFFER_BIT_DEPTH
:
263 /* just the depth buffer */
264 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
265 FX_grColorMaskv_NoLock(ctx
, false4
);
266 fxMesa
->Glide
.grDepthMask(FXTRUE
);
267 if (stencil_size
> 0)
268 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
269 fxMesa
->Color
.ClearAlpha
,
271 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
273 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
274 fxMesa
->Color
.ClearAlpha
,
275 fxMesa
->Depth
.Clear
);
276 FX_grColorMaskv_NoLock(ctx
, true4
);
277 if (ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[0] == BUFFER_FRONT_LEFT
)
278 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
279 if (!ctx
->Depth
.Test
|| !ctx
->Depth
.Mask
)
280 fxMesa
->Glide
.grDepthMask(FXFALSE
);
283 /* clear no color buffers or depth buffer but might clear stencil */
284 if (stencil_size
> 0 && (mask
& BUFFER_BIT_STENCIL
)) {
285 /* XXX need this RenderBuffer call to work around Glide bug */
286 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
287 fxMesa
->Glide
.grDepthMask(FXFALSE
);
288 FX_grColorMaskv_NoLock(ctx
, false4
);
289 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
290 fxMesa
->Color
.ClearAlpha
,
292 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
293 if (ctx
->Depth
.Mask
&& ctx
->Depth
.Test
) {
294 fxMesa
->Glide
.grDepthMask(FXTRUE
);
296 FX_grColorMaskv_NoLock(ctx
, true4
);
297 if (ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[0] == BUFFER_FRONT_LEFT
)
298 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
302 END_CLIP_LOOP(fxMesa
);
304 if (fxMesa
->haveHwStencil
&& (mask
& BUFFER_BIT_STENCIL
)) {
305 /* We changed the stencil state above. Signal that we need to
308 fxMesa
->dirty
|= TDFX_UPLOAD_STENCIL
;
312 _swrast_Clear(ctx
, softwareMask
);
317 static void tdfxFinish( GLcontext
*ctx
)
319 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
321 FLUSH_BATCH( fxMesa
);
323 LOCK_HARDWARE( fxMesa
);
324 fxMesa
->Glide
.grFinish();
325 UNLOCK_HARDWARE( fxMesa
);
328 static void tdfxFlush( GLcontext
*ctx
)
330 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
332 FLUSH_BATCH( fxMesa
);
334 LOCK_HARDWARE( fxMesa
);
335 fxMesa
->Glide
.grFlush();
336 UNLOCK_HARDWARE( fxMesa
);
341 static const char *texSource(int k
)
345 return "GR_CMBX_ZERO";
346 case GR_CMBX_TEXTURE_ALPHA
:
347 return "GR_CMBX_TEXTURE_ALPHA";
349 return "GR_CMBX_ALOCAL";
351 return "GR_CMBX_AOTHER";
354 case GR_CMBX_CONSTANT_ALPHA
:
355 return "GR_CMBX_CONSTANT_ALPHA";
356 case GR_CMBX_CONSTANT_COLOR
:
357 return "GR_CMBX_CONSTANT_COLOR";
358 case GR_CMBX_DETAIL_FACTOR
:
359 return "GR_CMBX_DETAIL_FACTOR";
360 case GR_CMBX_ITALPHA
:
361 return "GR_CMBX_ITALPHA";
363 return "GR_CMBX_ITRGB";
364 case GR_CMBX_LOCAL_TEXTURE_ALPHA
:
365 return "GR_CMBX_LOCAL_TEXTURE_ALPHA";
366 case GR_CMBX_LOCAL_TEXTURE_RGB
:
367 return "GR_CMBX_LOCAL_TEXTURE_RGB";
368 case GR_CMBX_LOD_FRAC
:
369 return "GR_CMBX_LOD_FRAC";
370 case GR_CMBX_OTHER_TEXTURE_ALPHA
:
371 return "GR_CMBX_OTHER_TEXTURE_ALPHA";
372 case GR_CMBX_OTHER_TEXTURE_RGB
:
373 return "GR_CMBX_OTHER_TEXTURE_RGB";
374 case GR_CMBX_TEXTURE_RGB
:
375 return "GR_CMBX_TEXTURE_RGB";
376 case GR_CMBX_TMU_CALPHA
:
377 return "GR_CMBX_TMU_CALPHA";
378 case GR_CMBX_TMU_CCOLOR
:
379 return "GR_CMBX_TMU_CCOLOR";
387 static const char *texMode(int k
)
390 case GR_FUNC_MODE_ZERO
:
391 return "GR_FUNC_MODE_ZERO";
393 return "GR_FUNC_MODE_X";
394 case GR_FUNC_MODE_ONE_MINUS_X
:
395 return "GR_FUNC_MODE_ONE_MINUS_X";
396 case GR_FUNC_MODE_NEGATIVE_X
:
397 return "GR_FUNC_MODE_NEGATIVE_X";
398 case GR_FUNC_MODE_X_MINUS_HALF
:
399 return "GR_FUNC_MODE_X_MINUS_HALF";
407 static const char *texInvert(int k
)
409 return k
? "FXTRUE" : "FXFALSE";
413 static void uploadTextureEnv( tdfxContextPtr fxMesa
)
415 if (TDFX_IS_NAPALM(fxMesa
)) {
417 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
419 printf("upload env %d\n", unit
);
420 printf(" cSourceA = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Color
.SourceA
));
421 printf(" cModeA = %s\n", texMode(fxMesa
->TexCombineExt
[unit
].Color
.ModeA
));
422 printf(" cSourceB = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Color
.SourceB
));
423 printf(" cModeB = %s\n", texMode(fxMesa
->TexCombineExt
[unit
].Color
.ModeB
));
424 printf(" cSourceC = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Color
.SourceC
));
425 printf(" cInvertC = %s\n", texInvert(fxMesa
->TexCombineExt
[unit
].Color
.InvertC
));
426 printf(" cSourceD = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Color
.SourceD
));
427 printf(" cInvertD = %s\n", texInvert(fxMesa
->TexCombineExt
[unit
].Color
.InvertD
));
428 printf(" cShift = %d\t", fxMesa
->TexCombineExt
[unit
].Color
.Shift
);
429 printf(" cInvert = %d\n", fxMesa
->TexCombineExt
[unit
].Color
.Invert
);
430 printf(" aSourceA = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Alpha
.SourceA
));
431 printf(" aModeA = %s\n", texMode(fxMesa
->TexCombineExt
[unit
].Alpha
.ModeA
));
432 printf(" aSourceB = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Alpha
.SourceB
));
433 printf(" aModeB = %s\n", texMode(fxMesa
->TexCombineExt
[unit
].Alpha
.ModeB
));
434 printf(" aSourceC = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Alpha
.SourceC
));
435 printf(" aInvertC = %s\n", texInvert(fxMesa
->TexCombineExt
[unit
].Alpha
.InvertC
));
436 printf(" aSourceD = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Alpha
.SourceD
));
437 printf(" aInvertD = %s\n", texInvert(fxMesa
->TexCombineExt
[unit
].Alpha
.InvertD
));
438 printf(" aShift = %d\t", fxMesa
->TexCombineExt
[unit
].Alpha
.Shift
);
439 printf(" aInvert = %d\n", fxMesa
->TexCombineExt
[unit
].Alpha
.Invert
);
440 printf(" Color = 0x%08x\n", fxMesa
->TexCombineExt
[unit
].EnvColor
);
442 fxMesa
->Glide
.grTexColorCombineExt(TDFX_TMU0
+ unit
,
443 fxMesa
->TexCombineExt
[unit
].Color
.SourceA
,
444 fxMesa
->TexCombineExt
[unit
].Color
.ModeA
,
445 fxMesa
->TexCombineExt
[unit
].Color
.SourceB
,
446 fxMesa
->TexCombineExt
[unit
].Color
.ModeB
,
447 fxMesa
->TexCombineExt
[unit
].Color
.SourceC
,
448 fxMesa
->TexCombineExt
[unit
].Color
.InvertC
,
449 fxMesa
->TexCombineExt
[unit
].Color
.SourceD
,
450 fxMesa
->TexCombineExt
[unit
].Color
.InvertD
,
451 fxMesa
->TexCombineExt
[unit
].Color
.Shift
,
452 fxMesa
->TexCombineExt
[unit
].Color
.Invert
);
453 fxMesa
->Glide
.grTexAlphaCombineExt(TDFX_TMU0
+ unit
,
454 fxMesa
->TexCombineExt
[unit
].Alpha
.SourceA
,
455 fxMesa
->TexCombineExt
[unit
].Alpha
.ModeA
,
456 fxMesa
->TexCombineExt
[unit
].Alpha
.SourceB
,
457 fxMesa
->TexCombineExt
[unit
].Alpha
.ModeB
,
458 fxMesa
->TexCombineExt
[unit
].Alpha
.SourceC
,
459 fxMesa
->TexCombineExt
[unit
].Alpha
.InvertC
,
460 fxMesa
->TexCombineExt
[unit
].Alpha
.SourceD
,
461 fxMesa
->TexCombineExt
[unit
].Alpha
.InvertD
,
462 fxMesa
->TexCombineExt
[unit
].Alpha
.Shift
,
463 fxMesa
->TexCombineExt
[unit
].Alpha
.Invert
);
464 fxMesa
->Glide
.grConstantColorValueExt(TDFX_TMU0
+ unit
,
465 fxMesa
->TexCombineExt
[unit
].EnvColor
);
471 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
472 struct tdfx_texcombine
*comb
= &fxMesa
->TexCombine
[unit
];
473 fxMesa
->Glide
.grTexCombine(TDFX_TMU0
+ unit
,
485 static void uploadTextureParams( tdfxContextPtr fxMesa
)
488 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
489 const struct tdfx_texparams
*p
= &fxMesa
->TexParams
[unit
];
491 printf("upload params %d\n", unit);
492 printf(" clamp %x %x\n", env->sClamp, env->tClamp);
493 printf(" filter %x %x\n", env->minFilt, env->magFilt);
494 printf(" mipmap %x %x\n", env->mmMode, env->LODblend);
495 printf(" lod bias %f\n", env->LodBias);
497 fxMesa
->Glide
.grTexClampMode(GR_TMU0
+ unit
, p
->sClamp
, p
->tClamp
);
498 fxMesa
->Glide
.grTexFilterMode(GR_TMU0
+ unit
, p
->minFilt
, p
->magFilt
);
499 fxMesa
->Glide
.grTexMipMapMode(GR_TMU0
+ unit
, p
->mmMode
, p
->LODblend
);
500 fxMesa
->Glide
.grTexLodBiasValue(GR_TMU0
+ unit
, CLAMP(p
->LodBias
, -8, 7.75));
505 static void uploadTextureSource( tdfxContextPtr fxMesa
)
508 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
509 const struct tdfx_texsource
*src
= &fxMesa
->TexSource
[unit
];
511 printf("upload source %d @ %d %p\n", unit, src->StartAddress, src->Info);
515 printf(" smallLodLog2=%d largeLodLog2=%d ar=%d format=%d data=%p\n",
516 src->Info->smallLodLog2, src->Info->largeLodLog2,
517 src->Info->aspectRatioLog2, src->Info->format,
520 fxMesa
->Glide
.grTexSource(GR_TMU0
+ unit
,
529 static void uploadTextureImages( tdfxContextPtr fxMesa
)
531 GLcontext
*ctx
= fxMesa
->glCtx
;
533 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
534 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
535 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[unit
]._Current
;
536 tdfxTexInfo
*ti
= TDFX_TEXTURE_DATA(tObj
);
537 if (ti
&& ti
->reloadImages
&& ti
->whichTMU
!= TDFX_TMU_NONE
) {
539 printf("download texture image on unit %d\n", unit);
541 tdfxTMDownloadTexture(fxMesa
, tObj
);
542 ti
->reloadImages
= GL_FALSE
;
551 * If scissoring is enabled, compute intersection of scissor region
552 * with all X clip rects, resulting in new cliprect list.
553 * If number of cliprects is zero or one, call grClipWindow to setup
554 * the clip region. Otherwise we'll call grClipWindow inside the
555 * BEGIN_CLIP_LOOP macro.
557 void tdfxUploadClipping( tdfxContextPtr fxMesa
)
559 __DRIdrawablePrivate
*dPriv
= fxMesa
->driDrawable
;
563 if (fxMesa
->numClipRects
== 0) {
564 /* all drawing clipped away */
565 fxMesa
->Glide
.grClipWindow(0, 0, 0, 0);
567 else if (fxMesa
->numClipRects
== 1) {
568 fxMesa
->Glide
.grClipWindow(fxMesa
->pClipRects
[0].x1
,
569 fxMesa
->screen_height
- fxMesa
->pClipRects
[0].y2
,
570 fxMesa
->pClipRects
[0].x2
,
571 fxMesa
->screen_height
- fxMesa
->pClipRects
[0].y1
);
573 /* else, we'll do a cliprect loop around all drawing */
575 fxMesa
->Glide
.grDRIPosition( dPriv
->x
, dPriv
->y
, dPriv
->w
, dPriv
->h
,
576 fxMesa
->numClipRects
, fxMesa
->pClipRects
);
580 void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa
)
582 if ( !fxMesa
->dirty
)
585 if ( fxMesa
->dirty
& TDFX_UPLOAD_COLOR_COMBINE
) {
586 if (TDFX_IS_NAPALM(fxMesa
)) {
587 fxMesa
->Glide
.grColorCombineExt(fxMesa
->ColorCombineExt
.SourceA
,
588 fxMesa
->ColorCombineExt
.ModeA
,
589 fxMesa
->ColorCombineExt
.SourceB
,
590 fxMesa
->ColorCombineExt
.ModeB
,
591 fxMesa
->ColorCombineExt
.SourceC
,
592 fxMesa
->ColorCombineExt
.InvertC
,
593 fxMesa
->ColorCombineExt
.SourceD
,
594 fxMesa
->ColorCombineExt
.InvertD
,
595 fxMesa
->ColorCombineExt
.Shift
,
596 fxMesa
->ColorCombineExt
.Invert
);
600 fxMesa
->Glide
.grColorCombine( fxMesa
->ColorCombine
.Function
,
601 fxMesa
->ColorCombine
.Factor
,
602 fxMesa
->ColorCombine
.Local
,
603 fxMesa
->ColorCombine
.Other
,
604 fxMesa
->ColorCombine
.Invert
);
606 fxMesa
->dirty
&= ~TDFX_UPLOAD_COLOR_COMBINE
;
608 if ( fxMesa
->dirty
& TDFX_UPLOAD_ALPHA_COMBINE
) {
609 if (TDFX_IS_NAPALM(fxMesa
)) {
610 fxMesa
->Glide
.grAlphaCombineExt(fxMesa
->AlphaCombineExt
.SourceA
,
611 fxMesa
->AlphaCombineExt
.ModeA
,
612 fxMesa
->AlphaCombineExt
.SourceB
,
613 fxMesa
->AlphaCombineExt
.ModeB
,
614 fxMesa
->AlphaCombineExt
.SourceC
,
615 fxMesa
->AlphaCombineExt
.InvertC
,
616 fxMesa
->AlphaCombineExt
.SourceD
,
617 fxMesa
->AlphaCombineExt
.InvertD
,
618 fxMesa
->AlphaCombineExt
.Shift
,
619 fxMesa
->AlphaCombineExt
.Invert
);
623 fxMesa
->Glide
.grAlphaCombine( fxMesa
->AlphaCombine
.Function
,
624 fxMesa
->AlphaCombine
.Factor
,
625 fxMesa
->AlphaCombine
.Local
,
626 fxMesa
->AlphaCombine
.Other
,
627 fxMesa
->AlphaCombine
.Invert
);
629 fxMesa
->dirty
&= ~TDFX_UPLOAD_ALPHA_COMBINE
;
632 if ( fxMesa
->dirty
& TDFX_UPLOAD_RENDER_BUFFER
) {
633 fxMesa
->Glide
.grRenderBuffer( fxMesa
->DrawBuffer
);
634 fxMesa
->dirty
&= ~TDFX_UPLOAD_RENDER_BUFFER
;
637 if ( fxMesa
->dirty
& TDFX_UPLOAD_STIPPLE
) {
638 fxMesa
->Glide
.grStipplePattern( fxMesa
->Stipple
.Pattern
);
639 fxMesa
->Glide
.grStippleMode( fxMesa
->Stipple
.Mode
);
640 fxMesa
->dirty
&= ~TDFX_UPLOAD_STIPPLE
;
643 if ( fxMesa
->dirty
& TDFX_UPLOAD_ALPHA_TEST
) {
644 fxMesa
->Glide
.grAlphaTestFunction( fxMesa
->Color
.AlphaFunc
);
645 fxMesa
->dirty
&= ~TDFX_UPLOAD_ALPHA_TEST
;
647 if ( fxMesa
->dirty
& TDFX_UPLOAD_ALPHA_REF
) {
648 fxMesa
->Glide
.grAlphaTestReferenceValue( fxMesa
->Color
.AlphaRef
);
649 fxMesa
->dirty
&= ~TDFX_UPLOAD_ALPHA_REF
;
651 if ( fxMesa
->dirty
& TDFX_UPLOAD_BLEND_FUNC
) {
652 if (fxMesa
->Glide
.grAlphaBlendFunctionExt
) {
653 fxMesa
->Glide
.grAlphaBlendFunctionExt( fxMesa
->Color
.BlendSrcRGB
,
654 fxMesa
->Color
.BlendDstRGB
,
655 fxMesa
->Color
.BlendEqRGB
,
656 fxMesa
->Color
.BlendSrcA
,
657 fxMesa
->Color
.BlendDstA
,
658 fxMesa
->Color
.BlendEqA
);
661 fxMesa
->Glide
.grAlphaBlendFunction( fxMesa
->Color
.BlendSrcRGB
,
662 fxMesa
->Color
.BlendDstRGB
,
663 fxMesa
->Color
.BlendSrcA
,
664 fxMesa
->Color
.BlendDstA
);
666 fxMesa
->dirty
&= ~TDFX_UPLOAD_BLEND_FUNC
;
669 if ( fxMesa
->dirty
& TDFX_UPLOAD_DEPTH_MODE
) {
670 fxMesa
->Glide
.grDepthBufferMode( fxMesa
->Depth
.Mode
);
671 fxMesa
->dirty
&= ~TDFX_UPLOAD_DEPTH_MODE
;
673 if ( fxMesa
->dirty
& TDFX_UPLOAD_DEPTH_BIAS
) {
674 fxMesa
->Glide
.grDepthBiasLevel( fxMesa
->Depth
.Bias
);
675 fxMesa
->dirty
&= ~TDFX_UPLOAD_DEPTH_BIAS
;
677 if ( fxMesa
->dirty
& TDFX_UPLOAD_DEPTH_FUNC
) {
678 fxMesa
->Glide
.grDepthBufferFunction( fxMesa
->Depth
.Func
);
679 fxMesa
->dirty
&= ~TDFX_UPLOAD_DEPTH_FUNC
;
681 if ( fxMesa
->dirty
& TDFX_UPLOAD_DEPTH_MASK
) {
682 fxMesa
->Glide
.grDepthMask( fxMesa
->Depth
.Mask
);
683 fxMesa
->dirty
&= ~TDFX_UPLOAD_DEPTH_MASK
;
686 if ( fxMesa
->dirty
& TDFX_UPLOAD_DITHER
) {
687 fxMesa
->Glide
.grDitherMode( fxMesa
->Color
.Dither
);
690 if ( fxMesa
->dirty
& TDFX_UPLOAD_FOG_MODE
) {
691 fxMesa
->Glide
.grFogMode( fxMesa
->Fog
.Mode
);
692 fxMesa
->dirty
&= ~TDFX_UPLOAD_FOG_MODE
;
694 if ( fxMesa
->dirty
& TDFX_UPLOAD_FOG_COLOR
) {
695 fxMesa
->Glide
.grFogColorValue( fxMesa
->Fog
.Color
);
696 fxMesa
->dirty
&= ~TDFX_UPLOAD_FOG_COLOR
;
698 if ( fxMesa
->dirty
& TDFX_UPLOAD_FOG_TABLE
) {
699 fxMesa
->Glide
.grFogTable( fxMesa
->Fog
.Table
);
700 fxMesa
->dirty
&= ~TDFX_UPLOAD_FOG_TABLE
;
703 if ( fxMesa
->dirty
& TDFX_UPLOAD_CULL
) {
704 fxMesa
->Glide
.grCullMode( fxMesa
->CullMode
);
705 fxMesa
->dirty
&= ~TDFX_UPLOAD_CULL
;
708 if ( fxMesa
->dirty
& TDFX_UPLOAD_CLIP
) {
709 tdfxUploadClipping( fxMesa
);
710 fxMesa
->dirty
&= ~TDFX_UPLOAD_CLIP
;
713 if ( fxMesa
->dirty
& TDFX_UPLOAD_COLOR_MASK
) {
714 if ( fxMesa
->Glide
.grColorMaskExt
715 && fxMesa
->glCtx
->Visual
.redBits
== 8) {
716 fxMesa
->Glide
.grColorMaskExt( fxMesa
->Color
.ColorMask
[RCOMP
],
717 fxMesa
->Color
.ColorMask
[GCOMP
],
718 fxMesa
->Color
.ColorMask
[BCOMP
],
719 fxMesa
->Color
.ColorMask
[ACOMP
] );
721 fxMesa
->Glide
.grColorMask( fxMesa
->Color
.ColorMask
[RCOMP
] ||
722 fxMesa
->Color
.ColorMask
[GCOMP
] ||
723 fxMesa
->Color
.ColorMask
[BCOMP
],
724 /*fxMesa->Color.ColorMask[ACOMP]*/GL_FALSE
/*[dBorca] no-no*/ );
726 fxMesa
->dirty
&= ~TDFX_UPLOAD_COLOR_MASK
;
729 if ( fxMesa
->dirty
& TDFX_UPLOAD_CONSTANT_COLOR
) {
730 fxMesa
->Glide
.grConstantColorValue( fxMesa
->Color
.MonoColor
);
731 fxMesa
->dirty
&= ~TDFX_UPLOAD_CONSTANT_COLOR
;
734 if ( fxMesa
->dirty
& TDFX_UPLOAD_LINE
) {
735 if (fxMesa
->glCtx
->Line
.SmoothFlag
&& fxMesa
->glCtx
->Line
.Width
== 1.0)
736 fxMesa
->Glide
.grEnable(GR_AA_ORDERED
);
738 fxMesa
->Glide
.grDisable(GR_AA_ORDERED
);
739 fxMesa
->dirty
&= ~TDFX_UPLOAD_LINE
;
742 if ( fxMesa
->dirty
& TDFX_UPLOAD_STENCIL
) {
743 if (fxMesa
->glCtx
->Stencil
._Enabled
) {
744 fxMesa
->Glide
.grEnable(GR_STENCIL_MODE_EXT
);
745 fxMesa
->Glide
.grStencilOp(fxMesa
->Stencil
.FailFunc
,
746 fxMesa
->Stencil
.ZFailFunc
,
747 fxMesa
->Stencil
.ZPassFunc
);
748 fxMesa
->Glide
.grStencilFunc(fxMesa
->Stencil
.Function
,
749 fxMesa
->Stencil
.RefValue
,
750 fxMesa
->Stencil
.ValueMask
);
751 fxMesa
->Glide
.grStencilMask(fxMesa
->Stencil
.WriteMask
);
754 fxMesa
->Glide
.grDisable(GR_STENCIL_MODE_EXT
);
756 fxMesa
->dirty
&= ~TDFX_UPLOAD_STENCIL
;
759 if ( fxMesa
->dirty
& TDFX_UPLOAD_VERTEX_LAYOUT
) {
760 fxMesa
->Glide
.grGlideSetVertexLayout( fxMesa
->layout
[fxMesa
->vertexFormat
] );
761 /* [dborca] enable fogcoord */
762 fxMesa
->Glide
.grVertexLayout(GR_PARAM_FOG_EXT
, TDFX_FOG_OFFSET
,
763 fxMesa
->Fog
.Mode
== GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT
);
764 fxMesa
->dirty
&= ~TDFX_UPLOAD_VERTEX_LAYOUT
;
767 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_ENV
) {
768 uploadTextureEnv(fxMesa
);
769 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_ENV
;
772 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_PARAMS
) {
773 uploadTextureParams(fxMesa
);
774 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_PARAMS
;
777 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_PALETTE
) {
778 if (fxMesa
->TexPalette
.Data
) {
779 fxMesa
->Glide
.grTexDownloadTable(fxMesa
->TexPalette
.Type
, fxMesa
->TexPalette
.Data
);
781 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_PALETTE
;
784 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_SOURCE
) {
785 uploadTextureSource(fxMesa
);
786 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_SOURCE
;
789 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_IMAGES
) {
790 uploadTextureImages(fxMesa
);
791 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_IMAGES
;
799 void tdfxInitRenderFuncs( struct dd_function_table
*functions
)
801 functions
->Clear
= tdfxClear
;
802 functions
->Finish
= tdfxFinish
;
803 functions
->Flush
= tdfxFlush
;