/* * Mesa 3-D graphics library * Version: 4.0 * * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* Authors: * David Bucciarelli * Brian Paul * Daryll Strauss * Keith Whitwell * Daniel Borca * Hiroshi Morii */ /* fxsetup.c - 3Dfx VooDoo rendering mode setup functions */ /* This code belongs to fxsetup.c, but I didn't want to clutter * the original code with Napalm specifics, in order to keep things * clear -- especially for backward compatibility. I should have * put it into another .c file, but I didn't want to export so many * things... * The point is, Napalm uses a different technique for texture env. * SST1 Single texturing: * setup standard grTexCombine * fiddle with grColorCombine/grAlphaCombine * SST1 Multi texturing: * fiddle with grTexCombine/grColorCombine/grAlphaCombine * Napalm Single texturing: * setup standard grColorCombineExt/grAlphaCombineExt * fiddle with grTexColorCombine/grTexAlphaCombine * Napalm Multi texturing: * setup standard grColorCombineExt/grAlphaCombineExt * fiddle with grTexColorCombine/grTexAlphaCombine */ /* * These macros are used below when handling COMBINE_EXT. */ #define TEXENV_OPERAND_INVERTED(operand) \ (((operand) == GL_ONE_MINUS_SRC_ALPHA) \ || ((operand) == GL_ONE_MINUS_SRC_COLOR)) #define TEXENV_OPERAND_ALPHA(operand) \ (((operand) == GL_SRC_ALPHA) || ((operand) == GL_ONE_MINUS_SRC_ALPHA)) #define TEXENV_SETUP_ARG_A(param, source, operand, iteratedAlpha) \ switch (source) { \ case GL_TEXTURE: \ param = GR_CMBX_LOCAL_TEXTURE_ALPHA; \ break; \ case GL_CONSTANT_EXT: \ param = GR_CMBX_TMU_CALPHA; \ break; \ case GL_PRIMARY_COLOR_EXT: \ param = GR_CMBX_ITALPHA; \ break; \ case GL_PREVIOUS_EXT: \ param = iteratedAlpha; \ break; \ default: \ /* \ * This is here just to keep from getting \ * compiler warnings. \ */ \ param = GR_CMBX_ZERO; \ break; \ } #define TEXENV_SETUP_ARG_RGB(param, source, operand, iteratedColor, iteratedAlpha) \ if (!TEXENV_OPERAND_ALPHA(operand)) { \ switch (source) { \ case GL_TEXTURE: \ param = GR_CMBX_LOCAL_TEXTURE_RGB; \ break; \ case GL_CONSTANT_EXT: \ param = GR_CMBX_TMU_CCOLOR; \ break; \ case GL_PRIMARY_COLOR_EXT: \ param = GR_CMBX_ITRGB; \ break; \ case GL_PREVIOUS_EXT: \ param = iteratedColor; \ break; \ default: \ /* \ * This is here just to keep from getting \ * compiler warnings. \ */ \ param = GR_CMBX_ZERO; \ break; \ } \ } else { \ switch (source) { \ case GL_TEXTURE: \ param = GR_CMBX_LOCAL_TEXTURE_ALPHA; \ break; \ case GL_CONSTANT_EXT: \ param = GR_CMBX_TMU_CALPHA; \ break; \ case GL_PRIMARY_COLOR_EXT: \ param = GR_CMBX_ITALPHA; \ break; \ case GL_PREVIOUS_EXT: \ param = iteratedAlpha; \ break; \ default: \ /* \ * This is here just to keep from getting \ * compiler warnings. \ */ \ param = GR_CMBX_ZERO; \ break; \ } \ } #define TEXENV_SETUP_MODE_RGB(param, operand) \ switch (operand) { \ case GL_SRC_COLOR: \ case GL_SRC_ALPHA: \ param = GR_FUNC_MODE_X; \ break; \ case GL_ONE_MINUS_SRC_ALPHA: \ case GL_ONE_MINUS_SRC_COLOR: \ param = GR_FUNC_MODE_ONE_MINUS_X; \ break; \ default: \ param = GR_FUNC_MODE_ZERO; \ break; \ } #define TEXENV_SETUP_MODE_A(param, operand) \ switch (operand) { \ case GL_SRC_ALPHA: \ param = GR_FUNC_MODE_X; \ break; \ case GL_ONE_MINUS_SRC_ALPHA: \ param = GR_FUNC_MODE_ONE_MINUS_X; \ break; \ default: \ param = GR_FUNC_MODE_ZERO; \ break; \ } static void fxSetupTextureEnvNapalm_NoLock(GLcontext * ctx, GLuint textureset, GLuint tmu, GLboolean iterated) { fxMesaContext fxMesa = FX_CONTEXT(ctx); const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[textureset]; struct tdfx_combine_alpha_ext alphaComb; struct tdfx_combine_color_ext colorComb; const GLfloat *envColor = texUnit->EnvColor; GrCombineLocal_t localc, locala; /* fragmentColor/Alpha */ GLint ifmt; tfxTexInfo *ti; struct gl_texture_object *tObj = texUnit->_Current; if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxSetupTextureEnvNapalm_NoLock(unit %u, TMU %u, iterated %d)\n", textureset, tmu, iterated); } ti = fxTMGetTexInfo(tObj); ifmt = ti->baseLevelInternalFormat; if (iterated) { /* we don't have upstream TMU */ locala = GR_CMBX_ITALPHA; localc = GR_CMBX_ITRGB; } else { /* we have upstream TMU */ locala = GR_CMBX_OTHER_TEXTURE_ALPHA; localc = GR_CMBX_OTHER_TEXTURE_RGB; } alphaComb.InvertD = FXFALSE; alphaComb.Shift = 0; alphaComb.Invert = FXFALSE; colorComb.InvertD = FXFALSE; colorComb.Shift = 0; colorComb.Invert = FXFALSE; switch (texUnit->EnvMode) { case GL_DECAL: alphaComb.SourceA = locala; alphaComb.ModeA = GR_FUNC_MODE_X; alphaComb.SourceB = GR_CMBX_ZERO; alphaComb.ModeB = GR_FUNC_MODE_X; alphaComb.SourceC = GR_CMBX_ZERO; alphaComb.InvertC = FXTRUE; alphaComb.SourceD = GR_CMBX_ZERO; colorComb.SourceA = GR_CMBX_LOCAL_TEXTURE_RGB; colorComb.ModeA = GR_FUNC_MODE_X; colorComb.SourceB = localc; colorComb.ModeB = GR_FUNC_MODE_NEGATIVE_X; colorComb.SourceC = GR_CMBX_LOCAL_TEXTURE_ALPHA; colorComb.InvertC = FXFALSE; colorComb.SourceD = GR_CMBX_B; break; case GL_MODULATE: if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) { alphaComb.SourceA = locala; alphaComb.ModeA = GR_FUNC_MODE_X; alphaComb.SourceB = GR_CMBX_ZERO; alphaComb.ModeB = GR_FUNC_MODE_X; alphaComb.SourceC = GR_CMBX_ZERO; alphaComb.InvertC = FXTRUE; alphaComb.SourceD = GR_CMBX_ZERO; } else { alphaComb.SourceA = locala; alphaComb.ModeA = GR_FUNC_MODE_X; alphaComb.SourceB = GR_CMBX_ZERO; alphaComb.ModeB = GR_FUNC_MODE_X; alphaComb.SourceC = GR_CMBX_LOCAL_TEXTURE_ALPHA; alphaComb.InvertC = FXFALSE; alphaComb.SourceD = GR_CMBX_ZERO; } if (ifmt == GL_ALPHA) { colorComb.SourceA = localc; colorComb.ModeA = GR_FUNC_MODE_X; colorComb.SourceB = GR_CMBX_ZERO; colorComb.ModeB = GR_FUNC_MODE_X; colorComb.SourceC = GR_CMBX_ZERO; colorComb.InvertC = FXTRUE; colorComb.SourceD = GR_CMBX_ZERO; } else { colorComb.SourceA = localc; colorComb.ModeA = GR_FUNC_MODE_X; colorComb.SourceB = GR_CMBX_ZERO; colorComb.ModeB = GR_FUNC_MODE_X; colorComb.SourceC = GR_CMBX_LOCAL_TEXTURE_RGB; colorComb.InvertC = FXFALSE; colorComb.SourceD = GR_CMBX_ZERO; } break; case GL_BLEND: if (ifmt == GL_INTENSITY) { alphaComb.SourceA = GR_CMBX_TMU_CALPHA; alphaComb.ModeA = GR_FUNC_MODE_X; alphaComb.SourceB = locala; alphaComb.ModeB = GR_FUNC_MODE_X; alphaComb.SourceC = GR_CMBX_LOCAL_TEXTURE_ALPHA; alphaComb.InvertC = FXFALSE; alphaComb.SourceD = GR_CMBX_ZERO; } else { alphaComb.SourceA = locala; alphaComb.ModeA = GR_FUNC_MODE_X; alphaComb.SourceB = GR_CMBX_ZERO; alphaComb.ModeB = GR_FUNC_MODE_X; alphaComb.SourceC = GR_CMBX_LOCAL_TEXTURE_ALPHA; alphaComb.InvertC = FXFALSE; alphaComb.SourceD = GR_CMBX_ZERO; } if (ifmt == GL_ALPHA) { colorComb.SourceA = localc; colorComb.ModeA = GR_FUNC_MODE_X; colorComb.SourceB = GR_CMBX_ZERO; colorComb.ModeB = GR_FUNC_MODE_X; colorComb.SourceC = GR_CMBX_ZERO; colorComb.InvertC = FXTRUE; colorComb.SourceD = GR_CMBX_ZERO; } else { colorComb.SourceA = GR_CMBX_TMU_CCOLOR; colorComb.ModeA = GR_FUNC_MODE_X; colorComb.SourceB = localc; colorComb.ModeB = GR_FUNC_MODE_NEGATIVE_X; colorComb.SourceC = GR_CMBX_LOCAL_TEXTURE_RGB; colorComb.InvertC = FXFALSE; colorComb.SourceD = GR_CMBX_B; } fxMesa->Glide.grConstantColorValueExt(tmu, (((GLuint)(envColor[0] * 255.0f)) ) | (((GLuint)(envColor[1] * 255.0f)) << 8) | (((GLuint)(envColor[2] * 255.0f)) << 16) | (((GLuint)(envColor[3] * 255.0f)) << 24)); break; case GL_REPLACE: if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) { alphaComb.SourceA = locala; alphaComb.ModeA = GR_FUNC_MODE_X; alphaComb.SourceB = GR_CMBX_ZERO; alphaComb.ModeB = GR_FUNC_MODE_X; alphaComb.SourceC = GR_CMBX_ZERO; alphaComb.InvertC = FXTRUE; alphaComb.SourceD = GR_CMBX_ZERO; } else { alphaComb.SourceA = GR_CMBX_LOCAL_TEXTURE_ALPHA; alphaComb.ModeA = GR_FUNC_MODE_X; alphaComb.SourceB = GR_CMBX_ZERO; alphaComb.ModeB = GR_FUNC_MODE_X; alphaComb.SourceC = GR_CMBX_ZERO; alphaComb.InvertC = FXTRUE; alphaComb.SourceD = GR_CMBX_ZERO; } if (ifmt == GL_ALPHA) { colorComb.SourceA = localc; colorComb.ModeA = GR_FUNC_MODE_X; colorComb.SourceB = GR_CMBX_ZERO; colorComb.ModeB = GR_FUNC_MODE_X; colorComb.SourceC = GR_CMBX_ZERO; colorComb.InvertC = FXTRUE; colorComb.SourceD = GR_CMBX_ZERO; } else { colorComb.SourceA = GR_CMBX_LOCAL_TEXTURE_RGB; colorComb.ModeA = GR_FUNC_MODE_X; colorComb.SourceB = GR_CMBX_ZERO; colorComb.ModeB = GR_FUNC_MODE_X; colorComb.SourceC = GR_CMBX_ZERO; colorComb.InvertC = FXTRUE; colorComb.SourceD = GR_CMBX_ZERO; } break; case GL_ADD: if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) { alphaComb.SourceA = locala; alphaComb.ModeA = GR_FUNC_MODE_X; alphaComb.SourceB = GR_CMBX_ZERO; alphaComb.ModeB = GR_FUNC_MODE_X; alphaComb.SourceC = GR_CMBX_ZERO; alphaComb.InvertC = FXTRUE; alphaComb.SourceD = GR_CMBX_ZERO; } else if (ifmt == GL_INTENSITY) { alphaComb.SourceA = locala; alphaComb.ModeA = GR_FUNC_MODE_X; alphaComb.SourceB = GR_CMBX_LOCAL_TEXTURE_ALPHA; alphaComb.ModeB = GR_FUNC_MODE_X; alphaComb.SourceC = GR_CMBX_ZERO; alphaComb.InvertC = FXTRUE; alphaComb.SourceD = GR_CMBX_ZERO; } else { alphaComb.SourceA = locala; alphaComb.ModeA = GR_FUNC_MODE_X; alphaComb.SourceB = GR_CMBX_ZERO; alphaComb.ModeB = GR_FUNC_MODE_X; alphaComb.SourceC = GR_CMBX_LOCAL_TEXTURE_ALPHA; alphaComb.InvertC = FXFALSE; alphaComb.SourceD = GR_CMBX_ZERO; } if (ifmt == GL_ALPHA) { colorComb.SourceA = localc; colorComb.ModeA = GR_FUNC_MODE_X; colorComb.SourceB = GR_CMBX_ZERO; colorComb.ModeB = GR_FUNC_MODE_X; colorComb.SourceC = GR_CMBX_ZERO; colorComb.InvertC = FXTRUE; colorComb.SourceD = GR_CMBX_ZERO; } else { colorComb.SourceA = localc; colorComb.ModeA = GR_FUNC_MODE_X; colorComb.SourceB = GR_CMBX_LOCAL_TEXTURE_RGB; colorComb.ModeB = GR_FUNC_MODE_X; colorComb.SourceC = GR_CMBX_ZERO; colorComb.InvertC = FXTRUE; colorComb.SourceD = GR_CMBX_ZERO; } break; /* COMBINE_EXT */ case GL_COMBINE_EXT: /* XXX todo - INCOMPLETE!!! */ if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) { #if 1 fprintf(stderr, "COMBINE_EXT: %s + %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB), _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA)); #else fprintf(stderr, "Texture Unit %d\n", textureset); fprintf(stderr, " GL_TEXTURE_ENV_MODE = %s\n", _mesa_lookup_enum_by_nr(texUnit->EnvMode)); fprintf(stderr, " GL_COMBINE_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB)); fprintf(stderr, " GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA)); fprintf(stderr, " GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[0])); fprintf(stderr, " GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[1])); fprintf(stderr, " GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[2])); fprintf(stderr, " GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[0])); fprintf(stderr, " GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[1])); fprintf(stderr, " GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[2])); fprintf(stderr, " GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[0])); fprintf(stderr, " GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[1])); fprintf(stderr, " GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[2])); fprintf(stderr, " GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[0])); fprintf(stderr, " GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[1])); fprintf(stderr, " GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[2])); fprintf(stderr, " GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB); fprintf(stderr, " GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA); fprintf(stderr, " GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", envColor[0], envColor[1], envColor[2], envColor[3]); #endif } alphaComb.Shift = texUnit->Combine.ScaleShiftA; colorComb.Shift = texUnit->Combine.ScaleShiftRGB; switch (texUnit->Combine.ModeRGB) { case GL_MODULATE: /* Arg0 * Arg1 == (A + 0) * C + 0 */ TEXENV_SETUP_ARG_RGB(colorComb.SourceA, texUnit->Combine.SourceRGB[0], texUnit->Combine.OperandRGB[0], localc, locala); TEXENV_SETUP_MODE_RGB(colorComb.ModeA, texUnit->Combine.OperandRGB[0]); colorComb.SourceB = GR_CMBX_ZERO; colorComb.ModeB = GR_FUNC_MODE_ZERO; TEXENV_SETUP_ARG_RGB(colorComb.SourceC, texUnit->Combine.SourceRGB[1], texUnit->Combine.OperandRGB[1], localc, locala); colorComb.InvertC = TEXENV_OPERAND_INVERTED( texUnit->Combine.OperandRGB[1]); colorComb.SourceD = GR_CMBX_ZERO; break; case GL_REPLACE: /* Arg0 == (A + 0) * 1 + 0 */ TEXENV_SETUP_ARG_RGB(colorComb.SourceA, texUnit->Combine.SourceRGB[0], texUnit->Combine.OperandRGB[0], localc, locala); TEXENV_SETUP_MODE_RGB(colorComb.ModeA, texUnit->Combine.OperandRGB[0]); colorComb.SourceB = GR_CMBX_ZERO; colorComb.ModeB = GR_FUNC_MODE_ZERO; colorComb.SourceC = GR_CMBX_ZERO; colorComb.InvertC = FXTRUE; colorComb.SourceD = GR_CMBX_ZERO; break; case GL_ADD: /* Arg0 + Arg1 = (A + B) * 1 + 0 */ TEXENV_SETUP_ARG_RGB(colorComb.SourceA, texUnit->Combine.SourceRGB[0], texUnit->Combine.OperandRGB[0], localc, locala); TEXENV_SETUP_MODE_RGB(colorComb.ModeA, texUnit->Combine.OperandRGB[0]); TEXENV_SETUP_ARG_RGB(colorComb.SourceB, texUnit->Combine.SourceRGB[1], texUnit->Combine.OperandRGB[1], localc, locala); TEXENV_SETUP_MODE_RGB(colorComb.ModeB, texUnit->Combine.OperandRGB[1]); colorComb.SourceC = GR_CMBX_ZERO; colorComb.InvertC = FXTRUE; colorComb.SourceD = GR_CMBX_ZERO; break; case GL_INTERPOLATE_EXT: /* Arg0 * Arg2 + Arg1 * (1 - Arg2) == * (Arg0 - Arg1) * Arg2 + Arg1 == (A - B) * C + D */ TEXENV_SETUP_ARG_RGB(colorComb.SourceA, texUnit->Combine.SourceRGB[0], texUnit->Combine.OperandRGB[0], localc, locala); TEXENV_SETUP_MODE_RGB(colorComb.ModeA, texUnit->Combine.OperandRGB[0]); TEXENV_SETUP_ARG_RGB(colorComb.SourceB, texUnit->Combine.SourceRGB[1], texUnit->Combine.OperandRGB[1], localc, locala); if (TEXENV_OPERAND_INVERTED(texUnit->Combine.OperandRGB[1])) { /* Hack alert!!! This case is wrong!!! */ fprintf(stderr, "COMBINE_EXT_color: WRONG!!!\n"); colorComb.ModeB = GR_FUNC_MODE_NEGATIVE_X; } else { colorComb.ModeB = GR_FUNC_MODE_NEGATIVE_X; } /* * The Source/Operand for the C value must * specify some kind of alpha value. */ TEXENV_SETUP_ARG_A(colorComb.SourceC, texUnit->Combine.SourceRGB[2], texUnit->Combine.OperandRGB[2], locala); colorComb.InvertC = FXFALSE; colorComb.SourceD = GR_CMBX_B; break; default: fprintf(stderr, "COMBINE_EXT_color: %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB)); } switch (texUnit->Combine.ModeA) { case GL_MODULATE: /* Arg0 * Arg1 == (A + 0) * C + 0 */ TEXENV_SETUP_ARG_A(alphaComb.SourceA, texUnit->Combine.SourceA[0], texUnit->Combine.OperandA[0], locala); TEXENV_SETUP_MODE_A(alphaComb.ModeA, texUnit->Combine.OperandA[0]); alphaComb.SourceB = GR_CMBX_ZERO; alphaComb.ModeB = GR_FUNC_MODE_ZERO; TEXENV_SETUP_ARG_A(alphaComb.SourceC, texUnit->Combine.SourceA[1], texUnit->Combine.OperandA[1], locala); alphaComb.InvertC = TEXENV_OPERAND_INVERTED( texUnit->Combine.OperandA[1]); alphaComb.SourceD = GR_CMBX_ZERO; break; case GL_REPLACE: /* Arg0 == (A + 0) * 1 + 0 */ TEXENV_SETUP_ARG_A(alphaComb.SourceA, texUnit->Combine.SourceA[0], texUnit->Combine.OperandA[0], locala); TEXENV_SETUP_MODE_A(alphaComb.ModeA, texUnit->Combine.OperandA[0]); alphaComb.SourceB = GR_CMBX_ZERO; alphaComb.ModeB = GR_FUNC_MODE_ZERO; alphaComb.SourceC = GR_CMBX_ZERO; alphaComb.InvertC = FXTRUE; alphaComb.SourceD = GR_CMBX_ZERO; break; case GL_ADD: /* Arg0 + Arg1 = (A + B) * 1 + 0 */ TEXENV_SETUP_ARG_A(alphaComb.SourceA, texUnit->Combine.SourceA[0], texUnit->Combine.OperandA[0], locala); TEXENV_SETUP_MODE_A(alphaComb.ModeA, texUnit->Combine.OperandA[0]); TEXENV_SETUP_ARG_A(alphaComb.SourceB, texUnit->Combine.SourceA[1], texUnit->Combine.OperandA[1], locala); TEXENV_SETUP_MODE_A(alphaComb.ModeB, texUnit->Combine.OperandA[1]); alphaComb.SourceC = GR_CMBX_ZERO; alphaComb.InvertC = FXTRUE; alphaComb.SourceD = GR_CMBX_ZERO; break; default: fprintf(stderr, "COMBINE_EXT_alpha: %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA)); } fxMesa->Glide.grConstantColorValueExt(tmu, (((GLuint)(envColor[0] * 255.0f)) ) | (((GLuint)(envColor[1] * 255.0f)) << 8) | (((GLuint)(envColor[2] * 255.0f)) << 16) | (((GLuint)(envColor[3] * 255.0f)) << 24)); break; default: if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxSetupTextureEnvNapalm_NoLock: %x Texture.EnvMode not yet supported\n", texUnit->EnvMode); } return; } /* On Napalm we simply put the color combine unit into passthrough mode * and do everything we need with the texture combine units. */ fxMesa->Glide.grColorCombineExt(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_X, GR_CMBX_ZERO, FXTRUE, GR_CMBX_ZERO, FXFALSE, 0, FXFALSE); fxMesa->Glide.grAlphaCombineExt(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_X, GR_CMBX_ZERO, FXTRUE, GR_CMBX_ZERO, FXFALSE, 0, FXFALSE); fxMesa->Glide.grTexAlphaCombineExt(tmu, alphaComb.SourceA, alphaComb.ModeA, alphaComb.SourceB, alphaComb.ModeB, alphaComb.SourceC, alphaComb.InvertC, alphaComb.SourceD, alphaComb.InvertD, alphaComb.Shift, alphaComb.Invert); fxMesa->Glide.grTexColorCombineExt(tmu, colorComb.SourceA, colorComb.ModeA, colorComb.SourceB, colorComb.ModeB, colorComb.SourceC, colorComb.InvertC, colorComb.SourceD, colorComb.InvertD, colorComb.Shift, colorComb.Invert); } /************************* Single Texture Set ***************************/ static void fxSelectSingleTMUSrcNapalm_NoLock(fxMesaContext fxMesa, GLint tmu, FxBool LODblend) { if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxSelectSingleTMUSrcNapalm_NoLock(%d, %d)\n", tmu, LODblend); } if (LODblend) { /* XXX todo - GR_CMBX_LOD_FRAC? */ fxMesa->tmuSrc = FX_TMU_SPLIT; } else { if (tmu != FX_TMU1) { /* disable tex1 */ if (fxMesa->haveTwoTMUs) { fxMesa->Glide.grTexAlphaCombineExt(FX_TMU1, GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, FXTRUE, GR_CMBX_ZERO, FXFALSE, 0, FXFALSE); fxMesa->Glide.grTexColorCombineExt(FX_TMU1, GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, FXTRUE, GR_CMBX_ZERO, FXFALSE, 0, FXFALSE); } fxMesa->tmuSrc = FX_TMU0; } else { #if 1 grTexCombine(GR_TMU0, GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_ONE, GR_COMBINE_FUNCTION_BLEND, GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE); #else /* [dBorca] why, oh why? doesn't work! stupid Glide? */ fxMesa->Glide.grTexAlphaCombineExt(FX_TMU0, GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_X, GR_CMBX_ZERO, FXTRUE, GR_CMBX_ZERO, FXFALSE, 0, FXFALSE); fxMesa->Glide.grTexColorCombineExt(FX_TMU0, GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_X, GR_CMBX_ZERO, FXTRUE, GR_CMBX_ZERO, FXFALSE, 0, FXFALSE); #endif fxMesa->tmuSrc = FX_TMU1; } } } static void fxSetupTextureSingleTMUNapalm_NoLock(GLcontext * ctx, GLuint textureset) { fxMesaContext fxMesa = FX_CONTEXT(ctx); GLuint unitsmode; tfxTexInfo *ti; struct gl_texture_object *tObj = ctx->Texture.Unit[textureset]._Current; int tmu; if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxSetupTextureSingleTMUNapalm_NoLock(%d)\n", textureset); } ti = fxTMGetTexInfo(tObj); fxTexValidate(ctx, tObj); fxSetupSingleTMU_NoLock(fxMesa, tObj); if (ti->whichTMU == FX_TMU_BOTH) tmu = FX_TMU0; else tmu = ti->whichTMU; if (fxMesa->tmuSrc != tmu) fxSelectSingleTMUSrcNapalm_NoLock(fxMesa, tmu, ti->LODblend); if (textureset == 0 || !fxMesa->haveTwoTMUs) unitsmode = fxGetTexSetConfiguration(ctx, tObj, NULL); else unitsmode = fxGetTexSetConfiguration(ctx, NULL, tObj); /* if(fxMesa->lastUnitsMode==unitsmode) */ /* return; */ fxMesa->lastUnitsMode = unitsmode; fxMesa->stw_hint_state = 0; FX_grHints_NoLock(GR_HINT_STWHINT, 0); if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) fprintf(stderr, "fxSetupTextureSingleTMUNapalm_NoLock: envmode is %s\n", _mesa_lookup_enum_by_nr(ctx->Texture.Unit[textureset].EnvMode)); /* [dBorca] Hack alert: * what if we're in split mode? (LODBlend) * also should we update BOTH TMUs in FX_TMU_BOTH mode? */ fxSetupTextureEnvNapalm_NoLock(ctx, textureset, tmu, GL_TRUE); } /************************* Double Texture Set ***************************/ static void fxSetupTextureDoubleTMUNapalm_NoLock(GLcontext * ctx) { fxMesaContext fxMesa = FX_CONTEXT(ctx); tfxTexInfo *ti0, *ti1; struct gl_texture_object *tObj0 = ctx->Texture.Unit[1]._Current; struct gl_texture_object *tObj1 = ctx->Texture.Unit[0]._Current; GLuint unitsmode; int tmu0 = 0, tmu1 = 1; if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxSetupTextureDoubleTMUNapalm_NoLock(...)\n"); } ti0 = fxTMGetTexInfo(tObj0); fxTexValidate(ctx, tObj0); ti1 = fxTMGetTexInfo(tObj1); fxTexValidate(ctx, tObj1); fxSetupDoubleTMU_NoLock(fxMesa, tObj0, tObj1); unitsmode = fxGetTexSetConfiguration(ctx, tObj0, tObj1); /* if(fxMesa->lastUnitsMode==unitsmode) */ /* return; */ fxMesa->lastUnitsMode = unitsmode; fxMesa->stw_hint_state |= GR_STWHINT_ST_DIFF_TMU1; FX_grHints_NoLock(GR_HINT_STWHINT, fxMesa->stw_hint_state); if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) fprintf(stderr, "fxSetupTextureDoubleTMUNapalm_NoLock: envmode is %s/%s\n", _mesa_lookup_enum_by_nr(ctx->Texture.Unit[0].EnvMode), _mesa_lookup_enum_by_nr(ctx->Texture.Unit[1].EnvMode)); if ((ti0->whichTMU == FX_TMU1) || (ti1->whichTMU == FX_TMU0)) { tmu0 = 1; tmu1 = 0; } fxMesa->tmuSrc = FX_TMU_BOTH; /* OpenGL vs Glide texture pipeline */ fxSetupTextureEnvNapalm_NoLock(ctx, 0, 1, GL_TRUE); fxSetupTextureEnvNapalm_NoLock(ctx, 1, 0, GL_FALSE); } /************************* No Texture ***************************/ static void fxSetupTextureNoneNapalm_NoLock(GLcontext * ctx) { fxMesaContext fxMesa = FX_CONTEXT(ctx); if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxSetupTextureNoneNapalm_NoLock(...)\n"); } /* the combiner formula is: (A + B) * C + D ** ** a = tc_otherselect ** a_mode = tc_invert_other ** b = tc_localselect ** b_mode = tc_invert_local ** c = (tc_mselect, tc_mselect_7) ** d = (tc_add_clocal, tc_add_alocal) ** shift = tc_outshift ** invert = tc_invert_output */ fxMesa->Glide.grColorCombineExt(GR_CMBX_ITRGB, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, FXTRUE, GR_CMBX_ZERO, FXFALSE, 0, FXFALSE); fxMesa->Glide.grAlphaCombineExt(GR_CMBX_ITALPHA, GR_FUNC_MODE_X, GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, GR_CMBX_ZERO, FXTRUE, GR_CMBX_ZERO, FXFALSE, 0, FXFALSE); fxMesa->lastUnitsMode = FX_UM_NONE; }