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 xFoo
, GLint yFoo
, GLint widthFoo
, GLint heightFoo
)
53 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
54 GLbitfield softwareMask
= mask
& (BUFFER_BIT_ACCUM
);
55 const GLuint stencil_size
=
56 fxMesa
->haveHwStencil
? fxMesa
->glCtx
->Visual
.stencilBits
: 0;
58 if ( TDFX_DEBUG
& DEBUG_VERBOSE_API
) {
59 fprintf( stderr
, "tdfxClear(0x%x)\n", mask
);
62 /* Need this check to respond to glScissor and clipping updates */
63 if ((fxMesa
->new_state
& (TDFX_NEW_CLIP
| TDFX_NEW_DEPTH
)) ||
64 (fxMesa
->dirty
& TDFX_UPLOAD_COLOR_MASK
)) {
65 tdfxDDUpdateHwState(ctx
);
68 /* we can't clear accum buffers */
69 mask
&= ~(BUFFER_BIT_ACCUM
);
71 if (mask
& BUFFER_BIT_STENCIL
) {
72 if (!fxMesa
->haveHwStencil
|| (ctx
->Stencil
.WriteMask
[0] & 0xff) != 0xff) {
73 /* Napalm seems to have trouble with stencil write masks != 0xff */
74 /* do stencil clear in software */
75 mask
&= ~(BUFFER_BIT_STENCIL
);
76 softwareMask
|= BUFFER_BIT_STENCIL
;
80 if (fxMesa
->glCtx
->Visual
.redBits
!= 8) {
81 /* can only do color masking if running in 24/32bpp on Napalm */
82 if (ctx
->Color
.ColorMask
[RCOMP
] != ctx
->Color
.ColorMask
[GCOMP
] ||
83 ctx
->Color
.ColorMask
[GCOMP
] != ctx
->Color
.ColorMask
[BCOMP
]) {
84 softwareMask
|= (mask
& (BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
));
85 mask
&= ~(BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
);
89 if (fxMesa
->haveHwStencil
) {
91 * If we want to clear stencil, it must be enabled
92 * in the HW, even if the stencil test is not enabled
95 LOCK_HARDWARE(fxMesa
);
96 if (mask
& BUFFER_BIT_STENCIL
) {
97 fxMesa
->Glide
.grStencilMask(/*ctx->Stencil.WriteMask*/ 0xff);
98 /* set stencil ref value = desired clear value */
99 fxMesa
->Glide
.grStencilFunc(GR_CMP_ALWAYS
,
100 (fxMesa
->Stencil
.Clear
& 0xff), 0xff);
101 fxMesa
->Glide
.grStencilOp(GR_STENCILOP_REPLACE
,
102 GR_STENCILOP_REPLACE
, GR_STENCILOP_REPLACE
);
103 fxMesa
->Glide
.grEnable(GR_STENCIL_MODE_EXT
);
106 fxMesa
->Glide
.grDisable(GR_STENCIL_MODE_EXT
);
108 UNLOCK_HARDWARE(fxMesa
);
112 * This may be ugly, but it's needed in order to work around a number
115 BEGIN_CLIP_LOOP(fxMesa
);
118 * This could probably be done fancier but doing each possible case
119 * explicitly is less error prone.
121 switch (mask
& ~BUFFER_BIT_STENCIL
) {
122 case BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_DEPTH
:
123 /* back buffer & depth */
124 FX_grColorMaskv_NoLock(ctx
, true4
); /* work around Voodoo3 bug */
125 fxMesa
->Glide
.grDepthMask(FXTRUE
);
126 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
127 if (stencil_size
> 0) {
128 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
129 fxMesa
->Color
.ClearAlpha
,
131 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
134 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
135 fxMesa
->Color
.ClearAlpha
,
136 fxMesa
->Depth
.Clear
);
137 if (!ctx
->Depth
.Mask
|| !ctx
->Depth
.Test
) {
138 fxMesa
->Glide
.grDepthMask(FXFALSE
);
141 case BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_DEPTH
:
142 /* XXX it appears that the depth buffer isn't cleared when
143 * glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set.
144 * This is a work-around/
147 fxMesa
->Glide
.grDepthMask(FXTRUE
);
148 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
149 FX_grColorMaskv_NoLock(ctx
, false4
);
150 if (stencil_size
> 0)
151 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
152 fxMesa
->Color
.ClearAlpha
,
154 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
156 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
157 fxMesa
->Color
.ClearAlpha
,
158 fxMesa
->Depth
.Clear
& 0xff);
160 FX_grColorMaskv_NoLock(ctx
, true4
);
161 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
162 if (stencil_size
> 0)
163 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
164 fxMesa
->Color
.ClearAlpha
,
166 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
168 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
169 fxMesa
->Color
.ClearAlpha
,
170 fxMesa
->Depth
.Clear
);
171 if (!ctx
->Depth
.Mask
|| !ctx
->Depth
.Test
) {
172 fxMesa
->Glide
.grDepthMask(FXFALSE
);
175 case BUFFER_BIT_BACK_LEFT
:
176 /* back buffer only */
177 fxMesa
->Glide
.grDepthMask(FXFALSE
);
178 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
179 if (stencil_size
> 0)
180 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
181 fxMesa
->Color
.ClearAlpha
,
183 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
185 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
186 fxMesa
->Color
.ClearAlpha
,
187 fxMesa
->Depth
.Clear
);
188 if (ctx
->Depth
.Mask
&& ctx
->Depth
.Test
) {
189 fxMesa
->Glide
.grDepthMask(FXTRUE
);
192 case BUFFER_BIT_FRONT_LEFT
:
193 /* front buffer only */
194 fxMesa
->Glide
.grDepthMask(FXFALSE
);
195 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
196 if (stencil_size
> 0)
197 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
198 fxMesa
->Color
.ClearAlpha
,
200 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
202 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
203 fxMesa
->Color
.ClearAlpha
,
204 fxMesa
->Depth
.Clear
);
205 if (ctx
->Depth
.Mask
&& ctx
->Depth
.Test
) {
206 fxMesa
->Glide
.grDepthMask(FXTRUE
);
209 case BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
:
211 fxMesa
->Glide
.grDepthMask(FXFALSE
);
212 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
213 if (stencil_size
> 0)
214 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
215 fxMesa
->Color
.ClearAlpha
,
217 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
219 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
220 fxMesa
->Color
.ClearAlpha
,
221 fxMesa
->Depth
.Clear
);
222 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
223 if (stencil_size
> 0)
224 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
225 fxMesa
->Color
.ClearAlpha
,
227 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
229 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
230 fxMesa
->Color
.ClearAlpha
,
231 fxMesa
->Depth
.Clear
);
232 if (ctx
->Depth
.Mask
&& ctx
->Depth
.Test
) {
233 fxMesa
->Glide
.grDepthMask(FXTRUE
);
236 case BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_DEPTH
:
238 fxMesa
->Glide
.grDepthMask(FXFALSE
);
239 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
240 if (stencil_size
> 0)
241 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
242 fxMesa
->Color
.ClearAlpha
,
244 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
246 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
247 fxMesa
->Color
.ClearAlpha
,
248 fxMesa
->Depth
.Clear
);
249 /* clear back and depth */
250 fxMesa
->Glide
.grDepthMask(FXTRUE
);
251 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
252 if (stencil_size
> 0)
253 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
254 fxMesa
->Color
.ClearAlpha
,
256 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
258 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
259 fxMesa
->Color
.ClearAlpha
,
260 fxMesa
->Depth
.Clear
);
261 if (!ctx
->Depth
.Mask
|| !ctx
->Depth
.Mask
) {
262 fxMesa
->Glide
.grDepthMask(FXFALSE
);
265 case BUFFER_BIT_DEPTH
:
266 /* just the depth buffer */
267 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
268 FX_grColorMaskv_NoLock(ctx
, false4
);
269 fxMesa
->Glide
.grDepthMask(FXTRUE
);
270 if (stencil_size
> 0)
271 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
272 fxMesa
->Color
.ClearAlpha
,
274 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
276 fxMesa
->Glide
.grBufferClear(fxMesa
->Color
.ClearColor
,
277 fxMesa
->Color
.ClearAlpha
,
278 fxMesa
->Depth
.Clear
);
279 FX_grColorMaskv_NoLock(ctx
, true4
);
280 if (ctx
->DrawBuffer
->_ColorDrawBufferMask
[0] & BUFFER_BIT_FRONT_LEFT
)
281 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
282 if (!ctx
->Depth
.Test
|| !ctx
->Depth
.Mask
)
283 fxMesa
->Glide
.grDepthMask(FXFALSE
);
286 /* clear no color buffers or depth buffer but might clear stencil */
287 if (stencil_size
> 0 && (mask
& BUFFER_BIT_STENCIL
)) {
288 /* XXX need this RenderBuffer call to work around Glide bug */
289 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_BACKBUFFER
);
290 fxMesa
->Glide
.grDepthMask(FXFALSE
);
291 FX_grColorMaskv_NoLock(ctx
, false4
);
292 fxMesa
->Glide
.grBufferClearExt(fxMesa
->Color
.ClearColor
,
293 fxMesa
->Color
.ClearAlpha
,
295 (FxU32
) (ctx
->Stencil
.Clear
& 0xff));
296 if (ctx
->Depth
.Mask
&& ctx
->Depth
.Test
) {
297 fxMesa
->Glide
.grDepthMask(FXTRUE
);
299 FX_grColorMaskv_NoLock(ctx
, true4
);
300 if (ctx
->DrawBuffer
->_ColorDrawBufferMask
[0] & BUFFER_BIT_FRONT_LEFT
)
301 fxMesa
->Glide
.grRenderBuffer(GR_BUFFER_FRONTBUFFER
);
305 END_CLIP_LOOP(fxMesa
);
307 if (fxMesa
->haveHwStencil
&& (mask
& BUFFER_BIT_STENCIL
)) {
308 /* We changed the stencil state above. Signal that we need to
311 fxMesa
->dirty
|= TDFX_UPLOAD_STENCIL
;
315 _swrast_Clear( ctx
, softwareMask
, 0, 0, 0, 0, 0);
320 static void tdfxFinish( GLcontext
*ctx
)
322 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
324 FLUSH_BATCH( fxMesa
);
326 LOCK_HARDWARE( fxMesa
);
327 fxMesa
->Glide
.grFinish();
328 UNLOCK_HARDWARE( fxMesa
);
331 static void tdfxFlush( GLcontext
*ctx
)
333 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
335 FLUSH_BATCH( fxMesa
);
337 LOCK_HARDWARE( fxMesa
);
338 fxMesa
->Glide
.grFlush();
339 UNLOCK_HARDWARE( fxMesa
);
344 static const char *texSource(int k
)
348 return "GR_CMBX_ZERO";
349 case GR_CMBX_TEXTURE_ALPHA
:
350 return "GR_CMBX_TEXTURE_ALPHA";
352 return "GR_CMBX_ALOCAL";
354 return "GR_CMBX_AOTHER";
357 case GR_CMBX_CONSTANT_ALPHA
:
358 return "GR_CMBX_CONSTANT_ALPHA";
359 case GR_CMBX_CONSTANT_COLOR
:
360 return "GR_CMBX_CONSTANT_COLOR";
361 case GR_CMBX_DETAIL_FACTOR
:
362 return "GR_CMBX_DETAIL_FACTOR";
363 case GR_CMBX_ITALPHA
:
364 return "GR_CMBX_ITALPHA";
366 return "GR_CMBX_ITRGB";
367 case GR_CMBX_LOCAL_TEXTURE_ALPHA
:
368 return "GR_CMBX_LOCAL_TEXTURE_ALPHA";
369 case GR_CMBX_LOCAL_TEXTURE_RGB
:
370 return "GR_CMBX_LOCAL_TEXTURE_RGB";
371 case GR_CMBX_LOD_FRAC
:
372 return "GR_CMBX_LOD_FRAC";
373 case GR_CMBX_OTHER_TEXTURE_ALPHA
:
374 return "GR_CMBX_OTHER_TEXTURE_ALPHA";
375 case GR_CMBX_OTHER_TEXTURE_RGB
:
376 return "GR_CMBX_OTHER_TEXTURE_RGB";
377 case GR_CMBX_TEXTURE_RGB
:
378 return "GR_CMBX_TEXTURE_RGB";
379 case GR_CMBX_TMU_CALPHA
:
380 return "GR_CMBX_TMU_CALPHA";
381 case GR_CMBX_TMU_CCOLOR
:
382 return "GR_CMBX_TMU_CCOLOR";
390 static const char *texMode(int k
)
393 case GR_FUNC_MODE_ZERO
:
394 return "GR_FUNC_MODE_ZERO";
396 return "GR_FUNC_MODE_X";
397 case GR_FUNC_MODE_ONE_MINUS_X
:
398 return "GR_FUNC_MODE_ONE_MINUS_X";
399 case GR_FUNC_MODE_NEGATIVE_X
:
400 return "GR_FUNC_MODE_NEGATIVE_X";
401 case GR_FUNC_MODE_X_MINUS_HALF
:
402 return "GR_FUNC_MODE_X_MINUS_HALF";
410 static const char *texInvert(int k
)
412 return k
? "FXTRUE" : "FXFALSE";
416 static void uploadTextureEnv( tdfxContextPtr fxMesa
)
418 if (TDFX_IS_NAPALM(fxMesa
)) {
420 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
422 printf("upload env %d\n", unit
);
423 printf(" cSourceA = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Color
.SourceA
));
424 printf(" cModeA = %s\n", texMode(fxMesa
->TexCombineExt
[unit
].Color
.ModeA
));
425 printf(" cSourceB = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Color
.SourceB
));
426 printf(" cModeB = %s\n", texMode(fxMesa
->TexCombineExt
[unit
].Color
.ModeB
));
427 printf(" cSourceC = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Color
.SourceC
));
428 printf(" cInvertC = %s\n", texInvert(fxMesa
->TexCombineExt
[unit
].Color
.InvertC
));
429 printf(" cSourceD = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Color
.SourceD
));
430 printf(" cInvertD = %s\n", texInvert(fxMesa
->TexCombineExt
[unit
].Color
.InvertD
));
431 printf(" cShift = %d\t", fxMesa
->TexCombineExt
[unit
].Color
.Shift
);
432 printf(" cInvert = %d\n", fxMesa
->TexCombineExt
[unit
].Color
.Invert
);
433 printf(" aSourceA = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Alpha
.SourceA
));
434 printf(" aModeA = %s\n", texMode(fxMesa
->TexCombineExt
[unit
].Alpha
.ModeA
));
435 printf(" aSourceB = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Alpha
.SourceB
));
436 printf(" aModeB = %s\n", texMode(fxMesa
->TexCombineExt
[unit
].Alpha
.ModeB
));
437 printf(" aSourceC = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Alpha
.SourceC
));
438 printf(" aInvertC = %s\n", texInvert(fxMesa
->TexCombineExt
[unit
].Alpha
.InvertC
));
439 printf(" aSourceD = %s\t", texSource(fxMesa
->TexCombineExt
[unit
].Alpha
.SourceD
));
440 printf(" aInvertD = %s\n", texInvert(fxMesa
->TexCombineExt
[unit
].Alpha
.InvertD
));
441 printf(" aShift = %d\t", fxMesa
->TexCombineExt
[unit
].Alpha
.Shift
);
442 printf(" aInvert = %d\n", fxMesa
->TexCombineExt
[unit
].Alpha
.Invert
);
443 printf(" Color = 0x%08x\n", fxMesa
->TexCombineExt
[unit
].EnvColor
);
445 fxMesa
->Glide
.grTexColorCombineExt(TDFX_TMU0
+ unit
,
446 fxMesa
->TexCombineExt
[unit
].Color
.SourceA
,
447 fxMesa
->TexCombineExt
[unit
].Color
.ModeA
,
448 fxMesa
->TexCombineExt
[unit
].Color
.SourceB
,
449 fxMesa
->TexCombineExt
[unit
].Color
.ModeB
,
450 fxMesa
->TexCombineExt
[unit
].Color
.SourceC
,
451 fxMesa
->TexCombineExt
[unit
].Color
.InvertC
,
452 fxMesa
->TexCombineExt
[unit
].Color
.SourceD
,
453 fxMesa
->TexCombineExt
[unit
].Color
.InvertD
,
454 fxMesa
->TexCombineExt
[unit
].Color
.Shift
,
455 fxMesa
->TexCombineExt
[unit
].Color
.Invert
);
456 fxMesa
->Glide
.grTexAlphaCombineExt(TDFX_TMU0
+ unit
,
457 fxMesa
->TexCombineExt
[unit
].Alpha
.SourceA
,
458 fxMesa
->TexCombineExt
[unit
].Alpha
.ModeA
,
459 fxMesa
->TexCombineExt
[unit
].Alpha
.SourceB
,
460 fxMesa
->TexCombineExt
[unit
].Alpha
.ModeB
,
461 fxMesa
->TexCombineExt
[unit
].Alpha
.SourceC
,
462 fxMesa
->TexCombineExt
[unit
].Alpha
.InvertC
,
463 fxMesa
->TexCombineExt
[unit
].Alpha
.SourceD
,
464 fxMesa
->TexCombineExt
[unit
].Alpha
.InvertD
,
465 fxMesa
->TexCombineExt
[unit
].Alpha
.Shift
,
466 fxMesa
->TexCombineExt
[unit
].Alpha
.Invert
);
467 fxMesa
->Glide
.grConstantColorValueExt(TDFX_TMU0
+ unit
,
468 fxMesa
->TexCombineExt
[unit
].EnvColor
);
474 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
475 struct tdfx_texcombine
*comb
= &fxMesa
->TexCombine
[unit
];
476 fxMesa
->Glide
.grTexCombine(TDFX_TMU0
+ unit
,
488 static void uploadTextureParams( tdfxContextPtr fxMesa
)
491 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
492 const struct tdfx_texparams
*p
= &fxMesa
->TexParams
[unit
];
494 printf("upload params %d\n", unit);
495 printf(" clamp %x %x\n", env->sClamp, env->tClamp);
496 printf(" filter %x %x\n", env->minFilt, env->magFilt);
497 printf(" mipmap %x %x\n", env->mmMode, env->LODblend);
498 printf(" lod bias %f\n", env->LodBias);
500 fxMesa
->Glide
.grTexClampMode(GR_TMU0
+ unit
, p
->sClamp
, p
->tClamp
);
501 fxMesa
->Glide
.grTexFilterMode(GR_TMU0
+ unit
, p
->minFilt
, p
->magFilt
);
502 fxMesa
->Glide
.grTexMipMapMode(GR_TMU0
+ unit
, p
->mmMode
, p
->LODblend
);
503 fxMesa
->Glide
.grTexLodBiasValue(GR_TMU0
+ unit
, CLAMP(p
->LodBias
, -8, 7.75));
508 static void uploadTextureSource( tdfxContextPtr fxMesa
)
511 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
512 const struct tdfx_texsource
*src
= &fxMesa
->TexSource
[unit
];
514 printf("upload source %d @ %d %p\n", unit, src->StartAddress, src->Info);
518 printf(" smallLodLog2=%d largeLodLog2=%d ar=%d format=%d data=%p\n",
519 src->Info->smallLodLog2, src->Info->largeLodLog2,
520 src->Info->aspectRatioLog2, src->Info->format,
523 fxMesa
->Glide
.grTexSource(GR_TMU0
+ unit
,
532 static void uploadTextureImages( tdfxContextPtr fxMesa
)
534 GLcontext
*ctx
= fxMesa
->glCtx
;
536 for (unit
= 0; unit
< TDFX_NUM_TMU
; unit
++) {
537 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
538 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[unit
]._Current
;
539 tdfxTexInfo
*ti
= TDFX_TEXTURE_DATA(tObj
);
540 if (ti
&& ti
->reloadImages
&& ti
->whichTMU
!= TDFX_TMU_NONE
) {
542 printf("download texture image on unit %d\n", unit);
544 tdfxTMDownloadTexture(fxMesa
, tObj
);
545 ti
->reloadImages
= GL_FALSE
;
554 * If scissoring is enabled, compute intersection of scissor region
555 * with all X clip rects, resulting in new cliprect list.
556 * If number of cliprects is zero or one, call grClipWindow to setup
557 * the clip region. Otherwise we'll call grClipWindow inside the
558 * BEGIN_CLIP_LOOP macro.
560 void tdfxUploadClipping( tdfxContextPtr fxMesa
)
562 __DRIdrawablePrivate
*dPriv
= fxMesa
->driDrawable
;
566 if (fxMesa
->numClipRects
== 0) {
567 /* all drawing clipped away */
568 fxMesa
->Glide
.grClipWindow(0, 0, 0, 0);
570 else if (fxMesa
->numClipRects
== 1) {
571 fxMesa
->Glide
.grClipWindow(fxMesa
->pClipRects
[0].x1
,
572 fxMesa
->screen_height
- fxMesa
->pClipRects
[0].y2
,
573 fxMesa
->pClipRects
[0].x2
,
574 fxMesa
->screen_height
- fxMesa
->pClipRects
[0].y1
);
576 /* else, we'll do a cliprect loop around all drawing */
578 fxMesa
->Glide
.grDRIPosition( dPriv
->x
, dPriv
->y
, dPriv
->w
, dPriv
->h
,
579 fxMesa
->numClipRects
, fxMesa
->pClipRects
);
583 void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa
)
585 if ( !fxMesa
->dirty
)
588 if ( fxMesa
->dirty
& TDFX_UPLOAD_COLOR_COMBINE
) {
589 if (TDFX_IS_NAPALM(fxMesa
)) {
590 fxMesa
->Glide
.grColorCombineExt(fxMesa
->ColorCombineExt
.SourceA
,
591 fxMesa
->ColorCombineExt
.ModeA
,
592 fxMesa
->ColorCombineExt
.SourceB
,
593 fxMesa
->ColorCombineExt
.ModeB
,
594 fxMesa
->ColorCombineExt
.SourceC
,
595 fxMesa
->ColorCombineExt
.InvertC
,
596 fxMesa
->ColorCombineExt
.SourceD
,
597 fxMesa
->ColorCombineExt
.InvertD
,
598 fxMesa
->ColorCombineExt
.Shift
,
599 fxMesa
->ColorCombineExt
.Invert
);
603 fxMesa
->Glide
.grColorCombine( fxMesa
->ColorCombine
.Function
,
604 fxMesa
->ColorCombine
.Factor
,
605 fxMesa
->ColorCombine
.Local
,
606 fxMesa
->ColorCombine
.Other
,
607 fxMesa
->ColorCombine
.Invert
);
609 fxMesa
->dirty
&= ~TDFX_UPLOAD_COLOR_COMBINE
;
611 if ( fxMesa
->dirty
& TDFX_UPLOAD_ALPHA_COMBINE
) {
612 if (TDFX_IS_NAPALM(fxMesa
)) {
613 fxMesa
->Glide
.grAlphaCombineExt(fxMesa
->AlphaCombineExt
.SourceA
,
614 fxMesa
->AlphaCombineExt
.ModeA
,
615 fxMesa
->AlphaCombineExt
.SourceB
,
616 fxMesa
->AlphaCombineExt
.ModeB
,
617 fxMesa
->AlphaCombineExt
.SourceC
,
618 fxMesa
->AlphaCombineExt
.InvertC
,
619 fxMesa
->AlphaCombineExt
.SourceD
,
620 fxMesa
->AlphaCombineExt
.InvertD
,
621 fxMesa
->AlphaCombineExt
.Shift
,
622 fxMesa
->AlphaCombineExt
.Invert
);
626 fxMesa
->Glide
.grAlphaCombine( fxMesa
->AlphaCombine
.Function
,
627 fxMesa
->AlphaCombine
.Factor
,
628 fxMesa
->AlphaCombine
.Local
,
629 fxMesa
->AlphaCombine
.Other
,
630 fxMesa
->AlphaCombine
.Invert
);
632 fxMesa
->dirty
&= ~TDFX_UPLOAD_ALPHA_COMBINE
;
635 if ( fxMesa
->dirty
& TDFX_UPLOAD_RENDER_BUFFER
) {
636 fxMesa
->Glide
.grRenderBuffer( fxMesa
->DrawBuffer
);
637 fxMesa
->dirty
&= ~TDFX_UPLOAD_RENDER_BUFFER
;
640 if ( fxMesa
->dirty
& TDFX_UPLOAD_STIPPLE
) {
641 fxMesa
->Glide
.grStipplePattern( fxMesa
->Stipple
.Pattern
);
642 fxMesa
->Glide
.grStippleMode( fxMesa
->Stipple
.Mode
);
643 fxMesa
->dirty
&= ~TDFX_UPLOAD_STIPPLE
;
646 if ( fxMesa
->dirty
& TDFX_UPLOAD_ALPHA_TEST
) {
647 fxMesa
->Glide
.grAlphaTestFunction( fxMesa
->Color
.AlphaFunc
);
648 fxMesa
->dirty
&= ~TDFX_UPLOAD_ALPHA_TEST
;
650 if ( fxMesa
->dirty
& TDFX_UPLOAD_ALPHA_REF
) {
651 fxMesa
->Glide
.grAlphaTestReferenceValue( fxMesa
->Color
.AlphaRef
);
652 fxMesa
->dirty
&= ~TDFX_UPLOAD_ALPHA_REF
;
654 if ( fxMesa
->dirty
& TDFX_UPLOAD_BLEND_FUNC
) {
655 if (fxMesa
->Glide
.grAlphaBlendFunctionExt
) {
656 fxMesa
->Glide
.grAlphaBlendFunctionExt( fxMesa
->Color
.BlendSrcRGB
,
657 fxMesa
->Color
.BlendDstRGB
,
658 fxMesa
->Color
.BlendEqRGB
,
659 fxMesa
->Color
.BlendSrcA
,
660 fxMesa
->Color
.BlendDstA
,
661 fxMesa
->Color
.BlendEqA
);
664 fxMesa
->Glide
.grAlphaBlendFunction( fxMesa
->Color
.BlendSrcRGB
,
665 fxMesa
->Color
.BlendDstRGB
,
666 fxMesa
->Color
.BlendSrcA
,
667 fxMesa
->Color
.BlendDstA
);
669 fxMesa
->dirty
&= ~TDFX_UPLOAD_BLEND_FUNC
;
672 if ( fxMesa
->dirty
& TDFX_UPLOAD_DEPTH_MODE
) {
673 fxMesa
->Glide
.grDepthBufferMode( fxMesa
->Depth
.Mode
);
674 fxMesa
->dirty
&= ~TDFX_UPLOAD_DEPTH_MODE
;
676 if ( fxMesa
->dirty
& TDFX_UPLOAD_DEPTH_BIAS
) {
677 fxMesa
->Glide
.grDepthBiasLevel( fxMesa
->Depth
.Bias
);
678 fxMesa
->dirty
&= ~TDFX_UPLOAD_DEPTH_BIAS
;
680 if ( fxMesa
->dirty
& TDFX_UPLOAD_DEPTH_FUNC
) {
681 fxMesa
->Glide
.grDepthBufferFunction( fxMesa
->Depth
.Func
);
682 fxMesa
->dirty
&= ~TDFX_UPLOAD_DEPTH_FUNC
;
684 if ( fxMesa
->dirty
& TDFX_UPLOAD_DEPTH_MASK
) {
685 fxMesa
->Glide
.grDepthMask( fxMesa
->Depth
.Mask
);
686 fxMesa
->dirty
&= ~TDFX_UPLOAD_DEPTH_MASK
;
689 if ( fxMesa
->dirty
& TDFX_UPLOAD_DITHER
) {
690 fxMesa
->Glide
.grDitherMode( fxMesa
->Color
.Dither
);
693 if ( fxMesa
->dirty
& TDFX_UPLOAD_FOG_MODE
) {
694 fxMesa
->Glide
.grFogMode( fxMesa
->Fog
.Mode
);
695 fxMesa
->dirty
&= ~TDFX_UPLOAD_FOG_MODE
;
697 if ( fxMesa
->dirty
& TDFX_UPLOAD_FOG_COLOR
) {
698 fxMesa
->Glide
.grFogColorValue( fxMesa
->Fog
.Color
);
699 fxMesa
->dirty
&= ~TDFX_UPLOAD_FOG_COLOR
;
701 if ( fxMesa
->dirty
& TDFX_UPLOAD_FOG_TABLE
) {
702 fxMesa
->Glide
.grFogTable( fxMesa
->Fog
.Table
);
703 fxMesa
->dirty
&= ~TDFX_UPLOAD_FOG_TABLE
;
706 if ( fxMesa
->dirty
& TDFX_UPLOAD_CULL
) {
707 fxMesa
->Glide
.grCullMode( fxMesa
->CullMode
);
708 fxMesa
->dirty
&= ~TDFX_UPLOAD_CULL
;
711 if ( fxMesa
->dirty
& TDFX_UPLOAD_CLIP
) {
712 tdfxUploadClipping( fxMesa
);
713 fxMesa
->dirty
&= ~TDFX_UPLOAD_CLIP
;
716 if ( fxMesa
->dirty
& TDFX_UPLOAD_COLOR_MASK
) {
717 if ( fxMesa
->Glide
.grColorMaskExt
718 && fxMesa
->glCtx
->Visual
.redBits
== 8) {
719 fxMesa
->Glide
.grColorMaskExt( fxMesa
->Color
.ColorMask
[RCOMP
],
720 fxMesa
->Color
.ColorMask
[GCOMP
],
721 fxMesa
->Color
.ColorMask
[BCOMP
],
722 fxMesa
->Color
.ColorMask
[ACOMP
] );
724 fxMesa
->Glide
.grColorMask( fxMesa
->Color
.ColorMask
[RCOMP
] ||
725 fxMesa
->Color
.ColorMask
[GCOMP
] ||
726 fxMesa
->Color
.ColorMask
[BCOMP
],
727 /*fxMesa->Color.ColorMask[ACOMP]*/GL_FALSE
/*[dBorca] no-no*/ );
729 fxMesa
->dirty
&= ~TDFX_UPLOAD_COLOR_MASK
;
732 if ( fxMesa
->dirty
& TDFX_UPLOAD_CONSTANT_COLOR
) {
733 fxMesa
->Glide
.grConstantColorValue( fxMesa
->Color
.MonoColor
);
734 fxMesa
->dirty
&= ~TDFX_UPLOAD_CONSTANT_COLOR
;
737 if ( fxMesa
->dirty
& TDFX_UPLOAD_LINE
) {
738 if (fxMesa
->glCtx
->Line
.SmoothFlag
&& fxMesa
->glCtx
->Line
.Width
== 1.0)
739 fxMesa
->Glide
.grEnable(GR_AA_ORDERED
);
741 fxMesa
->Glide
.grDisable(GR_AA_ORDERED
);
742 fxMesa
->dirty
&= ~TDFX_UPLOAD_LINE
;
745 if ( fxMesa
->dirty
& TDFX_UPLOAD_STENCIL
) {
746 if (fxMesa
->glCtx
->Stencil
.Enabled
) {
747 fxMesa
->Glide
.grEnable(GR_STENCIL_MODE_EXT
);
748 fxMesa
->Glide
.grStencilOp(fxMesa
->Stencil
.FailFunc
,
749 fxMesa
->Stencil
.ZFailFunc
,
750 fxMesa
->Stencil
.ZPassFunc
);
751 fxMesa
->Glide
.grStencilFunc(fxMesa
->Stencil
.Function
,
752 fxMesa
->Stencil
.RefValue
,
753 fxMesa
->Stencil
.ValueMask
);
754 fxMesa
->Glide
.grStencilMask(fxMesa
->Stencil
.WriteMask
);
757 fxMesa
->Glide
.grDisable(GR_STENCIL_MODE_EXT
);
759 fxMesa
->dirty
&= ~TDFX_UPLOAD_STENCIL
;
762 if ( fxMesa
->dirty
& TDFX_UPLOAD_VERTEX_LAYOUT
) {
763 fxMesa
->Glide
.grGlideSetVertexLayout( fxMesa
->layout
[fxMesa
->vertexFormat
] );
764 /* [dborca] enable fogcoord */
765 fxMesa
->Glide
.grVertexLayout(GR_PARAM_FOG_EXT
, TDFX_FOG_OFFSET
,
766 fxMesa
->Fog
.Mode
== GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT
);
767 fxMesa
->dirty
&= ~TDFX_UPLOAD_VERTEX_LAYOUT
;
770 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_ENV
) {
771 uploadTextureEnv(fxMesa
);
772 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_ENV
;
775 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_PARAMS
) {
776 uploadTextureParams(fxMesa
);
777 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_PARAMS
;
780 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_PALETTE
) {
781 if (fxMesa
->TexPalette
.Data
) {
782 fxMesa
->Glide
.grTexDownloadTable(fxMesa
->TexPalette
.Type
, fxMesa
->TexPalette
.Data
);
784 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_PALETTE
;
787 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_SOURCE
) {
788 uploadTextureSource(fxMesa
);
789 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_SOURCE
;
792 if ( fxMesa
->dirty
& TDFX_UPLOAD_TEXTURE_IMAGES
) {
793 uploadTextureImages(fxMesa
);
794 fxMesa
->dirty
&= ~TDFX_UPLOAD_TEXTURE_IMAGES
;
802 void tdfxInitRenderFuncs( struct dd_function_table
*functions
)
804 functions
->Clear
= tdfxClear
;
805 functions
->Finish
= tdfxFinish
;
806 functions
->Flush
= tdfxFlush
;