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 /* [dBorca] Hack alert:
507 * don't use GR_COMBINE_FUNCTION_SCALE_OTHER
508 * such that Glide recognizes TMU0 in passthrough mode
510 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND
;
511 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
512 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND
;
513 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
515 fxMesa
->tmuSrc
= FX_TMU1
;
519 grTexCombine(GR_TMU0
,
526 if (fxMesa
->haveTwoTMUs
) {
527 grTexCombine(GR_TMU1
,
538 fxSetupTextureSingleTMU_NoLock(GLcontext
* ctx
, GLuint textureset
)
540 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
541 struct tdfx_combine alphaComb
, colorComb
;
542 GrCombineLocal_t localc
, locala
;
546 struct gl_texture_object
*tObj
= ctx
->Texture
.Unit
[textureset
]._Current
;
549 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
550 fprintf(stderr
, "fxSetupTextureSingleTMU_NoLock(%d)\n", textureset
);
553 ti
= fxTMGetTexInfo(tObj
);
555 fxTexValidate(ctx
, tObj
);
557 fxSetupSingleTMU_NoLock(fxMesa
, tObj
);
559 if (ti
->whichTMU
== FX_TMU_BOTH
)
563 if (fxMesa
->tmuSrc
!= tmu
)
564 fxSelectSingleTMUSrc_NoLock(fxMesa
, tmu
, ti
->LODblend
);
566 if (textureset
== 0 || !fxMesa
->haveTwoTMUs
)
567 unitsmode
= fxGetTexSetConfiguration(ctx
, tObj
, NULL
);
569 unitsmode
= fxGetTexSetConfiguration(ctx
, NULL
, tObj
);
571 /* if(fxMesa->lastUnitsMode==unitsmode) */
574 fxMesa
->lastUnitsMode
= unitsmode
;
576 fxMesa
->stw_hint_state
= 0;
577 FX_grHints_NoLock(GR_HINT_STWHINT
, 0);
579 ifmt
= ti
->baseLevelInternalFormat
;
581 if (unitsmode
& FX_UM_ALPHA_ITERATED
)
582 locala
= GR_COMBINE_LOCAL_ITERATED
;
584 locala
= GR_COMBINE_LOCAL_CONSTANT
;
586 if (unitsmode
& FX_UM_COLOR_ITERATED
)
587 localc
= GR_COMBINE_LOCAL_ITERATED
;
589 localc
= GR_COMBINE_LOCAL_CONSTANT
;
591 if (TDFX_DEBUG
& (VERBOSE_DRIVER
| VERBOSE_TEXTURE
))
592 fprintf(stderr
, "fxSetupTextureSingleTMU_NoLock: envmode is %s\n",
593 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[textureset
].EnvMode
));
595 alphaComb
.Local
= locala
;
596 alphaComb
.Invert
= FXFALSE
;
597 colorComb
.Local
= localc
;
598 colorComb
.Invert
= FXFALSE
;
600 switch (ctx
->Texture
.Unit
[textureset
].EnvMode
) {
602 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
603 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
604 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
606 colorComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
607 colorComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_ALPHA
;
608 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
611 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
612 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
613 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
615 if (ifmt
== GL_ALPHA
) {
616 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
617 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
618 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
620 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
621 colorComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
622 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
626 if (ifmt
== GL_LUMINANCE
|| ifmt
== GL_RGB
) {
628 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
629 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
630 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
632 else if (ifmt
== GL_INTENSITY
) {
633 /* Av = Af * (1 - It) + Ac * It */
634 alphaComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
635 alphaComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_ALPHA
;
636 alphaComb
.Other
= GR_COMBINE_OTHER_CONSTANT
;
640 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
641 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
642 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
645 if (ifmt
== GL_ALPHA
) {
646 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
647 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
648 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
650 if (fxMesa
->type
>= GR_SSTTYPE_Voodoo2
) {
651 colorComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
652 colorComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_RGB
;
653 colorComb
.Other
= GR_COMBINE_OTHER_CONSTANT
;
654 } else if (ifmt
== GL_INTENSITY
) {
655 /* just a hack: RGB == ALPHA */
656 colorComb
.Function
= GR_COMBINE_FUNCTION_BLEND
;
657 colorComb
.Factor
= GR_COMBINE_FACTOR_TEXTURE_ALPHA
;
658 colorComb
.Other
= GR_COMBINE_OTHER_CONSTANT
;
660 /* [dBorca] Hack alert:
661 * only Voodoo^2 can GL_BLEND (GR_COMBINE_FACTOR_TEXTURE_RGB)
662 * These settings assume that the TexEnv color is black
663 * and incoming fragment color is white.
665 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
666 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
667 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
668 colorComb
.Invert
= FXTRUE
;
669 _mesa_problem(NULL
, "can't GL_BLEND with SST1");
673 grConstantColorValue(
674 (((GLuint
)(ctx
->Texture
.Unit
[textureset
].EnvColor
[0] * 255.0f
)) ) |
675 (((GLuint
)(ctx
->Texture
.Unit
[textureset
].EnvColor
[1] * 255.0f
)) << 8) |
676 (((GLuint
)(ctx
->Texture
.Unit
[textureset
].EnvColor
[2] * 255.0f
)) << 16) |
677 (((GLuint
)(ctx
->Texture
.Unit
[textureset
].EnvColor
[3] * 255.0f
)) << 24));
680 if ((ifmt
== GL_RGB
) || (ifmt
== GL_LUMINANCE
)) {
681 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
682 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
683 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
685 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
686 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
687 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
690 if (ifmt
== GL_ALPHA
) {
691 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
692 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
693 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
695 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
696 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
697 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
701 if (ifmt
== GL_ALPHA
||
702 ifmt
== GL_LUMINANCE_ALPHA
||
704 /* product of texel and fragment alpha */
705 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
706 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
707 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
709 else if (ifmt
== GL_LUMINANCE
|| ifmt
== GL_RGB
) {
710 /* fragment alpha is unchanged */
711 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
712 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
713 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
716 /* sum of texel and fragment alpha */
717 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
718 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
719 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
722 if (ifmt
== GL_ALPHA
) {
724 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
725 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
726 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
729 /* sum of texel and fragment rgb */
730 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
731 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
732 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
736 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
737 fprintf(stderr
, "fxSetupTextureSingleTMU_NoLock: %x Texture.EnvMode not yet supported\n",
738 ctx
->Texture
.Unit
[textureset
].EnvMode
);
743 grAlphaCombine(alphaComb
.Function
,
748 grColorCombine(colorComb
.Function
,
757 fxSetupTextureSingleTMU(GLcontext
* ctx
, GLuint textureset
)
760 fxSetupTextureSingleTMU_NoLock(ctx
, textureset
);
766 /************************* Double Texture Set ***************************/
769 fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa
,
770 struct gl_texture_object
*tObj0
,
771 struct gl_texture_object
*tObj1
)
773 #define T0_NOT_IN_TMU 0x01
774 #define T1_NOT_IN_TMU 0x02
775 #define T0_IN_TMU0 0x04
776 #define T1_IN_TMU0 0x08
777 #define T0_IN_TMU1 0x10
778 #define T1_IN_TMU1 0x20
780 tfxTexInfo
*ti0
= fxTMGetTexInfo(tObj0
);
781 tfxTexInfo
*ti1
= fxTMGetTexInfo(tObj1
);
783 int tmu0
= 0, tmu1
= 1;
785 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
786 fprintf(stderr
, "fxSetupDoubleTMU_NoLock(...)\n");
789 /* We shouldn't need to do this. There is something wrong with
790 mutlitexturing when the TMUs are swapped. So, we're forcing
791 them to always be loaded correctly. !!! */
792 if (ti0
->whichTMU
== FX_TMU1
)
793 fxTMMoveOutTM_NoLock(fxMesa
, tObj0
);
794 if (ti1
->whichTMU
== FX_TMU0
)
795 fxTMMoveOutTM_NoLock(fxMesa
, tObj1
);
798 switch (ti0
->whichTMU
) {
800 tstate
|= T0_IN_TMU0
;
803 tstate
|= T0_IN_TMU1
;
806 tstate
|= T0_IN_TMU0
| T0_IN_TMU1
;
809 tstate
|= T0_NOT_IN_TMU
;
814 tstate
|= T0_NOT_IN_TMU
;
817 switch (ti1
->whichTMU
) {
819 tstate
|= T1_IN_TMU0
;
822 tstate
|= T1_IN_TMU1
;
825 tstate
|= T1_IN_TMU0
| T1_IN_TMU1
;
828 tstate
|= T1_NOT_IN_TMU
;
833 tstate
|= T1_NOT_IN_TMU
;
835 ti0
->lastTimeUsed
= fxMesa
->texBindNumber
;
836 ti1
->lastTimeUsed
= fxMesa
->texBindNumber
;
838 /* Move texture maps into TMUs */
840 if (!(((tstate
& T0_IN_TMU0
) && (tstate
& T1_IN_TMU1
)) ||
841 ((tstate
& T0_IN_TMU1
) && (tstate
& T1_IN_TMU0
)))) {
843 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU_BOTH
);
845 /* Find the minimal way to correct the situation */
846 if ((tstate
& T0_IN_TMU0
) || (tstate
& T1_IN_TMU1
)) {
847 /* We have one in the standard order, setup the other */
848 if (tstate
& T0_IN_TMU0
) { /* T0 is in TMU0, put T1 in TMU1 */
849 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU1
);
852 fxTMMoveInTM_NoLock(fxMesa
, tObj0
, FX_TMU0
);
854 /* tmu0 and tmu1 are setup */
856 else if ((tstate
& T0_IN_TMU1
) || (tstate
& T1_IN_TMU0
)) {
857 /* we have one in the reverse order, setup the other */
858 if (tstate
& T1_IN_TMU0
) { /* T1 is in TMU0, put T0 in TMU1 */
859 fxTMMoveInTM_NoLock(fxMesa
, tObj0
, FX_TMU1
);
862 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU0
);
867 else { /* Nothing is loaded */
868 fxTMMoveInTM_NoLock(fxMesa
, tObj0
, FX_TMU0
);
869 fxTMMoveInTM_NoLock(fxMesa
, tObj1
, FX_TMU1
);
870 /* tmu0 and tmu1 are setup */
875 /* [dBorca] Hack alert:
876 * we put these in reverse order, so that if we can't
877 * do _REAL_ pointcast, the TMU0 table gets broadcasted
879 if (!fxMesa
->haveGlobalPaletteTexture
) {
881 if (ti1
->info
.format
== GR_TEXFMT_P_8
) {
882 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
883 fprintf(stderr
, "fxSetupDoubleTMU_NoLock: uploading texture palette for TMU1\n");
885 fxMesa
->Glide
.grTexDownloadTableExt(ti1
->whichTMU
, ti1
->paltype
, &(ti1
->palette
));
887 if (ti0
->info
.format
== GR_TEXFMT_P_8
) {
888 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
889 fprintf(stderr
, "fxSetupDoubleTMU_NoLock: uploading texture palette for TMU0\n");
891 fxMesa
->Glide
.grTexDownloadTableExt(ti0
->whichTMU
, ti0
->paltype
, &(ti0
->palette
));
896 if ((ti1
->info
.format
== GR_TEXFMT_AYIQ_8422
) ||
897 (ti1
->info
.format
== GR_TEXFMT_YIQ_422
)) {
898 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
899 fprintf(stderr
, "fxSetupDoubleTMU_NoLock: uploading NCC0 table for TMU1\n");
901 fxMesa
->Glide
.grTexDownloadTableExt(ti1
->whichTMU
, GR_TEXTABLE_NCC0
, &(ti1
->palette
));
903 if ((ti0
->info
.format
== GR_TEXFMT_AYIQ_8422
) ||
904 (ti0
->info
.format
== GR_TEXFMT_YIQ_422
)) {
905 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
906 fprintf(stderr
, "fxSetupDoubleTMU_NoLock: uploading NCC0 table for TMU0\n");
908 fxMesa
->Glide
.grTexDownloadTableExt(ti0
->whichTMU
, GR_TEXTABLE_NCC0
, &(ti0
->palette
));
912 grTexSource(tmu0
, ti0
->tm
[tmu0
]->startAddr
,
913 GR_MIPMAPLEVELMASK_BOTH
, &(ti0
->info
));
914 grTexClampMode(tmu0
, ti0
->sClamp
, ti0
->tClamp
);
915 grTexFilterMode(tmu0
, ti0
->minFilt
, ti0
->maxFilt
);
916 grTexMipMapMode(tmu0
, ti0
->mmMode
, FXFALSE
);
918 grTexSource(tmu1
, ti1
->tm
[tmu1
]->startAddr
,
919 GR_MIPMAPLEVELMASK_BOTH
, &(ti1
->info
));
920 grTexClampMode(tmu1
, ti1
->sClamp
, ti1
->tClamp
);
921 grTexFilterMode(tmu1
, ti1
->minFilt
, ti1
->maxFilt
);
922 grTexMipMapMode(tmu1
, ti1
->mmMode
, FXFALSE
);
933 fxSetupTextureDoubleTMU_NoLock(GLcontext
* ctx
)
935 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
936 struct tdfx_combine alphaComb
, colorComb
;
937 struct tdfx_texcombine tex0
, tex1
;
938 GrCombineLocal_t localc
, locala
;
939 tfxTexInfo
*ti0
, *ti1
;
940 struct gl_texture_object
*tObj0
= ctx
->Texture
.Unit
[1]._Current
;
941 struct gl_texture_object
*tObj1
= ctx
->Texture
.Unit
[0]._Current
;
942 GLuint envmode
, ifmt
, unitsmode
;
943 int tmu0
= 0, tmu1
= 1;
945 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
946 fprintf(stderr
, "fxSetupTextureDoubleTMU_NoLock(...)\n");
949 ti0
= fxTMGetTexInfo(tObj0
);
950 fxTexValidate(ctx
, tObj0
);
952 ti1
= fxTMGetTexInfo(tObj1
);
953 fxTexValidate(ctx
, tObj1
);
955 fxSetupDoubleTMU_NoLock(fxMesa
, tObj0
, tObj1
);
957 unitsmode
= fxGetTexSetConfiguration(ctx
, tObj0
, tObj1
);
959 /* if(fxMesa->lastUnitsMode==unitsmode) */
962 fxMesa
->lastUnitsMode
= unitsmode
;
964 fxMesa
->stw_hint_state
|= GR_STWHINT_ST_DIFF_TMU1
;
965 FX_grHints_NoLock(GR_HINT_STWHINT
, fxMesa
->stw_hint_state
);
967 envmode
= unitsmode
& FX_UM_E_ENVMODE
;
968 ifmt
= unitsmode
& FX_UM_E_IFMT
;
970 if (unitsmode
& FX_UM_ALPHA_ITERATED
)
971 locala
= GR_COMBINE_LOCAL_ITERATED
;
973 locala
= GR_COMBINE_LOCAL_CONSTANT
;
975 if (unitsmode
& FX_UM_COLOR_ITERATED
)
976 localc
= GR_COMBINE_LOCAL_ITERATED
;
978 localc
= GR_COMBINE_LOCAL_CONSTANT
;
981 if (TDFX_DEBUG
& (VERBOSE_DRIVER
| VERBOSE_TEXTURE
))
982 fprintf(stderr
, "fxSetupTextureDoubleTMU_NoLock: envmode is %s/%s\n",
983 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[0].EnvMode
),
984 _mesa_lookup_enum_by_nr(ctx
->Texture
.Unit
[1].EnvMode
));
987 if ((ti0
->whichTMU
== FX_TMU1
) || (ti1
->whichTMU
== FX_TMU0
)) {
991 fxMesa
->tmuSrc
= FX_TMU_BOTH
;
993 tex0
.InvertRGB
= FXFALSE
;
994 tex0
.InvertAlpha
= FXFALSE
;
995 tex1
.InvertRGB
= FXFALSE
;
996 tex1
.InvertAlpha
= FXFALSE
;
997 alphaComb
.Local
= locala
;
998 alphaComb
.Invert
= FXFALSE
;
999 colorComb
.Local
= localc
;
1000 colorComb
.Invert
= FXFALSE
;
1003 case (FX_UM_E0_MODULATE
| FX_UM_E1_MODULATE
):
1005 GLboolean isalpha
[FX_NUM_TMU
];
1007 isalpha
[tmu0
] = (ti0
->baseLevelInternalFormat
== GL_ALPHA
);
1008 isalpha
[tmu1
] = (ti1
->baseLevelInternalFormat
== GL_ALPHA
);
1010 if (isalpha
[FX_TMU1
]) {
1011 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1012 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1013 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1014 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1015 tex1
.InvertRGB
= FXTRUE
;
1017 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1018 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1019 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1020 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1023 if (isalpha
[FX_TMU0
]) {
1024 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1025 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1026 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1027 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1029 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1030 tex0
.FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1031 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1032 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1035 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1036 colorComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1037 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1039 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1040 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1041 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1044 case (FX_UM_E0_REPLACE
| FX_UM_E1_BLEND
): /* Only for GLQuake */
1045 if (tmu0
== FX_TMU1
) {
1046 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1047 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1048 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1049 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1050 tex1
.InvertRGB
= FXTRUE
;
1052 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1053 tex0
.FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1054 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1055 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1058 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1059 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1060 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1061 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1063 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1064 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
;
1065 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1066 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE_MINUS_LOCAL
;
1069 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1070 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
1071 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
1073 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1074 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1075 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1077 case (FX_UM_E0_REPLACE
| FX_UM_E1_MODULATE
): /* Quake 2 and 3 */
1078 if (tmu1
== FX_TMU1
) {
1079 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1080 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1081 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
1082 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1083 tex1
.InvertAlpha
= FXTRUE
;
1085 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1086 tex0
.FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1087 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1088 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_LOCAL
;
1091 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1092 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1093 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1094 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1096 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1097 tex0
.FactorRGB
= GR_COMBINE_FACTOR_LOCAL
;
1098 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_BLEND_OTHER
;
1099 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1102 if (ti0
->baseLevelInternalFormat
== GL_RGB
) {
1103 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1104 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
1105 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
1107 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1108 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1109 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
1112 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1113 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1114 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1118 case (FX_UM_E0_MODULATE
| FX_UM_E1_ADD
): /* Quake 3 Sky */
1120 GLboolean isalpha
[FX_NUM_TMU
];
1122 isalpha
[tmu0
] = (ti0
->baseLevelInternalFormat
== GL_ALPHA
);
1123 isalpha
[tmu1
] = (ti1
->baseLevelInternalFormat
== GL_ALPHA
);
1125 if (isalpha
[FX_TMU1
]) {
1126 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1127 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1128 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1129 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1130 tex1
.InvertRGB
= FXTRUE
;
1132 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1133 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1134 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1135 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1138 if (isalpha
[FX_TMU0
]) {
1139 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1140 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1141 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1142 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1144 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1145 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1146 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1147 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1150 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1151 colorComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1152 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1154 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1155 alphaComb
.Factor
= GR_COMBINE_FACTOR_LOCAL
;
1156 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1160 case (FX_UM_E0_REPLACE
| FX_UM_E1_ADD
): /* Vulpine Sky */
1162 GLboolean isalpha
[FX_NUM_TMU
];
1164 isalpha
[tmu0
] = (ti0
->baseLevelInternalFormat
== GL_ALPHA
);
1165 isalpha
[tmu1
] = (ti1
->baseLevelInternalFormat
== GL_ALPHA
);
1167 if (isalpha
[FX_TMU1
]) {
1168 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1169 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1170 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1171 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1172 tex1
.InvertRGB
= FXTRUE
;
1174 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1175 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1176 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1177 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1180 if (isalpha
[FX_TMU0
]) {
1181 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1182 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1183 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1184 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1186 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1187 tex0
.FactorRGB
= GR_COMBINE_FACTOR_ONE
;
1188 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL
;
1189 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_ONE
;
1192 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1193 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1194 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1196 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1197 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1198 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1202 case (FX_UM_E0_MODULATE
| FX_UM_E1_REPLACE
): /* Homeworld2 */
1204 tex1
.FunctionRGB
= GR_COMBINE_FUNCTION_ZERO
;
1205 tex1
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1206 tex1
.FunctionAlpha
= GR_COMBINE_FUNCTION_ZERO
;
1207 tex1
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1209 tex0
.FunctionRGB
= GR_COMBINE_FUNCTION_LOCAL
;
1210 tex0
.FactorRGB
= GR_COMBINE_FACTOR_NONE
;
1211 tex0
.FunctionAlpha
= GR_COMBINE_FUNCTION_LOCAL
;
1212 tex0
.FactorAlpha
= GR_COMBINE_FACTOR_NONE
;
1214 if (ifmt
& (FX_UM_E0_RGB
| FX_UM_E0_LUMINANCE
)) {
1215 alphaComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1216 alphaComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
1217 alphaComb
.Other
= GR_COMBINE_OTHER_NONE
;
1219 alphaComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1220 alphaComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1221 alphaComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1224 if (ifmt
& FX_UM_E0_ALPHA
) {
1225 colorComb
.Function
= GR_COMBINE_FUNCTION_LOCAL
;
1226 colorComb
.Factor
= GR_COMBINE_FACTOR_NONE
;
1227 colorComb
.Other
= GR_COMBINE_OTHER_NONE
;
1229 colorComb
.Function
= GR_COMBINE_FUNCTION_SCALE_OTHER
;
1230 colorComb
.Factor
= GR_COMBINE_FACTOR_ONE
;
1231 colorComb
.Other
= GR_COMBINE_OTHER_TEXTURE
;
1236 fprintf(stderr
, "fxSetupTextureDoubleTMU_NoLock: Unexpected dual texture mode encountered\n");
1240 grAlphaCombine(alphaComb
.Function
,
1245 grColorCombine(colorComb
.Function
,
1250 grTexCombine(GR_TMU0
,
1257 grTexCombine(GR_TMU1
,
1266 /************************* No Texture ***************************/
1269 fxSetupTextureNone_NoLock(GLcontext
* ctx
)
1271 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1272 GrCombineLocal_t localc
, locala
;
1274 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
1275 fprintf(stderr
, "fxSetupTextureNone_NoLock(...)\n");
1278 if ((ctx
->Light
.ShadeModel
== GL_SMOOTH
) || 1 ||
1279 (ctx
->Point
.SmoothFlag
) ||
1280 (ctx
->Line
.SmoothFlag
) ||
1281 (ctx
->Polygon
.SmoothFlag
)) locala
= GR_COMBINE_LOCAL_ITERATED
;
1283 locala
= GR_COMBINE_LOCAL_CONSTANT
;
1285 if (ctx
->Light
.ShadeModel
== GL_SMOOTH
|| 1)
1286 localc
= GR_COMBINE_LOCAL_ITERATED
;
1288 localc
= GR_COMBINE_LOCAL_CONSTANT
;
1290 grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL
,
1291 GR_COMBINE_FACTOR_NONE
,
1293 GR_COMBINE_OTHER_NONE
,
1296 grColorCombine(GR_COMBINE_FUNCTION_LOCAL
,
1297 GR_COMBINE_FACTOR_NONE
,
1299 GR_COMBINE_OTHER_NONE
,
1302 fxMesa
->lastUnitsMode
= FX_UM_NONE
;
1305 #include "fxsetup.h"
1307 /************************************************************************/
1308 /************************** Texture Mode SetUp **************************/
1309 /************************************************************************/
1312 fxSetupTexture_NoLock(GLcontext
* ctx
)
1314 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1316 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
1317 fprintf(stderr
, "fxSetupTexture_NoLock(...)\n");
1320 if (fxMesa
->HaveCmbExt
) {
1321 /* Texture Combine, Color Combine and Alpha Combine. */
1322 if ((ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) &&
1323 (ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) &&
1324 fxMesa
->haveTwoTMUs
) {
1325 fxSetupTextureDoubleTMUNapalm_NoLock(ctx
);
1327 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
1328 fxSetupTextureSingleTMUNapalm_NoLock(ctx
, 0);
1330 else if (ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
1331 fxSetupTextureSingleTMUNapalm_NoLock(ctx
, 1);
1334 fxSetupTextureNoneNapalm_NoLock(ctx
);
1337 /* Texture Combine, Color Combine and Alpha Combine. */
1338 if ((ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) &&
1339 (ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) &&
1340 fxMesa
->haveTwoTMUs
) {
1341 fxSetupTextureDoubleTMU_NoLock(ctx
);
1343 else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
1344 fxSetupTextureSingleTMU_NoLock(ctx
, 0);
1346 else if (ctx
->Texture
.Unit
[1]._ReallyEnabled
& (TEXTURE_1D_BIT
|TEXTURE_2D_BIT
)) {
1347 fxSetupTextureSingleTMU_NoLock(ctx
, 1);
1350 fxSetupTextureNone_NoLock(ctx
);
1356 fxSetupTexture(GLcontext
* ctx
)
1359 fxSetupTexture_NoLock(ctx
);
1363 /************************************************************************/
1364 /**************************** Blend SetUp *******************************/
1365 /************************************************************************/
1368 fxDDBlendFuncSeparate(GLcontext
* ctx
, GLenum sfactor
, GLenum dfactor
, GLenum asfactor
, GLenum adfactor
)
1370 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1371 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1372 GLboolean isNapalm
= (fxMesa
->type
>= GR_SSTTYPE_Voodoo4
);
1373 GLboolean have32bpp
= (fxMesa
->colDepth
== 32);
1374 GLboolean haveAlpha
= fxMesa
->haveHwAlpha
;
1375 GrAlphaBlendFnc_t sfact
, dfact
, asfact
, adfact
;
1377 /* [dBorca] Hack alert:
1378 * 15/16 BPP alpha channel alpha blending modes
1382 * 32 BPP alpha channel alpha blending modes
1384 * 0x1 ASRC_ALPHA Source alpha
1385 * 0x3 ADST_ALPHA Destination alpha
1387 * 0x5 AOMSRC_ALPHA 1 - Source alpha
1388 * 0x7 AOMDST_ALPHA 1 - Destination alpha
1390 * If we don't have HW alpha buffer:
1392 * ONE_MINUS_DST_ALPHA == 0
1393 * Unsupported modes are:
1394 * 1 if used as src blending factor
1395 * 0 if used as dst blending factor
1400 sfact
= GR_BLEND_ZERO
;
1403 sfact
= GR_BLEND_ONE
;
1406 sfact
= GR_BLEND_DST_COLOR
;
1408 case GL_ONE_MINUS_DST_COLOR
:
1409 sfact
= GR_BLEND_ONE_MINUS_DST_COLOR
;
1412 sfact
= GR_BLEND_SRC_ALPHA
;
1414 case GL_ONE_MINUS_SRC_ALPHA
:
1415 sfact
= GR_BLEND_ONE_MINUS_SRC_ALPHA
;
1418 sfact
= haveAlpha
? GR_BLEND_DST_ALPHA
: GR_BLEND_ONE
/*bad*/;
1420 case GL_ONE_MINUS_DST_ALPHA
:
1421 sfact
= haveAlpha
? GR_BLEND_ONE_MINUS_DST_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1423 case GL_SRC_ALPHA_SATURATE
:
1424 sfact
= GR_BLEND_ALPHA_SATURATE
;
1428 sfact
= GR_BLEND_SAME_COLOR_EXT
;
1431 case GL_ONE_MINUS_SRC_COLOR
:
1433 sfact
= GR_BLEND_ONE_MINUS_SAME_COLOR_EXT
;
1437 sfact
= GR_BLEND_ONE
;
1443 asfact
= GR_BLEND_ZERO
;
1446 asfact
= GR_BLEND_ONE
;
1450 asfact
= have32bpp
? GR_BLEND_SRC_ALPHA
: GR_BLEND_ONE
/*bad*/;
1452 case GL_ONE_MINUS_SRC_COLOR
:
1453 case GL_ONE_MINUS_SRC_ALPHA
:
1454 asfact
= have32bpp
? GR_BLEND_ONE_MINUS_SRC_ALPHA
: GR_BLEND_ONE
/*bad*/;
1458 asfact
= (have32bpp
&& haveAlpha
) ? GR_BLEND_DST_ALPHA
: GR_BLEND_ONE
/*bad*/;
1460 case GL_ONE_MINUS_DST_COLOR
:
1461 case GL_ONE_MINUS_DST_ALPHA
:
1462 asfact
= (have32bpp
&& haveAlpha
) ? GR_BLEND_ONE_MINUS_DST_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1464 case GL_SRC_ALPHA_SATURATE
:
1465 asfact
= GR_BLEND_ONE
;
1468 asfact
= GR_BLEND_ONE
;
1474 dfact
= GR_BLEND_ZERO
;
1477 dfact
= GR_BLEND_ONE
;
1480 dfact
= GR_BLEND_SRC_COLOR
;
1482 case GL_ONE_MINUS_SRC_COLOR
:
1483 dfact
= GR_BLEND_ONE_MINUS_SRC_COLOR
;
1486 dfact
= GR_BLEND_SRC_ALPHA
;
1488 case GL_ONE_MINUS_SRC_ALPHA
:
1489 dfact
= GR_BLEND_ONE_MINUS_SRC_ALPHA
;
1492 dfact
= haveAlpha
? GR_BLEND_DST_ALPHA
: GR_BLEND_ONE
/*bad*/;
1494 case GL_ONE_MINUS_DST_ALPHA
:
1495 dfact
= haveAlpha
? GR_BLEND_ONE_MINUS_DST_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1499 dfact
= GR_BLEND_SAME_COLOR_EXT
;
1502 case GL_ONE_MINUS_DST_COLOR
:
1504 dfact
= GR_BLEND_ONE_MINUS_SAME_COLOR_EXT
;
1508 dfact
= GR_BLEND_ZERO
;
1514 adfact
= GR_BLEND_ZERO
;
1517 adfact
= GR_BLEND_ONE
;
1521 adfact
= have32bpp
? GR_BLEND_SRC_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1523 case GL_ONE_MINUS_SRC_COLOR
:
1524 case GL_ONE_MINUS_SRC_ALPHA
:
1525 adfact
= have32bpp
? GR_BLEND_ONE_MINUS_SRC_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1529 adfact
= (have32bpp
&& haveAlpha
) ? GR_BLEND_DST_ALPHA
: GR_BLEND_ONE
/*bad*/;
1531 case GL_ONE_MINUS_DST_COLOR
:
1532 case GL_ONE_MINUS_DST_ALPHA
:
1533 adfact
= (have32bpp
&& haveAlpha
) ? GR_BLEND_ONE_MINUS_DST_ALPHA
: GR_BLEND_ZERO
/*bad*/;
1536 adfact
= GR_BLEND_ZERO
;
1540 if ((sfact
!= us
->blendSrcFuncRGB
) || (asfact
!= us
->blendSrcFuncAlpha
)) {
1541 us
->blendSrcFuncRGB
= sfact
;
1542 us
->blendSrcFuncAlpha
= asfact
;
1543 fxMesa
->new_state
|= FX_NEW_BLEND
;
1546 if ((dfact
!= us
->blendDstFuncRGB
) || (adfact
!= us
->blendDstFuncAlpha
)) {
1547 us
->blendDstFuncRGB
= dfact
;
1548 us
->blendDstFuncAlpha
= adfact
;
1549 fxMesa
->new_state
|= FX_NEW_BLEND
;
1554 fxDDBlendEquationSeparate(GLcontext
* ctx
, GLenum modeRGB
, GLenum modeA
)
1556 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1557 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1562 q
= GR_BLEND_OP_ADD
;
1564 case GL_FUNC_SUBTRACT
:
1565 q
= GR_BLEND_OP_SUB
;
1567 case GL_FUNC_REVERSE_SUBTRACT
:
1568 q
= GR_BLEND_OP_REVSUB
;
1573 if (q
!= us
->blendEqRGB
) {
1575 fxMesa
->new_state
|= FX_NEW_BLEND
;
1580 q
= GR_BLEND_OP_ADD
;
1582 case GL_FUNC_SUBTRACT
:
1583 q
= GR_BLEND_OP_SUB
;
1585 case GL_FUNC_REVERSE_SUBTRACT
:
1586 q
= GR_BLEND_OP_REVSUB
;
1589 q
= us
->blendEqAlpha
;
1591 if (q
!= us
->blendEqAlpha
) {
1592 us
->blendEqAlpha
= q
;
1593 fxMesa
->new_state
|= FX_NEW_BLEND
;
1598 fxSetupBlend(GLcontext
* ctx
)
1600 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1601 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1603 if (fxMesa
->HavePixExt
) {
1604 if (us
->blendEnabled
) {
1605 fxMesa
->Glide
.grAlphaBlendFunctionExt(us
->blendSrcFuncRGB
, us
->blendDstFuncRGB
,
1607 us
->blendSrcFuncAlpha
, us
->blendDstFuncAlpha
,
1610 fxMesa
->Glide
.grAlphaBlendFunctionExt(GR_BLEND_ONE
, GR_BLEND_ZERO
,
1612 GR_BLEND_ONE
, GR_BLEND_ZERO
,
1616 if (us
->blendEnabled
) {
1617 grAlphaBlendFunction(us
->blendSrcFuncRGB
, us
->blendDstFuncRGB
,
1618 us
->blendSrcFuncAlpha
, us
->blendDstFuncAlpha
);
1620 grAlphaBlendFunction(GR_BLEND_ONE
, GR_BLEND_ZERO
,
1621 GR_BLEND_ONE
, GR_BLEND_ZERO
);
1626 /************************************************************************/
1627 /************************** Alpha Test SetUp ****************************/
1628 /************************************************************************/
1631 fxDDAlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
1633 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1634 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1637 (us
->alphaTestFunc
!= func
)
1639 (us
->alphaTestRefValue
!= ref
)
1641 us
->alphaTestFunc
= func
;
1642 us
->alphaTestRefValue
= ref
;
1643 fxMesa
->new_state
|= FX_NEW_ALPHA
;
1648 fxSetupAlphaTest(GLcontext
* ctx
)
1650 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1651 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1653 if (us
->alphaTestEnabled
) {
1654 GrAlpha_t ref
= (GLint
) (us
->alphaTestRefValue
* 255.0);
1655 grAlphaTestFunction(us
->alphaTestFunc
- GL_NEVER
+ GR_CMP_NEVER
);
1656 grAlphaTestReferenceValue(ref
);
1659 grAlphaTestFunction(GR_CMP_ALWAYS
);
1662 /************************************************************************/
1663 /************************** Depth Test SetUp ****************************/
1664 /************************************************************************/
1667 fxDDDepthFunc(GLcontext
* ctx
, GLenum func
)
1669 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1670 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1672 if (us
->depthTestFunc
!= func
) {
1673 us
->depthTestFunc
= func
;
1674 fxMesa
->new_state
|= FX_NEW_DEPTH
;
1679 fxDDDepthMask(GLcontext
* ctx
, GLboolean flag
)
1681 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1682 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1684 if (flag
!= us
->depthMask
) {
1685 us
->depthMask
= flag
;
1686 fxMesa
->new_state
|= FX_NEW_DEPTH
;
1691 fxSetupDepthTest(GLcontext
* ctx
)
1693 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1694 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1696 if (us
->depthTestEnabled
) {
1697 grDepthBufferFunction(us
->depthTestFunc
- GL_NEVER
+ GR_CMP_NEVER
);
1698 grDepthMask(us
->depthMask
);
1701 grDepthBufferFunction(GR_CMP_ALWAYS
);
1702 grDepthMask(FXFALSE
);
1706 /************************************************************************/
1707 /************************** Stencil SetUp *******************************/
1708 /************************************************************************/
1710 static GrStencil_t
convertGLStencilOp( GLenum op
)
1714 return GR_STENCILOP_KEEP
;
1716 return GR_STENCILOP_ZERO
;
1718 return GR_STENCILOP_REPLACE
;
1720 return GR_STENCILOP_INCR_CLAMP
;
1722 return GR_STENCILOP_DECR_CLAMP
;
1724 return GR_STENCILOP_INVERT
;
1725 case GL_INCR_WRAP_EXT
:
1726 return GR_STENCILOP_INCR_WRAP
;
1727 case GL_DECR_WRAP_EXT
:
1728 return GR_STENCILOP_DECR_WRAP
;
1730 _mesa_problem( NULL
, "bad stencil op in convertGLStencilOp" );
1732 return GR_STENCILOP_KEEP
; /* never get, silence compiler warning */
1736 fxDDStencilFunc (GLcontext
*ctx
, GLenum func
, GLint ref
, GLuint mask
)
1738 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1739 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1742 (us
->stencilFunction
!= func
)
1744 (us
->stencilRefValue
!= ref
)
1746 (us
->stencilValueMask
!= mask
)
1748 us
->stencilFunction
= func
;
1749 us
->stencilRefValue
= ref
;
1750 us
->stencilValueMask
= mask
;
1751 fxMesa
->new_state
|= FX_NEW_STENCIL
;
1756 fxDDStencilMask (GLcontext
*ctx
, GLuint mask
)
1758 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1759 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1761 if (us
->stencilWriteMask
!= mask
) {
1762 us
->stencilWriteMask
= mask
;
1763 fxMesa
->new_state
|= FX_NEW_STENCIL
;
1768 fxDDStencilOp (GLcontext
*ctx
, GLenum sfail
, GLenum zfail
, GLenum zpass
)
1770 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1771 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1774 (us
->stencilFailFunc
!= sfail
)
1776 (us
->stencilZFailFunc
!= zfail
)
1778 (us
->stencilZPassFunc
!= zpass
)
1780 us
->stencilFailFunc
= sfail
;
1781 us
->stencilZFailFunc
= zfail
;
1782 us
->stencilZPassFunc
= zpass
;
1783 fxMesa
->new_state
|= FX_NEW_STENCIL
;
1788 fxSetupStencil (GLcontext
* ctx
)
1790 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1791 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1793 if (us
->stencilEnabled
) {
1794 grEnable(GR_STENCIL_MODE_EXT
);
1795 fxMesa
->Glide
.grStencilOpExt(convertGLStencilOp(us
->stencilFailFunc
),
1796 convertGLStencilOp(us
->stencilZFailFunc
),
1797 convertGLStencilOp(us
->stencilZPassFunc
));
1798 fxMesa
->Glide
.grStencilFuncExt(us
->stencilFunction
- GL_NEVER
+ GR_CMP_NEVER
,
1799 us
->stencilRefValue
,
1800 us
->stencilValueMask
);
1801 fxMesa
->Glide
.grStencilMaskExt(us
->stencilWriteMask
);
1803 grDisable(GR_STENCIL_MODE_EXT
);
1807 /************************************************************************/
1808 /**************************** Color Mask SetUp **************************/
1809 /************************************************************************/
1812 fxDDColorMask(GLcontext
* ctx
,
1813 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
1815 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1816 fxMesa
->new_state
|= FX_NEW_COLOR_MASK
;
1824 fxSetupColorMask(GLcontext
* ctx
)
1826 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1828 if (fxMesa
->colDepth
== 32) {
1830 fxMesa
->Glide
.grColorMaskExt(ctx
->Color
.ColorMask
[RCOMP
],
1831 ctx
->Color
.ColorMask
[GCOMP
],
1832 ctx
->Color
.ColorMask
[BCOMP
],
1833 ctx
->Color
.ColorMask
[ACOMP
] && fxMesa
->haveHwAlpha
);
1836 /* 15/16 bpp mode */
1837 grColorMask(ctx
->Color
.ColorMask
[RCOMP
] |
1838 ctx
->Color
.ColorMask
[GCOMP
] |
1839 ctx
->Color
.ColorMask
[BCOMP
],
1840 ctx
->Color
.ColorMask
[ACOMP
] && fxMesa
->haveHwAlpha
);
1847 /************************************************************************/
1848 /**************************** Fog Mode SetUp ****************************/
1849 /************************************************************************/
1852 * This is called during state update in order to update the Glide fog state.
1855 fxSetupFog(GLcontext
* ctx
)
1857 if (ctx
->Fog
.Enabled
/*&& ctx->FogMode==FOG_FRAGMENT */ ) {
1858 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1860 /* update fog color */
1862 col
[0] = (unsigned int) (255 * ctx
->Fog
.Color
[0]);
1863 col
[1] = (unsigned int) (255 * ctx
->Fog
.Color
[1]);
1864 col
[2] = (unsigned int) (255 * ctx
->Fog
.Color
[2]);
1865 col
[3] = (unsigned int) (255 * ctx
->Fog
.Color
[3]);
1866 grFogColorValue(FXCOLOR4(col
));
1868 if (fxMesa
->fogTableMode
!= ctx
->Fog
.Mode
||
1869 fxMesa
->fogDensity
!= ctx
->Fog
.Density
||
1870 fxMesa
->fogStart
!= ctx
->Fog
.Start
||
1871 fxMesa
->fogEnd
!= ctx
->Fog
.End
) {
1872 /* reload the fog table */
1873 switch (ctx
->Fog
.Mode
) {
1875 guFogGenerateLinear(fxMesa
->fogTable
, ctx
->Fog
.Start
,
1877 if (fxMesa
->fogTable
[0] > 63) {
1878 /* [dBorca] Hack alert:
1879 * As per Glide3 Programming Guide:
1880 * The difference between consecutive fog values
1881 * must be less than 64.
1883 fxMesa
->fogTable
[0] = 63;
1887 guFogGenerateExp(fxMesa
->fogTable
, ctx
->Fog
.Density
);
1890 guFogGenerateExp2(fxMesa
->fogTable
, ctx
->Fog
.Density
);
1895 fxMesa
->fogTableMode
= ctx
->Fog
.Mode
;
1896 fxMesa
->fogDensity
= ctx
->Fog
.Density
;
1897 fxMesa
->fogStart
= ctx
->Fog
.Start
;
1898 fxMesa
->fogEnd
= ctx
->Fog
.End
;
1901 grFogTable(fxMesa
->fogTable
);
1902 if (ctx
->Fog
.FogCoordinateSource
== GL_FOG_COORDINATE_EXT
) {
1903 grVertexLayout(GR_PARAM_FOG_EXT
, GR_VERTEX_FOG_OFFSET
<< 2,
1905 grFogMode(GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT
);
1907 grVertexLayout(GR_PARAM_FOG_EXT
, GR_VERTEX_FOG_OFFSET
<< 2,
1909 grFogMode(GR_FOG_WITH_TABLE_ON_Q
);
1913 grFogMode(GR_FOG_DISABLE
);
1918 fxDDFogfv(GLcontext
* ctx
, GLenum pname
, const GLfloat
* params
)
1920 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_FOG
;
1922 case GL_FOG_COORDINATE_SOURCE_EXT
: {
1923 GLenum p
= (GLenum
)*params
;
1924 if (p
== GL_FOG_COORDINATE_EXT
) {
1925 _swrast_allow_vertex_fog(ctx
, GL_TRUE
);
1926 _swrast_allow_pixel_fog(ctx
, GL_FALSE
);
1927 _tnl_allow_vertex_fog( ctx
, GL_TRUE
);
1928 _tnl_allow_pixel_fog( ctx
, GL_FALSE
);
1930 _swrast_allow_vertex_fog(ctx
, GL_FALSE
);
1931 _swrast_allow_pixel_fog(ctx
, GL_TRUE
);
1932 _tnl_allow_vertex_fog( ctx
, GL_FALSE
);
1933 _tnl_allow_pixel_fog( ctx
, GL_TRUE
);
1942 /************************************************************************/
1943 /************************** Scissor Test SetUp **************************/
1944 /************************************************************************/
1946 /* This routine is used in managing the lock state, and therefore can't lock */
1948 fxSetScissorValues(GLcontext
* ctx
)
1950 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1954 if (ctx
->Scissor
.Enabled
) {
1955 xmin
= ctx
->Scissor
.X
;
1956 xmax
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
;
1957 ymin
= ctx
->Scissor
.Y
;
1958 ymax
= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
;
1962 if (xmax
> fxMesa
->width
)
1963 xmax
= fxMesa
->width
;
1964 if (ymin
< fxMesa
->screen_height
- fxMesa
->height
)
1965 ymin
= fxMesa
->screen_height
- fxMesa
->height
;
1966 if (ymax
> fxMesa
->screen_height
- 0)
1967 ymax
= fxMesa
->screen_height
- 0;
1972 xmax
= fxMesa
->width
;
1973 ymax
= fxMesa
->height
;
1976 fxMesa
->clipMinX
= xmin
;
1977 fxMesa
->clipMinY
= ymin
;
1978 fxMesa
->clipMaxX
= xmax
;
1979 fxMesa
->clipMaxY
= ymax
;
1980 grClipWindow(xmin
, ymin
, xmax
, ymax
);
1984 fxSetupScissor(GLcontext
* ctx
)
1987 fxSetScissorValues(ctx
);
1992 fxDDScissor(GLcontext
* ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
1994 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_SCISSOR
;
1997 /************************************************************************/
1998 /*************************** Cull mode setup ****************************/
1999 /************************************************************************/
2003 fxDDCullFace(GLcontext
* ctx
, GLenum mode
)
2006 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_CULL
;
2010 fxDDFrontFace(GLcontext
* ctx
, GLenum mode
)
2013 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_CULL
;
2018 fxSetupCull(GLcontext
* ctx
)
2020 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
2021 GrCullMode_t mode
= GR_CULL_DISABLE
;
2023 if (ctx
->Polygon
.CullFlag
&& (fxMesa
->raster_primitive
== GL_TRIANGLES
)) {
2024 switch (ctx
->Polygon
.CullFaceMode
) {
2026 if (ctx
->Polygon
.FrontFace
== GL_CCW
)
2027 mode
= GR_CULL_NEGATIVE
;
2029 mode
= GR_CULL_POSITIVE
;
2032 if (ctx
->Polygon
.FrontFace
== GL_CCW
)
2033 mode
= GR_CULL_POSITIVE
;
2035 mode
= GR_CULL_NEGATIVE
;
2037 case GL_FRONT_AND_BACK
:
2038 /* Handled as a fallback on triangles in tdfx_tris.c */
2046 if (fxMesa
->cullMode
!= mode
) {
2047 fxMesa
->cullMode
= mode
;
2053 /************************************************************************/
2054 /****************************** DD Enable ******************************/
2055 /************************************************************************/
2058 fxDDEnable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
2060 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
2061 tfxUnitsState
*us
= &fxMesa
->unitsState
;
2063 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
2064 fprintf(stderr
, "%s(%s)\n", state
? "fxDDEnable" : "fxDDDisable",
2065 _mesa_lookup_enum_by_nr(cap
));
2070 if (state
!= us
->alphaTestEnabled
) {
2071 us
->alphaTestEnabled
= state
;
2072 fxMesa
->new_state
|= FX_NEW_ALPHA
;
2076 if (state
!= us
->blendEnabled
) {
2077 us
->blendEnabled
= state
;
2078 fxMesa
->new_state
|= FX_NEW_BLEND
;
2082 if (state
!= us
->depthTestEnabled
) {
2083 us
->depthTestEnabled
= state
;
2084 fxMesa
->new_state
|= FX_NEW_DEPTH
;
2087 case GL_STENCIL_TEST
:
2088 if (fxMesa
->haveHwStencil
&& state
!= us
->stencilEnabled
) {
2089 us
->stencilEnabled
= state
;
2090 fxMesa
->new_state
|= FX_NEW_STENCIL
;
2095 grDitherMode(GR_DITHER_4x4
);
2098 grDitherMode(GR_DITHER_DISABLE
);
2101 case GL_SCISSOR_TEST
:
2102 fxMesa
->new_state
|= FX_NEW_SCISSOR
;
2104 case GL_SHARED_TEXTURE_PALETTE_EXT
:
2105 fxDDTexUseGlbPalette(ctx
, state
);
2108 fxMesa
->new_state
|= FX_NEW_FOG
;
2111 fxMesa
->new_state
|= FX_NEW_CULL
;
2113 case GL_LINE_SMOOTH
:
2114 case GL_LINE_STIPPLE
:
2115 case GL_POINT_SMOOTH
:
2116 case GL_POLYGON_SMOOTH
:
2119 fxMesa
->new_state
|= FX_NEW_TEXTURING
;
2129 /************************************************************************/
2130 /************************** Changes to units state **********************/
2131 /************************************************************************/
2134 /* All units setup is handled under texture setup.
2137 fxDDShadeModel(GLcontext
* ctx
, GLenum mode
)
2139 FX_CONTEXT(ctx
)->new_state
|= FX_NEW_TEXTURING
;
2144 /************************************************************************/
2145 /****************************** Units SetUp *****************************/
2146 /************************************************************************/
2148 fx_print_state_flags(const char *msg
, GLuint flags
)
2151 "%s: (0x%x) %s%s%s%s%s%s%s%s\n",
2154 (flags
& FX_NEW_TEXTURING
) ? "texture, " : "",
2155 (flags
& FX_NEW_BLEND
) ? "blend, " : "",
2156 (flags
& FX_NEW_ALPHA
) ? "alpha, " : "",
2157 (flags
& FX_NEW_FOG
) ? "fog, " : "",
2158 (flags
& FX_NEW_SCISSOR
) ? "scissor, " : "",
2159 (flags
& FX_NEW_COLOR_MASK
) ? "colormask, " : "",
2160 (flags
& FX_NEW_CULL
) ? "cull, " : "",
2161 (flags
& FX_NEW_STENCIL
) ? "stencil, " : "");
2165 fxSetupFXUnits(GLcontext
* ctx
)
2167 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
2168 GLuint newstate
= fxMesa
->new_state
;
2170 if (TDFX_DEBUG
& VERBOSE_DRIVER
)
2171 fx_print_state_flags("fxSetupFXUnits", newstate
);
2174 if (newstate
& FX_NEW_TEXTURING
)
2175 fxSetupTexture(ctx
);
2177 if (newstate
& FX_NEW_BLEND
)
2180 if (newstate
& FX_NEW_ALPHA
)
2181 fxSetupAlphaTest(ctx
);
2183 if (newstate
& FX_NEW_DEPTH
)
2184 fxSetupDepthTest(ctx
);
2186 if (newstate
& FX_NEW_STENCIL
)
2187 fxSetupStencil(ctx
);
2189 if (newstate
& FX_NEW_FOG
)
2192 if (newstate
& FX_NEW_SCISSOR
)
2193 fxSetupScissor(ctx
);
2195 if (newstate
& FX_NEW_COLOR_MASK
)
2196 fxSetupColorMask(ctx
);
2198 if (newstate
& FX_NEW_CULL
)
2201 fxMesa
->new_state
= 0;
2211 * Need this to provide at least one external definition.
2214 extern int gl_fx_dummy_function_setup(void);
2216 gl_fx_dummy_function_setup(void)