#include "fxdrv.h"
#include "enums.h"
+#include "tnl.h"
#include "tnl/t_context.h"
+#include "swrast.h"
+#include "texstore.h"
+
static void
fxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj)
ti->tObj = tObj;
minl = ti->minLevel = tObj->BaseLevel;
- maxl = ti->maxLevel = MIN2(tObj->MaxLevel, tObj->Image[0]->MaxLog2);
+ maxl = ti->maxLevel = MIN2(tObj->MaxLevel, tObj->Image[0][0]->MaxLog2);
-#if 1||FX_RESCALE_BIG_TEXURES
+#if FX_RESCALE_BIG_TEXURES_HACK
{
- extern void _mesa_rescale_teximage2d( GLuint bytesPerPixel,
- GLuint dstRowStride,
- GLint srcWidth, GLint srcHeight,
- GLint dstWidth, GLint dstHeight,
- const GLvoid *srcImage, GLvoid *dstImage );
fxMesaContext fxMesa = FX_CONTEXT(ctx);
- if (maxl - minl > fxMesa->textureMaxLod) {
- /* [dBorca]
- * Ooooooook! Here's a(nother) long story.
- * We get here because we need to handle a texture larger
- * than hardware can support. Two cases:
- * 1) we have mipmaps. Then we just push up to the first supported
- * LOD. A possible drawback is that Mesa will ignore the skipped
- * LODs on further texture handling.
- * Will this interfere with GL_TEXTURE_[MIN|BASE]_LEVEL? How?
- * 2) we don't have mipmaps. We need to rescale texture; two ways:
- * a) create a new LOD and push up ti->minLevel and tObj->BaseLevel
- * but this means we need to rescale on both axes, which
- * yield unnecessary ugly texture. Also, same issues as 1)
- * b) rescale the biggest LOD in place and go two ways:
- * - update texImage->Width and texImage->Height, then
- * decrease maxLevel, so we won't rescale again on the
- * next validation. Changing texImage-> parameters is
- * not quite legal here (see convolution), but...
- * - leaving texImage-> parameters alone, while rescaling
- * texture and decreasing maxLevel makes Mesa puke. Also
- * this approach requires that mml->[wh]Scale go below 1,
- * otherwise bad ju-ju will be in our future (see fetch_texel)
- * Will this interfere with GL_TEXTURE_MAX_LEVEL? How?
- * The above approach is somehow dumb! we might have rescaled
- * once in TexImage2D to accomodate aspect ratio, and now we
- * are rescaling again. The thing is, in TexImage2D we don't
- * know whether we'll hit 1) or 2) by the time of validation.
- * NB: we could handle mml->[wh]Scale nicely, using (biased) shifts.
- *
- * Which brings me to another issue. How can we handle NPOT textures?
- * - rescaling NPOT to the next bigger POT (mml->[wh]Scale can't shift)
- * - upping the max LOD to the next power-of-two, in fxTexGetInfo; then
- * choosing non-power-of-two values for ti->[st]Scale... Anyhow, we
- * still need to align mipmaps correctly in texture memory!
- */
- if ((tObj->MinFilter == GL_NEAREST) || (tObj->MinFilter == GL_LINEAR)) {
- /* no mipmaps! need to rescale */
- struct gl_texture_image *texImage = tObj->Image[minl];
- tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
+ /* [dBorca]
+ * Fake textures larger than HW supports:
+ * 1) we have mipmaps. Then we just push up to the first supported
+ * LOD. A possible drawback is that Mesa will ignore the skipped
+ * LODs on further texture handling.
+ * Will this interfere with GL_TEXTURE_[MIN|BASE]_LEVEL? How?
+ * 2) we don't have mipmaps. We need to rescale the big LOD in place.
+ * The above approach is somehow dumb! we might have rescaled
+ * once in TexImage2D to accomodate aspect ratio, and now we
+ * are rescaling again. The thing is, in TexImage2D we don't
+ * know whether we'll hit 1) or 2) by the time of validation.
+ */
+ if ((tObj->MinFilter == GL_NEAREST) || (tObj->MinFilter == GL_LINEAR)) {
+ /* no mipmaps! */
+ struct gl_texture_image *texImage = tObj->Image[0][minl];
+ tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
+ GLint _w, _h, maxSize = 1 << fxMesa->textureMaxLod;
+ if ((mml->width > maxSize) || (mml->height > maxSize)) {
+ /* need to rescale */
GLint texelBytes = texImage->TexFormat->TexelBytes;
GLvoid *texImage_Data = texImage->Data;
- GLint _w = MIN2(mml->width, 1 << fxMesa->textureMaxLod);
- GLint _h = MIN2(mml->height, 1 << fxMesa->textureMaxLod);
+ _w = MIN2(texImage->Width, maxSize);
+ _h = MIN2(texImage->Height, maxSize);
if (TDFX_DEBUG & VERBOSE_TEXTURE) {
fprintf(stderr, "fxTexValidate: rescaling %d x %d -> %d x %d\n",
- mml->width, mml->height,
- _w, _h);
+ texImage->Width, texImage->Height, _w, _h);
}
+ /* we should leave these as is and... (!) */
+ texImage->Width = _w;
+ texImage->Height = _h;
fxTexGetInfo(_w, _h, NULL, NULL, NULL, NULL,
&(mml->wScale), &(mml->hScale));
- texImage->Width = _w / mml->wScale;
- texImage->Height = _h / mml->hScale;
- texImage->Data = MESA_PBUFFER_ALLOC(_w * _h * texelBytes);
+ _w *= mml->wScale;
+ _h *= mml->hScale;
+ texImage->Data = _mesa_malloc(_w * _h * texelBytes);
_mesa_rescale_teximage2d(texelBytes,
+ mml->width,
_w * texelBytes, /* dst stride */
mml->width, mml->height, /* src */
_w, _h, /* dst */
texImage_Data /*src*/, texImage->Data /*dst*/ );
- MESA_PBUFFER_FREE(texImage_Data);
+ _mesa_free(texImage_Data);
mml->width = _w;
mml->height = _h;
- maxl = ti->maxLevel = tObj->Image[0]->MaxLog2 = minl + fxMesa->textureMaxLod;
- } else {
+ /* (!) ... and set mml->wScale = _w / texImage->Width */
+ }
+ } else {
+ /* mipmapping */
+ if (maxl - minl > fxMesa->textureMaxLod) {
/* skip a certain number of LODs */
minl += maxl - fxMesa->textureMaxLod;
if (TDFX_DEBUG & VERBOSE_TEXTURE) {
}
#endif
- fxTexGetInfo(tObj->Image[minl]->Width, tObj->Image[minl]->Height,
+ fxTexGetInfo(tObj->Image[0][minl]->Width, tObj->Image[0][minl]->Height,
&(FX_largeLodLog2(ti->info)), &(FX_aspectRatioLog2(ti->info)),
&(ti->sScale), &(ti->tScale),
NULL, NULL);
if ((tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR))
- fxTexGetInfo(tObj->Image[maxl]->Width, tObj->Image[maxl]->Height,
+ fxTexGetInfo(tObj->Image[0][maxl]->Width, tObj->Image[0][maxl]->Height,
&(FX_smallLodLog2(ti->info)), NULL,
NULL, NULL, NULL, NULL);
else
FX_smallLodLog2(ti->info) = FX_largeLodLog2(ti->info);
- ti->baseLevelInternalFormat = tObj->Image[minl]->Format;
+ /* [dBorca] this is necessary because of fxDDCompressedTexImage2D */
+ if (ti->padded) {
+ struct gl_texture_image *texImage = tObj->Image[0][minl];
+ tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
+ if (mml->wScale != 1 || mml->hScale != 1) {
+ ti->sScale /= mml->wScale;
+ ti->tScale /= mml->hScale;
+ }
+ }
+
+ ti->baseLevelInternalFormat = tObj->Image[0][minl]->Format;
ti->validated = GL_TRUE;
fprintf(stderr, "fxSetupSingleTMU_NoLock(%p (%d))\n", (void *)tObj, tObj->Name);
}
-#if 1 /* [dBorca] Good... bad... I'm the guy with the gun! */
ti->lastTimeUsed = fxMesa->texBindNumber;
-#endif
/* Make sure we're not loaded incorrectly */
if (ti->isInTM) {
}
grTexDownloadTable(ti->paltype, &(ti->palette));
}
-#if FX_TC_NCC
- if ((ti->info.format == GR_TEXFMT_AYIQ_8422) ||
- (ti->info.format == GR_TEXFMT_YIQ_422)) {
- if (TDFX_DEBUG & VERBOSE_DRIVER) {
- fprintf(stderr, "fxSetupSingleTMU_NoLock: uploading NCC table\n");
- }
- grTexDownloadTable(GR_TEXTABLE_NCC0, &(ti->palette));
- }
-#endif
grTexClampMode(GR_TMU0, ti->sClamp, ti->tClamp);
grTexClampMode(GR_TMU1, ti->sClamp, ti->tClamp);
}
fxMesa->Glide.grTexDownloadTableExt(tmu, ti->paltype, &(ti->palette));
}
-#if FX_TC_NCC
- if ((ti->info.format == GR_TEXFMT_AYIQ_8422) ||
- (ti->info.format == GR_TEXFMT_YIQ_422)) {
- if (TDFX_DEBUG & VERBOSE_DRIVER) {
- fprintf(stderr, "fxSetupSingleTMU_NoLock: uploading NCC table\n");
- }
- fxMesa->Glide.grTexDownloadTableExt(tmu, GR_TEXTABLE_NCC0, &(ti->palette));
- }
-#endif
/* KW: The alternative is to do the download to the other tmu. If
* we get to this point, I think it means we are thrashing the
tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
- /* [dBorca] Hack alert:
- * don't use GR_COMBINE_FUNCTION_SCALE_OTHER
- * such that Glide recognizes TMU0 in passthrough mode
- */
+ /* correct values to set TMU0 in passthrough mode */
tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND;
tex0.FactorRGB = GR_COMBINE_FACTOR_ONE;
tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND;
GLuint unitsmode;
GLint ifmt;
tfxTexInfo *ti;
- struct gl_texture_object *tObj = ctx->Texture.Unit[textureset].Current2D;
+ struct gl_texture_object *tObj = ctx->Texture.Unit[textureset]._Current;
int tmu;
if (TDFX_DEBUG & VERBOSE_DRIVER) {
colorComb.Factor = GR_COMBINE_FACTOR_NONE;
colorComb.Other = GR_COMBINE_OTHER_NONE;
} else {
- /* [dBorca] Hack alert:
- * only Voodoo^2 can GL_BLEND (GR_COMBINE_FACTOR_TEXTURE_RGB)
- */
if (fxMesa->type >= GR_SSTTYPE_Voodoo2) {
colorComb.Function = GR_COMBINE_FUNCTION_BLEND;
colorComb.Factor = GR_COMBINE_FACTOR_TEXTURE_RGB;
colorComb.Other = GR_COMBINE_OTHER_CONSTANT;
+ } else if (ifmt == GL_INTENSITY) {
+ /* just a hack: RGB == ALPHA */
+ colorComb.Function = GR_COMBINE_FUNCTION_BLEND;
+ colorComb.Factor = GR_COMBINE_FACTOR_TEXTURE_ALPHA;
+ colorComb.Other = GR_COMBINE_OTHER_CONSTANT;
} else {
+ /* Only Voodoo^2 can GL_BLEND (GR_COMBINE_FACTOR_TEXTURE_RGB)
+ * These settings assume that the TexEnv color is black and
+ * incoming fragment color is white.
+ */
+ colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+ colorComb.Factor = GR_COMBINE_FACTOR_ONE;
+ colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
+ colorComb.Invert = FXTRUE;
_mesa_problem(NULL, "can't GL_BLEND with SST1");
- return;
}
}
}
else {
/* sum of texel and fragment alpha */
- alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
+ alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
alphaComb.Factor = GR_COMBINE_FACTOR_ONE;
alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
}
}
else {
/* sum of texel and fragment rgb */
- colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
+ colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
colorComb.Factor = GR_COMBINE_FACTOR_ONE;
colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
}
fxMesa->Glide.grTexDownloadTableExt(ti0->whichTMU, ti0->paltype, &(ti0->palette));
}
}
-#if FX_TC_NCC
- /* pointcast */
- if ((ti1->info.format == GR_TEXFMT_AYIQ_8422) ||
- (ti1->info.format == GR_TEXFMT_YIQ_422)) {
- if (TDFX_DEBUG & VERBOSE_DRIVER) {
- fprintf(stderr, "fxSetupDoubleTMU_NoLock: uploading NCC0 table for TMU1\n");
- }
- fxMesa->Glide.grTexDownloadTableExt(ti1->whichTMU, GR_TEXTABLE_NCC0, &(ti1->palette));
- }
- if ((ti0->info.format == GR_TEXFMT_AYIQ_8422) ||
- (ti0->info.format == GR_TEXFMT_YIQ_422)) {
- if (TDFX_DEBUG & VERBOSE_DRIVER) {
- fprintf(stderr, "fxSetupDoubleTMU_NoLock: uploading NCC0 table for TMU0\n");
- }
- fxMesa->Glide.grTexDownloadTableExt(ti0->whichTMU, GR_TEXTABLE_NCC0, &(ti0->palette));
- }
-#endif
grTexSource(tmu0, ti0->tm[tmu0]->startAddr,
GR_MIPMAPLEVELMASK_BOTH, &(ti0->info));
struct tdfx_texcombine tex0, tex1;
GrCombineLocal_t localc, locala;
tfxTexInfo *ti0, *ti1;
- struct gl_texture_object *tObj0 = ctx->Texture.Unit[1].Current2D;
- struct gl_texture_object *tObj1 = ctx->Texture.Unit[0].Current2D;
+ struct gl_texture_object *tObj0 = ctx->Texture.Unit[1]._Current;
+ struct gl_texture_object *tObj1 = ctx->Texture.Unit[0]._Current;
GLuint envmode, ifmt, unitsmode;
int tmu0 = 0, tmu1 = 1;
alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
break;
}
+
+ case (FX_UM_E0_MODULATE | FX_UM_E1_REPLACE): /* Homeworld2 */
+ {
+ tex1.FunctionRGB = GR_COMBINE_FUNCTION_ZERO;
+ tex1.FactorRGB = GR_COMBINE_FACTOR_NONE;
+ tex1.FunctionAlpha = GR_COMBINE_FUNCTION_ZERO;
+ tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
+
+ tex0.FunctionRGB = GR_COMBINE_FUNCTION_LOCAL;
+ tex0.FactorRGB = GR_COMBINE_FACTOR_NONE;
+ tex0.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
+ tex0.FactorAlpha = GR_COMBINE_FACTOR_NONE;
+
+ if (ifmt & (FX_UM_E0_RGB | FX_UM_E0_LUMINANCE)) {
+ alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
+ alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
+ alphaComb.Other = GR_COMBINE_OTHER_NONE;
+ } else {
+ alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+ alphaComb.Factor = GR_COMBINE_FACTOR_ONE;
+ alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
+ }
+
+ if (ifmt & FX_UM_E0_ALPHA) {
+ colorComb.Function = GR_COMBINE_FUNCTION_LOCAL;
+ colorComb.Factor = GR_COMBINE_FACTOR_NONE;
+ colorComb.Other = GR_COMBINE_OTHER_NONE;
+ } else {
+ colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+ colorComb.Factor = GR_COMBINE_FACTOR_ONE;
+ colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
+ }
+ break;
+ }
default:
fprintf(stderr, "fxSetupTextureDoubleTMU_NoLock: Unexpected dual texture mode encountered\n");
return;
if (fxMesa->HaveCmbExt) {
/* Texture Combine, Color Combine and Alpha Combine. */
- if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT &&
- ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT &&
+ if ((ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) &&
+ (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) &&
fxMesa->haveTwoTMUs) {
fxSetupTextureDoubleTMUNapalm_NoLock(ctx);
}
- else if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) {
+ else if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
fxSetupTextureSingleTMUNapalm_NoLock(ctx, 0);
}
- else if (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) {
+ else if (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
fxSetupTextureSingleTMUNapalm_NoLock(ctx, 1);
}
else {
}
} else {
/* Texture Combine, Color Combine and Alpha Combine. */
- if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT &&
- ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT &&
+ if ((ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) &&
+ (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) &&
fxMesa->haveTwoTMUs) {
fxSetupTextureDoubleTMU_NoLock(ctx);
}
- else if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) {
+ else if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
fxSetupTextureSingleTMU_NoLock(ctx, 0);
}
- else if (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) {
+ else if (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
fxSetupTextureSingleTMU_NoLock(ctx, 1);
}
else {
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
tfxUnitsState *us = &fxMesa->unitsState;
+ GLboolean isNapalm = (fxMesa->type >= GR_SSTTYPE_Voodoo4);
GLboolean have32bpp = (fxMesa->colDepth == 32);
GLboolean haveAlpha = fxMesa->haveHwAlpha;
GrAlphaBlendFnc_t sfact, dfact, asfact, adfact;
- /* [dBorca] Hack alert:
- * We should condition *DST_ALPHA* modes
- * by the boolean `haveAlpha' above!
- * It indicates whether we really have HW alpha buffer...
+ /*
+ * 15/16 BPP alpha channel alpha blending modes
+ * 0x0 AZERO Zero
+ * 0x4 AONE One
+ *
+ * 32 BPP alpha channel alpha blending modes
+ * 0x0 AZERO Zero
+ * 0x1 ASRC_ALPHA Source alpha
+ * 0x3 ADST_ALPHA Destination alpha
+ * 0x4 AONE One
+ * 0x5 AOMSRC_ALPHA 1 - Source alpha
+ * 0x7 AOMDST_ALPHA 1 - Destination alpha
+ *
+ * If we don't have HW alpha buffer:
+ * DST_ALPHA == 1
+ * ONE_MINUS_DST_ALPHA == 0
+ * Unsupported modes are:
+ * 1 if used as src blending factor
+ * 0 if used as dst blending factor
*/
-/*
-When the value A_COLOR is selected as the destination alpha blending factor,
-the source pixel color is used as the destination blending factor. When the
-value A_COLOR is selected as the source alpha blending factor, the destination
-pixel color is used as the source blending factor. When the value A_SAMECOLOR
-is selected as the destination alpha blending factor, the destination pixel
-color is used as the destination blending factor. When the value A_SAMECOLOR
-is selected as the source alpha blending factor, the source pixel color is
-used as the source blending factor. Note also that the alpha blending
-function 0xf (A_COLORBEFOREFOG/ASATURATE) is different depending upon whether
-it is being used as a source or destination alpha blending function. When the
-value 0xf is selected as the destination alpha blending factor, the source
-color before the fog unit ("unfogged" color) is used as the destination
-blending factor -- this alpha blending function is useful for multi-pass
-rendering with atmospheric effects. When the value 0xf is selected as the
-source alpha blending factor, the alpha-saturate anti-aliasing algorithm is
-selected -- this MIN function performs polygonal anti-aliasing for polygons
-which are drawn front-to-back.
-
-15/16 BPP alpha channel alpha blending modes
- 0x0 AZERO Zero
- 0x4 AONE One
-
-32 BPP alpha channel alpha blending modes
- 0x0 AZERO Zero
- 0x1 ASRC_ALPHA Source alpha
- 0x3 ADST_ALPHA Destination alpha
- 0x4 AONE One
- 0x5 AOMSRC_ALPHA 1 - Source alpha
- 0x7 AOMDST_ALPHA 1 - Destination alpha
-*/
-
switch (sfactor) {
case GL_ZERO:
sfact = GR_BLEND_ZERO;
sfact = GR_BLEND_ONE_MINUS_SRC_ALPHA;
break;
case GL_DST_ALPHA:
- sfact = GR_BLEND_DST_ALPHA;
+ sfact = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/;
break;
case GL_ONE_MINUS_DST_ALPHA:
- sfact = GR_BLEND_ONE_MINUS_DST_ALPHA;
+ sfact = haveAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/;
break;
case GL_SRC_ALPHA_SATURATE:
sfact = GR_BLEND_ALPHA_SATURATE;
break;
case GL_SRC_COLOR:
+ if (isNapalm) {
+ sfact = GR_BLEND_SAME_COLOR_EXT;
+ break;
+ }
case GL_ONE_MINUS_SRC_COLOR:
- /* USELESS */
- sfact = GR_BLEND_ONE;
- break;
+ if (isNapalm) {
+ sfact = GR_BLEND_ONE_MINUS_SAME_COLOR_EXT;
+ break;
+ }
default:
sfact = GR_BLEND_ONE;
break;
case GL_ONE:
asfact = GR_BLEND_ONE;
break;
- case GL_DST_COLOR:
- asfact = GR_BLEND_ONE/*bad*/;
- break;
- case GL_ONE_MINUS_DST_COLOR:
- asfact = GR_BLEND_ONE/*bad*/;
- break;
+ case GL_SRC_COLOR:
case GL_SRC_ALPHA:
asfact = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ONE/*bad*/;
break;
+ case GL_ONE_MINUS_SRC_COLOR:
case GL_ONE_MINUS_SRC_ALPHA:
asfact = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ONE/*bad*/;
break;
+ case GL_DST_COLOR:
case GL_DST_ALPHA:
- asfact = have32bpp ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/;
+ asfact = (have32bpp && haveAlpha) ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/;
break;
+ case GL_ONE_MINUS_DST_COLOR:
case GL_ONE_MINUS_DST_ALPHA:
- asfact = have32bpp ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ONE/*bad*/;
+ asfact = (have32bpp && haveAlpha) ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/;
break;
case GL_SRC_ALPHA_SATURATE:
- asfact = GR_BLEND_ONE/*bad*/;
- break;
- case GL_SRC_COLOR:
- case GL_ONE_MINUS_SRC_COLOR:
- /* USELESS */
- asfact = GR_BLEND_ONE/*bad*/;
+ asfact = GR_BLEND_ONE;
break;
default:
- asfact = GR_BLEND_ONE/*bad*/;
+ asfact = GR_BLEND_ONE;
break;
}
dfact = GR_BLEND_ONE_MINUS_SRC_ALPHA;
break;
case GL_DST_ALPHA:
- /* dfact=GR_BLEND_DST_ALPHA; */
- /* We can't do DST_ALPHA */
- dfact = GR_BLEND_ONE;
+ dfact = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/;
break;
case GL_ONE_MINUS_DST_ALPHA:
- /* dfact=GR_BLEND_ONE_MINUS_DST_ALPHA; */
- /* We can't do DST_ALPHA */
- dfact = GR_BLEND_ZERO;
+ dfact = haveAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/;
break;
- case GL_SRC_ALPHA_SATURATE:
case GL_DST_COLOR:
+ if (isNapalm) {
+ dfact = GR_BLEND_SAME_COLOR_EXT;
+ break;
+ }
case GL_ONE_MINUS_DST_COLOR:
- /* USELESS */
- dfact = GR_BLEND_ZERO;
- break;
+ if (isNapalm) {
+ dfact = GR_BLEND_ONE_MINUS_SAME_COLOR_EXT;
+ break;
+ }
default:
dfact = GR_BLEND_ZERO;
break;
adfact = GR_BLEND_ONE;
break;
case GL_SRC_COLOR:
- adfact = GR_BLEND_ZERO/*bad*/;
- break;
- case GL_ONE_MINUS_SRC_COLOR:
- adfact = GR_BLEND_ZERO/*bad*/;
- break;
case GL_SRC_ALPHA:
adfact = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ZERO/*bad*/;
break;
+ case GL_ONE_MINUS_SRC_COLOR:
case GL_ONE_MINUS_SRC_ALPHA:
adfact = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ZERO/*bad*/;
break;
+ case GL_DST_COLOR:
case GL_DST_ALPHA:
- adfact = have32bpp ? GR_BLEND_DST_ALPHA : GR_BLEND_ZERO/*bad*/;
- break;
- case GL_ONE_MINUS_DST_ALPHA:
- adfact = have32bpp ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/;
+ adfact = (have32bpp && haveAlpha) ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/;
break;
- case GL_SRC_ALPHA_SATURATE:
- case GL_DST_COLOR:
case GL_ONE_MINUS_DST_COLOR:
- /* USELESS */
- adfact = GR_BLEND_ZERO/*bad*/;
+ case GL_ONE_MINUS_DST_ALPHA:
+ adfact = (have32bpp && haveAlpha) ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/;
break;
default:
- adfact = GR_BLEND_ZERO/*bad*/;
+ adfact = GR_BLEND_ZERO;
break;
}
}
void
-fxDDBlendEquation(GLcontext * ctx, GLenum mode)
+fxDDBlendEquationSeparate(GLcontext * ctx, GLenum modeRGB, GLenum modeA)
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
tfxUnitsState *us = &fxMesa->unitsState;
GrAlphaBlendOp_t q;
- switch (mode) {
- case GL_FUNC_ADD_EXT:
+ switch (modeRGB) {
+ case GL_FUNC_ADD:
q = GR_BLEND_OP_ADD;
break;
- case GL_FUNC_SUBTRACT_EXT:
+ case GL_FUNC_SUBTRACT:
q = GR_BLEND_OP_SUB;
break;
- case GL_FUNC_REVERSE_SUBTRACT_EXT:
+ case GL_FUNC_REVERSE_SUBTRACT:
q = GR_BLEND_OP_REVSUB;
break;
default:
- return;
+ q = us->blendEqRGB;
+ }
+ if (q != us->blendEqRGB) {
+ us->blendEqRGB = q;
+ fxMesa->new_state |= FX_NEW_BLEND;
}
- if ((q != us->blendEq) && fxMesa->HavePixExt) {
- us->blendEq = q;
+ switch (modeA) {
+ case GL_FUNC_ADD:
+ q = GR_BLEND_OP_ADD;
+ break;
+ case GL_FUNC_SUBTRACT:
+ q = GR_BLEND_OP_SUB;
+ break;
+ case GL_FUNC_REVERSE_SUBTRACT:
+ q = GR_BLEND_OP_REVSUB;
+ break;
+ default:
+ q = us->blendEqAlpha;
+ }
+ if (q != us->blendEqAlpha) {
+ us->blendEqAlpha = q;
fxMesa->new_state |= FX_NEW_BLEND;
}
}
if (fxMesa->HavePixExt) {
if (us->blendEnabled) {
fxMesa->Glide.grAlphaBlendFunctionExt(us->blendSrcFuncRGB, us->blendDstFuncRGB,
- us->blendEq,
+ us->blendEqRGB,
us->blendSrcFuncAlpha, us->blendDstFuncAlpha,
- us->blendEq);
+ us->blendEqAlpha);
} else {
fxMesa->Glide.grAlphaBlendFunctionExt(GR_BLEND_ONE, GR_BLEND_ZERO,
GR_BLEND_OP_ADD,
}
void
-fxDDStencilFunc (GLcontext *ctx, GLenum func, GLint ref, GLuint mask)
+fxDDStencilFuncSeparate (GLcontext *ctx, GLenum face, GLenum func,
+ GLint ref, GLuint mask)
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
tfxUnitsState *us = &fxMesa->unitsState;
+ if (ctx->Stencil.ActiveFace) {
+ return;
+ }
+
if (
(us->stencilFunction != func)
||
}
void
-fxDDStencilMask (GLcontext *ctx, GLuint mask)
+fxDDStencilMaskSeparate (GLcontext *ctx, GLenum face, GLuint mask)
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
tfxUnitsState *us = &fxMesa->unitsState;
+ if (ctx->Stencil.ActiveFace) {
+ return;
+ }
+
if (us->stencilWriteMask != mask) {
us->stencilWriteMask = mask;
fxMesa->new_state |= FX_NEW_STENCIL;
}
void
-fxDDStencilOp (GLcontext *ctx, GLenum sfail, GLenum zfail, GLenum zpass)
+fxDDStencilOpSeparate (GLcontext *ctx, GLenum face, GLenum sfail,
+ GLenum zfail, GLenum zpass)
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
tfxUnitsState *us = &fxMesa->unitsState;
+ if (ctx->Stencil.ActiveFace) {
+ return;
+ }
+
if (
(us->stencilFailFunc != sfail)
||
}
}
-static void
+void
fxSetupStencil (GLcontext * ctx)
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
tfxUnitsState *us = &fxMesa->unitsState;
if (us->stencilEnabled) {
+ GrCmpFnc_t stencilFailFunc = GR_STENCILOP_KEEP;
+ GrCmpFnc_t stencilZFailFunc = GR_STENCILOP_KEEP;
+ GrCmpFnc_t stencilZPassFunc = GR_STENCILOP_KEEP;
+ if (!fxMesa->multipass) {
+ stencilFailFunc = convertGLStencilOp(us->stencilFailFunc);
+ stencilZFailFunc = convertGLStencilOp(us->stencilZFailFunc);
+ stencilZPassFunc = convertGLStencilOp(us->stencilZPassFunc);
+ }
grEnable(GR_STENCIL_MODE_EXT);
- fxMesa->Glide.grStencilOpExt(convertGLStencilOp(us->stencilFailFunc),
- convertGLStencilOp(us->stencilZFailFunc),
- convertGLStencilOp(us->stencilZPassFunc));
+ fxMesa->Glide.grStencilOpExt(stencilFailFunc,
+ stencilZFailFunc,
+ stencilZPassFunc);
fxMesa->Glide.grStencilFuncExt(us->stencilFunction - GL_NEVER + GR_CMP_NEVER,
us->stencilRefValue,
us->stencilValueMask);
}
}
+void
+fxSetupStencilFace (GLcontext * ctx, GLint face)
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ tfxUnitsState *us = &fxMesa->unitsState;
+
+ if (us->stencilEnabled) {
+ GrCmpFnc_t stencilFailFunc = GR_STENCILOP_KEEP;
+ GrCmpFnc_t stencilZFailFunc = GR_STENCILOP_KEEP;
+ GrCmpFnc_t stencilZPassFunc = GR_STENCILOP_KEEP;
+ if (!fxMesa->multipass) {
+ stencilFailFunc = convertGLStencilOp(ctx->Stencil.FailFunc[face]);
+ stencilZFailFunc = convertGLStencilOp(ctx->Stencil.ZFailFunc[face]);
+ stencilZPassFunc = convertGLStencilOp(ctx->Stencil.ZPassFunc[face]);
+ }
+ grEnable(GR_STENCIL_MODE_EXT);
+ fxMesa->Glide.grStencilOpExt(stencilFailFunc,
+ stencilZFailFunc,
+ stencilZPassFunc);
+ fxMesa->Glide.grStencilFuncExt(ctx->Stencil.Function[face] - GL_NEVER + GR_CMP_NEVER,
+ ctx->Stencil.Ref[face],
+ ctx->Stencil.ValueMask[face]);
+ fxMesa->Glide.grStencilMaskExt(ctx->Stencil.WriteMask[face]);
+ } else {
+ grDisable(GR_STENCIL_MODE_EXT);
+ }
+}
+
/************************************************************************/
/**************************** Color Mask SetUp **************************/
/************************************************************************/
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
- if (fxMesa->colDepth != 16) {
- /* 32bpp mode or 15bpp mode */
+ if (fxMesa->colDepth == 32) {
+ /* 32bpp mode */
fxMesa->Glide.grColorMaskExt(ctx->Color.ColorMask[RCOMP],
ctx->Color.ColorMask[GCOMP],
ctx->Color.ColorMask[BCOMP],
ctx->Color.ColorMask[ACOMP] && fxMesa->haveHwAlpha);
}
else {
- /* 16 bpp mode */
+ /* 15/16 bpp mode */
grColorMask(ctx->Color.ColorMask[RCOMP] |
ctx->Color.ColorMask[GCOMP] |
ctx->Color.ColorMask[BCOMP],
case GL_LINEAR:
guFogGenerateLinear(fxMesa->fogTable, ctx->Fog.Start,
ctx->Fog.End);
+ if (fxMesa->fogTable[0] > 63) {
+ /* [dBorca] Hack alert:
+ * As per Glide3 Programming Guide:
+ * The difference between consecutive fog values
+ * must be less than 64.
+ */
+ fxMesa->fogTable[0] = 63;
+ }
break;
case GL_EXP:
guFogGenerateExp(fxMesa->fogTable, ctx->Fog.Density);
}
grFogTable(fxMesa->fogTable);
- grFogMode(GR_FOG_WITH_TABLE_ON_Q);
+ if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) {
+ grVertexLayout(GR_PARAM_FOG_EXT, GR_VERTEX_FOG_OFFSET << 2,
+ GR_PARAM_ENABLE);
+ grFogMode(GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);
+ } else {
+ grVertexLayout(GR_PARAM_FOG_EXT, GR_VERTEX_FOG_OFFSET << 2,
+ GR_PARAM_DISABLE);
+ grFogMode(GR_FOG_WITH_TABLE_ON_Q);
+ }
}
else {
grFogMode(GR_FOG_DISABLE);
fxDDFogfv(GLcontext * ctx, GLenum pname, const GLfloat * params)
{
FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG;
+ switch (pname) {
+ case GL_FOG_COORDINATE_SOURCE_EXT: {
+ GLenum p = (GLenum)*params;
+ if (p == GL_FOG_COORDINATE_EXT) {
+ _swrast_allow_vertex_fog(ctx, GL_TRUE);
+ _swrast_allow_pixel_fog(ctx, GL_FALSE);
+ _tnl_allow_vertex_fog( ctx, GL_TRUE);
+ _tnl_allow_pixel_fog( ctx, GL_FALSE);
+ } else {
+ _swrast_allow_vertex_fog(ctx, GL_FALSE);
+ _swrast_allow_pixel_fog(ctx, GL_TRUE);
+ _tnl_allow_vertex_fog( ctx, GL_FALSE);
+ _tnl_allow_pixel_fog( ctx, GL_TRUE);
+ }
+ break;
+ }
+ default:
+ ;
+ }
}
/************************************************************************/
case GL_LINE_STIPPLE:
case GL_POINT_SMOOTH:
case GL_POLYGON_SMOOTH:
+ case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
fxMesa->new_state |= FX_NEW_TEXTURING;
break;