texture env combine refactor (Andreas Stenglein), following the same principles as...
authorRoland Scheidegger <rscheidegger@gmx.ch>
Mon, 16 Feb 2004 17:34:03 +0000 (17:34 +0000)
committerRoland Scheidegger <rscheidegger@gmx.ch>
Mon, 16 Feb 2004 17:34:03 +0000 (17:34 +0000)
src/mesa/drivers/dri/radeon/radeon_texstate.c

index 563a7e9ea02fd0778e6342700e97e7fc3ce3392c..16682b1f64925e03a70363f2c277438737748b15 100644 (file)
@@ -238,375 +238,6 @@ static void radeonSetTexImages( radeonContextPtr rmesa,
  * Texture combine functions
  */
 
-#define RADEON_DISABLE         0
-#define RADEON_REPLACE         1
-#define RADEON_MODULATE                2
-#define RADEON_DECAL           3
-#define RADEON_BLEND           4
-#define RADEON_ADD             5
-#define RADEON_MAX_COMBFUNC    6
-
-static GLuint radeon_color_combine[][RADEON_MAX_COMBFUNC] =
-{
-   /* Unit 0:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (RADEON_COLOR_ARG_A_ZERO |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_CURRENT_COLOR |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_REPLACE = 0x00802800
-       */
-      (RADEON_COLOR_ARG_A_ZERO |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_T0_COLOR |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_MODULATE = 0x00800142
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_T0_COLOR |
-       RADEON_COLOR_ARG_C_ZERO |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_DECAL = 0x008c2d42
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_T0_COLOR |
-       RADEON_COLOR_ARG_C_T0_ALPHA |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_BLEND = 0x008c2902
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_TFACTOR_COLOR |
-       RADEON_COLOR_ARG_C_T0_COLOR |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_ADD = 0x00812802
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_T0_COLOR |
-       RADEON_COMP_ARG_B |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-   },
-
-   /* Unit 1:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (RADEON_COLOR_ARG_A_ZERO |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_CURRENT_COLOR |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_REPLACE = 0x00803000
-       */
-      (RADEON_COLOR_ARG_A_ZERO |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_T1_COLOR |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_MODULATE = 0x00800182
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_T1_COLOR |
-       RADEON_COLOR_ARG_C_ZERO |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_DECAL = 0x008c3582
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_T1_COLOR |
-       RADEON_COLOR_ARG_C_T1_ALPHA |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_BLEND = 0x008c3102
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_TFACTOR_COLOR |
-       RADEON_COLOR_ARG_C_T1_COLOR |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_ADD = 0x00813002
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_T1_COLOR |
-       RADEON_COMP_ARG_B |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-   },
-
-   /* Unit 2:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (RADEON_COLOR_ARG_A_ZERO |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_CURRENT_COLOR |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_REPLACE = 0x00803800
-       */
-      (RADEON_COLOR_ARG_A_ZERO |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_T2_COLOR |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_MODULATE = 0x008001c2
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_T2_COLOR |
-       RADEON_COLOR_ARG_C_ZERO |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_DECAL = 0x008c3dc2
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_T2_COLOR |
-       RADEON_COLOR_ARG_C_T2_ALPHA |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_BLEND = 0x008c3902
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_TFACTOR_COLOR |
-       RADEON_COLOR_ARG_C_T2_COLOR |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_ADD = 0x00813802
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_T2_COLOR |
-       RADEON_COMP_ARG_B |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-   }
-};
-
-static GLuint radeon_alpha_combine[][RADEON_MAX_COMBFUNC] =
-{
-   /* Unit 0:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_REPLACE = 0x00800500
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_T0_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_MODULATE = 0x00800051
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_T0_ALPHA |
-       RADEON_ALPHA_ARG_C_ZERO |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_DECAL = 0x00800100
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_BLEND = 0x00800051
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
-       RADEON_ALPHA_ARG_C_T0_ALPHA |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_ADD = 0x00800051
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_T0_ALPHA |
-       RADEON_COMP_ARG_B |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-   },
-
-   /* Unit 1:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_REPLACE = 0x00800600
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_T1_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_MODULATE = 0x00800061
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_T1_ALPHA |
-       RADEON_ALPHA_ARG_C_ZERO |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_DECAL = 0x00800100
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_BLEND = 0x00800061
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
-       RADEON_ALPHA_ARG_C_T1_ALPHA |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_ADD = 0x00800061
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_T1_ALPHA |
-       RADEON_COMP_ARG_B |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-   },
-
-   /* Unit 2:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_REPLACE = 0x00800700
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_T2_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_MODULATE = 0x00800071
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_T2_ALPHA |
-       RADEON_ALPHA_ARG_C_ZERO |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_DECAL = 0x00800100
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_BLEND = 0x00800071
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
-       RADEON_ALPHA_ARG_C_T2_ALPHA |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_ADD = 0x00800021
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_T2_ALPHA |
-       RADEON_COMP_ARG_B |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-   }
-};
-
-
 /* GL_ARB_texture_env_combine support
  */
 
@@ -774,441 +405,275 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
        */
       rmesa->state.texture.unit[unit].format = 0;
       rmesa->state.texture.unit[unit].envMode = 0;
-      color_combine = radeon_color_combine[unit][RADEON_DISABLE];
-      alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
+      color_combine = RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO
+         | RADEON_COLOR_ARG_C_CURRENT_COLOR | RADEON_BLEND_CTL_ADD
+         | RADEON_SCALE_1X | RADEON_CLAMP_TX;
+      alpha_combine = RADEON_ALPHA_ARG_A_ZERO | RADEON_ALPHA_ARG_B_ZERO
+         | RADEON_ALPHA_ARG_C_CURRENT_ALPHA | RADEON_BLEND_CTL_ADD
+         | RADEON_SCALE_1X | RADEON_CLAMP_TX;
    }
    else {
-      const struct gl_texture_object *tObj = texUnit->_Current;
-      const GLenum format = tObj->Image[0][tObj->BaseLevel]->Format;
       GLuint color_arg[3], alpha_arg[3];
-      GLuint i, numColorArgs = 0, numAlphaArgs = 0;
-      GLuint RGBshift = texUnit->Combine.ScaleShiftRGB;
-      GLuint Ashift = texUnit->Combine.ScaleShiftA;
+      GLuint i;
+      const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
+      const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
+      GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB;
+      GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA;
 
-      switch ( texUnit->EnvMode ) {
-      case GL_REPLACE:
-         switch ( format ) {
-        case GL_RGBA:
-         case GL_LUMINANCE_ALPHA:
-         case GL_INTENSITY:
-           color_combine = radeon_color_combine[unit][RADEON_REPLACE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE];
-           break;
-        case GL_ALPHA:
-           color_combine = radeon_color_combine[unit][RADEON_DISABLE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE];
-           break;
-        case GL_LUMINANCE:
-        case GL_RGB:
-        case GL_YCBCR_MESA:
-           color_combine = radeon_color_combine[unit][RADEON_REPLACE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
-           break;
-        case GL_COLOR_INDEX:
-        default:
-           return GL_FALSE;
-        }
-        break;
+      /* Don't cache these results.
+       */
+      rmesa->state.texture.unit[unit].format = 0;
+      rmesa->state.texture.unit[unit].envMode = 0;
 
-      case GL_MODULATE:
-        switch ( format ) {
-        case GL_RGBA:
-        case GL_LUMINANCE_ALPHA:
-        case GL_INTENSITY:
-           color_combine = radeon_color_combine[unit][RADEON_MODULATE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
-           break;
-        case GL_ALPHA:
-           color_combine = radeon_color_combine[unit][RADEON_DISABLE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
-           break;
-        case GL_RGB:
-        case GL_LUMINANCE:
-        case GL_YCBCR_MESA:
-           color_combine = radeon_color_combine[unit][RADEON_MODULATE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
-           break;
-        case GL_COLOR_INDEX:
-        default:
-           return GL_FALSE;
-        }
-        break;
 
-      case GL_DECAL:
-        switch ( format ) {
-        case GL_RGBA:
-        case GL_RGB:
-        case GL_YCBCR_MESA:
-           color_combine = radeon_color_combine[unit][RADEON_DECAL];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
-           break;
-        case GL_ALPHA:
-        case GL_LUMINANCE:
-        case GL_LUMINANCE_ALPHA:
-        case GL_INTENSITY:
-           color_combine = radeon_color_combine[unit][RADEON_DISABLE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
-           break;
-        case GL_COLOR_INDEX:
-        default:
-           return GL_FALSE;
-        }
-        break;
-
-      case GL_BLEND:
-        switch ( format ) {
-        case GL_RGBA:
-        case GL_RGB:
-        case GL_LUMINANCE:
-        case GL_LUMINANCE_ALPHA:
-        case GL_YCBCR_MESA:
-           color_combine = radeon_color_combine[unit][RADEON_BLEND];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+      /* Step 1:
+       * Extract the color and alpha combine function arguments.
+       */
+      for ( i = 0 ; i < numColorArgs ; i++ ) {
+        const GLuint op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR;
+        assert(op >= 0);
+        assert(op <= 3);
+        switch ( texUnit->_CurrentCombine->SourceRGB[i] ) {
+        case GL_TEXTURE:
+           color_arg[i] = radeon_texture_color[op][unit];
            break;
-        case GL_ALPHA:
-           color_combine = radeon_color_combine[unit][RADEON_DISABLE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+        case GL_CONSTANT:
+           color_arg[i] = radeon_tfactor_color[op];
            break;
-        case GL_INTENSITY:
-           color_combine = radeon_color_combine[unit][RADEON_BLEND];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_BLEND];
+        case GL_PRIMARY_COLOR:
+           color_arg[i] = radeon_primary_color[op];
            break;
-        case GL_COLOR_INDEX:
-        default:
-           return GL_FALSE;
-        }
-        break;
-
-      case GL_ADD:
-        switch ( format ) {
-        case GL_RGBA:
-        case GL_RGB:
-        case GL_LUMINANCE:
-        case GL_LUMINANCE_ALPHA:
-        case GL_YCBCR_MESA:
-           color_combine = radeon_color_combine[unit][RADEON_ADD];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+        case GL_PREVIOUS:
+           color_arg[i] = radeon_previous_color[op];
            break;
-        case GL_ALPHA:
-           color_combine = radeon_color_combine[unit][RADEON_DISABLE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+        case GL_ZERO:
+           color_arg[i] = radeon_zero_color[op];
            break;
-        case GL_INTENSITY:
-           color_combine = radeon_color_combine[unit][RADEON_ADD];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_ADD];
+        case GL_ONE:
+           color_arg[i] = radeon_zero_color[op+1];
            break;
-        case GL_COLOR_INDEX:
         default:
            return GL_FALSE;
         }
-        break;
-
-      case GL_COMBINE:
-        /* Don't cache these results.
-         */
-        rmesa->state.texture.unit[unit].format = 0;
-        rmesa->state.texture.unit[unit].envMode = 0;
+      }
 
-        /* Step 0:
-         * Calculate how many arguments we need to process.
-         */
-        switch ( texUnit->Combine.ModeRGB ) {
-        case GL_REPLACE:
-           numColorArgs = 1;
+      for ( i = 0 ; i < numAlphaArgs ; i++ ) {
+        const GLuint op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA;
+        assert(op >= 0);
+        assert(op <= 1);
+        switch ( texUnit->_CurrentCombine->SourceA[i] ) {
+        case GL_TEXTURE:
+           alpha_arg[i] = radeon_texture_alpha[op][unit];
            break;
-        case GL_MODULATE:
-        case GL_ADD:
-        case GL_ADD_SIGNED:
-        case GL_SUBTRACT:
-        case GL_DOT3_RGB:
-        case GL_DOT3_RGBA:
-        case GL_DOT3_RGB_EXT:
-        case GL_DOT3_RGBA_EXT:
-           numColorArgs = 2;
+        case GL_CONSTANT:
+           alpha_arg[i] = radeon_tfactor_alpha[op];
            break;
-        case GL_INTERPOLATE:
-        case GL_MODULATE_ADD_ATI:
-        case GL_MODULATE_SIGNED_ADD_ATI:
-        case GL_MODULATE_SUBTRACT_ATI:
-           numColorArgs = 3;
+        case GL_PRIMARY_COLOR:
+           alpha_arg[i] = radeon_primary_alpha[op];
            break;
-        default:
-           return GL_FALSE;
-        }
-
-        switch ( texUnit->Combine.ModeA ) {
-        case GL_REPLACE:
-           numAlphaArgs = 1;
+        case GL_PREVIOUS:
+           alpha_arg[i] = radeon_previous_alpha[op];
            break;
-        case GL_MODULATE:
-        case GL_ADD:
-        case GL_ADD_SIGNED:
-        case GL_SUBTRACT:
-           numAlphaArgs = 2;
+        case GL_ZERO:
+           alpha_arg[i] = radeon_zero_alpha[op];
            break;
-        case GL_INTERPOLATE:
-        case GL_MODULATE_ADD_ATI:
-        case GL_MODULATE_SIGNED_ADD_ATI:
-        case GL_MODULATE_SUBTRACT_ATI:
-           numAlphaArgs = 3;
+        case GL_ONE:
+           alpha_arg[i] = radeon_zero_alpha[op+1];
            break;
         default:
            return GL_FALSE;
         }
+      }
 
-        /* Step 1:
-         * Extract the color and alpha combine function arguments.
-         */
-        for ( i = 0 ; i < numColorArgs ; i++ ) {
-           const GLuint op = texUnit->Combine.OperandRGB[i] - GL_SRC_COLOR;
-           assert(op >= 0);
-           assert(op <= 3);
-           switch ( texUnit->Combine.SourceRGB[i] ) {
-           case GL_TEXTURE:
-              color_arg[i] = radeon_texture_color[op][unit];
-              break;
-           case GL_CONSTANT:
-              color_arg[i] = radeon_tfactor_color[op];
-              break;
-           case GL_PRIMARY_COLOR:
-              color_arg[i] = radeon_primary_color[op];
-              break;
-           case GL_PREVIOUS:
-              color_arg[i] = radeon_previous_color[op];
-              break;
-           case GL_ZERO:
-              color_arg[i] = radeon_zero_color[op];
-              break;
-           case GL_ONE:
-              color_arg[i] = radeon_zero_color[op+1];
-              break;
-           default:
-              return GL_FALSE;
-           }
-        }
-
-        for ( i = 0 ; i < numAlphaArgs ; i++ ) {
-           const GLuint op = texUnit->Combine.OperandA[i] - GL_SRC_ALPHA;
-           assert(op >= 0);
-           assert(op <= 1);
-           switch ( texUnit->Combine.SourceA[i] ) {
-           case GL_TEXTURE:
-              alpha_arg[i] = radeon_texture_alpha[op][unit];
-              break;
-           case GL_CONSTANT:
-              alpha_arg[i] = radeon_tfactor_alpha[op];
-              break;
-           case GL_PRIMARY_COLOR:
-              alpha_arg[i] = radeon_primary_alpha[op];
-              break;
-           case GL_PREVIOUS:
-              alpha_arg[i] = radeon_previous_alpha[op];
-              break;
-           case GL_ZERO:
-              alpha_arg[i] = radeon_zero_alpha[op];
-              break;
-           case GL_ONE:
-              alpha_arg[i] = radeon_zero_alpha[op+1];
-              break;
-           default:
-              return GL_FALSE;
-           }
-        }
+      /* Step 2:
+       * Build up the color and alpha combine functions.
+       */
+      switch ( texUnit->_CurrentCombine->ModeRGB ) {
+      case GL_REPLACE:
+        color_combine = (RADEON_COLOR_ARG_A_ZERO |
+                         RADEON_COLOR_ARG_B_ZERO |
+                         RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, C );
+        break;
+      case GL_MODULATE:
+        color_combine = (RADEON_COLOR_ARG_C_ZERO |
+                         RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, B );
+        break;
+      case GL_ADD:
+        color_combine = (RADEON_COLOR_ARG_B_ZERO |
+                         RADEON_COMP_ARG_B |
+                         RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, C );
+        break;
+      case GL_ADD_SIGNED:
+        color_combine = (RADEON_COLOR_ARG_B_ZERO |
+                         RADEON_COMP_ARG_B |
+                         RADEON_BLEND_CTL_ADDSIGNED |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, C );
+        break;
+      case GL_SUBTRACT:
+        color_combine = (RADEON_COLOR_ARG_B_ZERO |
+                         RADEON_COMP_ARG_B |
+                         RADEON_BLEND_CTL_SUBTRACT |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, C );
+        break;
+      case GL_INTERPOLATE:
+        color_combine = (RADEON_BLEND_CTL_BLEND |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, B );
+        RADEON_COLOR_ARG( 1, A );
+        RADEON_COLOR_ARG( 2, C );
+        break;
 
-        /* Step 2:
-         * Build up the color and alpha combine functions.
+      case GL_DOT3_RGB_EXT:
+      case GL_DOT3_RGBA_EXT:
+        /* The EXT version of the DOT3 extension does not support the
+         * scale factor, but the ARB version (and the version in OpenGL
+         * 1.3) does.
          */
-        switch ( texUnit->Combine.ModeRGB ) {
-        case GL_REPLACE:
-           color_combine = (RADEON_COLOR_ARG_A_ZERO |
-                            RADEON_COLOR_ARG_B_ZERO |
-                            RADEON_BLEND_CTL_ADD |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, C );
-           break;
-        case GL_MODULATE:
-           color_combine = (RADEON_COLOR_ARG_C_ZERO |
-                            RADEON_BLEND_CTL_ADD |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, A );
-           RADEON_COLOR_ARG( 1, B );
-           break;
-        case GL_ADD:
-           color_combine = (RADEON_COLOR_ARG_B_ZERO |
-                            RADEON_COMP_ARG_B |
-                            RADEON_BLEND_CTL_ADD |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, A );
-           RADEON_COLOR_ARG( 1, C );
-           break;
-        case GL_ADD_SIGNED:
-           color_combine = (RADEON_COLOR_ARG_B_ZERO |
-                            RADEON_COMP_ARG_B |
-                            RADEON_BLEND_CTL_ADDSIGNED |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, A );
-           RADEON_COLOR_ARG( 1, C );
-           break;
-        case GL_SUBTRACT:
-           color_combine = (RADEON_COLOR_ARG_B_ZERO |
-                            RADEON_COMP_ARG_B |
-                            RADEON_BLEND_CTL_SUBTRACT |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, A );
-           RADEON_COLOR_ARG( 1, C );
-           break;
-        case GL_INTERPOLATE:
-           color_combine = (RADEON_BLEND_CTL_BLEND |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, B );
-           RADEON_COLOR_ARG( 1, A );
-           RADEON_COLOR_ARG( 2, C );
-           break;
-
-        case GL_DOT3_RGB_EXT:
-        case GL_DOT3_RGBA_EXT:
-           /* The EXT version of the DOT3 extension does not support the
-            * scale factor, but the ARB version (and the version in OpenGL
-            * 1.3) does.
-            */
-           RGBshift = 0;
-           Ashift = 0;
-           /* FALLTHROUGH */
-
-        case GL_DOT3_RGB:
-        case GL_DOT3_RGBA:
-           /* The R100 / RV200 only support a 1X multiplier in hardware
-            * w/the ARB version.
-            */
-           if ( RGBshift != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) {
-              return GL_FALSE;
-           }
-
-           RGBshift += 2;
-           Ashift = RGBshift;
-
-           color_combine = (RADEON_COLOR_ARG_C_ZERO |
-                            RADEON_BLEND_CTL_DOT3 |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, A );
-           RADEON_COLOR_ARG( 1, B );
-           break;
-
-        case GL_MODULATE_ADD_ATI:
-           color_combine = (RADEON_BLEND_CTL_ADD |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, A );
-           RADEON_COLOR_ARG( 1, C );
-           RADEON_COLOR_ARG( 2, B );
-           break;
-        case GL_MODULATE_SIGNED_ADD_ATI:
-           color_combine = (RADEON_BLEND_CTL_ADDSIGNED |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, A );
-           RADEON_COLOR_ARG( 1, C );
-           RADEON_COLOR_ARG( 2, B );
-           break;
-        case GL_MODULATE_SUBTRACT_ATI:
-           color_combine = (RADEON_BLEND_CTL_SUBTRACT |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, A );
-           RADEON_COLOR_ARG( 1, C );
-           RADEON_COLOR_ARG( 2, B );
-           break;
-        default:
+        RGBshift = 0;
+        Ashift = 0;
+        /* FALLTHROUGH */
+
+      case GL_DOT3_RGB:
+      case GL_DOT3_RGBA:
+        /* The R100 / RV200 only support a 1X multiplier in hardware
+         * w/the ARB version.
+         */
+        if ( RGBshift != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) {
            return GL_FALSE;
         }
 
-        switch ( texUnit->Combine.ModeA ) {
-        case GL_REPLACE:
-           alpha_combine = (RADEON_ALPHA_ARG_A_ZERO |
-                            RADEON_ALPHA_ARG_B_ZERO |
-                            RADEON_BLEND_CTL_ADD |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, C );
-           break;
-        case GL_MODULATE:
-           alpha_combine = (RADEON_ALPHA_ARG_C_ZERO |
-                            RADEON_BLEND_CTL_ADD |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, A );
-           RADEON_ALPHA_ARG( 1, B );
-           break;
-        case GL_ADD:
-           alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
-                            RADEON_COMP_ARG_B |
-                            RADEON_BLEND_CTL_ADD |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, A );
-           RADEON_ALPHA_ARG( 1, C );
-           break;
-        case GL_ADD_SIGNED:
-           alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
-                            RADEON_COMP_ARG_B |
-                            RADEON_BLEND_CTL_ADDSIGNED |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, A );
-           RADEON_ALPHA_ARG( 1, C );
-           break;
-        case GL_SUBTRACT:
-           alpha_combine = (RADEON_COLOR_ARG_B_ZERO |
-                            RADEON_COMP_ARG_B |
-                            RADEON_BLEND_CTL_SUBTRACT |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, A );
-           RADEON_ALPHA_ARG( 1, C );
-           break;
-        case GL_INTERPOLATE:
-           alpha_combine = (RADEON_BLEND_CTL_BLEND |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, B );
-           RADEON_ALPHA_ARG( 1, A );
-           RADEON_ALPHA_ARG( 2, C );
-           break;
-
-        case GL_MODULATE_ADD_ATI:
-           alpha_combine = (RADEON_BLEND_CTL_ADD |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, A );
-           RADEON_ALPHA_ARG( 1, C );
-           RADEON_ALPHA_ARG( 2, B );
-           break;
-        case GL_MODULATE_SIGNED_ADD_ATI:
-           alpha_combine = (RADEON_BLEND_CTL_ADDSIGNED |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, A );
-           RADEON_ALPHA_ARG( 1, C );
-           RADEON_ALPHA_ARG( 2, B );
-           break;
-        case GL_MODULATE_SUBTRACT_ATI:
-           alpha_combine = (RADEON_BLEND_CTL_SUBTRACT |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, A );
-           RADEON_ALPHA_ARG( 1, C );
-           RADEON_ALPHA_ARG( 2, B );
-           break;
-        default:
-           return GL_FALSE;
-        }
+        RGBshift += 2;
+        Ashift = RGBshift;
 
-        if ( (texUnit->Combine.ModeRGB == GL_DOT3_RGB_EXT)
-             || (texUnit->Combine.ModeRGB == GL_DOT3_RGB) ) {
-           alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
-        }
+        color_combine = (RADEON_COLOR_ARG_C_ZERO |
+                         RADEON_BLEND_CTL_DOT3 |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, B );
+        break;
 
-        /* Step 3:
-         * Apply the scale factor.
-         */
-        color_combine |= (RGBshift << RADEON_SCALE_SHIFT);
-        alpha_combine |= (Ashift   << RADEON_SCALE_SHIFT);
+      case GL_MODULATE_ADD_ATI:
+        color_combine = (RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, C );
+        RADEON_COLOR_ARG( 2, B );
+        break;
+      case GL_MODULATE_SIGNED_ADD_ATI:
+        color_combine = (RADEON_BLEND_CTL_ADDSIGNED |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, C );
+        RADEON_COLOR_ARG( 2, B );
+        break;
+      case GL_MODULATE_SUBTRACT_ATI:
+        color_combine = (RADEON_BLEND_CTL_SUBTRACT |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, C );
+        RADEON_COLOR_ARG( 2, B );
+        break;
+      default:
+        return GL_FALSE;
+      }
 
-        /* All done!
-         */
+      switch ( texUnit->_CurrentCombine->ModeA ) {
+      case GL_REPLACE:
+        alpha_combine = (RADEON_ALPHA_ARG_A_ZERO |
+                         RADEON_ALPHA_ARG_B_ZERO |
+                         RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, C );
+        break;
+      case GL_MODULATE:
+        alpha_combine = (RADEON_ALPHA_ARG_C_ZERO |
+                         RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, A );
+        RADEON_ALPHA_ARG( 1, B );
+        break;
+      case GL_ADD:
+        alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
+                         RADEON_COMP_ARG_B |
+                         RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, A );
+        RADEON_ALPHA_ARG( 1, C );
+        break;
+      case GL_ADD_SIGNED:
+        alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
+                         RADEON_COMP_ARG_B |
+                         RADEON_BLEND_CTL_ADDSIGNED |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, A );
+        RADEON_ALPHA_ARG( 1, C );
+        break;
+      case GL_SUBTRACT:
+        alpha_combine = (RADEON_COLOR_ARG_B_ZERO |
+                         RADEON_COMP_ARG_B |
+                         RADEON_BLEND_CTL_SUBTRACT |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, A );
+        RADEON_ALPHA_ARG( 1, C );
+        break;
+      case GL_INTERPOLATE:
+        alpha_combine = (RADEON_BLEND_CTL_BLEND |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, B );
+        RADEON_ALPHA_ARG( 1, A );
+        RADEON_ALPHA_ARG( 2, C );
         break;
 
+      case GL_MODULATE_ADD_ATI:
+        alpha_combine = (RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, A );
+        RADEON_ALPHA_ARG( 1, C );
+        RADEON_ALPHA_ARG( 2, B );
+        break;
+      case GL_MODULATE_SIGNED_ADD_ATI:
+        alpha_combine = (RADEON_BLEND_CTL_ADDSIGNED |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, A );
+        RADEON_ALPHA_ARG( 1, C );
+        RADEON_ALPHA_ARG( 2, B );
+        break;
+      case GL_MODULATE_SUBTRACT_ATI:
+        alpha_combine = (RADEON_BLEND_CTL_SUBTRACT |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, A );
+        RADEON_ALPHA_ARG( 1, C );
+        RADEON_ALPHA_ARG( 2, B );
+        break;
       default:
         return GL_FALSE;
       }
+
+      if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB_EXT)
+          || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB) ) {
+        alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
+      }
+
+      /* Step 3:
+       * Apply the scale factor.
+       */
+      color_combine |= (RGBshift << RADEON_SCALE_SHIFT);
+      alpha_combine |= (Ashift   << RADEON_SCALE_SHIFT);
+
+      /* All done!
+       */
    }
 
    if ( rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] != color_combine ||