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 */
46 #include "tnl/t_context.h"
50 fxTexValidate(GLcontext
* ctx
, struct gl_texture_object
*tObj
)
52 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
56 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
57 fprintf(stderr
, "fxTexValidate(NOP)\n");
62 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
63 fprintf(stderr
, "fxTexValidate(%p (%d))\n", (void *)tObj
, tObj
->Name
);
67 minl
= ti
->minLevel
= tObj
->BaseLevel
;
68 maxl
= ti
->maxLevel
= MIN2(tObj
->MaxLevel
, tObj
->Image
[0][0]->MaxLog2
);
70 #if FX_RESCALE_BIG_TEXURES_HACK
72 extern void _mesa_rescale_teximage2d( GLuint bytesPerPixel
,
74 GLint srcWidth
, GLint srcHeight
,
75 GLint dstWidth
, GLint dstHeight
,
76 const GLvoid
*srcImage
, GLvoid
*dstImage
);
77 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
79 * Ooooooook! Here's a(nother) long story.
80 * We get here because we need to handle a texture larger
81 * than hardware can support. Two cases:
82 * 1) we have mipmaps. Then we just push up to the first supported
83 * LOD. A possible drawback is that Mesa will ignore the skipped
84 * LODs on further texture handling.
85 * Will this interfere with GL_TEXTURE_[MIN|BASE]_LEVEL? How?
86 * 2) we don't have mipmaps. We need to rescale the big LOD in place.
87 * The above approach is somehow dumb! we might have rescaled
88 * once in TexImage2D to accomodate aspect ratio, and now we
89 * are rescaling again. The thing is, in TexImage2D we don't
90 * know whether we'll hit 1) or 2) by the time of validation.
91 * NB: we could handle mml->[wh]Scale nicely, using (biased) shifts.
93 * Which brings me to another issue. How can we handle NPOT textures?
94 * - rescaling NPOT to the next bigger POT (mml->[wh]Scale can't shift)
95 * - upping the max LOD to the next power-of-two, in fxTexGetInfo; then
96 * choosing non-power-of-two values for ti->[st]Scale... Anyhow, we
97 * still need to align mipmaps correctly in texture memory!
99 if ((tObj
->MinFilter
== GL_NEAREST
) || (tObj
->MinFilter
== GL_LINEAR
)) {
101 struct gl_texture_image
*texImage
= tObj
->Image
[0][minl
];
102 tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
103 GLint _w
, _h
, maxSize
= 1 << fxMesa
->textureMaxLod
;
104 if ((mml
->width
> maxSize
) || (mml
->height
> maxSize
)) {
105 /* need to rescale */
106 GLint texelBytes
= texImage
->TexFormat
->TexelBytes
;
107 GLvoid
*texImage_Data
= texImage
->Data
;
108 _w
= MIN2(texImage
->Width
, maxSize
);
109 _h
= MIN2(texImage
->Height
, maxSize
);
110 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
111 fprintf(stderr
, "fxTexValidate: rescaling %d x %d -> %d x %d\n",
112 texImage
->Width
, texImage
->Height
, _w
, _h
);
114 /* we should leave these as is and... (!) */
115 texImage
->Width
= _w
;
116 texImage
->Height
= _h
;
117 fxTexGetInfo(_w
, _h
, NULL
, NULL
, NULL
, NULL
,
118 &(mml
->wScale
), &(mml
->hScale
));
121 texImage
->Data
= MESA_PBUFFER_ALLOC(_w
* _h
* texelBytes
);
122 _mesa_rescale_teximage2d(texelBytes
,
123 _w
* texelBytes
, /* dst stride */
124 mml
->width
, mml
->height
, /* src */
126 texImage_Data
/*src*/, texImage
->Data
/*dst*/ );
127 MESA_PBUFFER_FREE(texImage_Data
);
130 /* (!) ... and set mml->wScale = _w / texImage->Width */
134 if (maxl
- minl
> fxMesa
->textureMaxLod
) {
135 /* skip a certain number of LODs */
136 minl
+= maxl
- fxMesa
->textureMaxLod
;
137 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
138 fprintf(stderr
, "fxTexValidate: skipping %d LODs\n", minl
- ti
->minLevel
);
140 ti
->minLevel
= tObj
->BaseLevel
= minl
;
146 fxTexGetInfo(tObj
->Image
[0][minl
]->Width
, tObj
->Image
[0][minl
]->Height
,
147 &(FX_largeLodLog2(ti
->info
)), &(FX_aspectRatioLog2(ti
->info
)),
148 &(ti
->sScale
), &(ti
->tScale
),
151 if ((tObj
->MinFilter
!= GL_NEAREST
) && (tObj
->MinFilter
!= GL_LINEAR
))
152 fxTexGetInfo(tObj
->Image
[0][maxl
]->Width
, tObj
->Image
[0][maxl
]->Height
,
153 &(FX_smallLodLog2(ti
->info
)), NULL
,
154 NULL
, NULL
, NULL
, NULL
);
156 FX_smallLodLog2(ti
->info
) = FX_largeLodLog2(ti
->info
);
158 /* this is necessary because of fxDDCompressedTexImage2D */
160 struct gl_texture_image
*texImage
= tObj
->Image
[0][minl
];
161 tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
162 if (mml
->wScale
!= 1 || mml
->hScale
!= 1) {
163 ti
->sScale
/= mml
->wScale
;
164 ti
->tScale
/= mml
->hScale
;
168 ti
->baseLevelInternalFormat
= tObj
->Image
[0][minl
]->Format
;
170 ti
->validated
= GL_TRUE
;
172 ti
->info
.data
= NULL
;
176 fxPrintUnitsMode(const char *msg
, GLuint mode
)
179 "%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",
182 (mode
& FX_UM_E0_REPLACE
) ? "E0_REPLACE, " : "",
183 (mode
& FX_UM_E0_MODULATE
) ? "E0_MODULATE, " : "",
184 (mode
& FX_UM_E0_DECAL
) ? "E0_DECAL, " : "",
185 (mode
& FX_UM_E0_BLEND
) ? "E0_BLEND, " : "",
186 (mode
& FX_UM_E1_REPLACE
) ? "E1_REPLACE, " : "",
187 (mode
& FX_UM_E1_MODULATE
) ? "E1_MODULATE, " : "",
188 (mode
& FX_UM_E1_DECAL
) ? "E1_DECAL, " : "",
189 (mode
& FX_UM_E1_BLEND
) ? "E1_BLEND, " : "",
190 (mode
& FX_UM_E0_ALPHA
) ? "E0_ALPHA, " : "",
191 (mode
& FX_UM_E0_LUMINANCE
) ? "E0_LUMINANCE, " : "",
192 (mode
& FX_UM_E0_LUMINANCE_ALPHA
) ? "E0_LUMINANCE_ALPHA, " : "",
193 (mode
& FX_UM_E0_INTENSITY
) ? "E0_INTENSITY, " : "",
194 (mode
& FX_UM_E0_RGB
) ? "E0_RGB, " : "",
195 (mode
& FX_UM_E0_RGBA
) ? "E0_RGBA, " : "",
196 (mode
& FX_UM_E1_ALPHA
) ? "E1_ALPHA, " : "",
197 (mode
& FX_UM_E1_LUMINANCE
) ? "E1_LUMINANCE, " : "",
198 (mode
& FX_UM_E1_LUMINANCE_ALPHA
) ? "E1_LUMINANCE_ALPHA, " : "",
199 (mode
& FX_UM_E1_INTENSITY
) ? "E1_INTENSITY, " : "",
200 (mode
& FX_UM_E1_RGB
) ? "E1_RGB, " : "",
201 (mode
& FX_UM_E1_RGBA
) ? "E1_RGBA, " : "",
202 (mode
& FX_UM_COLOR_ITERATED
) ? "COLOR_ITERATED, " : "",
203 (mode
& FX_UM_COLOR_CONSTANT
) ? "COLOR_CONSTANT, " : "",
204 (mode
& FX_UM_ALPHA_ITERATED
) ? "ALPHA_ITERATED, " : "",
205 (mode
& FX_UM_ALPHA_CONSTANT
) ? "ALPHA_CONSTANT, " : "");
209 fxGetTexSetConfiguration(GLcontext
* ctx
,
210 struct gl_texture_object
*tObj0
,
211 struct gl_texture_object
*tObj1
)
213 GLuint unitsmode
= 0;
217 if ((ctx
->Light
.ShadeModel
== GL_SMOOTH
) || 1 ||
218 (ctx
->Point
.SmoothFlag
) ||
219 (ctx
->Line
.SmoothFlag
) ||
220 (ctx
->Polygon
.SmoothFlag
)) unitsmode
|= FX_UM_ALPHA_ITERATED
;
222 unitsmode
|= FX_UM_ALPHA_CONSTANT
;
224 if (ctx
->Light
.ShadeModel
== GL_SMOOTH
|| 1)
225 unitsmode
|= FX_UM_COLOR_ITERATED
;
227 unitsmode
|= FX_UM_COLOR_CONSTANT
;
232 OpenGL Feeds Texture 0 into Texture 1
233 Glide Feeds Texture 1 into Texture 0
236 tfxTexInfo
*ti0
= fxTMGetTexInfo(tObj0
);
238 switch (ti0
->baseLevelInternalFormat
) {
240 ifmt
|= FX_UM_E0_ALPHA
;
243 ifmt
|= FX_UM_E0_LUMINANCE
;
245 case GL_LUMINANCE_ALPHA
:
246 ifmt
|= FX_UM_E0_LUMINANCE_ALPHA
;
249 ifmt
|= FX_UM_E0_INTENSITY
;
252 ifmt
|= FX_UM_E0_RGB
;
255 ifmt
|= FX_UM_E0_RGBA
;
259 switch (ctx
->Texture
.Unit
[0].EnvMode
) {
261 envmode
|= FX_UM_E0_DECAL
;
264 envmode
|= FX_UM_E0_MODULATE
;
267 envmode
|= FX_UM_E0_REPLACE
;
270 envmode
|= FX_UM_E0_BLEND
;
273 envmode
|= FX_UM_E0_ADD
;
282 tfxTexInfo
*ti1
= fxTMGetTexInfo(tObj1
);
284 switch (ti1
->baseLevelInternalFormat
) {
286 ifmt
|= FX_UM_E1_ALPHA
;
289 ifmt
|= FX_UM_E1_LUMINANCE
;
291 case GL_LUMINANCE_ALPHA
:
292 ifmt
|= FX_UM_E1_LUMINANCE_ALPHA
;
295 ifmt
|= FX_UM_E1_INTENSITY
;
298 ifmt
|= FX_UM_E1_RGB
;
301 ifmt
|= FX_UM_E1_RGBA
;
308 switch (ctx
->Texture
.Unit
[1].EnvMode
) {
310 envmode
|= FX_UM_E1_DECAL
;
313 envmode
|= FX_UM_E1_MODULATE
;
316 envmode
|= FX_UM_E1_REPLACE
;
319 envmode
|= FX_UM_E1_BLEND
;
322 envmode
|= FX_UM_E1_ADD
;
330 unitsmode
|= (ifmt
| envmode
);
332 if (TDFX_DEBUG
& (VERBOSE_DRIVER
| VERBOSE_TEXTURE
))
333 fxPrintUnitsMode("fxGetTexSetConfiguration", unitsmode
);
338 /************************************************************************/
339 /************************* Rendering Mode SetUp *************************/
340 /************************************************************************/
342 /************************* Single Texture Set ***************************/
345 fxSetupSingleTMU_NoLock(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
)
347 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
350 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
351 fprintf(stderr
, "fxSetupSingleTMU_NoLock(%p (%d))\n", (void *)tObj
, tObj
->Name
);
354 #if 1 /* [dBorca] Good... bad... I'm the guy with the gun! */
355 ti
->lastTimeUsed
= fxMesa
->texBindNumber
;
358 /* Make sure we're not loaded incorrectly */
361 if (ti
->whichTMU
!= FX_TMU_SPLIT
)
362 fxTMMoveOutTM(fxMesa
, tObj
);
365 if (ti
->whichTMU
== FX_TMU_SPLIT
)
366 fxTMMoveOutTM(fxMesa
, tObj
);
370 /* Make sure we're loaded correctly */
373 fxTMMoveInTM_NoLock(fxMesa
, tObj
, FX_TMU_SPLIT
);
375 if (fxMesa
->haveTwoTMUs
) {
376 if (fxTMCheckStartAddr(fxMesa
, FX_TMU0
, ti
)) {
377 fxTMMoveInTM_NoLock(fxMesa
, tObj
, FX_TMU0
);
380 fxTMMoveInTM_NoLock(fxMesa
, tObj
, FX_TMU1
);
384 fxTMMoveInTM_NoLock(fxMesa
, tObj
, FX_TMU0
);
388 if (ti
->LODblend
&& ti
->whichTMU
== FX_TMU_SPLIT
) {
390 if ((ti
->info
.format
== GR_TEXFMT_P_8
)
391 && (!fxMesa
->haveGlobalPaletteTexture
)) {
392 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
393 fprintf(stderr
, "fxSetupSingleTMU_NoLock: uploading texture palette\n");
395 grTexDownloadTable(ti
->paltype
, &(ti
->palette
));
398 if ((ti
->info
.format
== GR_TEXFMT_AYIQ_8422
) ||
399 (ti
->info
.format
== GR_TEXFMT_YIQ_422
)) {
400 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
401 fprintf(stderr
, "fxSetupSingleTMU_NoLock: uploading NCC table\n");
403 grTexDownloadTable(GR_TEXTABLE_NCC0
, &(ti
->palette
));
407 grTexClampMode(GR_TMU0
, ti
->sClamp
, ti
->tClamp
);
408 grTexClampMode(GR_TMU1
, ti
->sClamp
, ti
->tClamp
);
409 grTexFilterMode(GR_TMU0
, ti
->minFilt
, ti
->maxFilt
);
410 grTexFilterMode(GR_TMU1
, ti
->minFilt
, ti
->maxFilt
);
411 grTexMipMapMode(GR_TMU0
, ti
->mmMode
, ti
->LODblend
);
412 grTexMipMapMode(GR_TMU1
, ti
->mmMode
, ti
->LODblend
);
414 grTexSource(GR_TMU0
, ti
->tm
[FX_TMU0
]->startAddr
,
415 GR_MIPMAPLEVELMASK_ODD
, &(ti
->info
));
416 grTexSource(GR_TMU1
, ti
->tm
[FX_TMU1
]->startAddr
,
417 GR_MIPMAPLEVELMASK_EVEN
, &(ti
->info
));
420 if (ti
->whichTMU
== FX_TMU_BOTH
)
426 if ((ti
->info
.format
== GR_TEXFMT_P_8
)
427 && (!fxMesa
->haveGlobalPaletteTexture
)) {
428 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
429 fprintf(stderr
, "fxSetupSingleTMU_NoLock: uploading texture palette\n");
431 fxMesa
->Glide
.grTexDownloadTableExt(tmu
, ti
->paltype
, &(ti
->palette
));
434 if ((ti
->info
.format
== GR_TEXFMT_AYIQ_8422
) ||
435 (ti
->info
.format
== GR_TEXFMT_YIQ_422
)) {
436 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
437 fprintf(stderr
, "fxSetupSingleTMU_NoLock: uploading NCC table\n");
439 fxMesa
->Glide
.grTexDownloadTableExt(tmu
, GR_TEXTABLE_NCC0
, &(ti
->palette
));
443 /* KW: The alternative is to do the download to the other tmu. If
444 * we get to this point, I think it means we are thrashing the
445 * texture memory, so perhaps it's not a good idea.
447 if (ti
->LODblend
&& (TDFX_DEBUG
& VERBOSE_DRIVER
)) {
448 fprintf(stderr
, "fxSetupSingleTMU_NoLock: not blending texture - only one tmu\n");
451 grTexClampMode(tmu
, ti
->sClamp
, ti
->tClamp
);
452 grTexFilterMode(tmu
, ti
->minFilt
, ti
->maxFilt
);
453 grTexMipMapMode(tmu
, ti
->mmMode
, FXFALSE
);
455 grTexSource(tmu
, ti
->tm
[tmu
]->startAddr
, GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
460 fxSelectSingleTMUSrc_NoLock(fxMesaContext fxMesa
, GLint tmu
, FxBool LODblend
)
462 struct tdfx_texcombine tex0
, tex1
;
464 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
465 fprintf(stderr
, "fxSelectSingleTMUSrc_NoLock(%d, %d)\n", tmu
, LODblend
);
468 tex0
.InvertRGB
= FXFALSE
;
469 tex0
.InvertAlpha
= FXFALSE
;
470 tex1
.InvertRGB
= FXFALSE
;
471 tex1
.InvertAlpha
= FXFALSE
;
474 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND
;
475 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION
;
476 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND
;
477 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION
;
479 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
480 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
481 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
482 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
484 fxMesa
->tmuSrc
= FX_TMU_SPLIT
;
487 if (tmu
!= FX_TMU1
) {
488 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
489 tex0
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
490 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
491 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
493 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
494 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
495 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
496 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
498 fxMesa
->tmuSrc
= FX_TMU0
;
501 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
502 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
503 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
504 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
506 /* correct values to set TMU0 in passthrough mode */
507 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND
;
508 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
509 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND
;
510 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
512 fxMesa
->tmuSrc
= FX_TMU1
;
516 grTexCombine(GR_TMU0
,
523 if (fxMesa
->haveTwoTMUs
) {
524 grTexCombine(GR_TMU1
,
535 fxSetupTextureSingleTMU_NoLock(GLcontext
* ctx
, GLuint textureset
)
537 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
538 struct tdfx_combine alphaComb
, colorComb
;
539 GrCombineLocal_t localc
, locala
;
543 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[textureset
]._Current
;
546 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
547 fprintf(stderr
, "fxSetupTextureSingleTMU_NoLock(%d)\n", textureset
);
550 ti
= fxTMGetTexInfo(tObj
);
552 fxTexValidate(ctx
, tObj
);
554 fxSetupSingleTMU_NoLock(fxMesa
, tObj
);
556 if (ti
->whichTMU
== FX_TMU_BOTH
)
560 if (fxMesa
->tmuSrc
!= tmu
)
561 fxSelectSingleTMUSrc_NoLock(fxMesa
, tmu
, ti
->LODblend
);
563 if (textureset
== 0 || !fxMesa
->haveTwoTMUs
)
564 unitsmode
= fxGetTexSetConfiguration(ctx
, tObj
, NULL
);
566 unitsmode
= fxGetTexSetConfiguration(ctx
, NULL
, tObj
);
568 /* if(fxMesa->lastUnitsMode==unitsmode) */
571 fxMesa
->lastUnitsMode
= unitsmode
;
573 fxMesa
->stw_hint_state
= 0;
574 FX_grHints_NoLock(GR_HINT_STWHINT
, 0);
576 ifmt
= ti
->baseLevelInternalFormat
;
578 if (unitsmode
& FX_UM_ALPHA_ITERATED
)
579 locala
= GR_COMBINE_LOCAL_ITERATED
;
581 locala
= GR_COMBINE_LOCAL_CONSTANT
;
583 if (unitsmode
& FX_UM_COLOR_ITERATED
)
584 localc
= GR_COMBINE_LOCAL_ITERATED
;
586 localc
= GR_COMBINE_LOCAL_CONSTANT
;
588 if (TDFX_DEBUG
& (VERBOSE_DRIVER
| VERBOSE_TEXTURE
))
589 fprintf(stderr
, "fxSetupTextureSingleTMU_NoLock: envmode is %s\n",
590 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[textureset
].EnvMode
));
592 alphaComb
.Local
= locala
;
593 alphaComb
.Invert
= FXFALSE
;
594 colorComb
.Local
= localc
;
595 colorComb
.Invert
= FXFALSE
;
597 switch (ctx
->Texture
.Unit
[textureset
].EnvMode
) {
599 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
600 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
601 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
603 colorComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
604 colorComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_ALPHA
;
605 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
608 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
609 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
610 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 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
618 colorComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
619 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
623 if (ifmt
== GL_LUMINANCE
|| ifmt
== GL_RGB
) {
625 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
626 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
627 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
629 else if (ifmt
== GL_INTENSITY
) {
630 /* Av = Af * (1 - It) + Ac * It */
631 alphaComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
632 alphaComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_ALPHA
;
633 alphaComb
.Other
= GR_COMBINE_OTHER_CONSTANT
;
637 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
638 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
639 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
642 if (ifmt
== GL_ALPHA
) {
643 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
644 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
645 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
647 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo2
) {
648 colorComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
649 colorComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_RGB
;
650 colorComb
.Other
= GR_COMBINE_OTHER_CONSTANT
;
651 } else if (ifmt
== GL_INTENSITY
) {
652 /* just a hack: RGB == ALPHA */
653 colorComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
654 colorComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_ALPHA
;
655 colorComb
.Other
= GR_COMBINE_OTHER_CONSTANT
;
657 /* [dBorca] Hack alert:
658 * only Voodoo^2 can GL_BLEND (GR_COMBINE_FACTOR_TEXTURE_RGB)
659 * These settings assume that the TexEnv color is black
660 * and incoming fragment color is white.
662 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
663 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
664 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
665 colorComb
.Invert
= FXTRUE
;
666 _mesa_problem(NULL
, "can't GL_BLEND with SST1");
670 grConstantColorValue(
671 (((GLuint
)(ctx
->Texture
.Unit
[textureset
].EnvColor
[0] * 255.0f
)) ) |
672 (((GLuint
)(ctx
->Texture
.Unit
[textureset
].EnvColor
[1] * 255.0f
)) << 8) |
673 (((GLuint
)(ctx
->Texture
.Unit
[textureset
].EnvColor
[2] * 255.0f
)) << 16) |
674 (((GLuint
)(ctx
->Texture
.Unit
[textureset
].EnvColor
[3] * 255.0f
)) << 24));
677 if ((ifmt
== GL_RGB
) || (ifmt
== GL_LUMINANCE
)) {
678 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
679 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
680 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
682 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
683 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
684 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
687 if (ifmt
== GL_ALPHA
) {
688 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
689 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
690 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
692 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
693 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
694 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
698 if (ifmt
== GL_ALPHA
||
699 ifmt
== GL_LUMINANCE_ALPHA
||
701 /* product of texel and fragment alpha */
702 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
703 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
704 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
706 else if (ifmt
== GL_LUMINANCE
|| ifmt
== GL_RGB
) {
707 /* fragment alpha is unchanged */
708 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
709 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
710 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
713 /* sum of texel and fragment alpha */
714 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
715 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
716 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
719 if (ifmt
== GL_ALPHA
) {
721 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
722 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
723 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
726 /* sum of texel and fragment rgb */
727 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
728 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
729 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
733 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
734 fprintf(stderr
, "fxSetupTextureSingleTMU_NoLock: %x Texture.EnvMode not yet supported\n",
735 ctx
->Texture
.Unit
[textureset
].EnvMode
);
740 grAlphaCombine(alphaComb
.Function
,
745 grColorCombine(colorComb
.Function
,
754 fxSetupTextureSingleTMU(GLcontext
* ctx
, GLuint textureset
)
757 fxSetupTextureSingleTMU_NoLock(ctx
, textureset
);
763 /************************* Double Texture Set ***************************/
766 fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa
,
767 struct gl_texture_object
*tObj0
,
768 struct gl_texture_object
*tObj1
)
770 #define T0_NOT_IN_TMU 0x01
771 #define T1_NOT_IN_TMU 0x02
772 #define T0_IN_TMU0 0x04
773 #define T1_IN_TMU0 0x08
774 #define T0_IN_TMU1 0x10
775 #define T1_IN_TMU1 0x20
777 tfxTexInfo
*ti0
= fxTMGetTexInfo(tObj0
);
778 tfxTexInfo
*ti1
= fxTMGetTexInfo(tObj1
);
780 int tmu0
= 0, tmu1
= 1;
782 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
783 fprintf(stderr
, "fxSetupDoubleTMU_NoLock(...)\n");
786 /* We shouldn't need to do this. There is something wrong with
787 mutlitexturing when the TMUs are swapped. So, we're forcing
788 them to always be loaded correctly. !!! */
789 if (ti0
->whichTMU
== FX_TMU1
)
790 fxTMMoveOutTM_NoLock(fxMesa
, tObj0
);
791 if (ti1
->whichTMU
== FX_TMU0
)
792 fxTMMoveOutTM_NoLock(fxMesa
, tObj1
);
795 switch (ti0
->whichTMU
) {
797 tstate
|= T0_IN_TMU0
;
800 tstate
|= T0_IN_TMU1
;
803 tstate
|= T0_IN_TMU0
| T0_IN_TMU1
;
806 tstate
|= T0_NOT_IN_TMU
;
811 tstate
|= T0_NOT_IN_TMU
;
814 switch (ti1
->whichTMU
) {
816 tstate
|= T1_IN_TMU0
;
819 tstate
|= T1_IN_TMU1
;
822 tstate
|= T1_IN_TMU0
| T1_IN_TMU1
;
825 tstate
|= T1_NOT_IN_TMU
;
830 tstate
|= T1_NOT_IN_TMU
;
832 ti0
->lastTimeUsed
= fxMesa
->texBindNumber
;
833 ti1
->lastTimeUsed
= fxMesa
->texBindNumber
;
835 /* Move texture maps into TMUs */
837 if (!(((tstate
& T0_IN_TMU0
) && (tstate
& T1_IN_TMU1
)) ||
838 ((tstate
& T0_IN_TMU1
) && (tstate
& T1_IN_TMU0
)))) {
840 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU_BOTH
);
842 /* Find the minimal way to correct the situation */
843 if ((tstate
& T0_IN_TMU0
) || (tstate
& T1_IN_TMU1
)) {
844 /* We have one in the standard order, setup the other */
845 if (tstate
& T0_IN_TMU0
) { /* T0 is in TMU0, put T1 in TMU1 */
846 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU1
);
849 fxTMMoveInTM_NoLock(fxMesa
, tObj0
, FX_TMU0
);
851 /* tmu0 and tmu1 are setup */
853 else if ((tstate
& T0_IN_TMU1
) || (tstate
& T1_IN_TMU0
)) {
854 /* we have one in the reverse order, setup the other */
855 if (tstate
& T1_IN_TMU0
) { /* T1 is in TMU0, put T0 in TMU1 */
856 fxTMMoveInTM_NoLock(fxMesa
, tObj0
, FX_TMU1
);
859 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU0
);
864 else { /* Nothing is loaded */
865 fxTMMoveInTM_NoLock(fxMesa
, tObj0
, FX_TMU0
);
866 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU1
);
867 /* tmu0 and tmu1 are setup */
872 /* [dBorca] Hack alert:
873 * we put these in reverse order, so that if we can't
874 * do _REAL_ pointcast, the TMU0 table gets broadcasted
876 if (!fxMesa
->haveGlobalPaletteTexture
) {
878 if (ti1
->info
.format
== GR_TEXFMT_P_8
) {
879 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
880 fprintf(stderr
, "fxSetupDoubleTMU_NoLock: uploading texture palette for TMU1\n");
882 fxMesa
->Glide
.grTexDownloadTableExt(ti1
->whichTMU
, ti1
->paltype
, &(ti1
->palette
));
884 if (ti0
->info
.format
== GR_TEXFMT_P_8
) {
885 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
886 fprintf(stderr
, "fxSetupDoubleTMU_NoLock: uploading texture palette for TMU0\n");
888 fxMesa
->Glide
.grTexDownloadTableExt(ti0
->whichTMU
, ti0
->paltype
, &(ti0
->palette
));
893 if ((ti1
->info
.format
== GR_TEXFMT_AYIQ_8422
) ||
894 (ti1
->info
.format
== GR_TEXFMT_YIQ_422
)) {
895 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
896 fprintf(stderr
, "fxSetupDoubleTMU_NoLock: uploading NCC0 table for TMU1\n");
898 fxMesa
->Glide
.grTexDownloadTableExt(ti1
->whichTMU
, GR_TEXTABLE_NCC0
, &(ti1
->palette
));
900 if ((ti0
->info
.format
== GR_TEXFMT_AYIQ_8422
) ||
901 (ti0
->info
.format
== GR_TEXFMT_YIQ_422
)) {
902 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
903 fprintf(stderr
, "fxSetupDoubleTMU_NoLock: uploading NCC0 table for TMU0\n");
905 fxMesa
->Glide
.grTexDownloadTableExt(ti0
->whichTMU
, GR_TEXTABLE_NCC0
, &(ti0
->palette
));
909 grTexSource(tmu0
, ti0
->tm
[tmu0
]->startAddr
,
910 GR_MIPMAPLEVELMASK_BOTH
, &(ti0
->info
));
911 grTexClampMode(tmu0
, ti0
->sClamp
, ti0
->tClamp
);
912 grTexFilterMode(tmu0
, ti0
->minFilt
, ti0
->maxFilt
);
913 grTexMipMapMode(tmu0
, ti0
->mmMode
, FXFALSE
);
915 grTexSource(tmu1
, ti1
->tm
[tmu1
]->startAddr
,
916 GR_MIPMAPLEVELMASK_BOTH
, &(ti1
->info
));
917 grTexClampMode(tmu1
, ti1
->sClamp
, ti1
->tClamp
);
918 grTexFilterMode(tmu1
, ti1
->minFilt
, ti1
->maxFilt
);
919 grTexMipMapMode(tmu1
, ti1
->mmMode
, FXFALSE
);
930 fxSetupTextureDoubleTMU_NoLock(GLcontext
* ctx
)
932 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
933 struct tdfx_combine alphaComb
, colorComb
;
934 struct tdfx_texcombine tex0
, tex1
;
935 GrCombineLocal_t localc
, locala
;
936 tfxTexInfo
*ti0
, *ti1
;
937 struct gl_texture_object
*tObj0
= ctx
->Texture
.Unit
[1]._Current
;
938 struct gl_texture_object
*tObj1
= ctx
->Texture
.Unit
[0]._Current
;
939 GLuint envmode
, ifmt
, unitsmode
;
940 int tmu0
= 0, tmu1
= 1;
942 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
943 fprintf(stderr
, "fxSetupTextureDoubleTMU_NoLock(...)\n");
946 ti0
= fxTMGetTexInfo(tObj0
);
947 fxTexValidate(ctx
, tObj0
);
949 ti1
= fxTMGetTexInfo(tObj1
);
950 fxTexValidate(ctx
, tObj1
);
952 fxSetupDoubleTMU_NoLock(fxMesa
, tObj0
, tObj1
);
954 unitsmode
= fxGetTexSetConfiguration(ctx
, tObj0
, tObj1
);
956 /* if(fxMesa->lastUnitsMode==unitsmode) */
959 fxMesa
->lastUnitsMode
= unitsmode
;
961 fxMesa
->stw_hint_state
|= GR_STWHINT_ST_DIFF_TMU1
;
962 FX_grHints_NoLock(GR_HINT_STWHINT
, fxMesa
->stw_hint_state
);
964 envmode
= unitsmode
& FX_UM_E_ENVMODE
;
965 ifmt
= unitsmode
& FX_UM_E_IFMT
;
967 if (unitsmode
& FX_UM_ALPHA_ITERATED
)
968 locala
= GR_COMBINE_LOCAL_ITERATED
;
970 locala
= GR_COMBINE_LOCAL_CONSTANT
;
972 if (unitsmode
& FX_UM_COLOR_ITERATED
)
973 localc
= GR_COMBINE_LOCAL_ITERATED
;
975 localc
= GR_COMBINE_LOCAL_CONSTANT
;
978 if (TDFX_DEBUG
& (VERBOSE_DRIVER
| VERBOSE_TEXTURE
))
979 fprintf(stderr
, "fxSetupTextureDoubleTMU_NoLock: envmode is %s/%s\n",
980 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[0].EnvMode
),
981 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[1].EnvMode
));
984 if ((ti0
->whichTMU
== FX_TMU1
) || (ti1
->whichTMU
== FX_TMU0
)) {
988 fxMesa
->tmuSrc
= FX_TMU_BOTH
;
990 tex0
.InvertRGB
= FXFALSE
;
991 tex0
.InvertAlpha
= FXFALSE
;
992 tex1
.InvertRGB
= FXFALSE
;
993 tex1
.InvertAlpha
= FXFALSE
;
994 alphaComb
.Local
= locala
;
995 alphaComb
.Invert
= FXFALSE
;
996 colorComb
.Local
= localc
;
997 colorComb
.Invert
= FXFALSE
;
1000 case (FX_UM_E0_MODULATE
| FX_UM_E1_MODULATE
):
1002 GLboolean isalpha
[FX_NUM_TMU
];
1004 isalpha
[tmu0
] = (ti0
->baseLevelInternalFormat
== GL_ALPHA
);
1005 isalpha
[tmu1
] = (ti1
->baseLevelInternalFormat
== GL_ALPHA
);
1007 if (isalpha
[FX_TMU1
]) {
1008 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1009 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1010 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1011 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1012 tex1
.InvertRGB
= FXTRUE
;
1014 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1015 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1016 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1017 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1020 if (isalpha
[FX_TMU0
]) {
1021 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1022 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1023 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1024 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1026 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1027 tex0
.FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1028 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1029 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1032 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1033 colorComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1034 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1036 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1037 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1038 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1041 case (FX_UM_E0_REPLACE
| FX_UM_E1_BLEND
): /* Only for GLQuake */
1042 if (tmu0
== FX_TMU1
) {
1043 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1044 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1045 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1046 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1047 tex1
.InvertRGB
= FXTRUE
;
1049 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1050 tex0
.FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1051 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1052 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1055 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1056 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1057 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1058 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1060 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1061 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
;
1062 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1063 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
;
1066 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1067 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
1068 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
1070 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1071 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1072 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1074 case (FX_UM_E0_REPLACE
| FX_UM_E1_MODULATE
): /* Quake 2 and 3 */
1075 if (tmu1
== FX_TMU1
) {
1076 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1077 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1078 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
1079 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1080 tex1
.InvertAlpha
= FXTRUE
;
1082 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1083 tex0
.FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1084 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1085 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1088 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1089 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1090 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1091 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1093 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1094 tex0
.FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1095 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1096 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1099 if (ti0
->baseLevelInternalFormat
== GL_RGB
) {
1100 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1101 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
1102 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
1104 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1105 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1106 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
1109 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1110 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1111 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1115 case (FX_UM_E0_MODULATE
| FX_UM_E1_ADD
): /* Quake 3 Sky */
1117 GLboolean isalpha
[FX_NUM_TMU
];
1119 isalpha
[tmu0
] = (ti0
->baseLevelInternalFormat
== GL_ALPHA
);
1120 isalpha
[tmu1
] = (ti1
->baseLevelInternalFormat
== GL_ALPHA
);
1122 if (isalpha
[FX_TMU1
]) {
1123 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1124 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1125 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1126 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1127 tex1
.InvertRGB
= FXTRUE
;
1129 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1130 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1131 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1132 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1135 if (isalpha
[FX_TMU0
]) {
1136 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1137 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1138 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1139 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1141 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1142 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1143 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1144 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1147 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1148 colorComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1149 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1151 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1152 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1153 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1157 case (FX_UM_E0_REPLACE
| FX_UM_E1_ADD
): /* Vulpine Sky */
1159 GLboolean isalpha
[FX_NUM_TMU
];
1161 isalpha
[tmu0
] = (ti0
->baseLevelInternalFormat
== GL_ALPHA
);
1162 isalpha
[tmu1
] = (ti1
->baseLevelInternalFormat
== GL_ALPHA
);
1164 if (isalpha
[FX_TMU1
]) {
1165 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1166 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1167 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1168 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1169 tex1
.InvertRGB
= FXTRUE
;
1171 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1172 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1173 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1174 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1177 if (isalpha
[FX_TMU0
]) {
1178 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1179 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1180 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1181 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1183 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1184 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1185 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1186 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1189 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1190 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1191 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1193 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1194 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1195 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1199 case (FX_UM_E0_MODULATE
| FX_UM_E1_REPLACE
): /* Homeworld2 */
1201 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1202 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1203 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
1204 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1206 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1207 tex0
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1208 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1209 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1211 if (ifmt
& (FX_UM_E0_RGB
| FX_UM_E0_LUMINANCE
)) {
1212 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1213 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
1214 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
1216 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1217 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1218 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1221 if (ifmt
& FX_UM_E0_ALPHA
) {
1222 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1223 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
1224 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
1226 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1227 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1228 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1233 fprintf(stderr
, "fxSetupTextureDoubleTMU_NoLock: Unexpected dual texture mode encountered\n");
1237 grAlphaCombine(alphaComb
.Function
,
1242 grColorCombine(colorComb
.Function
,
1247 grTexCombine(GR_TMU0
,
1254 grTexCombine(GR_TMU1
,
1263 /************************* No Texture ***************************/
1266 fxSetupTextureNone_NoLock(GLcontext
* ctx
)
1268 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1269 GrCombineLocal_t localc
, locala
;
1271 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
1272 fprintf(stderr
, "fxSetupTextureNone_NoLock(...)\n");
1275 if ((ctx
->Light
.ShadeModel
== GL_SMOOTH
) || 1 ||
1276 (ctx
->Point
.SmoothFlag
) ||
1277 (ctx
->Line
.SmoothFlag
) ||
1278 (ctx
->Polygon
.SmoothFlag
)) locala
= GR_COMBINE_LOCAL_ITERATED
;
1280 locala
= GR_COMBINE_LOCAL_CONSTANT
;
1282 if (ctx
->Light
.ShadeModel
== GL_SMOOTH
|| 1)
1283 localc
= GR_COMBINE_LOCAL_ITERATED
;
1285 localc
= GR_COMBINE_LOCAL_CONSTANT
;
1287 grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL
,
1288 GR_COMBINE_FACTOR_NONE
,
1290 GR_COMBINE_OTHER_NONE
,
1293 grColorCombine(GR_COMBINE_FUNCTION_LOCAL
,
1294 GR_COMBINE_FACTOR_NONE
,
1296 GR_COMBINE_OTHER_NONE
,
1299 fxMesa
->lastUnitsMode
= FX_UM_NONE
;
1302 #include "fxsetup.h"
1304 /************************************************************************/
1305 /************************** Texture Mode SetUp **************************/
1306 /************************************************************************/
1309 fxSetupTexture_NoLock(GLcontext
* ctx
)
1311 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1313 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
1314 fprintf(stderr
, "fxSetupTexture_NoLock(...)\n");
1317 if (fxMesa
->HaveCmbExt
) {
1318 /* Texture Combine, Color Combine and Alpha Combine. */
1319 if ((ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) &&
1320 (ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) &&
1321 fxMesa
->haveTwoTMUs
) {
1322 fxSetupTextureDoubleTMUNapalm_NoLock(ctx
);
1324 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
1325 fxSetupTextureSingleTMUNapalm_NoLock(ctx
, 0);
1327 else if (ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
1328 fxSetupTextureSingleTMUNapalm_NoLock(ctx
, 1);
1331 fxSetupTextureNoneNapalm_NoLock(ctx
);
1334 /* Texture Combine, Color Combine and Alpha Combine. */
1335 if ((ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) &&
1336 (ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) &&
1337 fxMesa
->haveTwoTMUs
) {
1338 fxSetupTextureDoubleTMU_NoLock(ctx
);
1340 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
1341 fxSetupTextureSingleTMU_NoLock(ctx
, 0);
1343 else if (ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
1344 fxSetupTextureSingleTMU_NoLock(ctx
, 1);
1347 fxSetupTextureNone_NoLock(ctx
);
1353 fxSetupTexture(GLcontext
* ctx
)
1356 fxSetupTexture_NoLock(ctx
);
1360 /************************************************************************/
1361 /**************************** Blend SetUp *******************************/
1362 /************************************************************************/
1365 fxDDBlendFuncSeparate(GLcontext
* ctx
, GLenum sfactor
, GLenum dfactor
, GLenum asfactor
, GLenum adfactor
)
1367 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1368 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1369 GLboolean isNapalm
= (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
);
1370 GLboolean have32bpp
= (fxMesa
->colDepth
== 32);
1371 GLboolean haveAlpha
= fxMesa
->haveHwAlpha
;
1372 GrAlphaBlendFnc_t sfact
, dfact
, asfact
, adfact
;
1375 * 15/16 BPP alpha channel alpha blending modes
1379 * 32 BPP alpha channel alpha blending modes
1381 * 0x1 ASRC_ALPHA Source alpha
1382 * 0x3 ADST_ALPHA Destination alpha
1384 * 0x5 AOMSRC_ALPHA 1 - Source alpha
1385 * 0x7 AOMDST_ALPHA 1 - Destination alpha
1387 * If we don't have HW alpha buffer:
1389 * ONE_MINUS_DST_ALPHA == 0
1390 * Unsupported modes are:
1391 * 1 if used as src blending factor
1392 * 0 if used as dst blending factor
1397 sfact
= GR_BLEND_ZERO
;
1400 sfact
= GR_BLEND_ONE
;
1403 sfact
= GR_BLEND_DST_COLOR
;
1405 case GL_ONE_MINUS_DST_COLOR
:
1406 sfact
= GR_BLEND_ONE_MINUS_DST_COLOR
;
1409 sfact
= GR_BLEND_SRC_ALPHA
;
1411 case GL_ONE_MINUS_SRC_ALPHA
:
1412 sfact
= GR_BLEND_ONE_MINUS_SRC_ALPHA
;
1415 sfact
= haveAlpha
? GR_BLEND_DST_ALPHA
: GR_BLEND_ONE
/*bad*/;
1417 case GL_ONE_MINUS_DST_ALPHA
:
1418 sfact
= haveAlpha
? GR_BLEND_ONE_MINUS_DST_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1420 case GL_SRC_ALPHA_SATURATE
:
1421 sfact
= GR_BLEND_ALPHA_SATURATE
;
1425 sfact
= GR_BLEND_SAME_COLOR_EXT
;
1428 case GL_ONE_MINUS_SRC_COLOR
:
1430 sfact
= GR_BLEND_ONE_MINUS_SAME_COLOR_EXT
;
1434 sfact
= GR_BLEND_ONE
;
1440 asfact
= GR_BLEND_ZERO
;
1443 asfact
= GR_BLEND_ONE
;
1447 asfact
= have32bpp
? GR_BLEND_SRC_ALPHA
: GR_BLEND_ONE
/*bad*/;
1449 case GL_ONE_MINUS_SRC_COLOR
:
1450 case GL_ONE_MINUS_SRC_ALPHA
:
1451 asfact
= have32bpp
? GR_BLEND_ONE_MINUS_SRC_ALPHA
: GR_BLEND_ONE
/*bad*/;
1455 asfact
= (have32bpp
&& haveAlpha
) ? GR_BLEND_DST_ALPHA
: GR_BLEND_ONE
/*bad*/;
1457 case GL_ONE_MINUS_DST_COLOR
:
1458 case GL_ONE_MINUS_DST_ALPHA
:
1459 asfact
= (have32bpp
&& haveAlpha
) ? GR_BLEND_ONE_MINUS_DST_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1461 case GL_SRC_ALPHA_SATURATE
:
1462 asfact
= GR_BLEND_ONE
;
1465 asfact
= GR_BLEND_ONE
;
1471 dfact
= GR_BLEND_ZERO
;
1474 dfact
= GR_BLEND_ONE
;
1477 dfact
= GR_BLEND_SRC_COLOR
;
1479 case GL_ONE_MINUS_SRC_COLOR
:
1480 dfact
= GR_BLEND_ONE_MINUS_SRC_COLOR
;
1483 dfact
= GR_BLEND_SRC_ALPHA
;
1485 case GL_ONE_MINUS_SRC_ALPHA
:
1486 dfact
= GR_BLEND_ONE_MINUS_SRC_ALPHA
;
1489 dfact
= haveAlpha
? GR_BLEND_DST_ALPHA
: GR_BLEND_ONE
/*bad*/;
1491 case GL_ONE_MINUS_DST_ALPHA
:
1492 dfact
= haveAlpha
? GR_BLEND_ONE_MINUS_DST_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1496 dfact
= GR_BLEND_SAME_COLOR_EXT
;
1499 case GL_ONE_MINUS_DST_COLOR
:
1501 dfact
= GR_BLEND_ONE_MINUS_SAME_COLOR_EXT
;
1505 dfact
= GR_BLEND_ZERO
;
1511 adfact
= GR_BLEND_ZERO
;
1514 adfact
= GR_BLEND_ONE
;
1518 adfact
= have32bpp
? GR_BLEND_SRC_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1520 case GL_ONE_MINUS_SRC_COLOR
:
1521 case GL_ONE_MINUS_SRC_ALPHA
:
1522 adfact
= have32bpp
? GR_BLEND_ONE_MINUS_SRC_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1526 adfact
= (have32bpp
&& haveAlpha
) ? GR_BLEND_DST_ALPHA
: GR_BLEND_ONE
/*bad*/;
1528 case GL_ONE_MINUS_DST_COLOR
:
1529 case GL_ONE_MINUS_DST_ALPHA
:
1530 adfact
= (have32bpp
&& haveAlpha
) ? GR_BLEND_ONE_MINUS_DST_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1533 adfact
= GR_BLEND_ZERO
;
1537 if ((sfact
!= us
->blendSrcFuncRGB
) || (asfact
!= us
->blendSrcFuncAlpha
)) {
1538 us
->blendSrcFuncRGB
= sfact
;
1539 us
->blendSrcFuncAlpha
= asfact
;
1540 fxMesa
->new_state
|= FX_NEW_BLEND
;
1543 if ((dfact
!= us
->blendDstFuncRGB
) || (adfact
!= us
->blendDstFuncAlpha
)) {
1544 us
->blendDstFuncRGB
= dfact
;
1545 us
->blendDstFuncAlpha
= adfact
;
1546 fxMesa
->new_state
|= FX_NEW_BLEND
;
1551 fxDDBlendEquationSeparate(GLcontext
* ctx
, GLenum modeRGB
, GLenum modeA
)
1553 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1554 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1559 q
= GR_BLEND_OP_ADD
;
1561 case GL_FUNC_SUBTRACT
:
1562 q
= GR_BLEND_OP_SUB
;
1564 case GL_FUNC_REVERSE_SUBTRACT
:
1565 q
= GR_BLEND_OP_REVSUB
;
1570 if (q
!= us
->blendEqRGB
) {
1572 fxMesa
->new_state
|= FX_NEW_BLEND
;
1577 q
= GR_BLEND_OP_ADD
;
1579 case GL_FUNC_SUBTRACT
:
1580 q
= GR_BLEND_OP_SUB
;
1582 case GL_FUNC_REVERSE_SUBTRACT
:
1583 q
= GR_BLEND_OP_REVSUB
;
1586 q
= us
->blendEqAlpha
;
1588 if (q
!= us
->blendEqAlpha
) {
1589 us
->blendEqAlpha
= q
;
1590 fxMesa
->new_state
|= FX_NEW_BLEND
;
1595 fxSetupBlend(GLcontext
* ctx
)
1597 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1598 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1600 if (fxMesa
->HavePixExt
) {
1601 if (us
->blendEnabled
) {
1602 fxMesa
->Glide
.grAlphaBlendFunctionExt(us
->blendSrcFuncRGB
, us
->blendDstFuncRGB
,
1604 us
->blendSrcFuncAlpha
, us
->blendDstFuncAlpha
,
1607 fxMesa
->Glide
.grAlphaBlendFunctionExt(GR_BLEND_ONE
, GR_BLEND_ZERO
,
1609 GR_BLEND_ONE
, GR_BLEND_ZERO
,
1613 if (us
->blendEnabled
) {
1614 grAlphaBlendFunction(us
->blendSrcFuncRGB
, us
->blendDstFuncRGB
,
1615 us
->blendSrcFuncAlpha
, us
->blendDstFuncAlpha
);
1617 grAlphaBlendFunction(GR_BLEND_ONE
, GR_BLEND_ZERO
,
1618 GR_BLEND_ONE
, GR_BLEND_ZERO
);
1623 /************************************************************************/
1624 /************************** Alpha Test SetUp ****************************/
1625 /************************************************************************/
1628 fxDDAlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
1630 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1631 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1634 (us
->alphaTestFunc
!= func
)
1636 (us
->alphaTestRefValue
!= ref
)
1638 us
->alphaTestFunc
= func
;
1639 us
->alphaTestRefValue
= ref
;
1640 fxMesa
->new_state
|= FX_NEW_ALPHA
;
1645 fxSetupAlphaTest(GLcontext
* ctx
)
1647 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1648 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1650 if (us
->alphaTestEnabled
) {
1651 GrAlpha_t ref
= (GLint
) (us
->alphaTestRefValue
* 255.0);
1652 grAlphaTestFunction(us
->alphaTestFunc
- GL_NEVER
+ GR_CMP_NEVER
);
1653 grAlphaTestReferenceValue(ref
);
1656 grAlphaTestFunction(GR_CMP_ALWAYS
);
1659 /************************************************************************/
1660 /************************** Depth Test SetUp ****************************/
1661 /************************************************************************/
1664 fxDDDepthFunc(GLcontext
* ctx
, GLenum func
)
1666 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1667 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1669 if (us
->depthTestFunc
!= func
) {
1670 us
->depthTestFunc
= func
;
1671 fxMesa
->new_state
|= FX_NEW_DEPTH
;
1676 fxDDDepthMask(GLcontext
* ctx
, GLboolean flag
)
1678 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1679 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1681 if (flag
!= us
->depthMask
) {
1682 us
->depthMask
= flag
;
1683 fxMesa
->new_state
|= FX_NEW_DEPTH
;
1688 fxSetupDepthTest(GLcontext
* ctx
)
1690 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1691 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1693 if (us
->depthTestEnabled
) {
1694 grDepthBufferFunction(us
->depthTestFunc
- GL_NEVER
+ GR_CMP_NEVER
);
1695 grDepthMask(us
->depthMask
);
1698 grDepthBufferFunction(GR_CMP_ALWAYS
);
1699 grDepthMask(FXFALSE
);
1703 /************************************************************************/
1704 /************************** Stencil SetUp *******************************/
1705 /************************************************************************/
1707 static GrStencil_t
convertGLStencilOp( GLenum op
)
1711 return GR_STENCILOP_KEEP
;
1713 return GR_STENCILOP_ZERO
;
1715 return GR_STENCILOP_REPLACE
;
1717 return GR_STENCILOP_INCR_CLAMP
;
1719 return GR_STENCILOP_DECR_CLAMP
;
1721 return GR_STENCILOP_INVERT
;
1722 case GL_INCR_WRAP_EXT
:
1723 return GR_STENCILOP_INCR_WRAP
;
1724 case GL_DECR_WRAP_EXT
:
1725 return GR_STENCILOP_DECR_WRAP
;
1727 _mesa_problem( NULL
, "bad stencil op in convertGLStencilOp" );
1729 return GR_STENCILOP_KEEP
; /* never get, silence compiler warning */
1733 fxDDStencilFunc (GLcontext
*ctx
, GLenum func
, GLint ref
, GLuint mask
)
1735 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1736 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1739 (us
->stencilFunction
!= func
)
1741 (us
->stencilRefValue
!= ref
)
1743 (us
->stencilValueMask
!= mask
)
1745 us
->stencilFunction
= func
;
1746 us
->stencilRefValue
= ref
;
1747 us
->stencilValueMask
= mask
;
1748 fxMesa
->new_state
|= FX_NEW_STENCIL
;
1753 fxDDStencilMask (GLcontext
*ctx
, GLuint mask
)
1755 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1756 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1758 if (us
->stencilWriteMask
!= mask
) {
1759 us
->stencilWriteMask
= mask
;
1760 fxMesa
->new_state
|= FX_NEW_STENCIL
;
1765 fxDDStencilOp (GLcontext
*ctx
, GLenum sfail
, GLenum zfail
, GLenum zpass
)
1767 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1768 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1771 (us
->stencilFailFunc
!= sfail
)
1773 (us
->stencilZFailFunc
!= zfail
)
1775 (us
->stencilZPassFunc
!= zpass
)
1777 us
->stencilFailFunc
= sfail
;
1778 us
->stencilZFailFunc
= zfail
;
1779 us
->stencilZPassFunc
= zpass
;
1780 fxMesa
->new_state
|= FX_NEW_STENCIL
;
1785 fxSetupStencil (GLcontext
* ctx
)
1787 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1788 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1790 if (us
->stencilEnabled
) {
1791 grEnable(GR_STENCIL_MODE_EXT
);
1792 fxMesa
->Glide
.grStencilOpExt(convertGLStencilOp(us
->stencilFailFunc
),
1793 convertGLStencilOp(us
->stencilZFailFunc
),
1794 convertGLStencilOp(us
->stencilZPassFunc
));
1795 fxMesa
->Glide
.grStencilFuncExt(us
->stencilFunction
- GL_NEVER
+ GR_CMP_NEVER
,
1796 us
->stencilRefValue
,
1797 us
->stencilValueMask
);
1798 fxMesa
->Glide
.grStencilMaskExt(us
->stencilWriteMask
);
1800 grDisable(GR_STENCIL_MODE_EXT
);
1804 /************************************************************************/
1805 /**************************** Color Mask SetUp **************************/
1806 /************************************************************************/
1809 fxDDColorMask(GLcontext
* ctx
,
1810 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
1812 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1813 fxMesa
->new_state
|= FX_NEW_COLOR_MASK
;
1821 fxSetupColorMask(GLcontext
* ctx
)
1823 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1825 if (fxMesa
->colDepth
== 32) {
1827 fxMesa
->Glide
.grColorMaskExt(ctx
->Color
.ColorMask
[RCOMP
],
1828 ctx
->Color
.ColorMask
[GCOMP
],
1829 ctx
->Color
.ColorMask
[BCOMP
],
1830 ctx
->Color
.ColorMask
[ACOMP
] && fxMesa
->haveHwAlpha
);
1833 /* 15/16 bpp mode */
1834 grColorMask(ctx
->Color
.ColorMask
[RCOMP
] |
1835 ctx
->Color
.ColorMask
[GCOMP
] |
1836 ctx
->Color
.ColorMask
[BCOMP
],
1837 ctx
->Color
.ColorMask
[ACOMP
] && fxMesa
->haveHwAlpha
);
1844 /************************************************************************/
1845 /**************************** Fog Mode SetUp ****************************/
1846 /************************************************************************/
1849 * This is called during state update in order to update the Glide fog state.
1852 fxSetupFog(GLcontext
* ctx
)
1854 if (ctx
->Fog
.Enabled
/*&& ctx->FogMode==FOG_FRAGMENT */ ) {
1855 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1857 /* update fog color */
1859 col
[0] = (unsigned int) (255 * ctx
->Fog
.Color
[0]);
1860 col
[1] = (unsigned int) (255 * ctx
->Fog
.Color
[1]);
1861 col
[2] = (unsigned int) (255 * ctx
->Fog
.Color
[2]);
1862 col
[3] = (unsigned int) (255 * ctx
->Fog
.Color
[3]);
1863 grFogColorValue(FXCOLOR4(col
));
1865 if (fxMesa
->fogTableMode
!= ctx
->Fog
.Mode
||
1866 fxMesa
->fogDensity
!= ctx
->Fog
.Density
||
1867 fxMesa
->fogStart
!= ctx
->Fog
.Start
||
1868 fxMesa
->fogEnd
!= ctx
->Fog
.End
) {
1869 /* reload the fog table */
1870 switch (ctx
->Fog
.Mode
) {
1872 guFogGenerateLinear(fxMesa
->fogTable
, ctx
->Fog
.Start
,
1874 if (fxMesa
->fogTable
[0] > 63) {
1875 /* [dBorca] Hack alert:
1876 * As per Glide3 Programming Guide:
1877 * The difference between consecutive fog values
1878 * must be less than 64.
1880 fxMesa
->fogTable
[0] = 63;
1884 guFogGenerateExp(fxMesa
->fogTable
, ctx
->Fog
.Density
);
1887 guFogGenerateExp2(fxMesa
->fogTable
, ctx
->Fog
.Density
);
1892 fxMesa
->fogTableMode
= ctx
->Fog
.Mode
;
1893 fxMesa
->fogDensity
= ctx
->Fog
.Density
;
1894 fxMesa
->fogStart
= ctx
->Fog
.Start
;
1895 fxMesa
->fogEnd
= ctx
->Fog
.End
;
1898 grFogTable(fxMesa
->fogTable
);
1899 if (ctx
->Fog
.FogCoordinateSource
== GL_FOG_COORDINATE_EXT
) {
1900 grVertexLayout(GR_PARAM_FOG_EXT
, GR_VERTEX_FOG_OFFSET
<< 2,
1902 grFogMode(GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT
);
1904 grVertexLayout(GR_PARAM_FOG_EXT
, GR_VERTEX_FOG_OFFSET
<< 2,
1906 grFogMode(GR_FOG_WITH_TABLE_ON_Q
);
1910 grFogMode(GR_FOG_DISABLE
);
1915 fxDDFogfv(GLcontext
* ctx
, GLenum pname
, const GLfloat
* params
)
1917 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_FOG
;
1919 case GL_FOG_COORDINATE_SOURCE_EXT
: {
1920 GLenum p
= (GLenum
)*params
;
1921 if (p
== GL_FOG_COORDINATE_EXT
) {
1922 _swrast_allow_vertex_fog(ctx
, GL_TRUE
);
1923 _swrast_allow_pixel_fog(ctx
, GL_FALSE
);
1924 _tnl_allow_vertex_fog( ctx
, GL_TRUE
);
1925 _tnl_allow_pixel_fog( ctx
, GL_FALSE
);
1927 _swrast_allow_vertex_fog(ctx
, GL_FALSE
);
1928 _swrast_allow_pixel_fog(ctx
, GL_TRUE
);
1929 _tnl_allow_vertex_fog( ctx
, GL_FALSE
);
1930 _tnl_allow_pixel_fog( ctx
, GL_TRUE
);
1939 /************************************************************************/
1940 /************************** Scissor Test SetUp **************************/
1941 /************************************************************************/
1943 /* This routine is used in managing the lock state, and therefore can't lock */
1945 fxSetScissorValues(GLcontext
* ctx
)
1947 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1951 if (ctx
->Scissor
.Enabled
) {
1952 xmin
= ctx
->Scissor
.X
;
1953 xmax
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
;
1954 ymin
= ctx
->Scissor
.Y
;
1955 ymax
= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
;
1959 if (xmax
> fxMesa
->width
)
1960 xmax
= fxMesa
->width
;
1961 if (ymin
< fxMesa
->screen_height
- fxMesa
->height
)
1962 ymin
= fxMesa
->screen_height
- fxMesa
->height
;
1963 if (ymax
> fxMesa
->screen_height
- 0)
1964 ymax
= fxMesa
->screen_height
- 0;
1969 xmax
= fxMesa
->width
;
1970 ymax
= fxMesa
->height
;
1973 fxMesa
->clipMinX
= xmin
;
1974 fxMesa
->clipMinY
= ymin
;
1975 fxMesa
->clipMaxX
= xmax
;
1976 fxMesa
->clipMaxY
= ymax
;
1977 grClipWindow(xmin
, ymin
, xmax
, ymax
);
1981 fxSetupScissor(GLcontext
* ctx
)
1984 fxSetScissorValues(ctx
);
1989 fxDDScissor(GLcontext
* ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
1991 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_SCISSOR
;
1994 /************************************************************************/
1995 /*************************** Cull mode setup ****************************/
1996 /************************************************************************/
2000 fxDDCullFace(GLcontext
* ctx
, GLenum mode
)
2003 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_CULL
;
2007 fxDDFrontFace(GLcontext
* ctx
, GLenum mode
)
2010 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_CULL
;
2015 fxSetupCull(GLcontext
* ctx
)
2017 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
2018 GrCullMode_t mode
= GR_CULL_DISABLE
;
2020 if (ctx
->Polygon
.CullFlag
&& (fxMesa
->raster_primitive
== GL_TRIANGLES
)) {
2021 switch (ctx
->Polygon
.CullFaceMode
) {
2023 if (ctx
->Polygon
.FrontFace
== GL_CCW
)
2024 mode
= GR_CULL_NEGATIVE
;
2026 mode
= GR_CULL_POSITIVE
;
2029 if (ctx
->Polygon
.FrontFace
== GL_CCW
)
2030 mode
= GR_CULL_POSITIVE
;
2032 mode
= GR_CULL_NEGATIVE
;
2034 case GL_FRONT_AND_BACK
:
2035 /* Handled as a fallback on triangles in tdfx_tris.c */
2043 if (fxMesa
->cullMode
!= mode
) {
2044 fxMesa
->cullMode
= mode
;
2050 /************************************************************************/
2051 /****************************** DD Enable ******************************/
2052 /************************************************************************/
2055 fxDDEnable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
2057 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
2058 tfxUnitsState
*us
= &fxMesa
->unitsState
;
2060 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
2061 fprintf(stderr
, "%s(%s)\n", state
? "fxDDEnable" : "fxDDDisable",
2062 _mesa_lookup_enum_by_nr(cap
));
2067 if (state
!= us
->alphaTestEnabled
) {
2068 us
->alphaTestEnabled
= state
;
2069 fxMesa
->new_state
|= FX_NEW_ALPHA
;
2073 if (state
!= us
->blendEnabled
) {
2074 us
->blendEnabled
= state
;
2075 fxMesa
->new_state
|= FX_NEW_BLEND
;
2079 if (state
!= us
->depthTestEnabled
) {
2080 us
->depthTestEnabled
= state
;
2081 fxMesa
->new_state
|= FX_NEW_DEPTH
;
2084 case GL_STENCIL_TEST
:
2085 if (fxMesa
->haveHwStencil
&& state
!= us
->stencilEnabled
) {
2086 us
->stencilEnabled
= state
;
2087 fxMesa
->new_state
|= FX_NEW_STENCIL
;
2092 grDitherMode(GR_DITHER_4x4
);
2095 grDitherMode(GR_DITHER_DISABLE
);
2098 case GL_SCISSOR_TEST
:
2099 fxMesa
->new_state
|= FX_NEW_SCISSOR
;
2101 case GL_SHARED_TEXTURE_PALETTE_EXT
:
2102 fxDDTexUseGlbPalette(ctx
, state
);
2105 fxMesa
->new_state
|= FX_NEW_FOG
;
2108 fxMesa
->new_state
|= FX_NEW_CULL
;
2110 case GL_LINE_SMOOTH
:
2111 case GL_LINE_STIPPLE
:
2112 case GL_POINT_SMOOTH
:
2113 case GL_POLYGON_SMOOTH
:
2116 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
2126 /************************************************************************/
2127 /************************** Changes to units state **********************/
2128 /************************************************************************/
2131 /* All units setup is handled under texture setup.
2134 fxDDShadeModel(GLcontext
* ctx
, GLenum mode
)
2136 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_TEXTURING
;
2141 /************************************************************************/
2142 /****************************** Units SetUp *****************************/
2143 /************************************************************************/
2145 fx_print_state_flags(const char *msg
, GLuint flags
)
2148 "%s: (0x%x) %s%s%s%s%s%s%s%s\n",
2151 (flags
& FX_NEW_TEXTURING
) ? "texture, " : "",
2152 (flags
& FX_NEW_BLEND
) ? "blend, " : "",
2153 (flags
& FX_NEW_ALPHA
) ? "alpha, " : "",
2154 (flags
& FX_NEW_FOG
) ? "fog, " : "",
2155 (flags
& FX_NEW_SCISSOR
) ? "scissor, " : "",
2156 (flags
& FX_NEW_COLOR_MASK
) ? "colormask, " : "",
2157 (flags
& FX_NEW_CULL
) ? "cull, " : "",
2158 (flags
& FX_NEW_STENCIL
) ? "stencil, " : "");
2162 fxSetupFXUnits(GLcontext
* ctx
)
2164 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
2165 GLuint newstate
= fxMesa
->new_state
;
2167 if (TDFX_DEBUG
& VERBOSE_DRIVER
)
2168 fx_print_state_flags("fxSetupFXUnits", newstate
);
2171 if (newstate
& FX_NEW_TEXTURING
)
2172 fxSetupTexture(ctx
);
2174 if (newstate
& FX_NEW_BLEND
)
2177 if (newstate
& FX_NEW_ALPHA
)
2178 fxSetupAlphaTest(ctx
);
2180 if (newstate
& FX_NEW_DEPTH
)
2181 fxSetupDepthTest(ctx
);
2183 if (newstate
& FX_NEW_STENCIL
)
2184 fxSetupStencil(ctx
);
2186 if (newstate
& FX_NEW_FOG
)
2189 if (newstate
& FX_NEW_SCISSOR
)
2190 fxSetupScissor(ctx
);
2192 if (newstate
& FX_NEW_COLOR_MASK
)
2193 fxSetupColorMask(ctx
);
2195 if (newstate
& FX_NEW_CULL
)
2198 fxMesa
->new_state
= 0;
2208 * Need this to provide at least one external definition.
2211 extern int gl_fx_dummy_function_setup(void);
2213 gl_fx_dummy_function_setup(void)