2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
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 shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 /* fxsetup.c - 3Dfx VooDoo rendering mode setup functions */
44 #include "main/enums.h"
45 #include "main/formats.h"
46 #include "main/texstore.h"
48 #include "tnl/t_context.h"
49 #include "swrast/swrast.h"
53 fxTexValidate(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
55 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
59 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
60 fprintf(stderr
, "fxTexValidate(NOP)\n");
65 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
66 fprintf(stderr
, "fxTexValidate(%p (%d))\n", (void *)tObj
, tObj
->Name
);
70 minl
= ti
->minLevel
= tObj
->BaseLevel
;
71 maxl
= ti
->maxLevel
= MIN2(tObj
->MaxLevel
, tObj
->Image
[0][0]->MaxLog2
);
73 #if FX_RESCALE_BIG_TEXURES_HACK
75 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
77 * Fake textures larger than HW supports:
78 * 1) we have mipmaps. Then we just push up to the first supported
79 * LOD. A possible drawback is that Mesa will ignore the skipped
80 * LODs on further texture handling.
81 * Will this interfere with GL_TEXTURE_[MIN|BASE]_LEVEL? How?
82 * 2) we don't have mipmaps. We need to rescale the big LOD in place.
83 * The above approach is somehow dumb! we might have rescaled
84 * once in TexImage2D to accomodate aspect ratio, and now we
85 * are rescaling again. The thing is, in TexImage2D we don't
86 * know whether we'll hit 1) or 2) by the time of validation.
88 if ((tObj
->MinFilter
== GL_NEAREST
) || (tObj
->MinFilter
== GL_LINEAR
)) {
90 struct gl_texture_image
*texImage
= tObj
->Image
[0][minl
];
91 tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
92 GLint _w
, _h
, maxSize
= 1 << fxMesa
->textureMaxLod
;
93 if ((mml
->width
> maxSize
) || (mml
->height
> maxSize
)) {
95 GLint texelBytes
= _mesa_get_format_bytes(texImage
->TexFormat
->MesaFormat
);
96 GLvoid
*texImage_Data
= texImage
->Data
;
97 _w
= MIN2(texImage
->Width
, maxSize
);
98 _h
= MIN2(texImage
->Height
, maxSize
);
99 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
100 fprintf(stderr
, "fxTexValidate: rescaling %d x %d -> %d x %d\n",
101 texImage
->Width
, texImage
->Height
, _w
, _h
);
103 /* we should leave these as is and... (!) */
104 texImage
->Width
= _w
;
105 texImage
->Height
= _h
;
106 fxTexGetInfo(_w
, _h
, NULL
, NULL
, NULL
, NULL
,
107 &(mml
->wScale
), &(mml
->hScale
));
110 texImage
->Data
= _mesa_malloc(_w
* _h
* texelBytes
);
111 _mesa_rescale_teximage2d(texelBytes
,
113 _w
* texelBytes
, /* dst stride */
114 mml
->width
, mml
->height
, /* src */
116 texImage_Data
/*src*/, texImage
->Data
/*dst*/ );
117 _mesa_free(texImage_Data
);
120 /* (!) ... and set mml->wScale = _w / texImage->Width */
124 if (maxl
- minl
> fxMesa
->textureMaxLod
) {
125 /* skip a certain number of LODs */
126 minl
+= maxl
- fxMesa
->textureMaxLod
;
127 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
128 fprintf(stderr
, "fxTexValidate: skipping %d LODs\n", minl
- ti
->minLevel
);
130 ti
->minLevel
= tObj
->BaseLevel
= minl
;
136 fxTexGetInfo(tObj
->Image
[0][minl
]->Width
, tObj
->Image
[0][minl
]->Height
,
137 &(FX_largeLodLog2(ti
->info
)), &(FX_aspectRatioLog2(ti
->info
)),
138 &(ti
->sScale
), &(ti
->tScale
),
141 if ((tObj
->MinFilter
!= GL_NEAREST
) && (tObj
->MinFilter
!= GL_LINEAR
))
142 fxTexGetInfo(tObj
->Image
[0][maxl
]->Width
, tObj
->Image
[0][maxl
]->Height
,
143 &(FX_smallLodLog2(ti
->info
)), NULL
,
144 NULL
, NULL
, NULL
, NULL
);
146 FX_smallLodLog2(ti
->info
) = FX_largeLodLog2(ti
->info
);
148 /* [dBorca] this is necessary because of fxDDCompressedTexImage2D */
150 struct gl_texture_image
*texImage
= tObj
->Image
[0][minl
];
151 tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
152 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
153 ti
->sScale
/= mml
->wScale
;
154 ti
->tScale
/= mml
->hScale
;
158 ti
->baseLevelInternalFormat
= tObj
->Image
[0][minl
]->Format
;
160 ti
->validated
= GL_TRUE
;
162 ti
->info
.data
= NULL
;
166 fxPrintUnitsMode(const char *msg
, GLuint mode
)
169 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
172 (mode
& FX_UM_E0_REPLACE
) ? "E0_REPLACE, " : "",
173 (mode
& FX_UM_E0_MODULATE
) ? "E0_MODULATE, " : "",
174 (mode
& FX_UM_E0_DECAL
) ? "E0_DECAL, " : "",
175 (mode
& FX_UM_E0_BLEND
) ? "E0_BLEND, " : "",
176 (mode
& FX_UM_E1_REPLACE
) ? "E1_REPLACE, " : "",
177 (mode
& FX_UM_E1_MODULATE
) ? "E1_MODULATE, " : "",
178 (mode
& FX_UM_E1_DECAL
) ? "E1_DECAL, " : "",
179 (mode
& FX_UM_E1_BLEND
) ? "E1_BLEND, " : "",
180 (mode
& FX_UM_E0_ALPHA
) ? "E0_ALPHA, " : "",
181 (mode
& FX_UM_E0_LUMINANCE
) ? "E0_LUMINANCE, " : "",
182 (mode
& FX_UM_E0_LUMINANCE_ALPHA
) ? "E0_LUMINANCE_ALPHA, " : "",
183 (mode
& FX_UM_E0_INTENSITY
) ? "E0_INTENSITY, " : "",
184 (mode
& FX_UM_E0_RGB
) ? "E0_RGB, " : "",
185 (mode
& FX_UM_E0_RGBA
) ? "E0_RGBA, " : "",
186 (mode
& FX_UM_E1_ALPHA
) ? "E1_ALPHA, " : "",
187 (mode
& FX_UM_E1_LUMINANCE
) ? "E1_LUMINANCE, " : "",
188 (mode
& FX_UM_E1_LUMINANCE_ALPHA
) ? "E1_LUMINANCE_ALPHA, " : "",
189 (mode
& FX_UM_E1_INTENSITY
) ? "E1_INTENSITY, " : "",
190 (mode
& FX_UM_E1_RGB
) ? "E1_RGB, " : "",
191 (mode
& FX_UM_E1_RGBA
) ? "E1_RGBA, " : "",
192 (mode
& FX_UM_COLOR_ITERATED
) ? "COLOR_ITERATED, " : "",
193 (mode
& FX_UM_COLOR_CONSTANT
) ? "COLOR_CONSTANT, " : "",
194 (mode
& FX_UM_ALPHA_ITERATED
) ? "ALPHA_ITERATED, " : "",
195 (mode
& FX_UM_ALPHA_CONSTANT
) ? "ALPHA_CONSTANT, " : "");
199 fxGetTexSetConfiguration(GLcontext
* ctx
,
200 struct gl_texture_object
*tObj0
,
201 struct gl_texture_object
*tObj1
)
203 GLuint unitsmode
= 0;
207 if ((ctx
->Light
.ShadeModel
== GL_SMOOTH
) || 1 ||
208 (ctx
->Point
.SmoothFlag
) ||
209 (ctx
->Line
.SmoothFlag
) ||
210 (ctx
->Polygon
.SmoothFlag
)) unitsmode
|= FX_UM_ALPHA_ITERATED
;
212 unitsmode
|= FX_UM_ALPHA_CONSTANT
;
214 if (ctx
->Light
.ShadeModel
== GL_SMOOTH
|| 1)
215 unitsmode
|= FX_UM_COLOR_ITERATED
;
217 unitsmode
|= FX_UM_COLOR_CONSTANT
;
222 OpenGL Feeds Texture 0 into Texture 1
223 Glide Feeds Texture 1 into Texture 0
226 tfxTexInfo
*ti0
= fxTMGetTexInfo(tObj0
);
228 switch (ti0
->baseLevelInternalFormat
) {
230 ifmt
|= FX_UM_E0_ALPHA
;
233 ifmt
|= FX_UM_E0_LUMINANCE
;
235 case GL_LUMINANCE_ALPHA
:
236 ifmt
|= FX_UM_E0_LUMINANCE_ALPHA
;
239 ifmt
|= FX_UM_E0_INTENSITY
;
242 ifmt
|= FX_UM_E0_RGB
;
245 ifmt
|= FX_UM_E0_RGBA
;
249 switch (ctx
->Texture
.Unit
[0].EnvMode
) {
251 envmode
|= FX_UM_E0_DECAL
;
254 envmode
|= FX_UM_E0_MODULATE
;
257 envmode
|= FX_UM_E0_REPLACE
;
260 envmode
|= FX_UM_E0_BLEND
;
263 envmode
|= FX_UM_E0_ADD
;
272 tfxTexInfo
*ti1
= fxTMGetTexInfo(tObj1
);
274 switch (ti1
->baseLevelInternalFormat
) {
276 ifmt
|= FX_UM_E1_ALPHA
;
279 ifmt
|= FX_UM_E1_LUMINANCE
;
281 case GL_LUMINANCE_ALPHA
:
282 ifmt
|= FX_UM_E1_LUMINANCE_ALPHA
;
285 ifmt
|= FX_UM_E1_INTENSITY
;
288 ifmt
|= FX_UM_E1_RGB
;
291 ifmt
|= FX_UM_E1_RGBA
;
298 switch (ctx
->Texture
.Unit
[1].EnvMode
) {
300 envmode
|= FX_UM_E1_DECAL
;
303 envmode
|= FX_UM_E1_MODULATE
;
306 envmode
|= FX_UM_E1_REPLACE
;
309 envmode
|= FX_UM_E1_BLEND
;
312 envmode
|= FX_UM_E1_ADD
;
320 unitsmode
|= (ifmt
| envmode
);
322 if (TDFX_DEBUG
& (VERBOSE_DRIVER
| VERBOSE_TEXTURE
))
323 fxPrintUnitsMode("fxGetTexSetConfiguration", unitsmode
);
328 /************************************************************************/
329 /************************* Rendering Mode SetUp *************************/
330 /************************************************************************/
332 /************************* Single Texture Set ***************************/
335 fxSetupSingleTMU_NoLock(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
)
337 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
340 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
341 fprintf(stderr
, "fxSetupSingleTMU_NoLock(%p (%d))\n", (void *)tObj
, tObj
->Name
);
344 ti
->lastTimeUsed
= fxMesa
->texBindNumber
;
346 /* Make sure we're not loaded incorrectly */
349 if (ti
->whichTMU
!= FX_TMU_SPLIT
)
350 fxTMMoveOutTM(fxMesa
, tObj
);
353 if (ti
->whichTMU
== FX_TMU_SPLIT
)
354 fxTMMoveOutTM(fxMesa
, tObj
);
358 /* Make sure we're loaded correctly */
361 fxTMMoveInTM_NoLock(fxMesa
, tObj
, FX_TMU_SPLIT
);
363 if (fxMesa
->haveTwoTMUs
) {
364 if (fxTMCheckStartAddr(fxMesa
, FX_TMU0
, ti
)) {
365 fxTMMoveInTM_NoLock(fxMesa
, tObj
, FX_TMU0
);
368 fxTMMoveInTM_NoLock(fxMesa
, tObj
, FX_TMU1
);
372 fxTMMoveInTM_NoLock(fxMesa
, tObj
, FX_TMU0
);
376 if (ti
->LODblend
&& ti
->whichTMU
== FX_TMU_SPLIT
) {
378 if ((ti
->info
.format
== GR_TEXFMT_P_8
)
379 && (!fxMesa
->haveGlobalPaletteTexture
)) {
380 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
381 fprintf(stderr
, "fxSetupSingleTMU_NoLock: uploading texture palette\n");
383 grTexDownloadTable(ti
->paltype
, &(ti
->palette
));
386 grTexClampMode(GR_TMU0
, ti
->sClamp
, ti
->tClamp
);
387 grTexClampMode(GR_TMU1
, ti
->sClamp
, ti
->tClamp
);
388 grTexFilterMode(GR_TMU0
, ti
->minFilt
, ti
->maxFilt
);
389 grTexFilterMode(GR_TMU1
, ti
->minFilt
, ti
->maxFilt
);
390 grTexMipMapMode(GR_TMU0
, ti
->mmMode
, ti
->LODblend
);
391 grTexMipMapMode(GR_TMU1
, ti
->mmMode
, ti
->LODblend
);
393 grTexSource(GR_TMU0
, ti
->tm
[FX_TMU0
]->startAddr
,
394 GR_MIPMAPLEVELMASK_ODD
, &(ti
->info
));
395 grTexSource(GR_TMU1
, ti
->tm
[FX_TMU1
]->startAddr
,
396 GR_MIPMAPLEVELMASK_EVEN
, &(ti
->info
));
399 if (ti
->whichTMU
== FX_TMU_BOTH
)
405 if ((ti
->info
.format
== GR_TEXFMT_P_8
)
406 && (!fxMesa
->haveGlobalPaletteTexture
)) {
407 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
408 fprintf(stderr
, "fxSetupSingleTMU_NoLock: uploading texture palette\n");
410 fxMesa
->Glide
.grTexDownloadTableExt(tmu
, ti
->paltype
, &(ti
->palette
));
413 /* KW: The alternative is to do the download to the other tmu. If
414 * we get to this point, I think it means we are thrashing the
415 * texture memory, so perhaps it's not a good idea.
417 if (ti
->LODblend
&& (TDFX_DEBUG
& VERBOSE_DRIVER
)) {
418 fprintf(stderr
, "fxSetupSingleTMU_NoLock: not blending texture - only one tmu\n");
421 grTexClampMode(tmu
, ti
->sClamp
, ti
->tClamp
);
422 grTexFilterMode(tmu
, ti
->minFilt
, ti
->maxFilt
);
423 grTexMipMapMode(tmu
, ti
->mmMode
, FXFALSE
);
425 grTexSource(tmu
, ti
->tm
[tmu
]->startAddr
, GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
430 fxSelectSingleTMUSrc_NoLock(fxMesaContext fxMesa
, GLint tmu
, FxBool LODblend
)
432 struct tdfx_texcombine tex0
, tex1
;
434 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
435 fprintf(stderr
, "fxSelectSingleTMUSrc_NoLock(%d, %d)\n", tmu
, LODblend
);
438 tex0
.InvertRGB
= FXFALSE
;
439 tex0
.InvertAlpha
= FXFALSE
;
440 tex1
.InvertRGB
= FXFALSE
;
441 tex1
.InvertAlpha
= FXFALSE
;
444 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND
;
445 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION
;
446 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND
;
447 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION
;
449 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
450 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
451 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
452 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
454 fxMesa
->tmuSrc
= FX_TMU_SPLIT
;
457 if (tmu
!= FX_TMU1
) {
458 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
459 tex0
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
460 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
461 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
463 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
464 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
465 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
466 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
468 fxMesa
->tmuSrc
= FX_TMU0
;
471 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
472 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
473 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
474 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
476 /* correct values to set TMU0 in passthrough mode */
477 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND
;
478 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
479 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND
;
480 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
482 fxMesa
->tmuSrc
= FX_TMU1
;
486 grTexCombine(GR_TMU0
,
493 if (fxMesa
->haveTwoTMUs
) {
494 grTexCombine(GR_TMU1
,
505 fxSetupTextureSingleTMU_NoLock(GLcontext
* ctx
, GLuint textureset
)
507 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
508 struct tdfx_combine alphaComb
, colorComb
;
509 GrCombineLocal_t localc
, locala
;
513 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[textureset
]._Current
;
516 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
517 fprintf(stderr
, "fxSetupTextureSingleTMU_NoLock(%d)\n", textureset
);
520 ti
= fxTMGetTexInfo(tObj
);
522 fxTexValidate(ctx
, tObj
);
524 fxSetupSingleTMU_NoLock(fxMesa
, tObj
);
526 if (ti
->whichTMU
== FX_TMU_BOTH
)
530 if (fxMesa
->tmuSrc
!= tmu
)
531 fxSelectSingleTMUSrc_NoLock(fxMesa
, tmu
, ti
->LODblend
);
533 if (textureset
== 0 || !fxMesa
->haveTwoTMUs
)
534 unitsmode
= fxGetTexSetConfiguration(ctx
, tObj
, NULL
);
536 unitsmode
= fxGetTexSetConfiguration(ctx
, NULL
, tObj
);
538 /* if(fxMesa->lastUnitsMode==unitsmode) */
541 fxMesa
->lastUnitsMode
= unitsmode
;
543 fxMesa
->stw_hint_state
= 0;
544 FX_grHints_NoLock(GR_HINT_STWHINT
, 0);
546 ifmt
= ti
->baseLevelInternalFormat
;
548 if (unitsmode
& FX_UM_ALPHA_ITERATED
)
549 locala
= GR_COMBINE_LOCAL_ITERATED
;
551 locala
= GR_COMBINE_LOCAL_CONSTANT
;
553 if (unitsmode
& FX_UM_COLOR_ITERATED
)
554 localc
= GR_COMBINE_LOCAL_ITERATED
;
556 localc
= GR_COMBINE_LOCAL_CONSTANT
;
558 if (TDFX_DEBUG
& (VERBOSE_DRIVER
| VERBOSE_TEXTURE
))
559 fprintf(stderr
, "fxSetupTextureSingleTMU_NoLock: envmode is %s\n",
560 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[textureset
].EnvMode
));
562 alphaComb
.Local
= locala
;
563 alphaComb
.Invert
= FXFALSE
;
564 colorComb
.Local
= localc
;
565 colorComb
.Invert
= FXFALSE
;
567 switch (ctx
->Texture
.Unit
[textureset
].EnvMode
) {
569 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
570 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
571 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
573 colorComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
574 colorComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_ALPHA
;
575 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
578 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
579 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
580 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
582 if (ifmt
== GL_ALPHA
) {
583 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
584 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
585 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
587 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
588 colorComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
589 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
593 if (ifmt
== GL_LUMINANCE
|| ifmt
== GL_RGB
) {
595 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
596 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
597 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
599 else if (ifmt
== GL_INTENSITY
) {
600 /* Av = Af * (1 - It) + Ac * It */
601 alphaComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
602 alphaComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_ALPHA
;
603 alphaComb
.Other
= GR_COMBINE_OTHER_CONSTANT
;
607 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
608 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
609 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
612 if (ifmt
== GL_ALPHA
) {
613 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
614 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
615 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
617 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo2
) {
618 colorComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
619 colorComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_RGB
;
620 colorComb
.Other
= GR_COMBINE_OTHER_CONSTANT
;
621 } else if (ifmt
== GL_INTENSITY
) {
622 /* just a hack: RGB == ALPHA */
623 colorComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
624 colorComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_ALPHA
;
625 colorComb
.Other
= GR_COMBINE_OTHER_CONSTANT
;
627 /* Only Voodoo^2 can GL_BLEND (GR_COMBINE_FACTOR_TEXTURE_RGB)
628 * These settings assume that the TexEnv color is black and
629 * incoming fragment color is white.
631 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
632 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
633 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
634 colorComb
.Invert
= FXTRUE
;
635 _mesa_problem(NULL
, "can't GL_BLEND with SST1");
639 grConstantColorValue(
640 (((GLuint
)(ctx
->Texture
.Unit
[textureset
].EnvColor
[0] * 255.0f
)) ) |
641 (((GLuint
)(ctx
->Texture
.Unit
[textureset
].EnvColor
[1] * 255.0f
)) << 8) |
642 (((GLuint
)(ctx
->Texture
.Unit
[textureset
].EnvColor
[2] * 255.0f
)) << 16) |
643 (((GLuint
)(ctx
->Texture
.Unit
[textureset
].EnvColor
[3] * 255.0f
)) << 24));
646 if ((ifmt
== GL_RGB
) || (ifmt
== GL_LUMINANCE
)) {
647 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
648 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
649 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
651 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
652 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
653 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
656 if (ifmt
== GL_ALPHA
) {
657 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
658 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
659 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
661 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
662 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
663 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
667 if (ifmt
== GL_ALPHA
||
668 ifmt
== GL_LUMINANCE_ALPHA
||
670 /* product of texel and fragment alpha */
671 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
672 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
673 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
675 else if (ifmt
== GL_LUMINANCE
|| ifmt
== GL_RGB
) {
676 /* fragment alpha is unchanged */
677 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
678 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
679 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
682 /* sum of texel and fragment alpha */
683 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
684 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
685 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
688 if (ifmt
== GL_ALPHA
) {
690 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
691 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
692 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
695 /* sum of texel and fragment rgb */
696 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
697 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
698 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
702 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
703 fprintf(stderr
, "fxSetupTextureSingleTMU_NoLock: %x Texture.EnvMode not yet supported\n",
704 ctx
->Texture
.Unit
[textureset
].EnvMode
);
709 grAlphaCombine(alphaComb
.Function
,
714 grColorCombine(colorComb
.Function
,
723 fxSetupTextureSingleTMU(GLcontext
* ctx
, GLuint textureset
)
726 fxSetupTextureSingleTMU_NoLock(ctx
, textureset
);
732 /************************* Double Texture Set ***************************/
735 fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa
,
736 struct gl_texture_object
*tObj0
,
737 struct gl_texture_object
*tObj1
)
739 #define T0_NOT_IN_TMU 0x01
740 #define T1_NOT_IN_TMU 0x02
741 #define T0_IN_TMU0 0x04
742 #define T1_IN_TMU0 0x08
743 #define T0_IN_TMU1 0x10
744 #define T1_IN_TMU1 0x20
746 tfxTexInfo
*ti0
= fxTMGetTexInfo(tObj0
);
747 tfxTexInfo
*ti1
= fxTMGetTexInfo(tObj1
);
749 int tmu0
= 0, tmu1
= 1;
751 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
752 fprintf(stderr
, "fxSetupDoubleTMU_NoLock(...)\n");
755 /* We shouldn't need to do this. There is something wrong with
756 mutlitexturing when the TMUs are swapped. So, we're forcing
757 them to always be loaded correctly. !!! */
758 if (ti0
->whichTMU
== FX_TMU1
)
759 fxTMMoveOutTM_NoLock(fxMesa
, tObj0
);
760 if (ti1
->whichTMU
== FX_TMU0
)
761 fxTMMoveOutTM_NoLock(fxMesa
, tObj1
);
764 switch (ti0
->whichTMU
) {
766 tstate
|= T0_IN_TMU0
;
769 tstate
|= T0_IN_TMU1
;
772 tstate
|= T0_IN_TMU0
| T0_IN_TMU1
;
775 tstate
|= T0_NOT_IN_TMU
;
780 tstate
|= T0_NOT_IN_TMU
;
783 switch (ti1
->whichTMU
) {
785 tstate
|= T1_IN_TMU0
;
788 tstate
|= T1_IN_TMU1
;
791 tstate
|= T1_IN_TMU0
| T1_IN_TMU1
;
794 tstate
|= T1_NOT_IN_TMU
;
799 tstate
|= T1_NOT_IN_TMU
;
801 ti0
->lastTimeUsed
= fxMesa
->texBindNumber
;
802 ti1
->lastTimeUsed
= fxMesa
->texBindNumber
;
804 /* Move texture maps into TMUs */
806 if (!(((tstate
& T0_IN_TMU0
) && (tstate
& T1_IN_TMU1
)) ||
807 ((tstate
& T0_IN_TMU1
) && (tstate
& T1_IN_TMU0
)))) {
809 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU_BOTH
);
811 /* Find the minimal way to correct the situation */
812 if ((tstate
& T0_IN_TMU0
) || (tstate
& T1_IN_TMU1
)) {
813 /* We have one in the standard order, setup the other */
814 if (tstate
& T0_IN_TMU0
) { /* T0 is in TMU0, put T1 in TMU1 */
815 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU1
);
818 fxTMMoveInTM_NoLock(fxMesa
, tObj0
, FX_TMU0
);
820 /* tmu0 and tmu1 are setup */
822 else if ((tstate
& T0_IN_TMU1
) || (tstate
& T1_IN_TMU0
)) {
823 /* we have one in the reverse order, setup the other */
824 if (tstate
& T1_IN_TMU0
) { /* T1 is in TMU0, put T0 in TMU1 */
825 fxTMMoveInTM_NoLock(fxMesa
, tObj0
, FX_TMU1
);
828 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU0
);
833 else { /* Nothing is loaded */
834 fxTMMoveInTM_NoLock(fxMesa
, tObj0
, FX_TMU0
);
835 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU1
);
836 /* tmu0 and tmu1 are setup */
841 /* [dBorca] Hack alert:
842 * we put these in reverse order, so that if we can't
843 * do _REAL_ pointcast, the TMU0 table gets broadcasted
845 if (!fxMesa
->haveGlobalPaletteTexture
) {
847 if (ti1
->info
.format
== GR_TEXFMT_P_8
) {
848 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
849 fprintf(stderr
, "fxSetupDoubleTMU_NoLock: uploading texture palette for TMU1\n");
851 fxMesa
->Glide
.grTexDownloadTableExt(ti1
->whichTMU
, ti1
->paltype
, &(ti1
->palette
));
853 if (ti0
->info
.format
== GR_TEXFMT_P_8
) {
854 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
855 fprintf(stderr
, "fxSetupDoubleTMU_NoLock: uploading texture palette for TMU0\n");
857 fxMesa
->Glide
.grTexDownloadTableExt(ti0
->whichTMU
, ti0
->paltype
, &(ti0
->palette
));
861 grTexSource(tmu0
, ti0
->tm
[tmu0
]->startAddr
,
862 GR_MIPMAPLEVELMASK_BOTH
, &(ti0
->info
));
863 grTexClampMode(tmu0
, ti0
->sClamp
, ti0
->tClamp
);
864 grTexFilterMode(tmu0
, ti0
->minFilt
, ti0
->maxFilt
);
865 grTexMipMapMode(tmu0
, ti0
->mmMode
, FXFALSE
);
867 grTexSource(tmu1
, ti1
->tm
[tmu1
]->startAddr
,
868 GR_MIPMAPLEVELMASK_BOTH
, &(ti1
->info
));
869 grTexClampMode(tmu1
, ti1
->sClamp
, ti1
->tClamp
);
870 grTexFilterMode(tmu1
, ti1
->minFilt
, ti1
->maxFilt
);
871 grTexMipMapMode(tmu1
, ti1
->mmMode
, FXFALSE
);
882 fxSetupTextureDoubleTMU_NoLock(GLcontext
* ctx
)
884 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
885 struct tdfx_combine alphaComb
, colorComb
;
886 struct tdfx_texcombine tex0
, tex1
;
887 GrCombineLocal_t localc
, locala
;
888 tfxTexInfo
*ti0
, *ti1
;
889 struct gl_texture_object
*tObj0
= ctx
->Texture
.Unit
[1]._Current
;
890 struct gl_texture_object
*tObj1
= ctx
->Texture
.Unit
[0]._Current
;
891 GLuint envmode
, ifmt
, unitsmode
;
892 int tmu0
= 0, tmu1
= 1;
894 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
895 fprintf(stderr
, "fxSetupTextureDoubleTMU_NoLock(...)\n");
898 ti0
= fxTMGetTexInfo(tObj0
);
899 fxTexValidate(ctx
, tObj0
);
901 ti1
= fxTMGetTexInfo(tObj1
);
902 fxTexValidate(ctx
, tObj1
);
904 fxSetupDoubleTMU_NoLock(fxMesa
, tObj0
, tObj1
);
906 unitsmode
= fxGetTexSetConfiguration(ctx
, tObj0
, tObj1
);
908 /* if(fxMesa->lastUnitsMode==unitsmode) */
911 fxMesa
->lastUnitsMode
= unitsmode
;
913 fxMesa
->stw_hint_state
|= GR_STWHINT_ST_DIFF_TMU1
;
914 FX_grHints_NoLock(GR_HINT_STWHINT
, fxMesa
->stw_hint_state
);
916 envmode
= unitsmode
& FX_UM_E_ENVMODE
;
917 ifmt
= unitsmode
& FX_UM_E_IFMT
;
919 if (unitsmode
& FX_UM_ALPHA_ITERATED
)
920 locala
= GR_COMBINE_LOCAL_ITERATED
;
922 locala
= GR_COMBINE_LOCAL_CONSTANT
;
924 if (unitsmode
& FX_UM_COLOR_ITERATED
)
925 localc
= GR_COMBINE_LOCAL_ITERATED
;
927 localc
= GR_COMBINE_LOCAL_CONSTANT
;
930 if (TDFX_DEBUG
& (VERBOSE_DRIVER
| VERBOSE_TEXTURE
))
931 fprintf(stderr
, "fxSetupTextureDoubleTMU_NoLock: envmode is %s/%s\n",
932 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[0].EnvMode
),
933 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[1].EnvMode
));
936 if ((ti0
->whichTMU
== FX_TMU1
) || (ti1
->whichTMU
== FX_TMU0
)) {
940 fxMesa
->tmuSrc
= FX_TMU_BOTH
;
942 tex0
.InvertRGB
= FXFALSE
;
943 tex0
.InvertAlpha
= FXFALSE
;
944 tex1
.InvertRGB
= FXFALSE
;
945 tex1
.InvertAlpha
= FXFALSE
;
946 alphaComb
.Local
= locala
;
947 alphaComb
.Invert
= FXFALSE
;
948 colorComb
.Local
= localc
;
949 colorComb
.Invert
= FXFALSE
;
952 case (FX_UM_E0_MODULATE
| FX_UM_E1_MODULATE
):
954 GLboolean isalpha
[FX_NUM_TMU
];
956 isalpha
[tmu0
] = (ti0
->baseLevelInternalFormat
== GL_ALPHA
);
957 isalpha
[tmu1
] = (ti1
->baseLevelInternalFormat
== GL_ALPHA
);
959 if (isalpha
[FX_TMU1
]) {
960 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
961 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
962 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
963 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
964 tex1
.InvertRGB
= FXTRUE
;
966 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
967 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
968 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
969 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
972 if (isalpha
[FX_TMU0
]) {
973 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
974 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
975 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
976 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
978 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
979 tex0
.FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
980 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
981 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
984 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
985 colorComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
986 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
988 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
989 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
990 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
993 case (FX_UM_E0_REPLACE
| FX_UM_E1_BLEND
): /* Only for GLQuake */
994 if (tmu0
== FX_TMU1
) {
995 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
996 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
997 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
998 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
999 tex1
.InvertRGB
= FXTRUE
;
1001 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1002 tex0
.FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1003 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1004 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1007 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1008 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1009 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1010 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1012 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1013 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
;
1014 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1015 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
;
1018 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1019 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
1020 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
1022 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1023 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1024 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1026 case (FX_UM_E0_REPLACE
| FX_UM_E1_MODULATE
): /* Quake 2 and 3 */
1027 if (tmu1
== FX_TMU1
) {
1028 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1029 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1030 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
1031 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1032 tex1
.InvertAlpha
= FXTRUE
;
1034 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1035 tex0
.FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1036 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1037 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1040 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1041 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1042 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1043 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1045 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1046 tex0
.FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1047 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1048 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1051 if (ti0
->baseLevelInternalFormat
== GL_RGB
) {
1052 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1053 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
1054 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
1056 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1057 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1058 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
1061 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1062 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1063 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1067 case (FX_UM_E0_MODULATE
| FX_UM_E1_ADD
): /* Quake 3 Sky */
1069 GLboolean isalpha
[FX_NUM_TMU
];
1071 isalpha
[tmu0
] = (ti0
->baseLevelInternalFormat
== GL_ALPHA
);
1072 isalpha
[tmu1
] = (ti1
->baseLevelInternalFormat
== GL_ALPHA
);
1074 if (isalpha
[FX_TMU1
]) {
1075 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1076 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1077 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1078 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1079 tex1
.InvertRGB
= FXTRUE
;
1081 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1082 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1083 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1084 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1087 if (isalpha
[FX_TMU0
]) {
1088 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1089 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1090 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1091 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1093 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1094 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1095 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1096 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1099 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1100 colorComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1101 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1103 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1104 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1105 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1109 case (FX_UM_E0_REPLACE
| FX_UM_E1_ADD
): /* Vulpine Sky */
1111 GLboolean isalpha
[FX_NUM_TMU
];
1113 isalpha
[tmu0
] = (ti0
->baseLevelInternalFormat
== GL_ALPHA
);
1114 isalpha
[tmu1
] = (ti1
->baseLevelInternalFormat
== GL_ALPHA
);
1116 if (isalpha
[FX_TMU1
]) {
1117 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1118 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1119 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1120 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1121 tex1
.InvertRGB
= FXTRUE
;
1123 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1124 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1125 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1126 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1129 if (isalpha
[FX_TMU0
]) {
1130 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1131 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1132 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1133 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1135 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1136 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1137 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1138 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1141 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1142 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1143 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1145 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1146 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1147 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1151 case (FX_UM_E0_MODULATE
| FX_UM_E1_REPLACE
): /* Homeworld2 */
1153 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1154 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1155 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
1156 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1158 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1159 tex0
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1160 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1161 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1163 if (ifmt
& (FX_UM_E0_RGB
| FX_UM_E0_LUMINANCE
)) {
1164 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1165 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
1166 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
1168 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1169 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1170 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1173 if (ifmt
& FX_UM_E0_ALPHA
) {
1174 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1175 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
1176 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
1178 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1179 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1180 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1185 fprintf(stderr
, "fxSetupTextureDoubleTMU_NoLock: Unexpected dual texture mode encountered\n");
1189 grAlphaCombine(alphaComb
.Function
,
1194 grColorCombine(colorComb
.Function
,
1199 grTexCombine(GR_TMU0
,
1206 grTexCombine(GR_TMU1
,
1215 /************************* No Texture ***************************/
1218 fxSetupTextureNone_NoLock(GLcontext
* ctx
)
1220 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1221 GrCombineLocal_t localc
, locala
;
1223 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
1224 fprintf(stderr
, "fxSetupTextureNone_NoLock(...)\n");
1227 if ((ctx
->Light
.ShadeModel
== GL_SMOOTH
) || 1 ||
1228 (ctx
->Point
.SmoothFlag
) ||
1229 (ctx
->Line
.SmoothFlag
) ||
1230 (ctx
->Polygon
.SmoothFlag
)) locala
= GR_COMBINE_LOCAL_ITERATED
;
1232 locala
= GR_COMBINE_LOCAL_CONSTANT
;
1234 if (ctx
->Light
.ShadeModel
== GL_SMOOTH
|| 1)
1235 localc
= GR_COMBINE_LOCAL_ITERATED
;
1237 localc
= GR_COMBINE_LOCAL_CONSTANT
;
1239 grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL
,
1240 GR_COMBINE_FACTOR_NONE
,
1242 GR_COMBINE_OTHER_NONE
,
1245 grColorCombine(GR_COMBINE_FUNCTION_LOCAL
,
1246 GR_COMBINE_FACTOR_NONE
,
1248 GR_COMBINE_OTHER_NONE
,
1251 fxMesa
->lastUnitsMode
= FX_UM_NONE
;
1254 #include "fxsetup.h"
1256 /************************************************************************/
1257 /************************** Texture Mode SetUp **************************/
1258 /************************************************************************/
1261 fxSetupTexture_NoLock(GLcontext
* ctx
)
1263 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1265 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
1266 fprintf(stderr
, "fxSetupTexture_NoLock(...)\n");
1269 if (fxMesa
->HaveCmbExt
) {
1270 /* Texture Combine, Color Combine and Alpha Combine. */
1271 if ((ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) &&
1272 (ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) &&
1273 fxMesa
->haveTwoTMUs
) {
1274 fxSetupTextureDoubleTMUNapalm_NoLock(ctx
);
1276 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
1277 fxSetupTextureSingleTMUNapalm_NoLock(ctx
, 0);
1279 else if (ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
1280 fxSetupTextureSingleTMUNapalm_NoLock(ctx
, 1);
1283 fxSetupTextureNoneNapalm_NoLock(ctx
);
1286 /* Texture Combine, Color Combine and Alpha Combine. */
1287 if ((ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) &&
1288 (ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) &&
1289 fxMesa
->haveTwoTMUs
) {
1290 fxSetupTextureDoubleTMU_NoLock(ctx
);
1292 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
1293 fxSetupTextureSingleTMU_NoLock(ctx
, 0);
1295 else if (ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
1296 fxSetupTextureSingleTMU_NoLock(ctx
, 1);
1299 fxSetupTextureNone_NoLock(ctx
);
1305 fxSetupTexture(GLcontext
* ctx
)
1308 fxSetupTexture_NoLock(ctx
);
1312 /************************************************************************/
1313 /**************************** Blend SetUp *******************************/
1314 /************************************************************************/
1317 fxDDBlendFuncSeparate(GLcontext
* ctx
, GLenum sfactor
, GLenum dfactor
, GLenum asfactor
, GLenum adfactor
)
1319 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1320 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1321 GLboolean isNapalm
= (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
);
1322 GLboolean have32bpp
= (fxMesa
->colDepth
== 32);
1323 GLboolean haveAlpha
= fxMesa
->haveHwAlpha
;
1324 GrAlphaBlendFnc_t sfact
, dfact
, asfact
, adfact
;
1327 * 15/16 BPP alpha channel alpha blending modes
1331 * 32 BPP alpha channel alpha blending modes
1333 * 0x1 ASRC_ALPHA Source alpha
1334 * 0x3 ADST_ALPHA Destination alpha
1336 * 0x5 AOMSRC_ALPHA 1 - Source alpha
1337 * 0x7 AOMDST_ALPHA 1 - Destination alpha
1339 * If we don't have HW alpha buffer:
1341 * ONE_MINUS_DST_ALPHA == 0
1342 * Unsupported modes are:
1343 * 1 if used as src blending factor
1344 * 0 if used as dst blending factor
1349 sfact
= GR_BLEND_ZERO
;
1352 sfact
= GR_BLEND_ONE
;
1355 sfact
= GR_BLEND_DST_COLOR
;
1357 case GL_ONE_MINUS_DST_COLOR
:
1358 sfact
= GR_BLEND_ONE_MINUS_DST_COLOR
;
1361 sfact
= GR_BLEND_SRC_ALPHA
;
1363 case GL_ONE_MINUS_SRC_ALPHA
:
1364 sfact
= GR_BLEND_ONE_MINUS_SRC_ALPHA
;
1367 sfact
= haveAlpha
? GR_BLEND_DST_ALPHA
: GR_BLEND_ONE
/*bad*/;
1369 case GL_ONE_MINUS_DST_ALPHA
:
1370 sfact
= haveAlpha
? GR_BLEND_ONE_MINUS_DST_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1372 case GL_SRC_ALPHA_SATURATE
:
1373 sfact
= GR_BLEND_ALPHA_SATURATE
;
1377 sfact
= GR_BLEND_SAME_COLOR_EXT
;
1380 case GL_ONE_MINUS_SRC_COLOR
:
1382 sfact
= GR_BLEND_ONE_MINUS_SAME_COLOR_EXT
;
1386 sfact
= GR_BLEND_ONE
;
1392 asfact
= GR_BLEND_ZERO
;
1395 asfact
= GR_BLEND_ONE
;
1399 asfact
= have32bpp
? GR_BLEND_SRC_ALPHA
: GR_BLEND_ONE
/*bad*/;
1401 case GL_ONE_MINUS_SRC_COLOR
:
1402 case GL_ONE_MINUS_SRC_ALPHA
:
1403 asfact
= have32bpp
? GR_BLEND_ONE_MINUS_SRC_ALPHA
: GR_BLEND_ONE
/*bad*/;
1407 asfact
= (have32bpp
&& haveAlpha
) ? GR_BLEND_DST_ALPHA
: GR_BLEND_ONE
/*bad*/;
1409 case GL_ONE_MINUS_DST_COLOR
:
1410 case GL_ONE_MINUS_DST_ALPHA
:
1411 asfact
= (have32bpp
&& haveAlpha
) ? GR_BLEND_ONE_MINUS_DST_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1413 case GL_SRC_ALPHA_SATURATE
:
1414 asfact
= GR_BLEND_ONE
;
1417 asfact
= GR_BLEND_ONE
;
1423 dfact
= GR_BLEND_ZERO
;
1426 dfact
= GR_BLEND_ONE
;
1429 dfact
= GR_BLEND_SRC_COLOR
;
1431 case GL_ONE_MINUS_SRC_COLOR
:
1432 dfact
= GR_BLEND_ONE_MINUS_SRC_COLOR
;
1435 dfact
= GR_BLEND_SRC_ALPHA
;
1437 case GL_ONE_MINUS_SRC_ALPHA
:
1438 dfact
= GR_BLEND_ONE_MINUS_SRC_ALPHA
;
1441 dfact
= haveAlpha
? GR_BLEND_DST_ALPHA
: GR_BLEND_ONE
/*bad*/;
1443 case GL_ONE_MINUS_DST_ALPHA
:
1444 dfact
= haveAlpha
? GR_BLEND_ONE_MINUS_DST_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1448 dfact
= GR_BLEND_SAME_COLOR_EXT
;
1451 case GL_ONE_MINUS_DST_COLOR
:
1453 dfact
= GR_BLEND_ONE_MINUS_SAME_COLOR_EXT
;
1457 dfact
= GR_BLEND_ZERO
;
1463 adfact
= GR_BLEND_ZERO
;
1466 adfact
= GR_BLEND_ONE
;
1470 adfact
= have32bpp
? GR_BLEND_SRC_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1472 case GL_ONE_MINUS_SRC_COLOR
:
1473 case GL_ONE_MINUS_SRC_ALPHA
:
1474 adfact
= have32bpp
? GR_BLEND_ONE_MINUS_SRC_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1478 adfact
= (have32bpp
&& haveAlpha
) ? GR_BLEND_DST_ALPHA
: GR_BLEND_ONE
/*bad*/;
1480 case GL_ONE_MINUS_DST_COLOR
:
1481 case GL_ONE_MINUS_DST_ALPHA
:
1482 adfact
= (have32bpp
&& haveAlpha
) ? GR_BLEND_ONE_MINUS_DST_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1485 adfact
= GR_BLEND_ZERO
;
1489 if ((sfact
!= us
->blendSrcFuncRGB
) || (asfact
!= us
->blendSrcFuncAlpha
)) {
1490 us
->blendSrcFuncRGB
= sfact
;
1491 us
->blendSrcFuncAlpha
= asfact
;
1492 fxMesa
->new_state
|= FX_NEW_BLEND
;
1495 if ((dfact
!= us
->blendDstFuncRGB
) || (adfact
!= us
->blendDstFuncAlpha
)) {
1496 us
->blendDstFuncRGB
= dfact
;
1497 us
->blendDstFuncAlpha
= adfact
;
1498 fxMesa
->new_state
|= FX_NEW_BLEND
;
1503 fxDDBlendEquationSeparate(GLcontext
* ctx
, GLenum modeRGB
, GLenum modeA
)
1505 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1506 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1511 q
= GR_BLEND_OP_ADD
;
1513 case GL_FUNC_SUBTRACT
:
1514 q
= GR_BLEND_OP_SUB
;
1516 case GL_FUNC_REVERSE_SUBTRACT
:
1517 q
= GR_BLEND_OP_REVSUB
;
1522 if (q
!= us
->blendEqRGB
) {
1524 fxMesa
->new_state
|= FX_NEW_BLEND
;
1529 q
= GR_BLEND_OP_ADD
;
1531 case GL_FUNC_SUBTRACT
:
1532 q
= GR_BLEND_OP_SUB
;
1534 case GL_FUNC_REVERSE_SUBTRACT
:
1535 q
= GR_BLEND_OP_REVSUB
;
1538 q
= us
->blendEqAlpha
;
1540 if (q
!= us
->blendEqAlpha
) {
1541 us
->blendEqAlpha
= q
;
1542 fxMesa
->new_state
|= FX_NEW_BLEND
;
1547 fxSetupBlend(GLcontext
* ctx
)
1549 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1550 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1552 if (fxMesa
->HavePixExt
) {
1553 if (us
->blendEnabled
) {
1554 fxMesa
->Glide
.grAlphaBlendFunctionExt(us
->blendSrcFuncRGB
, us
->blendDstFuncRGB
,
1556 us
->blendSrcFuncAlpha
, us
->blendDstFuncAlpha
,
1559 fxMesa
->Glide
.grAlphaBlendFunctionExt(GR_BLEND_ONE
, GR_BLEND_ZERO
,
1561 GR_BLEND_ONE
, GR_BLEND_ZERO
,
1565 if (us
->blendEnabled
) {
1566 grAlphaBlendFunction(us
->blendSrcFuncRGB
, us
->blendDstFuncRGB
,
1567 us
->blendSrcFuncAlpha
, us
->blendDstFuncAlpha
);
1569 grAlphaBlendFunction(GR_BLEND_ONE
, GR_BLEND_ZERO
,
1570 GR_BLEND_ONE
, GR_BLEND_ZERO
);
1575 /************************************************************************/
1576 /************************** Alpha Test SetUp ****************************/
1577 /************************************************************************/
1580 fxDDAlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
1582 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1583 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1586 (us
->alphaTestFunc
!= func
)
1588 (us
->alphaTestRefValue
!= ref
)
1590 us
->alphaTestFunc
= func
;
1591 us
->alphaTestRefValue
= ref
;
1592 fxMesa
->new_state
|= FX_NEW_ALPHA
;
1597 fxSetupAlphaTest(GLcontext
* ctx
)
1599 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1600 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1602 if (us
->alphaTestEnabled
) {
1603 GrAlpha_t ref
= (GLint
) (us
->alphaTestRefValue
* 255.0);
1604 grAlphaTestFunction(us
->alphaTestFunc
- GL_NEVER
+ GR_CMP_NEVER
);
1605 grAlphaTestReferenceValue(ref
);
1608 grAlphaTestFunction(GR_CMP_ALWAYS
);
1611 /************************************************************************/
1612 /************************** Depth Test SetUp ****************************/
1613 /************************************************************************/
1616 fxDDDepthFunc(GLcontext
* ctx
, GLenum func
)
1618 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1619 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1621 if (us
->depthTestFunc
!= func
) {
1622 us
->depthTestFunc
= func
;
1623 fxMesa
->new_state
|= FX_NEW_DEPTH
;
1628 fxDDDepthMask(GLcontext
* ctx
, GLboolean flag
)
1630 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1631 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1633 if (flag
!= us
->depthMask
) {
1634 us
->depthMask
= flag
;
1635 fxMesa
->new_state
|= FX_NEW_DEPTH
;
1640 fxSetupDepthTest(GLcontext
* ctx
)
1642 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1643 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1645 if (us
->depthTestEnabled
) {
1646 grDepthBufferFunction(us
->depthTestFunc
- GL_NEVER
+ GR_CMP_NEVER
);
1647 grDepthMask(us
->depthMask
);
1650 grDepthBufferFunction(GR_CMP_ALWAYS
);
1651 grDepthMask(FXFALSE
);
1655 /************************************************************************/
1656 /************************** Stencil SetUp *******************************/
1657 /************************************************************************/
1659 static GrStencil_t
convertGLStencilOp( GLenum op
)
1663 return GR_STENCILOP_KEEP
;
1665 return GR_STENCILOP_ZERO
;
1667 return GR_STENCILOP_REPLACE
;
1669 return GR_STENCILOP_INCR_CLAMP
;
1671 return GR_STENCILOP_DECR_CLAMP
;
1673 return GR_STENCILOP_INVERT
;
1674 case GL_INCR_WRAP_EXT
:
1675 return GR_STENCILOP_INCR_WRAP
;
1676 case GL_DECR_WRAP_EXT
:
1677 return GR_STENCILOP_DECR_WRAP
;
1679 _mesa_problem( NULL
, "bad stencil op in convertGLStencilOp" );
1681 return GR_STENCILOP_KEEP
; /* never get, silence compiler warning */
1685 fxDDStencilFuncSeparate (GLcontext
*ctx
, GLenum face
, GLenum func
,
1686 GLint ref
, GLuint mask
)
1688 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1689 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1691 if (ctx
->Stencil
.ActiveFace
) {
1696 (us
->stencilFunction
!= func
)
1698 (us
->stencilRefValue
!= ref
)
1700 (us
->stencilValueMask
!= mask
)
1702 us
->stencilFunction
= func
;
1703 us
->stencilRefValue
= ref
;
1704 us
->stencilValueMask
= mask
;
1705 fxMesa
->new_state
|= FX_NEW_STENCIL
;
1710 fxDDStencilMaskSeparate (GLcontext
*ctx
, GLenum face
, GLuint mask
)
1712 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1713 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1715 if (ctx
->Stencil
.ActiveFace
) {
1719 if (us
->stencilWriteMask
!= mask
) {
1720 us
->stencilWriteMask
= mask
;
1721 fxMesa
->new_state
|= FX_NEW_STENCIL
;
1726 fxDDStencilOpSeparate (GLcontext
*ctx
, GLenum face
, GLenum sfail
,
1727 GLenum zfail
, GLenum zpass
)
1729 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1730 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1732 if (ctx
->Stencil
.ActiveFace
) {
1737 (us
->stencilFailFunc
!= sfail
)
1739 (us
->stencilZFailFunc
!= zfail
)
1741 (us
->stencilZPassFunc
!= zpass
)
1743 us
->stencilFailFunc
= sfail
;
1744 us
->stencilZFailFunc
= zfail
;
1745 us
->stencilZPassFunc
= zpass
;
1746 fxMesa
->new_state
|= FX_NEW_STENCIL
;
1751 fxSetupStencil (GLcontext
* ctx
)
1753 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1754 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1756 if (us
->stencilEnabled
) {
1757 GrCmpFnc_t stencilFailFunc
= GR_STENCILOP_KEEP
;
1758 GrCmpFnc_t stencilZFailFunc
= GR_STENCILOP_KEEP
;
1759 GrCmpFnc_t stencilZPassFunc
= GR_STENCILOP_KEEP
;
1760 if (!fxMesa
->multipass
) {
1761 stencilFailFunc
= convertGLStencilOp(us
->stencilFailFunc
);
1762 stencilZFailFunc
= convertGLStencilOp(us
->stencilZFailFunc
);
1763 stencilZPassFunc
= convertGLStencilOp(us
->stencilZPassFunc
);
1765 grEnable(GR_STENCIL_MODE_EXT
);
1766 fxMesa
->Glide
.grStencilOpExt(stencilFailFunc
,
1769 fxMesa
->Glide
.grStencilFuncExt(us
->stencilFunction
- GL_NEVER
+ GR_CMP_NEVER
,
1770 us
->stencilRefValue
,
1771 us
->stencilValueMask
);
1772 fxMesa
->Glide
.grStencilMaskExt(us
->stencilWriteMask
);
1774 grDisable(GR_STENCIL_MODE_EXT
);
1779 fxSetupStencilFace (GLcontext
* ctx
, GLint face
)
1781 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1782 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1784 if (us
->stencilEnabled
) {
1785 GrCmpFnc_t stencilFailFunc
= GR_STENCILOP_KEEP
;
1786 GrCmpFnc_t stencilZFailFunc
= GR_STENCILOP_KEEP
;
1787 GrCmpFnc_t stencilZPassFunc
= GR_STENCILOP_KEEP
;
1788 if (!fxMesa
->multipass
) {
1789 stencilFailFunc
= convertGLStencilOp(ctx
->Stencil
.FailFunc
[face
]);
1790 stencilZFailFunc
= convertGLStencilOp(ctx
->Stencil
.ZFailFunc
[face
]);
1791 stencilZPassFunc
= convertGLStencilOp(ctx
->Stencil
.ZPassFunc
[face
]);
1793 grEnable(GR_STENCIL_MODE_EXT
);
1794 fxMesa
->Glide
.grStencilOpExt(stencilFailFunc
,
1797 fxMesa
->Glide
.grStencilFuncExt(ctx
->Stencil
.Function
[face
] - GL_NEVER
+ GR_CMP_NEVER
,
1798 ctx
->Stencil
.Ref
[face
],
1799 ctx
->Stencil
.ValueMask
[face
]);
1800 fxMesa
->Glide
.grStencilMaskExt(ctx
->Stencil
.WriteMask
[face
]);
1802 grDisable(GR_STENCIL_MODE_EXT
);
1806 /************************************************************************/
1807 /**************************** Color Mask SetUp **************************/
1808 /************************************************************************/
1811 fxDDColorMask(GLcontext
* ctx
,
1812 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
1814 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1815 fxMesa
->new_state
|= FX_NEW_COLOR_MASK
;
1823 fxSetupColorMask(GLcontext
* ctx
)
1825 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1827 if (fxMesa
->colDepth
== 32) {
1829 fxMesa
->Glide
.grColorMaskExt(ctx
->Color
.ColorMask
[RCOMP
],
1830 ctx
->Color
.ColorMask
[GCOMP
],
1831 ctx
->Color
.ColorMask
[BCOMP
],
1832 ctx
->Color
.ColorMask
[ACOMP
] && fxMesa
->haveHwAlpha
);
1835 /* 15/16 bpp mode */
1836 grColorMask(ctx
->Color
.ColorMask
[RCOMP
] |
1837 ctx
->Color
.ColorMask
[GCOMP
] |
1838 ctx
->Color
.ColorMask
[BCOMP
],
1839 ctx
->Color
.ColorMask
[ACOMP
] && fxMesa
->haveHwAlpha
);
1846 /************************************************************************/
1847 /**************************** Fog Mode SetUp ****************************/
1848 /************************************************************************/
1851 * This is called during state update in order to update the Glide fog state.
1854 fxSetupFog(GLcontext
* ctx
)
1856 if (ctx
->Fog
.Enabled
/*&& ctx->FogMode==FOG_FRAGMENT */ ) {
1857 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1859 /* update fog color */
1861 col
[0] = (unsigned int) (255 * ctx
->Fog
.Color
[0]);
1862 col
[1] = (unsigned int) (255 * ctx
->Fog
.Color
[1]);
1863 col
[2] = (unsigned int) (255 * ctx
->Fog
.Color
[2]);
1864 col
[3] = (unsigned int) (255 * ctx
->Fog
.Color
[3]);
1865 grFogColorValue(FXCOLOR4(col
));
1867 if (fxMesa
->fogTableMode
!= ctx
->Fog
.Mode
||
1868 fxMesa
->fogDensity
!= ctx
->Fog
.Density
||
1869 fxMesa
->fogStart
!= ctx
->Fog
.Start
||
1870 fxMesa
->fogEnd
!= ctx
->Fog
.End
) {
1871 /* reload the fog table */
1872 switch (ctx
->Fog
.Mode
) {
1874 guFogGenerateLinear(fxMesa
->fogTable
, ctx
->Fog
.Start
,
1876 if (fxMesa
->fogTable
[0] > 63) {
1877 /* [dBorca] Hack alert:
1878 * As per Glide3 Programming Guide:
1879 * The difference between consecutive fog values
1880 * must be less than 64.
1882 fxMesa
->fogTable
[0] = 63;
1886 guFogGenerateExp(fxMesa
->fogTable
, ctx
->Fog
.Density
);
1889 guFogGenerateExp2(fxMesa
->fogTable
, ctx
->Fog
.Density
);
1894 fxMesa
->fogTableMode
= ctx
->Fog
.Mode
;
1895 fxMesa
->fogDensity
= ctx
->Fog
.Density
;
1896 fxMesa
->fogStart
= ctx
->Fog
.Start
;
1897 fxMesa
->fogEnd
= ctx
->Fog
.End
;
1900 grFogTable(fxMesa
->fogTable
);
1901 if (ctx
->Fog
.FogCoordinateSource
== GL_FOG_COORDINATE_EXT
) {
1902 grVertexLayout(GR_PARAM_FOG_EXT
, GR_VERTEX_FOG_OFFSET
<< 2,
1904 grFogMode(GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT
);
1906 grVertexLayout(GR_PARAM_FOG_EXT
, GR_VERTEX_FOG_OFFSET
<< 2,
1908 grFogMode(GR_FOG_WITH_TABLE_ON_Q
);
1912 grFogMode(GR_FOG_DISABLE
);
1917 fxDDFogfv(GLcontext
* ctx
, GLenum pname
, const GLfloat
* params
)
1919 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_FOG
;
1921 case GL_FOG_COORDINATE_SOURCE_EXT
: {
1922 GLenum p
= (GLenum
)*params
;
1923 if (p
== GL_FOG_COORDINATE_EXT
) {
1924 _swrast_allow_vertex_fog(ctx
, GL_TRUE
);
1925 _swrast_allow_pixel_fog(ctx
, GL_FALSE
);
1926 _tnl_allow_vertex_fog( ctx
, GL_TRUE
);
1927 _tnl_allow_pixel_fog( ctx
, GL_FALSE
);
1929 _swrast_allow_vertex_fog(ctx
, GL_FALSE
);
1930 _swrast_allow_pixel_fog(ctx
, GL_TRUE
);
1931 _tnl_allow_vertex_fog( ctx
, GL_FALSE
);
1932 _tnl_allow_pixel_fog( ctx
, GL_TRUE
);
1941 /************************************************************************/
1942 /************************** Scissor Test SetUp **************************/
1943 /************************************************************************/
1945 /* This routine is used in managing the lock state, and therefore can't lock */
1947 fxSetScissorValues(GLcontext
* ctx
)
1949 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1953 if (ctx
->Scissor
.Enabled
) {
1954 xmin
= ctx
->Scissor
.X
;
1955 xmax
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
;
1956 ymin
= ctx
->Scissor
.Y
;
1957 ymax
= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
;
1961 if (xmax
> fxMesa
->width
)
1962 xmax
= fxMesa
->width
;
1963 if (ymin
< fxMesa
->screen_height
- fxMesa
->height
)
1964 ymin
= fxMesa
->screen_height
- fxMesa
->height
;
1965 if (ymax
> fxMesa
->screen_height
- 0)
1966 ymax
= fxMesa
->screen_height
- 0;
1971 xmax
= fxMesa
->width
;
1972 ymax
= fxMesa
->height
;
1975 fxMesa
->clipMinX
= xmin
;
1976 fxMesa
->clipMinY
= ymin
;
1977 fxMesa
->clipMaxX
= xmax
;
1978 fxMesa
->clipMaxY
= ymax
;
1979 grClipWindow(xmin
, ymin
, xmax
, ymax
);
1983 fxSetupScissor(GLcontext
* ctx
)
1986 fxSetScissorValues(ctx
);
1991 fxDDScissor(GLcontext
* ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
1993 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_SCISSOR
;
1996 /************************************************************************/
1997 /*************************** Cull mode setup ****************************/
1998 /************************************************************************/
2002 fxDDCullFace(GLcontext
* ctx
, GLenum mode
)
2005 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_CULL
;
2009 fxDDFrontFace(GLcontext
* ctx
, GLenum mode
)
2012 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_CULL
;
2017 fxSetupCull(GLcontext
* ctx
)
2019 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
2020 GrCullMode_t mode
= GR_CULL_DISABLE
;
2022 if (ctx
->Polygon
.CullFlag
&& (fxMesa
->raster_primitive
== GL_TRIANGLES
)) {
2023 switch (ctx
->Polygon
.CullFaceMode
) {
2025 if (ctx
->Polygon
.FrontFace
== GL_CCW
)
2026 mode
= GR_CULL_NEGATIVE
;
2028 mode
= GR_CULL_POSITIVE
;
2031 if (ctx
->Polygon
.FrontFace
== GL_CCW
)
2032 mode
= GR_CULL_POSITIVE
;
2034 mode
= GR_CULL_NEGATIVE
;
2036 case GL_FRONT_AND_BACK
:
2037 /* Handled as a fallback on triangles in tdfx_tris.c */
2045 if (fxMesa
->cullMode
!= mode
) {
2046 fxMesa
->cullMode
= mode
;
2052 /************************************************************************/
2053 /****************************** DD Enable ******************************/
2054 /************************************************************************/
2057 fxDDEnable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
2059 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
2060 tfxUnitsState
*us
= &fxMesa
->unitsState
;
2062 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
2063 fprintf(stderr
, "%s(%s)\n", state
? "fxDDEnable" : "fxDDDisable",
2064 _mesa_lookup_enum_by_nr(cap
));
2069 if (state
!= us
->alphaTestEnabled
) {
2070 us
->alphaTestEnabled
= state
;
2071 fxMesa
->new_state
|= FX_NEW_ALPHA
;
2075 if (state
!= us
->blendEnabled
) {
2076 us
->blendEnabled
= state
;
2077 fxMesa
->new_state
|= FX_NEW_BLEND
;
2081 if (state
!= us
->depthTestEnabled
) {
2082 us
->depthTestEnabled
= state
;
2083 fxMesa
->new_state
|= FX_NEW_DEPTH
;
2086 case GL_STENCIL_TEST
:
2087 if (fxMesa
->haveHwStencil
&& state
!= us
->stencilEnabled
) {
2088 us
->stencilEnabled
= state
;
2089 fxMesa
->new_state
|= FX_NEW_STENCIL
;
2094 grDitherMode(GR_DITHER_4x4
);
2097 grDitherMode(GR_DITHER_DISABLE
);
2100 case GL_SCISSOR_TEST
:
2101 fxMesa
->new_state
|= FX_NEW_SCISSOR
;
2103 case GL_SHARED_TEXTURE_PALETTE_EXT
:
2104 fxDDTexUseGlbPalette(ctx
, state
);
2107 fxMesa
->new_state
|= FX_NEW_FOG
;
2110 fxMesa
->new_state
|= FX_NEW_CULL
;
2112 case GL_LINE_SMOOTH
:
2113 case GL_LINE_STIPPLE
:
2114 case GL_POINT_SMOOTH
:
2115 case GL_POLYGON_SMOOTH
:
2118 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
2128 /************************************************************************/
2129 /************************** Changes to units state **********************/
2130 /************************************************************************/
2133 /* All units setup is handled under texture setup.
2136 fxDDShadeModel(GLcontext
* ctx
, GLenum mode
)
2138 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_TEXTURING
;
2143 /************************************************************************/
2144 /****************************** Units SetUp *****************************/
2145 /************************************************************************/
2147 fx_print_state_flags(const char *msg
, GLuint flags
)
2150 "%s: (0x%x) %s%s%s%s%s%s%s%s\n",
2153 (flags
& FX_NEW_TEXTURING
) ? "texture, " : "",
2154 (flags
& FX_NEW_BLEND
) ? "blend, " : "",
2155 (flags
& FX_NEW_ALPHA
) ? "alpha, " : "",
2156 (flags
& FX_NEW_FOG
) ? "fog, " : "",
2157 (flags
& FX_NEW_SCISSOR
) ? "scissor, " : "",
2158 (flags
& FX_NEW_COLOR_MASK
) ? "colormask, " : "",
2159 (flags
& FX_NEW_CULL
) ? "cull, " : "",
2160 (flags
& FX_NEW_STENCIL
) ? "stencil, " : "");
2164 fxSetupFXUnits(GLcontext
* ctx
)
2166 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
2167 GLuint newstate
= fxMesa
->new_state
;
2169 if (TDFX_DEBUG
& VERBOSE_DRIVER
)
2170 fx_print_state_flags("fxSetupFXUnits", newstate
);
2173 if (newstate
& FX_NEW_TEXTURING
)
2174 fxSetupTexture(ctx
);
2176 if (newstate
& FX_NEW_BLEND
)
2179 if (newstate
& FX_NEW_ALPHA
)
2180 fxSetupAlphaTest(ctx
);
2182 if (newstate
& FX_NEW_DEPTH
)
2183 fxSetupDepthTest(ctx
);
2185 if (newstate
& FX_NEW_STENCIL
)
2186 fxSetupStencil(ctx
);
2188 if (newstate
& FX_NEW_FOG
)
2191 if (newstate
& FX_NEW_SCISSOR
)
2192 fxSetupScissor(ctx
);
2194 if (newstate
& FX_NEW_COLOR_MASK
)
2195 fxSetupColorMask(ctx
);
2197 if (newstate
& FX_NEW_CULL
)
2200 fxMesa
->new_state
= 0;
2210 * Need this to provide at least one external definition.
2213 extern int gl_fx_dummy_function_setup(void);
2215 gl_fx_dummy_function_setup(void)