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 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
33 * Gareth Hughes <gareth@valinux.com>
34 * Brian Paul <brianp@valinux.com>
38 #include "tdfx_context.h"
39 #include "tdfx_render.h"
40 #include "tdfx_state.h"
41 #include "tdfx_texman.h"
42 #include "swrast/swrast.h"
44 /* Clear the color and/or depth buffers.
46 static void tdfxClear( GLcontext
*ctx
,
47 GLbitfield mask
, GLboolean all
,
48 GLint x
, GLint y
, GLint width
, GLint height
)
50 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
51 GLbitfield softwareMask
= mask
& (DD_ACCUM_BIT
);
52 const GLuint stencil_size
=
53 fxMesa
->haveHwStencil
? fxMesa
->glCtx
->Visual
.stencilBits
: 0;
55 if ( TDFX_DEBUG
& DEBUG_VERBOSE_API
) {
56 fprintf( stderr
, "%s( %d, %d, %d, %d )\n",
57 __FUNCTION__
, (int) x
, (int) y
, (int) width
, (int) height
);
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
);
66 /* we can't clear accum buffers */
67 mask
&= ~(DD_ACCUM_BIT
);
69 if (mask
& DD_STENCIL_BIT
) {
70 if (!fxMesa
->haveHwStencil
|| ctx
->Stencil
.WriteMask
[0] != 0xff) {
71 /* Napalm seems to have trouble with stencil write masks != 0xff */
72 /* do stencil clear in software */
73 mask
&= ~(DD_STENCIL_BIT
);
74 softwareMask
|= DD_STENCIL_BIT
;
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
& (DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
));
83 mask
&= ~(DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
);
87 if (fxMesa
->haveHwStencil
) {
89 * If we want to clear stencil, it must be enabled
90 * in the HW, even if the stencil test is not enabled
93 LOCK_HARDWARE(fxMesa
);
94 if (mask
& DD_STENCIL_BIT
) {
95 fxMesa
->Glide
.grStencilMask(/*ctx->Stencil.WriteMask*/ 0xff);
96 /* set stencil ref value = desired clear value */
97 fxMesa
->Glide
.grStencilFunc(GR_CMP_ALWAYS
,
98 ctx
->Stencil
.Clear
, 0xff);
99 fxMesa
->Glide
.grStencilOp(GR_STENCILOP_REPLACE
,
100 GR_STENCILOP_REPLACE
, GR_STENCILOP_REPLACE
);
101 fxMesa
->Glide
.grEnable(GR_STENCIL_MODE_EXT
);
104 fxMesa
->Glide
.grDisable(GR_STENCIL_MODE_EXT
);
106 UNLOCK_HARDWARE(fxMesa
);
110 * This may be ugly, but it's needed in order to work around a number
113 BEGIN_CLIP_LOOP(fxMesa
);
116 * This could probably be done fancier but doing each possible case
117 * explicitly is less error prone.
119 switch (mask
& ~DD_STENCIL_BIT
) {
120 case DD_BACK_LEFT_BIT
| DD_DEPTH_BIT
:
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
,
129 (FxU32
) ctx
->Stencil
.Clear
);
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
);
139 case DD_FRONT_LEFT_BIT
| DD_DEPTH_BIT
:
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/
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
,
152 (FxU32
) ctx
->Stencil
.Clear
);
154 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
155 fxMesa
->Color
.ClearAlpha
,
156 fxMesa
->Depth
.Clear
);
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
,
164 (FxU32
) ctx
->Stencil
.Clear
);
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
);
173 case DD_BACK_LEFT_BIT
:
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
,
181 (FxU32
) ctx
->Stencil
.Clear
);
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
);
190 case DD_FRONT_LEFT_BIT
:
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
,
198 (FxU32
) ctx
->Stencil
.Clear
);
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
);
207 case DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
:
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
,
215 (FxU32
) ctx
->Stencil
.Clear
);
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
,
225 (FxU32
) ctx
->Stencil
.Clear
);
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
);
234 case DD_FRONT_LEFT_BIT
| DD_BACK_LEFT_BIT
| DD_DEPTH_BIT
:
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
,
242 (FxU32
) ctx
->Stencil
.Clear
);
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
,
254 (FxU32
) ctx
->Stencil
.Clear
);
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
);
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
,
272 (FxU32
) ctx
->Stencil
.Clear
);
274 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
275 fxMesa
->Color
.ClearAlpha
,
276 fxMesa
->Depth
.Clear
);
277 FX_grColorMaskv_NoLock(ctx
, true4
);
278 if (ctx
->Color
._DrawDestMask
& DD_FRONT_LEFT_BIT
)
279 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
280 if (!ctx
->Depth
.Test
|| !ctx
->Depth
.Mask
)
281 fxMesa
->Glide
.grDepthMask(FXFALSE
);
284 /* clear no color buffers or depth buffer but might clear stencil */
285 if (stencil_size
> 0 && (mask
& DD_STENCIL_BIT
)) {
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
,
293 (FxU32
) ctx
->Stencil
.Clear
);
294 if (ctx
->Depth
.Mask
&& ctx
->Depth
.Test
) {
295 fxMesa
->Glide
.grDepthMask(FXTRUE
);
297 FX_grColorMaskv_NoLock(ctx
, true4
);
298 if (ctx
->Color
._DrawDestMask
& DD_FRONT_LEFT_BIT
)
299 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
303 END_CLIP_LOOP(fxMesa
);
305 if (fxMesa
->haveHwStencil
&& (mask
& DD_STENCIL_BIT
)) {
306 /* We changed the stencil state above. Signal that we need to
309 fxMesa
->dirty
|= TDFX_UPLOAD_STENCIL
;
313 _swrast_Clear( ctx
, softwareMask
, all
, x
, y
, width
, height
);
318 static void tdfxFinish( GLcontext
*ctx
)
320 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
322 FLUSH_BATCH( fxMesa
);
324 LOCK_HARDWARE( fxMesa
);
325 fxMesa
->Glide
.grFinish();
326 UNLOCK_HARDWARE( fxMesa
);
329 static void tdfxFlush( GLcontext
*ctx
)
331 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
333 FLUSH_BATCH( fxMesa
);
335 LOCK_HARDWARE( fxMesa
);
336 fxMesa
->Glide
.grFlush();
337 UNLOCK_HARDWARE( fxMesa
);
342 static const char *texSource(int k
)
346 return "GR_CMBX_ZERO";
347 case GR_CMBX_TEXTURE_ALPHA
:
348 return "GR_CMBX_TEXTURE_ALPHA";
350 return "GR_CMBX_ALOCAL";
352 return "GR_CMBX_AOTHER";
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";
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";
388 static const char *texMode(int k
)
391 case GR_FUNC_MODE_ZERO
:
392 return "GR_FUNC_MODE_ZERO";
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";
408 static const char *texInvert(int k
)
410 return k
? "FXTRUE" : "FXFALSE";
414 static void uploadTextureEnv( tdfxContextPtr fxMesa
)
416 if (TDFX_IS_NAPALM(fxMesa
)) {
418 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
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
);
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
);
472 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
473 struct tdfx_texcombine
*comb
= &fxMesa
->TexCombine
[unit
];
474 fxMesa
->Glide
.grTexCombine(TDFX_TMU0
+ unit
,
486 static void uploadTextureParams( tdfxContextPtr fxMesa
)
489 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
490 const struct tdfx_texparams
*p
= &fxMesa
->TexParams
[unit
];
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);
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
, p
->LodBias
);
506 static void uploadTextureSource( tdfxContextPtr fxMesa
)
509 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
510 const struct tdfx_texsource
*src
= &fxMesa
->TexSource
[unit
];
512 printf("upload source %d @ %d %p\n", unit, src->StartAddress, src->Info);
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,
521 fxMesa
->Glide
.grTexSource(GR_TMU0
+ unit
,
530 static void uploadTextureImages( tdfxContextPtr fxMesa
)
532 GLcontext
*ctx
= fxMesa
->glCtx
;
534 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
535 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
== TEXTURE_2D_BIT
) {
536 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[unit
].Current2D
;
537 tdfxTexInfo
*ti
= TDFX_TEXTURE_DATA(tObj
);
538 if (ti
&& ti
->reloadImages
&& ti
->whichTMU
!= TDFX_TMU_NONE
) {
540 printf("download texture image on unit %d\n", unit);
542 tdfxTMDownloadTexture(fxMesa
, tObj
);
543 ti
->reloadImages
= GL_FALSE
;
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.
558 void tdfxUploadClipping( tdfxContextPtr fxMesa
)
560 __DRIdrawablePrivate
*dPriv
= fxMesa
->driDrawable
;
564 if (fxMesa
->numClipRects
== 0) {
565 /* all drawing clipped away */
566 fxMesa
->Glide
.grClipWindow(0, 0, 0, 0);
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
);
574 /* else, we'll do a cliprect loop around all drawing */
576 fxMesa
->Glide
.grDRIPosition( dPriv
->x
, dPriv
->y
, dPriv
->w
, dPriv
->h
,
577 fxMesa
->numClipRects
, fxMesa
->pClipRects
);
581 void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa
)
583 if ( !fxMesa
->dirty
)
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
);
601 fxMesa
->Glide
.grColorCombine( fxMesa
->ColorCombine
.Function
,
602 fxMesa
->ColorCombine
.Factor
,
603 fxMesa
->ColorCombine
.Local
,
604 fxMesa
->ColorCombine
.Other
,
605 fxMesa
->ColorCombine
.Invert
);
607 fxMesa
->dirty
&= ~TDFX_UPLOAD_COLOR_COMBINE
;
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
);
624 fxMesa
->Glide
.grAlphaCombine( fxMesa
->AlphaCombine
.Function
,
625 fxMesa
->AlphaCombine
.Factor
,
626 fxMesa
->AlphaCombine
.Local
,
627 fxMesa
->AlphaCombine
.Other
,
628 fxMesa
->AlphaCombine
.Invert
);
630 fxMesa
->dirty
&= ~TDFX_UPLOAD_ALPHA_COMBINE
;
633 if ( fxMesa
->dirty
& TDFX_UPLOAD_RENDER_BUFFER
) {
634 fxMesa
->Glide
.grRenderBuffer( fxMesa
->DrawBuffer
);
635 fxMesa
->dirty
&= ~TDFX_UPLOAD_RENDER_BUFFER
;
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
;
644 if ( fxMesa
->dirty
& TDFX_UPLOAD_ALPHA_TEST
) {
645 fxMesa
->Glide
.grAlphaTestFunction( fxMesa
->Color
.AlphaFunc
);
646 fxMesa
->dirty
&= ~TDFX_UPLOAD_ALPHA_TEST
;
648 if ( fxMesa
->dirty
& TDFX_UPLOAD_ALPHA_REF
) {
649 fxMesa
->Glide
.grAlphaTestReferenceValue( fxMesa
->Color
.AlphaRef
);
650 fxMesa
->dirty
&= ~TDFX_UPLOAD_ALPHA_REF
;
652 if ( fxMesa
->dirty
& TDFX_UPLOAD_BLEND_FUNC
) {
653 if (fxMesa
->Glide
.grAlphaBlendFunctionExt
) {
654 fxMesa
->Glide
.grAlphaBlendFunctionExt( fxMesa
->Color
.BlendSrcRGB
,
655 fxMesa
->Color
.BlendDstRGB
,
657 fxMesa
->Color
.BlendSrcA
,
658 fxMesa
->Color
.BlendDstA
,
662 fxMesa
->Glide
.grAlphaBlendFunction( fxMesa
->Color
.BlendSrcRGB
,
663 fxMesa
->Color
.BlendDstRGB
,
664 fxMesa
->Color
.BlendSrcA
,
665 fxMesa
->Color
.BlendDstA
);
667 fxMesa
->dirty
&= ~TDFX_UPLOAD_BLEND_FUNC
;
670 if ( fxMesa
->dirty
& TDFX_UPLOAD_DEPTH_MODE
) {
671 fxMesa
->Glide
.grDepthBufferMode( fxMesa
->Depth
.Mode
);
672 fxMesa
->dirty
&= ~TDFX_UPLOAD_DEPTH_MODE
;
674 if ( fxMesa
->dirty
& TDFX_UPLOAD_DEPTH_BIAS
) {
675 fxMesa
->Glide
.grDepthBiasLevel( fxMesa
->Depth
.Bias
);
676 fxMesa
->dirty
&= ~TDFX_UPLOAD_DEPTH_BIAS
;
678 if ( fxMesa
->dirty
& TDFX_UPLOAD_DEPTH_FUNC
) {
679 fxMesa
->Glide
.grDepthBufferFunction( fxMesa
->Depth
.Func
);
680 fxMesa
->dirty
&= ~TDFX_UPLOAD_DEPTH_FUNC
;
682 if ( fxMesa
->dirty
& TDFX_UPLOAD_DEPTH_MASK
) {
683 fxMesa
->Glide
.grDepthMask( fxMesa
->Depth
.Mask
);
684 fxMesa
->dirty
&= ~TDFX_UPLOAD_DEPTH_MASK
;
687 if ( fxMesa
->dirty
& TDFX_UPLOAD_DITHER
) {
688 fxMesa
->Glide
.grDitherMode( fxMesa
->Color
.Dither
);
691 if ( fxMesa
->dirty
& TDFX_UPLOAD_FOG_MODE
) {
692 fxMesa
->Glide
.grFogMode( fxMesa
->Fog
.Mode
);
693 fxMesa
->dirty
&= ~TDFX_UPLOAD_FOG_MODE
;
695 if ( fxMesa
->dirty
& TDFX_UPLOAD_FOG_COLOR
) {
696 fxMesa
->Glide
.grFogColorValue( fxMesa
->Fog
.Color
);
697 fxMesa
->dirty
&= ~TDFX_UPLOAD_FOG_COLOR
;
699 if ( fxMesa
->dirty
& TDFX_UPLOAD_FOG_TABLE
) {
700 fxMesa
->Glide
.grFogTable( fxMesa
->Fog
.Table
);
701 fxMesa
->dirty
&= ~TDFX_UPLOAD_FOG_TABLE
;
704 if ( fxMesa
->dirty
& TDFX_UPLOAD_CULL
) {
705 fxMesa
->Glide
.grCullMode( fxMesa
->CullMode
);
706 fxMesa
->dirty
&= ~TDFX_UPLOAD_CULL
;
709 if ( fxMesa
->dirty
& TDFX_UPLOAD_CLIP
) {
710 tdfxUploadClipping( fxMesa
);
711 fxMesa
->dirty
&= ~TDFX_UPLOAD_CLIP
;
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
] );
722 fxMesa
->Glide
.grColorMask( fxMesa
->Color
.ColorMask
[RCOMP
] ||
723 fxMesa
->Color
.ColorMask
[GCOMP
] ||
724 fxMesa
->Color
.ColorMask
[BCOMP
],
725 fxMesa
->Color
.ColorMask
[ACOMP
] );
727 fxMesa
->dirty
&= ~TDFX_UPLOAD_COLOR_MASK
;
730 /* if ( fxMesa->dirty & TDFX_UPLOAD_CONSTANT_COLOR ) { */
731 /* grConstantColorValue( fxMesa->Color.MonoColor ); */
732 /* fxMesa->dirty &= ~TDFX_UPLOAD_CONSTANT_COLOR; */
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
);
739 fxMesa
->Glide
.grDisable(GR_AA_ORDERED
);
740 fxMesa
->dirty
&= ~TDFX_UPLOAD_LINE
;
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
);
755 fxMesa
->Glide
.grDisable(GR_STENCIL_MODE_EXT
);
757 fxMesa
->dirty
&= ~TDFX_UPLOAD_STENCIL
;
760 if ( fxMesa
->dirty
& TDFX_UPLOAD_VERTEX_LAYOUT
) {
761 fxMesa
->Glide
.grGlideSetVertexLayout( fxMesa
->layout
[fxMesa
->vertexFormat
] );
762 fxMesa
->dirty
&= ~TDFX_UPLOAD_VERTEX_LAYOUT
;
765 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_ENV
) {
766 uploadTextureEnv(fxMesa
);
767 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_ENV
;
770 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_PARAMS
) {
771 uploadTextureParams(fxMesa
);
772 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_PARAMS
;
775 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_PALETTE
) {
776 if (fxMesa
->TexPalette
.Data
) {
777 fxMesa
->Glide
.grTexDownloadTable(fxMesa
->TexPalette
.Type
, fxMesa
->TexPalette
.Data
);
779 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_PALETTE
;
782 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_SOURCE
) {
783 uploadTextureSource(fxMesa
);
784 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_SOURCE
;
787 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_IMAGES
) {
788 uploadTextureImages(fxMesa
);
789 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_IMAGES
;
797 void tdfxInitRenderFuncs( struct dd_function_table
*functions
)
799 functions
->Clear
= tdfxClear
;
800 functions
->Finish
= tdfxFinish
;
801 functions
->Flush
= tdfxFlush
;