| /* |
| * 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; |
| } |