Refactor "class" texture environments to be implemented in terms of
authorIan Romanick <idr@us.ibm.com>
Fri, 6 Feb 2004 17:39:03 +0000 (17:39 +0000)
committerIan Romanick <idr@us.ibm.com>
Fri, 6 Feb 2004 17:39:03 +0000 (17:39 +0000)
ARB_texture_env_combine state.

src/mesa/drivers/dri/i830/i830_texstate.c
src/mesa/drivers/dri/mga/mga_texcombine.c
src/mesa/drivers/dri/r200/r200_texstate.c
src/mesa/drivers/dri/radeon/radeon_texstate.c
src/mesa/drivers/dri/tdfx/tdfx_texstate.c
src/mesa/main/attrib.c
src/mesa/main/mtypes.h
src/mesa/main/texstate.c
src/mesa/main/texstore.c
src/mesa/swrast/s_texture.c

index 8e93a5b..19775db 100644 (file)
@@ -1021,14 +1021,14 @@ static void i830SetTexEnvCombine(i830ContextPtr imesa,
    GLuint args_RGB[3];
    GLuint args_A[3];
    GLuint texel_op = GetTexelOp(unit);
-   GLuint rgb_shift = texUnit->CombineScaleShiftRGB;
-   GLuint alpha_shift = texUnit->CombineScaleShiftA;
+   GLuint rgb_shift = texUnit->Combine.ScaleShiftRGB;
+   GLuint alpha_shift = texUnit->Combine.ScaleShiftA;
    int i;
 
    if(I830_DEBUG&DEBUG_TEXTURE)
       fprintf(stderr, "%s\n", __FUNCTION__);
 
-   switch(texUnit->CombineModeRGB) {
+   switch(texUnit->Combine.ModeRGB) {
    case GL_REPLACE: 
       blendop = TEXBLENDOP_ARG1;
       break;
@@ -1067,7 +1067,7 @@ static void i830SetTexEnvCombine(i830ContextPtr imesa,
 
    blendop |= (rgb_shift << TEXOP_SCALE_SHIFT);
 
-   switch(texUnit->CombineModeA) {
+   switch(texUnit->Combine.ModeA) {
    case GL_REPLACE: 
       ablendop = TEXBLENDOP_ARG1;
       break;
@@ -1090,8 +1090,8 @@ static void i830SetTexEnvCombine(i830ContextPtr imesa,
       return;
    }
 
-   if ( (texUnit->CombineModeRGB == GL_DOT3_RGBA_EXT)
-       || (texUnit->CombineModeRGB == GL_DOT3_RGBA) ) {
+   if ( (texUnit->Combine.ModeRGB == GL_DOT3_RGBA_EXT)
+       || (texUnit->Combine.ModeRGB == GL_DOT3_RGBA) ) {
       ablendop = TEXBLENDOP_DOT3;
    }
 
@@ -1099,7 +1099,7 @@ static void i830SetTexEnvCombine(i830ContextPtr imesa,
 
    /* Handle RGB args */
    for(i = 0; i < 3; i++) {
-      switch(texUnit->CombineSourceRGB[i]) {
+      switch(texUnit->Combine.SourceRGB[i]) {
       case GL_TEXTURE: 
         args_RGB[i] = texel_op;
         break;
@@ -1117,7 +1117,7 @@ static void i830SetTexEnvCombine(i830ContextPtr imesa,
         
       }
 
-      switch(texUnit->CombineOperandRGB[i]) {
+      switch(texUnit->Combine.OperandRGB[i]) {
       case GL_SRC_COLOR: 
         args_RGB[i] |= 0;
         break;
@@ -1138,7 +1138,7 @@ static void i830SetTexEnvCombine(i830ContextPtr imesa,
 
    /* Handle A args */
    for(i = 0; i < 3; i++) {
-      switch(texUnit->CombineSourceA[i]) {
+      switch(texUnit->Combine.SourceA[i]) {
       case GL_TEXTURE: 
         args_A[i] = texel_op;
         break;
@@ -1156,7 +1156,7 @@ static void i830SetTexEnvCombine(i830ContextPtr imesa,
         
       }
 
-      switch(texUnit->CombineOperandA[i]) {
+      switch(texUnit->Combine.OperandA[i]) {
       case GL_SRC_ALPHA: 
         args_A[i] |= 0;
         break;
index ca7322a..bbfa29b 100644 (file)
@@ -52,7 +52,7 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
    int args[3];
    int i;
 
-   switch (texUnit->CombineModeRGB) {
+   switch (texUnit->Combine.ModeRGB) {
    case GL_REPLACE:
       numColorArgs = 1;
       break;
@@ -72,7 +72,7 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
       return GL_FALSE;
    }
 
-   switch (texUnit->CombineModeA) {
+   switch (texUnit->Combine.ModeA) {
    case GL_REPLACE:
       numAlphaArgs = 1;
       break;
@@ -97,7 +97,7 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
    }
 
    for (i = 0;i < numColorArgs; i++) {
-      switch (texUnit->CombineSourceRGB[i]) {
+      switch (texUnit->Combine.SourceRGB[i]) {
       case GL_TEXTURE:
          arg1[i] |= 0;
          arg2[i] |= ARG_DISABLE;
@@ -181,11 +181,11 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
          return GL_FALSE;
       }
 
-      switch (texUnit->CombineOperandRGB[i]) {
+      switch (texUnit->Combine.OperandRGB[i]) {
       case GL_SRC_COLOR:
          arg1[i] |= 0;
          arg2[i] |= 0;
-         if (texUnit->CombineSourceRGB[i] == GL_CONSTANT &&
+         if (texUnit->Combine.SourceRGB[i] == GL_CONSTANT &&
              RGBA_EQUAL( mmesa->envcolor[source] )) {
             alpha[i] |= 0;
          } else {
@@ -195,7 +195,7 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
       case GL_ONE_MINUS_SRC_COLOR:
          arg1[i] |= TD0_color_arg1_inv_enable;
          arg2[i] |= TD0_color_arg2_inv_enable;
-         if (texUnit->CombineSourceRGB[i] == GL_CONSTANT &&
+         if (texUnit->Combine.SourceRGB[i] == GL_CONSTANT &&
              RGBA_EQUAL( mmesa->envcolor[source] )) {
             alpha[i] |= (TD0_color_alpha1inv_enable |
                          TD0_color_alpha2inv_enable);
@@ -219,7 +219,7 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
       }
    }
 
-   switch (texUnit->CombineModeRGB) {
+   switch (texUnit->Combine.ModeRGB) {
    case GL_MODULATE_ADD_ATI:
    case GL_MODULATE_SIGNED_ADD_ATI:
       /* Special handling for ATI_texture_env_combine3.
@@ -302,12 +302,12 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
          args[0] = MGA_ARG1; args[1] = MGA_ARG2; args[2] = MGA_ALPHA;
       } else
       if ((arg1[1] | arg2[0] | alpha[2]) != ARG_DISABLE &&
-          texUnit->CombineModeRGB != GL_MODULATE_SUBTRACT_ATI) {
+          texUnit->Combine.ModeRGB != GL_MODULATE_SUBTRACT_ATI) {
          *reg |= arg1[1] | arg2[0] | alpha[2];
          args[0] = MGA_ARG2; args[1] = MGA_ARG1; args[2] = MGA_ALPHA;
       } else
       if ((arg1[1] | arg2[2] | alpha[0]) != ARG_DISABLE &&
-          texUnit->CombineModeRGB != GL_MODULATE_SUBTRACT_ATI) {
+          texUnit->Combine.ModeRGB != GL_MODULATE_SUBTRACT_ATI) {
          *reg |= arg1[1] | arg2[2] | alpha[0];
          args[0] = MGA_ALPHA; args[1] = MGA_ARG1; args[2] = MGA_ARG2;
       } else
@@ -328,9 +328,9 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
       }
    }
 
-   switch (texUnit->CombineModeRGB) {
+   switch (texUnit->Combine.ModeRGB) {
    case GL_REPLACE:
-      if (texUnit->CombineScaleShiftRGB) {
+      if (texUnit->Combine.ScaleShiftRGB) {
          return GL_FALSE;
       }
 
@@ -344,9 +344,9 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
       }
       break;
    case GL_MODULATE:
-      if (texUnit->CombineScaleShiftRGB == 1) {
+      if (texUnit->Combine.ScaleShiftRGB == 1) {
          *reg |= TD0_color_modbright_2x;
-      } else if (texUnit->CombineScaleShiftRGB == 2) {
+      } else if (texUnit->Combine.ScaleShiftRGB == 2) {
          *reg |= TD0_color_modbright_4x;
       }
 
@@ -368,9 +368,9 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
          /* Can't get alpha to the adder */
          return GL_FALSE;
       }
-      if (texUnit->CombineScaleShiftRGB == 1) {
+      if (texUnit->Combine.ScaleShiftRGB == 1) {
          *reg |= TD0_color_add2x_enable;
-      } else if (texUnit->CombineScaleShiftRGB == 2) {
+      } else if (texUnit->Combine.ScaleShiftRGB == 2) {
          return GL_FALSE;
       }
 
@@ -382,9 +382,9 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
          /* Only alpha can function as Arg2 */
          return GL_FALSE;
       }
-      if (texUnit->CombineScaleShiftRGB == 1) {
+      if (texUnit->Combine.ScaleShiftRGB == 1) {
          *reg |= TD0_color_add2x_enable;
-      } else if (texUnit->CombineScaleShiftRGB == 2) {
+      } else if (texUnit->Combine.ScaleShiftRGB == 2) {
          return GL_FALSE;
       }
 
@@ -422,9 +422,9 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
          /* Can't get alpha to the adder */
          return GL_FALSE;
       }
-      if (texUnit->CombineScaleShiftRGB == 1) {
+      if (texUnit->Combine.ScaleShiftRGB == 1) {
          *reg |= TD0_color_add2x_enable;
-      } else if (texUnit->CombineScaleShiftRGB == 2) {
+      } else if (texUnit->Combine.ScaleShiftRGB == 2) {
          return GL_FALSE;
       }
 
@@ -445,9 +445,9 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
          /* Can't get alpha to the adder */
          return GL_FALSE;
       }
-      if (texUnit->CombineScaleShiftRGB == 1) {
+      if (texUnit->Combine.ScaleShiftRGB == 1) {
          *reg |= TD0_color_add2x_enable;
-      } else if (texUnit->CombineScaleShiftRGB == 2) {
+      } else if (texUnit->Combine.ScaleShiftRGB == 2) {
          return GL_FALSE;
       }
 
@@ -487,9 +487,9 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
          /* Can't swap arguments */
          return GL_FALSE;
       }
-      if (texUnit->CombineScaleShiftRGB == 1) {
+      if (texUnit->Combine.ScaleShiftRGB == 1) {
          *reg |= TD0_color_add2x_enable;
-      } else if (texUnit->CombineScaleShiftRGB == 2) {
+      } else if (texUnit->Combine.ScaleShiftRGB == 2) {
          return GL_FALSE;
       }
 
@@ -515,7 +515,7 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
    }
 
    for (i = 0; i < numAlphaArgs; i++) {
-      switch (texUnit->CombineSourceA[i]) {
+      switch (texUnit->Combine.SourceA[i]) {
       case GL_TEXTURE:
          arg1[i] |= 0;
          arg2[i] |= ARG_DISABLE;
@@ -589,7 +589,7 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
          return GL_FALSE;
       }
 
-      switch (texUnit->CombineOperandA[i]) {
+      switch (texUnit->Combine.OperandA[i]) {
       case GL_SRC_ALPHA:
          arg1[i] |= 0;
          arg2[i] |= 0;
@@ -614,9 +614,9 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
       return GL_FALSE;
    }
 
-   switch (texUnit->CombineModeA) {
+   switch (texUnit->Combine.ModeA) {
    case GL_REPLACE:
-      if (texUnit->CombineScaleShiftA) {
+      if (texUnit->Combine.ScaleShiftA) {
          return GL_FALSE;
       }
 
@@ -627,9 +627,9 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
       }
       break;
    case GL_MODULATE:
-      if (texUnit->CombineScaleShiftA == 1) {
+      if (texUnit->Combine.ScaleShiftA == 1) {
          *reg |= TD0_alpha_modbright_2x;
-      } else if (texUnit->CombineScaleShiftA == 2) {
+      } else if (texUnit->Combine.ScaleShiftA == 2) {
          *reg |= TD0_alpha_modbright_4x;
       }
 
@@ -639,9 +639,9 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
       *reg |= TD0_alpha_addbias_enable;
       /* fallthrough */
    case GL_ADD:
-      if (texUnit->CombineScaleShiftA == 1) {
+      if (texUnit->Combine.ScaleShiftA == 1) {
          *reg |= TD0_alpha_add2x_enable;
-      } else if (texUnit->CombineScaleShiftA == 2) {
+      } else if (texUnit->Combine.ScaleShiftA == 2) {
          return GL_FALSE;
       }
 
@@ -649,9 +649,9 @@ GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
                TD0_alpha_sel_add);
       break;
    case GL_SUBTRACT:
-      if (texUnit->CombineScaleShiftA == 1) {
+      if (texUnit->Combine.ScaleShiftA == 1) {
          *reg |= TD0_alpha_add2x_enable;
-      } else if (texUnit->CombineScaleShiftA == 2) {
+      } else if (texUnit->Combine.ScaleShiftA == 2) {
          return GL_FALSE;
       }
 
index 8e17166..dbd15ac 100644 (file)
@@ -279,304 +279,6 @@ static void r200SetTexImages( r200ContextPtr rmesa,
  * Texture combine functions
  */
 
-#define R200_DISABLE           0
-#define R200_REPLACE           1
-#define R200_MODULATE          2
-#define R200_DECAL             3
-#define R200_BLEND             4
-#define R200_ADD               5
-#define R200_MAX_COMBFUNC      6
-
-static GLuint r200_color_combine[][R200_MAX_COMBFUNC] =
-{
-   /* Unit 0:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (R200_TXC_ARG_A_ZERO  |
-       R200_TXC_ARG_B_ZERO |
-       R200_TXC_ARG_C_DIFFUSE_COLOR |
-       R200_TXC_OP_MADD),
-
-      /* GL_REPLACE = 0x00802800
-       */
-      (R200_TXC_ARG_A_ZERO |
-       R200_TXC_ARG_B_ZERO |
-       R200_TXC_ARG_C_R0_COLOR |
-       R200_TXC_OP_MADD),
-
-      /* GL_MODULATE = 0x00800142
-       */
-      (R200_TXC_ARG_A_DIFFUSE_COLOR | /* current starts in DIFFUSE */
-       R200_TXC_ARG_B_R0_COLOR |
-       R200_TXC_ARG_C_ZERO |
-       R200_TXC_OP_MADD),
-
-      /* GL_DECAL = 0x008c2d42
-       */
-      (R200_TXC_ARG_A_DIFFUSE_COLOR |
-       R200_TXC_ARG_B_R0_COLOR |
-       R200_TXC_ARG_C_R0_ALPHA |
-       R200_TXC_OP_LERP),
-
-      /* GL_BLEND = 0x008c2902
-       */
-      (R200_TXC_ARG_A_DIFFUSE_COLOR |
-       R200_TXC_ARG_B_TFACTOR_COLOR |
-       R200_TXC_ARG_C_R0_COLOR |
-       R200_TXC_OP_LERP),
-
-      /* GL_ADD = 0x00812802
-       */
-      (R200_TXC_ARG_A_DIFFUSE_COLOR |
-       R200_TXC_ARG_B_ZERO |
-       R200_TXC_ARG_C_R0_COLOR |
-       R200_TXC_COMP_ARG_B |
-       R200_TXC_OP_MADD),
-   },
-
-   /* Unit 1:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (R200_TXC_ARG_A_ZERO |
-       R200_TXC_ARG_B_ZERO |
-       R200_TXC_ARG_C_R0_COLOR |
-       R200_TXC_OP_MADD),
-
-      /* GL_REPLACE = 0x00803000
-       */
-      (R200_TXC_ARG_A_ZERO |
-       R200_TXC_ARG_B_ZERO |
-       R200_TXC_ARG_C_R1_COLOR |
-       R200_TXC_OP_MADD),
-
-      /* GL_MODULATE = 0x00800182
-       */
-      (R200_TXC_ARG_A_R0_COLOR | /* current in R0 thereafter */
-       R200_TXC_ARG_B_R1_COLOR |
-       R200_TXC_ARG_C_ZERO |
-       R200_TXC_OP_MADD),
-
-      /* GL_DECAL = 0x008c3582
-       */
-      (R200_TXC_ARG_A_R0_COLOR |
-       R200_TXC_ARG_B_R1_COLOR |
-       R200_TXC_ARG_C_R1_ALPHA |
-       R200_TXC_OP_LERP),
-
-      /* GL_BLEND = 0x008c3102
-       */
-      (R200_TXC_ARG_A_R0_COLOR |
-       R200_TXC_ARG_B_TFACTOR_COLOR |
-       R200_TXC_ARG_C_R1_COLOR |
-       R200_TXC_OP_LERP),
-
-      /* GL_ADD = 0x00813002
-       */
-      (R200_TXC_ARG_A_R0_COLOR |
-       R200_TXC_ARG_B_ZERO |
-       R200_TXC_ARG_C_R1_COLOR |
-       R200_TXC_COMP_ARG_B |
-       R200_TXC_OP_MADD),
-   },
-
-   /* Unit 2:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (R200_TXC_ARG_A_ZERO |
-       R200_TXC_ARG_B_ZERO |
-       R200_TXC_ARG_C_R0_COLOR |
-       R200_TXC_OP_MADD),
-
-      /* GL_REPLACE = 0x00803800
-       */
-      (R200_TXC_ARG_A_ZERO |
-       R200_TXC_ARG_B_ZERO |
-       R200_TXC_ARG_C_R2_COLOR |
-       R200_TXC_OP_MADD),
-
-      /* GL_MODULATE = 0x008001c2
-       */
-      (R200_TXC_ARG_A_R0_COLOR |
-       R200_TXC_ARG_B_R2_COLOR |
-       R200_TXC_ARG_C_ZERO |
-       R200_TXC_OP_MADD),
-
-      /* GL_DECAL = 0x008c3dc2
-       */
-      (R200_TXC_ARG_A_R0_COLOR |
-       R200_TXC_ARG_B_R2_COLOR |
-       R200_TXC_ARG_C_R2_ALPHA |
-       R200_TXC_OP_LERP),
-
-      /* GL_BLEND = 0x008c3902
-       */
-      (R200_TXC_ARG_A_R0_COLOR |
-       R200_TXC_ARG_B_TFACTOR_COLOR |
-       R200_TXC_ARG_C_R2_COLOR |
-       R200_TXC_OP_LERP),
-
-      /* GL_ADD = 0x00813802
-       */
-      (R200_TXC_ARG_A_R0_COLOR |
-       R200_TXC_ARG_B_ZERO |
-       R200_TXC_ARG_C_R2_COLOR |
-       R200_TXC_COMP_ARG_B |
-       R200_TXC_OP_MADD),
-   }
-};
-
-static GLuint r200_alpha_combine[][R200_MAX_COMBFUNC] =
-{
-   /* Unit 0:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (R200_TXA_ARG_A_ZERO |
-       R200_TXA_ARG_B_ZERO |
-       R200_TXA_ARG_C_DIFFUSE_ALPHA |
-       R200_TXA_OP_MADD),
-
-
-      /* GL_REPLACE = 0x00800500
-       */
-      (R200_TXA_ARG_A_ZERO |
-       R200_TXA_ARG_B_ZERO |
-       R200_TXA_ARG_C_R0_ALPHA |
-       R200_TXA_OP_MADD),
-
-      /* GL_MODULATE = 0x00800051
-       */
-      (R200_TXA_ARG_A_DIFFUSE_ALPHA |
-       R200_TXA_ARG_B_R0_ALPHA |
-       R200_TXA_ARG_C_ZERO |
-       R200_TXA_OP_MADD),
-
-      /* GL_DECAL = 0x00800100
-       */
-      (R200_TXA_ARG_A_ZERO |
-       R200_TXA_ARG_B_ZERO |
-       R200_TXA_ARG_C_DIFFUSE_ALPHA |
-       R200_TXA_OP_MADD),
-
-      /* GL_BLEND = 0x00800051
-       */
-      (R200_TXA_ARG_A_DIFFUSE_ALPHA |
-       R200_TXA_ARG_B_TFACTOR_ALPHA |
-       R200_TXA_ARG_C_R0_ALPHA |
-       R200_TXA_OP_LERP),
-
-      /* GL_ADD = 0x00800051
-       */
-      (R200_TXA_ARG_A_DIFFUSE_ALPHA |
-       R200_TXA_ARG_B_ZERO |
-       R200_TXA_ARG_C_R0_ALPHA |
-       R200_TXA_COMP_ARG_B |
-       R200_TXA_OP_MADD),
-   },
-
-   /* Unit 1:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (R200_TXA_ARG_A_ZERO |
-       R200_TXA_ARG_B_ZERO |
-       R200_TXA_ARG_C_R0_ALPHA |
-       R200_TXA_OP_MADD),
-
-      /* GL_REPLACE = 0x00800600
-       */
-      (R200_TXA_ARG_A_ZERO |
-       R200_TXA_ARG_B_ZERO |
-       R200_TXA_ARG_C_R1_ALPHA |
-       R200_TXA_OP_MADD),
-
-      /* GL_MODULATE = 0x00800061
-       */
-      (R200_TXA_ARG_A_R0_ALPHA |
-       R200_TXA_ARG_B_R1_ALPHA |
-       R200_TXA_ARG_C_ZERO |
-       R200_TXA_OP_MADD),
-
-      /* GL_DECAL = 0x00800100
-       */
-      (R200_TXA_ARG_A_ZERO |
-       R200_TXA_ARG_B_ZERO |
-       R200_TXA_ARG_C_R0_ALPHA |
-       R200_TXA_OP_MADD),
-
-      /* GL_BLEND = 0x00800061
-       */
-      (R200_TXA_ARG_A_R0_ALPHA |
-       R200_TXA_ARG_B_TFACTOR_ALPHA |
-       R200_TXA_ARG_C_R1_ALPHA |
-       R200_TXA_OP_LERP),
-
-      /* GL_ADD = 0x00800061
-       */
-      (R200_TXA_ARG_A_R0_ALPHA |
-       R200_TXA_ARG_B_ZERO |
-       R200_TXA_ARG_C_R1_ALPHA |
-       R200_TXA_COMP_ARG_B |
-       R200_TXA_OP_MADD),
-   },
-
-   /* Unit 2:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (R200_TXA_ARG_A_ZERO |
-       R200_TXA_ARG_B_ZERO |
-       R200_TXA_ARG_C_R0_ALPHA |
-       R200_TXA_OP_MADD),
-
-      /* GL_REPLACE = 0x00800700
-       */
-      (R200_TXA_ARG_A_ZERO |
-       R200_TXA_ARG_B_ZERO |
-       R200_TXA_ARG_C_R2_ALPHA |
-       R200_TXA_OP_MADD),
-
-      /* GL_MODULATE = 0x00800071
-       */
-      (R200_TXA_ARG_A_R0_ALPHA |
-       R200_TXA_ARG_B_R2_ALPHA |
-       R200_TXA_ARG_C_ZERO |
-       R200_TXA_OP_MADD),
-
-      /* GL_DECAL = 0x00800100
-       */
-      (R200_TXA_ARG_A_ZERO |
-       R200_TXA_ARG_B_ZERO |
-       R200_TXA_ARG_C_R0_ALPHA |
-       R200_TXA_OP_MADD),
-
-      /* GL_BLEND = 0x00800071
-       */
-      (R200_TXA_ARG_A_R0_ALPHA |
-       R200_TXA_ARG_B_TFACTOR_ALPHA |
-       R200_TXA_ARG_C_R2_ALPHA |
-       R200_TXA_OP_LERP),
-
-      /* GL_ADD = 0x00800021
-       */
-      (R200_TXA_ARG_A_R0_ALPHA |
-       R200_TXA_ARG_B_ZERO |
-       R200_TXA_ARG_C_R2_ALPHA |
-       R200_TXA_COMP_ARG_B |
-       R200_TXA_OP_MADD),
-   }
-};
-
-
 /* GL_ARB_texture_env_combine support
  */
 
@@ -731,443 +433,283 @@ static GLboolean r200UpdateTextureEnv( GLcontext *ctx, int unit )
        */
       rmesa->state.texture.unit[unit].format = 0;
       rmesa->state.texture.unit[unit].envMode = 0;
-      color_combine = r200_color_combine[unit][R200_DISABLE];
-      alpha_combine = r200_alpha_combine[unit][R200_DISABLE];
+      if ( unit == 0 ) {
+        color_combine = R200_TXC_ARG_A_ZERO | R200_TXC_ARG_B_ZERO
+            | R200_TXC_ARG_C_DIFFUSE_COLOR | R200_TXC_OP_MADD;
+        alpha_combine = R200_TXA_ARG_A_ZERO | R200_TXA_ARG_B_ZERO
+            | R200_TXA_ARG_C_DIFFUSE_ALPHA | R200_TXA_OP_MADD;
+      }
+      else {
+        color_combine = R200_TXC_ARG_A_ZERO | R200_TXC_ARG_B_ZERO
+            | R200_TXC_ARG_C_R0_COLOR | R200_TXC_OP_MADD;
+        alpha_combine = R200_TXA_ARG_A_ZERO | R200_TXA_ARG_B_ZERO
+            | R200_TXA_ARG_C_R0_ALPHA | R200_TXA_OP_MADD;
+      }
    }
    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->CombineScaleShiftRGB;
-      GLuint Ashift = texUnit->CombineScaleShiftA;
-
-      switch ( texUnit->EnvMode ) {
-      case GL_REPLACE:
-        switch ( format ) {
-        case GL_RGBA:
-        case GL_LUMINANCE_ALPHA:
-        case GL_INTENSITY:
-           color_combine = r200_color_combine[unit][R200_REPLACE];
-           alpha_combine = r200_alpha_combine[unit][R200_REPLACE];
-           break;
-        case GL_ALPHA:
-           color_combine = r200_color_combine[unit][R200_DISABLE];
-           alpha_combine = r200_alpha_combine[unit][R200_REPLACE];
-           break;
-        case GL_LUMINANCE:
-        case GL_RGB:
-        case GL_YCBCR_MESA:
-           color_combine = r200_color_combine[unit][R200_REPLACE];
-           alpha_combine = r200_alpha_combine[unit][R200_DISABLE];
-           break;
-        case GL_COLOR_INDEX:
-        default:
-           return GL_FALSE;
-        }
-        break;
+      GLuint i;
+      const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
+      const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
+      GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB;
+      GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA;
 
-      case GL_MODULATE:
-        switch ( format ) {
-        case GL_RGBA:
-        case GL_LUMINANCE_ALPHA:
-        case GL_INTENSITY:
-           color_combine = r200_color_combine[unit][R200_MODULATE];
-           alpha_combine = r200_alpha_combine[unit][R200_MODULATE];
-           break;
-        case GL_ALPHA:
-           color_combine = r200_color_combine[unit][R200_DISABLE];
-           alpha_combine = r200_alpha_combine[unit][R200_MODULATE];
-           break;
-        case GL_RGB:
-        case GL_LUMINANCE:
-        case GL_YCBCR_MESA:
-           color_combine = r200_color_combine[unit][R200_MODULATE];
-           alpha_combine = r200_alpha_combine[unit][R200_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_DECAL:
-        switch ( format ) {
-        case GL_RGBA:
-        case GL_RGB:
-        case GL_YCBCR_MESA:
-           color_combine = r200_color_combine[unit][R200_DECAL];
-           alpha_combine = r200_alpha_combine[unit][R200_DISABLE];
-           break;
-        case GL_ALPHA:
-        case GL_LUMINANCE:
-        case GL_LUMINANCE_ALPHA:
-        case GL_INTENSITY:
-           color_combine = r200_color_combine[unit][R200_DISABLE];
-           alpha_combine = r200_alpha_combine[unit][R200_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 = r200_color_combine[unit][R200_BLEND];
-           alpha_combine = r200_alpha_combine[unit][R200_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] = r200_register_color[op][unit];
            break;
-        case GL_ALPHA:
-           color_combine = r200_color_combine[unit][R200_DISABLE];
-           alpha_combine = r200_alpha_combine[unit][R200_MODULATE];
+        case GL_CONSTANT:
+           color_arg[i] = r200_tfactor_color[op];
            break;
-        case GL_INTENSITY:
-           color_combine = r200_color_combine[unit][R200_BLEND];
-           alpha_combine = r200_alpha_combine[unit][R200_BLEND];
+        case GL_PRIMARY_COLOR:
+           color_arg[i] = r200_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 = r200_color_combine[unit][R200_ADD];
-           alpha_combine = r200_alpha_combine[unit][R200_MODULATE];
+        case GL_PREVIOUS:
+           if (unit == 0)
+               color_arg[i] = r200_primary_color[op];
+           else
+               color_arg[i] = r200_register_color[op][0];
            break;
-        case GL_ALPHA:
-           color_combine = r200_color_combine[unit][R200_DISABLE];
-           alpha_combine = r200_alpha_combine[unit][R200_MODULATE];
+        case GL_ZERO:
+           color_arg[i] = r200_zero_color[op];
            break;
-        case GL_INTENSITY:
-           color_combine = r200_color_combine[unit][R200_ADD];
-           alpha_combine = r200_alpha_combine[unit][R200_ADD];
+        case GL_ONE:
+           color_arg[i] = r200_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->CombineModeRGB ) {
-        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] = r200_register_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] = r200_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] = r200_primary_alpha[op];
            break;
-        default:
-           return GL_FALSE;
-        }
-
-        switch ( texUnit->CombineModeA ) {
-        case GL_REPLACE:
-           numAlphaArgs = 1;
+        case GL_PREVIOUS:
+           if (unit == 0)
+               alpha_arg[i] = r200_primary_alpha[op];
+           else
+               alpha_arg[i] = r200_register_alpha[op][0];
            break;
-        case GL_MODULATE:
-        case GL_ADD:
-        case GL_ADD_SIGNED:
-        case GL_SUBTRACT:
-           numAlphaArgs = 2;
+        case GL_ZERO:
+           alpha_arg[i] = r200_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] = r200_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->CombineOperandRGB[i] - GL_SRC_COLOR;
-           assert(op >= 0);
-           assert(op <= 3);
-           switch ( texUnit->CombineSourceRGB[i] ) {
-           case GL_TEXTURE:
-              color_arg[i] = r200_register_color[op][unit];
-              break;
-           case GL_CONSTANT:
-              color_arg[i] = r200_tfactor_color[op];
-              break;
-           case GL_PRIMARY_COLOR:
-              color_arg[i] = r200_primary_color[op];
-              break;
-           case GL_PREVIOUS:
-              if (unit == 0)
-                 color_arg[i] = r200_primary_color[op];
-              else
-                 color_arg[i] = r200_register_color[op][0];
-              break;
-           case GL_ZERO:
-              color_arg[i] = r200_zero_color[op];
-              break;
-           case GL_ONE:
-              color_arg[i] = r200_zero_color[op+1];
-              break;
-           default:
-              return GL_FALSE;
-           }
-        }
-
-        for ( i = 0 ; i < numAlphaArgs ; i++ ) {
-           const GLuint op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA;
-           assert(op >= 0);
-           assert(op <= 1);
-           switch ( texUnit->CombineSourceA[i] ) {
-           case GL_TEXTURE:
-              alpha_arg[i] = r200_register_alpha[op][unit];
-              break;
-           case GL_CONSTANT:
-              alpha_arg[i] = r200_tfactor_alpha[op];
-              break;
-           case GL_PRIMARY_COLOR:
-              alpha_arg[i] = r200_primary_alpha[op];
-              break;
-           case GL_PREVIOUS:
-              if (unit == 0)
-                 alpha_arg[i] = r200_primary_alpha[op];
-              else
-                 alpha_arg[i] = r200_register_alpha[op][0];
-              break;
-           case GL_ZERO:
-              alpha_arg[i] = r200_zero_alpha[op];
-              break;
-           case GL_ONE:
-              alpha_arg[i] = r200_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 = (R200_TXC_ARG_A_ZERO |
+                         R200_TXC_ARG_B_ZERO |
+                         R200_TXC_OP_MADD);
+        R200_COLOR_ARG( 0, C );
+        break;
+      case GL_MODULATE:
+        color_combine = (R200_TXC_ARG_C_ZERO |
+                         R200_TXC_OP_MADD);
+        R200_COLOR_ARG( 0, A );
+        R200_COLOR_ARG( 1, B );
+        break;
+      case GL_ADD:
+        color_combine = (R200_TXC_ARG_B_ZERO |
+                         R200_TXC_COMP_ARG_B | 
+                         R200_TXC_OP_MADD);
+        R200_COLOR_ARG( 0, A );
+        R200_COLOR_ARG( 1, C );
+        break;
+      case GL_ADD_SIGNED:
+        color_combine = (R200_TXC_ARG_B_ZERO |
+                         R200_TXC_COMP_ARG_B |
+                         R200_TXC_BIAS_ARG_C | /* new */
+                         R200_TXC_OP_MADD); /* was ADDSIGNED */
+        R200_COLOR_ARG( 0, A );
+        R200_COLOR_ARG( 1, C );
+        break;
+      case GL_SUBTRACT:
+        color_combine = (R200_TXC_ARG_B_ZERO |
+                         R200_TXC_COMP_ARG_B | 
+                         R200_TXC_NEG_ARG_C |
+                         R200_TXC_OP_MADD);
+        R200_COLOR_ARG( 0, A );
+        R200_COLOR_ARG( 1, C );
+        break;
+      case GL_INTERPOLATE:
+        color_combine = (R200_TXC_OP_LERP);
+        R200_COLOR_ARG( 0, B );
+        R200_COLOR_ARG( 1, A );
+        R200_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.
+         */
+        RGBshift = 0;
+        Ashift = 0;
+        /* FALLTHROUGH */
+
+      case GL_DOT3_RGB:
+      case GL_DOT3_RGBA:
+        /* DOT3 works differently on R200 than on R100.  On R100, just
+         * setting the DOT3 mode did everything for you.  On R200, the
+         * driver has to enable the biasing and scale in the inputs to
+         * put them in the proper [-1,1] range.  This is what the 4x and
+         * the -0.5 in the DOT3 spec do.  The post-scale is then set
+         * normally.
          */
-        switch ( texUnit->CombineModeRGB ) {
-        case GL_REPLACE:
-           color_combine = (R200_TXC_ARG_A_ZERO |
-                            R200_TXC_ARG_B_ZERO |
-                            R200_TXC_OP_MADD);
-           R200_COLOR_ARG( 0, C );
-           break;
-        case GL_MODULATE:
-           color_combine = (R200_TXC_ARG_C_ZERO |
-                            R200_TXC_OP_MADD);
-           R200_COLOR_ARG( 0, A );
-           R200_COLOR_ARG( 1, B );
-           break;
-        case GL_ADD:
-           color_combine = (R200_TXC_ARG_B_ZERO |
-                            R200_TXC_COMP_ARG_B | 
-                            R200_TXC_OP_MADD);
-           R200_COLOR_ARG( 0, A );
-           R200_COLOR_ARG( 1, C );
-           break;
-        case GL_ADD_SIGNED:
-           color_combine = (R200_TXC_ARG_B_ZERO |
-                            R200_TXC_COMP_ARG_B |
-                            R200_TXC_BIAS_ARG_C |      /* new */
-                            R200_TXC_OP_MADD); /* was ADDSIGNED */
-           R200_COLOR_ARG( 0, A );
-           R200_COLOR_ARG( 1, C );
-           break;
-        case GL_SUBTRACT:
-           color_combine = (R200_TXC_ARG_B_ZERO |
-                            R200_TXC_COMP_ARG_B | 
-                            R200_TXC_NEG_ARG_C |
-                            R200_TXC_OP_MADD);
-           R200_COLOR_ARG( 0, A );
-           R200_COLOR_ARG( 1, C );
-           break;
-        case GL_INTERPOLATE:
-           color_combine = (R200_TXC_OP_LERP);
-           R200_COLOR_ARG( 0, B );
-           R200_COLOR_ARG( 1, A );
-           R200_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:
-           /* DOT3 works differently on R200 than on R100.  On R100, just
-            * setting the DOT3 mode did everything for you.  On R200, the
-            * driver has to enable the biasing and scale in the inputs to
-            * put them in the proper [-1,1] range.  This is what the 4x and
-            * the -0.5 in the DOT3 spec do.  The post-scale is then set
-            * normally.
-            */
-
-           RGBshift++;
-           Ashift = RGBshift;
-
-           color_combine = (R200_TXC_ARG_C_ZERO |
-                            R200_TXC_OP_DOT3 |
-                            R200_TXC_BIAS_ARG_A |
-                            R200_TXC_BIAS_ARG_B |
-                            R200_TXC_SCALE_ARG_A |
-                            R200_TXC_SCALE_ARG_B);
-           R200_COLOR_ARG( 0, A );
-           R200_COLOR_ARG( 1, B );
-           break;
-
-        case GL_MODULATE_ADD_ATI:
-           color_combine = (R200_TXC_OP_MADD);
-           R200_COLOR_ARG( 0, A );
-           R200_COLOR_ARG( 1, C );
-           R200_COLOR_ARG( 2, B );
-           break;
-        case GL_MODULATE_SIGNED_ADD_ATI:
-           color_combine = (R200_TXC_BIAS_ARG_C |      /* new */
-                            R200_TXC_OP_MADD); /* was ADDSIGNED */
-           R200_COLOR_ARG( 0, A );
-           R200_COLOR_ARG( 1, C );
-           R200_COLOR_ARG( 2, B );
-           break;
-        case GL_MODULATE_SUBTRACT_ATI:
-           color_combine = (R200_TXC_NEG_ARG_C |
-                            R200_TXC_OP_MADD);
-           R200_COLOR_ARG( 0, A );
-           R200_COLOR_ARG( 1, C );
-           R200_COLOR_ARG( 2, B );
-           break;
-        default:
-           return GL_FALSE;
-        }
-
-        switch ( texUnit->CombineModeA ) {
-        case GL_REPLACE:
-           alpha_combine = (R200_TXA_ARG_A_ZERO |
-                            R200_TXA_ARG_B_ZERO |
-                            R200_TXA_OP_MADD);
-           R200_ALPHA_ARG( 0, C );
-           break;
-        case GL_MODULATE:
-           alpha_combine = (R200_TXA_ARG_C_ZERO |
-                            R200_TXA_OP_MADD);
-           R200_ALPHA_ARG( 0, A );
-           R200_ALPHA_ARG( 1, B );
-           break;
-        case GL_ADD:
-           alpha_combine = (R200_TXA_ARG_B_ZERO |
-                            R200_TXA_COMP_ARG_B |
-                            R200_TXA_OP_MADD);
-           R200_ALPHA_ARG( 0, A );
-           R200_ALPHA_ARG( 1, C );
-           break;
-        case GL_ADD_SIGNED:
-           alpha_combine = (R200_TXA_ARG_B_ZERO |
-                            R200_TXA_COMP_ARG_B |
-                            R200_TXA_BIAS_ARG_C |      /* new */
-                            R200_TXA_OP_MADD); /* was ADDSIGNED */
-           R200_ALPHA_ARG( 0, A );
-           R200_ALPHA_ARG( 1, C );
-           break;
-        case GL_SUBTRACT:
-           alpha_combine = (R200_TXA_ARG_B_ZERO |
-                            R200_TXA_COMP_ARG_B |
-                            R200_TXA_NEG_ARG_C |
-                            R200_TXA_OP_MADD);
-           R200_ALPHA_ARG( 0, A );
-           R200_ALPHA_ARG( 1, C );
-           break;
-        case GL_INTERPOLATE:
-           alpha_combine = (R200_TXA_OP_LERP);
-           R200_ALPHA_ARG( 0, B );
-           R200_ALPHA_ARG( 1, A );
-           R200_ALPHA_ARG( 2, C );
-           break;
-
-        case GL_MODULATE_ADD_ATI:
-           alpha_combine = (R200_TXA_OP_MADD);
-           R200_ALPHA_ARG( 0, A );
-           R200_ALPHA_ARG( 1, C );
-           R200_ALPHA_ARG( 2, B );
-           break;
-        case GL_MODULATE_SIGNED_ADD_ATI:
-           alpha_combine = (R200_TXA_BIAS_ARG_C |      /* new */
-                            R200_TXA_OP_MADD); /* was ADDSIGNED */
-           R200_ALPHA_ARG( 0, A );
-           R200_ALPHA_ARG( 1, C );
-           R200_ALPHA_ARG( 2, B );
-           break;
-        case GL_MODULATE_SUBTRACT_ATI:
-           alpha_combine = (R200_TXA_NEG_ARG_C |
-                            R200_TXA_OP_MADD);
-           R200_ALPHA_ARG( 0, A );
-           R200_ALPHA_ARG( 1, C );
-           R200_ALPHA_ARG( 2, B );
-           break;
-        default:
-           return GL_FALSE;
-        }
 
-        if ( (texUnit->CombineModeRGB == GL_DOT3_RGB_EXT)
-             || (texUnit->CombineModeRGB == GL_DOT3_RGB) ) {
-           alpha_scale |= R200_TXA_DOT_ALPHA;
-        }
+        RGBshift++;
+        Ashift = RGBshift;
+
+        color_combine = (R200_TXC_ARG_C_ZERO |
+                         R200_TXC_OP_DOT3 |
+                         R200_TXC_BIAS_ARG_A |
+                         R200_TXC_BIAS_ARG_B |
+                         R200_TXC_SCALE_ARG_A |
+                         R200_TXC_SCALE_ARG_B);
+        R200_COLOR_ARG( 0, A );
+        R200_COLOR_ARG( 1, B );
+        break;
 
-        /* Step 3:
-         * Apply the scale factor.
-         */
-        color_scale &= ~R200_TXC_SCALE_MASK;
-        alpha_scale &= ~R200_TXA_SCALE_MASK;
-        color_scale |= (RGBshift << R200_TXC_SCALE_SHIFT);
-        alpha_scale |= (Ashift   << R200_TXA_SCALE_SHIFT);
+      case GL_MODULATE_ADD_ATI:
+        color_combine = (R200_TXC_OP_MADD);
+        R200_COLOR_ARG( 0, A );
+        R200_COLOR_ARG( 1, C );
+        R200_COLOR_ARG( 2, B );
+        break;
+      case GL_MODULATE_SIGNED_ADD_ATI:
+        color_combine = (R200_TXC_BIAS_ARG_C | /* new */
+                         R200_TXC_OP_MADD); /* was ADDSIGNED */
+        R200_COLOR_ARG( 0, A );
+        R200_COLOR_ARG( 1, C );
+        R200_COLOR_ARG( 2, B );
+        break;
+      case GL_MODULATE_SUBTRACT_ATI:
+        color_combine = (R200_TXC_NEG_ARG_C |
+                         R200_TXC_OP_MADD);
+        R200_COLOR_ARG( 0, A );
+        R200_COLOR_ARG( 1, C );
+        R200_COLOR_ARG( 2, B );
+        break;
+      default:
+        return GL_FALSE;
+      }
 
-        /* All done!
-         */
+      switch ( texUnit->_CurrentCombine->ModeA ) {
+      case GL_REPLACE:
+        alpha_combine = (R200_TXA_ARG_A_ZERO |
+                         R200_TXA_ARG_B_ZERO |
+                         R200_TXA_OP_MADD);
+        R200_ALPHA_ARG( 0, C );
+        break;
+      case GL_MODULATE:
+        alpha_combine = (R200_TXA_ARG_C_ZERO |
+                         R200_TXA_OP_MADD);
+        R200_ALPHA_ARG( 0, A );
+        R200_ALPHA_ARG( 1, B );
+        break;
+      case GL_ADD:
+        alpha_combine = (R200_TXA_ARG_B_ZERO |
+                         R200_TXA_COMP_ARG_B |
+                         R200_TXA_OP_MADD);
+        R200_ALPHA_ARG( 0, A );
+        R200_ALPHA_ARG( 1, C );
+        break;
+      case GL_ADD_SIGNED:
+        alpha_combine = (R200_TXA_ARG_B_ZERO |
+                         R200_TXA_COMP_ARG_B |
+                         R200_TXA_BIAS_ARG_C | /* new */
+                         R200_TXA_OP_MADD); /* was ADDSIGNED */
+        R200_ALPHA_ARG( 0, A );
+        R200_ALPHA_ARG( 1, C );
+        break;
+      case GL_SUBTRACT:
+        alpha_combine = (R200_TXA_ARG_B_ZERO |
+                         R200_TXA_COMP_ARG_B |
+                         R200_TXA_NEG_ARG_C |
+                         R200_TXA_OP_MADD);
+        R200_ALPHA_ARG( 0, A );
+        R200_ALPHA_ARG( 1, C );
+        break;
+      case GL_INTERPOLATE:
+        alpha_combine = (R200_TXA_OP_LERP);
+        R200_ALPHA_ARG( 0, B );
+        R200_ALPHA_ARG( 1, A );
+        R200_ALPHA_ARG( 2, C );
         break;
 
+      case GL_MODULATE_ADD_ATI:
+        alpha_combine = (R200_TXA_OP_MADD);
+        R200_ALPHA_ARG( 0, A );
+        R200_ALPHA_ARG( 1, C );
+        R200_ALPHA_ARG( 2, B );
+        break;
+      case GL_MODULATE_SIGNED_ADD_ATI:
+        alpha_combine = (R200_TXA_BIAS_ARG_C | /* new */
+                         R200_TXA_OP_MADD); /* was ADDSIGNED */
+        R200_ALPHA_ARG( 0, A );
+        R200_ALPHA_ARG( 1, C );
+        R200_ALPHA_ARG( 2, B );
+        break;
+      case GL_MODULATE_SUBTRACT_ATI:
+        alpha_combine = (R200_TXA_NEG_ARG_C |
+                         R200_TXA_OP_MADD);
+        R200_ALPHA_ARG( 0, A );
+        R200_ALPHA_ARG( 1, C );
+        R200_ALPHA_ARG( 2, B );
+        break;
       default:
         return GL_FALSE;
       }
+
+      if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB_EXT)
+          || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB) ) {
+        alpha_scale |= R200_TXA_DOT_ALPHA;
+      }
+
+      /* Step 3:
+       * Apply the scale factor.
+       */
+      color_scale &= ~R200_TXC_SCALE_MASK;
+      alpha_scale &= ~R200_TXA_SCALE_MASK;
+      color_scale |= (RGBshift << R200_TXC_SCALE_SHIFT);
+      alpha_scale |= (Ashift   << R200_TXA_SCALE_SHIFT);
+
+      /* All done!
+       */
    }
 
    if ( rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND] != color_combine ||
index f4991a7..563a7e9 100644 (file)
@@ -782,8 +782,8 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
       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->CombineScaleShiftRGB;
-      GLuint Ashift = texUnit->CombineScaleShiftA;
+      GLuint RGBshift = texUnit->Combine.ScaleShiftRGB;
+      GLuint Ashift = texUnit->Combine.ScaleShiftA;
 
       switch ( texUnit->EnvMode ) {
       case GL_REPLACE:
@@ -912,7 +912,7 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
         /* Step 0:
          * Calculate how many arguments we need to process.
          */
-        switch ( texUnit->CombineModeRGB ) {
+        switch ( texUnit->Combine.ModeRGB ) {
         case GL_REPLACE:
            numColorArgs = 1;
            break;
@@ -936,7 +936,7 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
            return GL_FALSE;
         }
 
-        switch ( texUnit->CombineModeA ) {
+        switch ( texUnit->Combine.ModeA ) {
         case GL_REPLACE:
            numAlphaArgs = 1;
            break;
@@ -960,10 +960,10 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
          * Extract the color and alpha combine function arguments.
          */
         for ( i = 0 ; i < numColorArgs ; i++ ) {
-           const GLuint op = texUnit->CombineOperandRGB[i] - GL_SRC_COLOR;
+           const GLuint op = texUnit->Combine.OperandRGB[i] - GL_SRC_COLOR;
            assert(op >= 0);
            assert(op <= 3);
-           switch ( texUnit->CombineSourceRGB[i] ) {
+           switch ( texUnit->Combine.SourceRGB[i] ) {
            case GL_TEXTURE:
               color_arg[i] = radeon_texture_color[op][unit];
               break;
@@ -988,10 +988,10 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
         }
 
         for ( i = 0 ; i < numAlphaArgs ; i++ ) {
-           const GLuint op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA;
+           const GLuint op = texUnit->Combine.OperandA[i] - GL_SRC_ALPHA;
            assert(op >= 0);
            assert(op <= 1);
-           switch ( texUnit->CombineSourceA[i] ) {
+           switch ( texUnit->Combine.SourceA[i] ) {
            case GL_TEXTURE:
               alpha_arg[i] = radeon_texture_alpha[op][unit];
               break;
@@ -1018,7 +1018,7 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
         /* Step 2:
          * Build up the color and alpha combine functions.
          */
-        switch ( texUnit->CombineModeRGB ) {
+        switch ( texUnit->Combine.ModeRGB ) {
         case GL_REPLACE:
            color_combine = (RADEON_COLOR_ARG_A_ZERO |
                             RADEON_COLOR_ARG_B_ZERO |
@@ -1119,7 +1119,7 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
            return GL_FALSE;
         }
 
-        switch ( texUnit->CombineModeA ) {
+        switch ( texUnit->Combine.ModeA ) {
         case GL_REPLACE:
            alpha_combine = (RADEON_ALPHA_ARG_A_ZERO |
                             RADEON_ALPHA_ARG_B_ZERO |
@@ -1191,8 +1191,8 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
            return GL_FALSE;
         }
 
-        if ( (texUnit->CombineModeRGB == GL_DOT3_RGB_EXT)
-             || (texUnit->CombineModeRGB == GL_DOT3_RGB) ) {
+        if ( (texUnit->Combine.ModeRGB == GL_DOT3_RGB_EXT)
+             || (texUnit->Combine.ModeRGB == GL_DOT3_RGB) ) {
            alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
         }
 
index 318d3a1..c9caea3 100644 (file)
@@ -424,9 +424,9 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA,
             *
             * Calculate the color combination.
             */
-            Shift_RGB = texUnit->CombineScaleShiftRGB;
-            Shift_A = texUnit->CombineScaleShiftA;
-            switch (texUnit->CombineModeRGB) {
+            Shift_RGB = texUnit->Combine.ScaleShiftRGB;
+            Shift_A = texUnit->Combine.ScaleShiftA;
+            switch (texUnit->Combine.ModeRGB) {
             case GL_REPLACE:
                /*
                 * The formula is: Arg0
@@ -434,11 +434,11 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA,
                 *   (Arg0 + 0(0))*(1-0) + 0
                 */
                 TEXENV_SETUP_ARG_RGB(A_RGB,
-                                     texUnit->CombineSourceRGB[0],
-                                     texUnit->CombineOperandRGB[0],
+                                     texUnit->Combine.SourceRGB[0],
+                                     texUnit->Combine.OperandRGB[0],
                                      incomingRGB, incomingAlpha);
                 TEXENV_SETUP_MODE_RGB(Amode_RGB,
-                                      texUnit->CombineOperandRGB[0]);
+                                      texUnit->Combine.OperandRGB[0]);
                 B_RGB = C_RGB = D_RGB = GR_CMBX_ZERO;
                 Bmode_RGB = GR_FUNC_MODE_ZERO;
                 Cinv_RGB = FXTRUE;
@@ -452,19 +452,19 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA,
                 *   (Arg0 + 0(0)) * Arg1 + 0(0)
                 */
                 TEXENV_SETUP_ARG_RGB(A_RGB,
-                                     texUnit->CombineSourceRGB[0],
-                                     texUnit->CombineOperandRGB[0],
+                                     texUnit->Combine.SourceRGB[0],
+                                     texUnit->Combine.OperandRGB[0],
                                      incomingRGB, incomingAlpha);
                 TEXENV_SETUP_MODE_RGB(Amode_RGB,
-                                      texUnit->CombineOperandRGB[0]);
+                                      texUnit->Combine.OperandRGB[0]);
                 B_RGB = GR_CMBX_ZERO;
                 Bmode_RGB = GR_CMBX_ZERO;
                 TEXENV_SETUP_ARG_RGB(C_RGB,
-                                     texUnit->CombineSourceRGB[1],
-                                     texUnit->CombineOperandRGB[1],
+                                     texUnit->Combine.SourceRGB[1],
+                                     texUnit->Combine.OperandRGB[1],
                                      incomingRGB, incomingAlpha);
                 Cinv_RGB = TEXENV_OPERAND_INVERTED
-                               (texUnit->CombineOperandRGB[1]);
+                               (texUnit->Combine.OperandRGB[1]);
                 D_RGB = GR_CMBX_ZERO;
                 Dinv_RGB = Ginv_RGB = FXFALSE;
                 break;
@@ -473,17 +473,17 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA,
                 * The formula is Arg0 + Arg1
                 */
                 TEXENV_SETUP_ARG_RGB(A_RGB,
-                                     texUnit->CombineSourceRGB[0],
-                                     texUnit->CombineOperandRGB[0],
+                                     texUnit->Combine.SourceRGB[0],
+                                     texUnit->Combine.OperandRGB[0],
                                      incomingRGB, incomingAlpha);
                 TEXENV_SETUP_MODE_RGB(Amode_RGB,
-                                      texUnit->CombineOperandRGB[0]);
+                                      texUnit->Combine.OperandRGB[0]);
                 TEXENV_SETUP_ARG_RGB(B_RGB,
-                                     texUnit->CombineSourceRGB[1],
-                                     texUnit->CombineOperandRGB[1],
+                                     texUnit->Combine.SourceRGB[1],
+                                     texUnit->Combine.OperandRGB[1],
                                      incomingRGB, incomingAlpha);
                 TEXENV_SETUP_MODE_RGB(Bmode_RGB,
-                                      texUnit->CombineOperandRGB[1]);
+                                      texUnit->Combine.OperandRGB[1]);
                 C_RGB = D_RGB = GR_CMBX_ZERO;
                 Cinv_RGB = FXTRUE;
                 Dinv_RGB = Ginv_RGB = FXFALSE;
@@ -498,20 +498,20 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA,
                 * we cannot implement the formula properly.
                 */
                 TEXENV_SETUP_ARG_RGB(A_RGB,
-                                     texUnit->CombineSourceRGB[0],
-                                     texUnit->CombineOperandRGB[0],
+                                     texUnit->Combine.SourceRGB[0],
+                                     texUnit->Combine.OperandRGB[0],
                                      incomingRGB, incomingAlpha);
                 TEXENV_SETUP_ARG_RGB(B_RGB,
-                                     texUnit->CombineSourceRGB[1],
-                                     texUnit->CombineOperandRGB[1],
+                                     texUnit->Combine.SourceRGB[1],
+                                     texUnit->Combine.OperandRGB[1],
                                      incomingRGB, incomingAlpha);
-                if (!TEXENV_OPERAND_INVERTED(texUnit->CombineOperandRGB[0])) {
+                if (!TEXENV_OPERAND_INVERTED(texUnit->Combine.OperandRGB[0])) {
                    /*
                     * A is not inverted.  So, choose it.
                     */
                     Amode_RGB = GR_FUNC_MODE_X_MINUS_HALF;
                     if (!TEXENV_OPERAND_INVERTED
-                            (texUnit->CombineOperandRGB[1])) {
+                            (texUnit->Combine.OperandRGB[1])) {
                         Bmode_RGB = GR_FUNC_MODE_X;
                     }
                     else {
@@ -525,7 +525,7 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA,
                     */
                     Amode_RGB = GR_FUNC_MODE_ONE_MINUS_X;
                     if (!TEXENV_OPERAND_INVERTED
-                            (texUnit->CombineOperandRGB[1])) {
+                            (texUnit->Combine.OperandRGB[1])) {
                         Bmode_RGB = GR_FUNC_MODE_X_MINUS_HALF;
                     }
                     else {
@@ -553,16 +553,16 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA,
                 * not support it properly.
                 */
                 TEXENV_SETUP_ARG_RGB(A_RGB,
-                                     texUnit->CombineSourceRGB[0],
-                                     texUnit->CombineOperandRGB[0],
+                                     texUnit->Combine.SourceRGB[0],
+                                     texUnit->Combine.OperandRGB[0],
                                      incomingRGB, incomingAlpha);
                 TEXENV_SETUP_MODE_RGB(Amode_RGB,
-                                      texUnit->CombineOperandRGB[0]);
+                                      texUnit->Combine.OperandRGB[0]);
                 TEXENV_SETUP_ARG_RGB(B_RGB,
-                                     texUnit->CombineSourceRGB[1],
-                                     texUnit->CombineOperandRGB[1],
+                                     texUnit->Combine.SourceRGB[1],
+                                     texUnit->Combine.OperandRGB[1],
                                      incomingRGB, incomingAlpha);
-                if (TEXENV_OPERAND_INVERTED(texUnit->CombineOperandRGB[1])) {
+                if (TEXENV_OPERAND_INVERTED(texUnit->Combine.OperandRGB[1])) {
                    /*
                     * This case is wrong.
                     */
@@ -577,8 +577,8 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA,
                 * specify some kind of alpha value.
                 */
                 TEXENV_SETUP_ARG_A(C_RGB,
-                                   texUnit->CombineSourceRGB[2],
-                                   texUnit->CombineOperandRGB[2],
+                                   texUnit->Combine.SourceRGB[2],
+                                   texUnit->Combine.OperandRGB[2],
                                    incomingAlpha);
                 Cinv_RGB = FXFALSE;
                 D_RGB = GR_CMBX_B;
@@ -599,7 +599,7 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA,
            /*
             * Calculate the alpha combination.
             */
-            switch (texUnit->CombineModeA) {
+            switch (texUnit->Combine.ModeA) {
             case GL_REPLACE:
                /*
                 * The formula is: Arg0
@@ -607,11 +607,11 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA,
                 *   (Arg0 + 0(0))*(1-0) + 0
                 */
                 TEXENV_SETUP_ARG_A(A_A,
-                                   texUnit->CombineSourceA[0],
-                                   texUnit->CombineOperandA[0],
+                                   texUnit->Combine.SourceA[0],
+                                   texUnit->Combine.OperandA[0],
                                    incomingAlpha);
                 TEXENV_SETUP_MODE_A(Amode_A,
-                                    texUnit->CombineOperandA[0]);
+                                    texUnit->Combine.OperandA[0]);
                 B_A = GR_CMBX_ITALPHA;
                 Bmode_A = GR_FUNC_MODE_ZERO;
                 C_A = D_A = GR_CMBX_ZERO;
@@ -626,19 +626,19 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA,
                 *   (Arg0 + 0(0)) * Arg1 + 0(0)
                 */
                 TEXENV_SETUP_ARG_A(A_A,
-                                   texUnit->CombineSourceA[0],
-                                   texUnit->CombineOperandA[0],
+                                   texUnit->Combine.SourceA[0],
+                                   texUnit->Combine.OperandA[0],
                                    incomingAlpha);
                 TEXENV_SETUP_MODE_A(Amode_A,
-                                    texUnit->CombineOperandA[0]);
+                                    texUnit->Combine.OperandA[0]);
                 B_A = GR_CMBX_ZERO;
                 Bmode_A = GR_CMBX_ZERO;
                 TEXENV_SETUP_ARG_A(C_A,
-                                   texUnit->CombineSourceA[1],
-                                   texUnit->CombineOperandA[1],
+                                   texUnit->Combine.SourceA[1],
+                                   texUnit->Combine.OperandA[1],
                                    incomingAlpha);
                 Cinv_A = TEXENV_OPERAND_INVERTED
-                               (texUnit->CombineOperandA[1]);
+                               (texUnit->Combine.OperandA[1]);
                 D_A = GR_CMBX_ZERO;
                 Dinv_A = Ginv_A = FXFALSE;
                 break;
@@ -647,17 +647,17 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA,
                 * The formula is Arg0 + Arg1
                 */
                 TEXENV_SETUP_ARG_A(A_A,
-                                   texUnit->CombineSourceA[0],
-                                   texUnit->CombineOperandA[0],
+                                   texUnit->Combine.SourceA[0],
+                                   texUnit->Combine.OperandA[0],
                                    incomingAlpha);
                 TEXENV_SETUP_MODE_A(Amode_A,
-                                    texUnit->CombineOperandA[0]);
+                                    texUnit->Combine.OperandA[0]);
                 TEXENV_SETUP_ARG_A(B_A,
-                                   texUnit->CombineSourceA[1],
-                                   texUnit->CombineOperandA[1],
+                                   texUnit->Combine.SourceA[1],
+                                   texUnit->Combine.OperandA[1],
                                    incomingAlpha);
                 TEXENV_SETUP_MODE_A(Bmode_A,
-                                    texUnit->CombineOperandA[1]);
+                                    texUnit->Combine.OperandA[1]);
                 C_A = D_A = GR_CMBX_ZERO;
                 Cinv_A = FXTRUE;
                 Dinv_A = Ginv_A = FXFALSE;
@@ -672,20 +672,20 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA,
                 * we cannot implement the formula properly.
                 */
                 TEXENV_SETUP_ARG_A(A_A,
-                                   texUnit->CombineSourceA[0],
-                                   texUnit->CombineOperandA[0],
+                                   texUnit->Combine.SourceA[0],
+                                   texUnit->Combine.OperandA[0],
                                    incomingAlpha);
                 TEXENV_SETUP_ARG_A(B_A,
-                                   texUnit->CombineSourceA[1],
-                                   texUnit->CombineOperandA[1],
+                                   texUnit->Combine.SourceA[1],
+                                   texUnit->Combine.OperandA[1],
                                    incomingAlpha);
-                if (!TEXENV_OPERAND_INVERTED(texUnit->CombineOperandA[0])) {
+                if (!TEXENV_OPERAND_INVERTED(texUnit->Combine.OperandA[0])) {
                    /*
                     * A is not inverted.  So, choose it.
                     */
                     Amode_A = GR_FUNC_MODE_X_MINUS_HALF;
                     if (!TEXENV_OPERAND_INVERTED
-                            (texUnit->CombineOperandA[1])) {
+                            (texUnit->Combine.OperandA[1])) {
                         Bmode_A = GR_FUNC_MODE_X;
                     } else {
                         Bmode_A = GR_FUNC_MODE_ONE_MINUS_X;
@@ -697,7 +697,7 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA,
                     */
                     Amode_A = GR_FUNC_MODE_ONE_MINUS_X;
                     if (!TEXENV_OPERAND_INVERTED
-                            (texUnit->CombineOperandA[1])) {
+                            (texUnit->Combine.OperandA[1])) {
                         Bmode_A = GR_FUNC_MODE_X_MINUS_HALF;
                     } else {
                        /*
@@ -724,16 +724,16 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA,
                 * not support it properly.
                 */
                 TEXENV_SETUP_ARG_A(A_A,
-                                   texUnit->CombineSourceA[0],
-                                   texUnit->CombineOperandA[0],
+                                   texUnit->Combine.SourceA[0],
+                                   texUnit->Combine.OperandA[0],
                                    incomingAlpha);
                 TEXENV_SETUP_MODE_A(Amode_A,
-                                    texUnit->CombineOperandA[0]);
+                                    texUnit->Combine.OperandA[0]);
                 TEXENV_SETUP_ARG_A(B_A,
-                                   texUnit->CombineSourceA[1],
-                                   texUnit->CombineOperandA[1],
+                                   texUnit->Combine.SourceA[1],
+                                   texUnit->Combine.OperandA[1],
                                    incomingAlpha);
-                if (!TEXENV_OPERAND_INVERTED(texUnit->CombineOperandA[1])) {
+                if (!TEXENV_OPERAND_INVERTED(texUnit->Combine.OperandA[1])) {
                     Bmode_A = GR_FUNC_MODE_NEGATIVE_X;
                 }
                 else {
@@ -748,8 +748,8 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA,
                 * specify some kind of alpha value.
                 */
                 TEXENV_SETUP_ARG_A(C_A,
-                                   texUnit->CombineSourceA[2],
-                                   texUnit->CombineOperandA[2],
+                                   texUnit->Combine.SourceA[2],
+                                   texUnit->Combine.OperandA[2],
                                    incomingAlpha);
                 Cinv_A = FXFALSE;
                 D_A = GR_CMBX_B;
index 8beb0a5..c5339fd 100644 (file)
@@ -652,38 +652,38 @@ pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib)
       }
       if (ctx->Extensions.EXT_texture_env_combine ||
           ctx->Extensions.ARB_texture_env_combine) {
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT,
-                       unit->CombineModeRGB);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT,
-                       unit->CombineModeA);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT,
-                       unit->CombineSourceRGB[0]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT,
-                       unit->CombineSourceRGB[1]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT,
-                       unit->CombineSourceRGB[2]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT,
-                       unit->CombineSourceA[0]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT,
-                       unit->CombineSourceA[1]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT,
-                       unit->CombineSourceA[2]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT,
-                       unit->CombineOperandRGB[0]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT,
-                       unit->CombineOperandRGB[1]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT,
-                       unit->CombineOperandRGB[2]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT,
-                       unit->CombineOperandA[0]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT,
-                       unit->CombineOperandA[1]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT,
-                       unit->CombineOperandA[2]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT,
-                       1 << unit->CombineScaleShiftRGB);
+         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,
+                       unit->Combine.ModeRGB);
+         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,
+                       unit->Combine.ModeA);
+         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB,
+                       unit->Combine.SourceRGB[0]);
+         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB,
+                       unit->Combine.SourceRGB[1]);
+         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB,
+                       unit->Combine.SourceRGB[2]);
+         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA,
+                       unit->Combine.SourceA[0]);
+         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA,
+                       unit->Combine.SourceA[1]);
+         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA,
+                       unit->Combine.SourceA[2]);
+         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB,
+                       unit->Combine.OperandRGB[0]);
+         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,
+                       unit->Combine.OperandRGB[1]);
+         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,
+                       unit->Combine.OperandRGB[2]);
+         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,
+                       unit->Combine.OperandA[0]);
+         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA,
+                       unit->Combine.OperandA[1]);
+         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA,
+                       unit->Combine.OperandA[2]);
+         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE,
+                       1 << unit->Combine.ScaleShiftRGB);
          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE,
-                       1 << unit->CombineScaleShiftA);
+                       1 << unit->Combine.ScaleShiftA);
       }
 
       /* Restore texture object state */
index 6665e13..5ed7942 100644 (file)
@@ -1164,6 +1164,25 @@ struct gl_texture_object {
    /*@}*/
 };
 
+/**
+ * Texture combine environment state.
+ * 
+ * \todo
+ * If GL_NV_texture_env_combine4 is ever supported, the arrays in this
+ * structure will need to be expanded for 4 elements.
+ */
+struct gl_tex_env_combine_state {
+   GLenum ModeRGB;       /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */
+   GLenum ModeA;         /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */
+   GLenum SourceRGB[3];  /**< GL_PRIMARY_COLOR, GL_TEXTURE, etc. */
+   GLenum SourceA[3];    /**< GL_PRIMARY_COLOR, GL_TEXTURE, etc. */
+   GLenum OperandRGB[3]; /**< SRC_COLOR, ONE_MINUS_SRC_COLOR, etc */
+   GLenum OperandA[3];   /**< SRC_ALPHA, ONE_MINUS_SRC_ALPHA, etc */
+   GLuint ScaleShiftRGB; /**< 0, 1 or 2 */
+   GLuint ScaleShiftA;   /**< 0, 1 or 2 */
+   GLuint _NumArgsRGB;   /**< Number of inputs used for the combine mode. */
+   GLuint _NumArgsA;     /**< Number of inputs used for the combine mode. */
+};
 
 /**
  * Texture unit record 
@@ -1201,16 +1220,19 @@ struct gl_texture_unit {
    /** 
     * \name GL_EXT_texture_env_combine 
     */
-   /*@{*/
-   GLenum CombineModeRGB;       /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */
-   GLenum CombineModeA;         /**< GL_REPLACE, GL_DECAL, GL_ADD, etc. */
-   GLenum CombineSourceRGB[3];  /**< GL_PRIMARY_COLOR, GL_TEXTURE, etc. */
-   GLenum CombineSourceA[3];    /**< GL_PRIMARY_COLOR, GL_TEXTURE, etc. */
-   GLenum CombineOperandRGB[3]; /**< SRC_COLOR, ONE_MINUS_SRC_COLOR, etc */
-   GLenum CombineOperandA[3];   /**< SRC_ALPHA, ONE_MINUS_SRC_ALPHA, etc */
-   GLuint CombineScaleShiftRGB; /**< 0, 1 or 2 */
-   GLuint CombineScaleShiftA;   /**< 0, 1 or 2 */
-   /*@}*/
+   struct gl_tex_env_combine_state Combine;
+
+   /**
+    * Derived state based on \c EnvMode and the \c BaseFormat of the
+    * currently enabled texture.
+    */
+   struct gl_tex_env_combine_state _EnvMode;
+
+   /**
+    * Currently enabled combiner state.  This will point to either
+    * \c Combine or \c _EnvMode.
+    */
+   struct gl_tex_env_combine_state *_CurrentCombine;
 
    struct gl_texture_object *Current1D;
    struct gl_texture_object *Current2D;
index e27c42e..8cb247e 100644 (file)
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
+/** 
+ * \file texstate.c
+ *
+ * Texture state handling.
+ */
 
 #include "glheader.h"
 #include "colormac.h"
 #define ENUM_TO_DOUBLE(X) ((GLdouble)(X))
 #endif
 
+/**
+ * Default texture combine environment state.  This is used to initialize
+ * a context's texture units and as the basis for converting "classic"
+ * texture environmnets to ARB_texture_env_combine style values.
+ */
+static const struct gl_tex_env_combine_state default_combine_state = {
+   GL_MODULATE, GL_MODULATE,
+   { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT },
+   { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT },
+   { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA },
+   { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA },
+   0, 0,
+   2, 2
+};
 
 
 void
@@ -92,14 +111,14 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst )
       dst->Texture.Unit[i].LodBias = src->Texture.Unit[i].LodBias;
 
       /* GL_EXT_texture_env_combine */
-      dst->Texture.Unit[i].CombineModeRGB = src->Texture.Unit[i].CombineModeRGB;
-      dst->Texture.Unit[i].CombineModeA = src->Texture.Unit[i].CombineModeA;
-      COPY_3V(dst->Texture.Unit[i].CombineSourceRGB, src->Texture.Unit[i].CombineSourceRGB);
-      COPY_3V(dst->Texture.Unit[i].CombineSourceA, src->Texture.Unit[i].CombineSourceA);
-      COPY_3V(dst->Texture.Unit[i].CombineOperandRGB, src->Texture.Unit[i].CombineOperandRGB);
-      COPY_3V(dst->Texture.Unit[i].CombineOperandA, src->Texture.Unit[i].CombineOperandA);
-      dst->Texture.Unit[i].CombineScaleShiftRGB = src->Texture.Unit[i].CombineScaleShiftRGB;
-      dst->Texture.Unit[i].CombineScaleShiftA = src->Texture.Unit[i].CombineScaleShiftA;
+      dst->Texture.Unit[i].Combine.ModeRGB = src->Texture.Unit[i].Combine.ModeRGB;
+      dst->Texture.Unit[i].Combine.ModeA = src->Texture.Unit[i].Combine.ModeA;
+      COPY_3V(dst->Texture.Unit[i].Combine.SourceRGB, src->Texture.Unit[i].Combine.SourceRGB);
+      COPY_3V(dst->Texture.Unit[i].Combine.SourceA, src->Texture.Unit[i].Combine.SourceA);
+      COPY_3V(dst->Texture.Unit[i].Combine.OperandRGB, src->Texture.Unit[i].Combine.OperandRGB);
+      COPY_3V(dst->Texture.Unit[i].Combine.OperandA, src->Texture.Unit[i].Combine.OperandA);
+      dst->Texture.Unit[i].Combine.ScaleShiftRGB = src->Texture.Unit[i].Combine.ScaleShiftRGB;
+      dst->Texture.Unit[i].Combine.ScaleShiftA = src->Texture.Unit[i].Combine.ScaleShiftA;
 
       /* texture object state */
       _mesa_copy_texture_object(dst->Texture.Unit[i].Current1D,
@@ -125,22 +144,22 @@ _mesa_print_texunit_state( GLcontext *ctx, GLuint unit )
    const struct gl_texture_unit *texUnit = ctx->Texture.Unit + unit;
    _mesa_printf("Texture Unit %d\n", unit);
    _mesa_printf("  GL_TEXTURE_ENV_MODE = %s\n", _mesa_lookup_enum_by_nr(texUnit->EnvMode));
-   _mesa_printf("  GL_COMBINE_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineModeRGB));
-   _mesa_printf("  GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineModeA));
-   _mesa_printf("  GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineSourceRGB[0]));
-   _mesa_printf("  GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineSourceRGB[1]));
-   _mesa_printf("  GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineSourceRGB[2]));
-   _mesa_printf("  GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineSourceA[0]));
-   _mesa_printf("  GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineSourceA[1]));
-   _mesa_printf("  GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineSourceA[2]));
-   _mesa_printf("  GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineOperandRGB[0]));
-   _mesa_printf("  GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineOperandRGB[1]));
-   _mesa_printf("  GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineOperandRGB[2]));
-   _mesa_printf("  GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineOperandA[0]));
-   _mesa_printf("  GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineOperandA[1]));
-   _mesa_printf("  GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineOperandA[2]));
-   _mesa_printf("  GL_RGB_SCALE = %d\n", 1 << texUnit->CombineScaleShiftRGB);
-   _mesa_printf("  GL_ALPHA_SCALE = %d\n", 1 << texUnit->CombineScaleShiftA);
+   _mesa_printf("  GL_COMBINE_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB));
+   _mesa_printf("  GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA));
+   _mesa_printf("  GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[0]));
+   _mesa_printf("  GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[1]));
+   _mesa_printf("  GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[2]));
+   _mesa_printf("  GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[0]));
+   _mesa_printf("  GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[1]));
+   _mesa_printf("  GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[2]));
+   _mesa_printf("  GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[0]));
+   _mesa_printf("  GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[1]));
+   _mesa_printf("  GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[2]));
+   _mesa_printf("  GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[0]));
+   _mesa_printf("  GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[1]));
+   _mesa_printf("  GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[2]));
+   _mesa_printf("  GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB);
+   _mesa_printf("  GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA);
    _mesa_printf("  GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]);
 }
 
@@ -150,6 +169,125 @@ _mesa_print_texunit_state( GLcontext *ctx, GLuint unit )
 /*                       Texture Environment                          */
 /**********************************************************************/
 
+/**
+ * Convert "classic" texture environment to ARB_texture_env_combine style
+ * environments.
+ * 
+ * \param state  texture_env_combine state vector to be filled-in.
+ * \param mode   Classic texture environment mode (i.e., \c GL_REPLACE,
+ *               \c GL_BLEND, \c GL_DECAL, etc.).
+ * \param tex_base_format  Base format of the texture associated with the
+ *               texture unit.
+ */
+static void
+calculate_derived_texenv( struct gl_tex_env_combine_state * state,
+                         GLenum mode, GLenum tex_base_format )
+{
+   GLenum mode_rgb;
+   GLenum mode_a;
+
+   *state = default_combine_state;
+
+   switch( tex_base_format ) {
+   case GL_ALPHA:
+      state->SourceRGB[0] = GL_PREVIOUS;
+      break;
+
+   case GL_LUMINANCE_ALPHA:
+   case GL_INTENSITY:
+   case GL_RGBA:
+      break;
+
+   case GL_LUMINANCE:
+   case GL_RGB:
+   case GL_YCBCR_MESA:
+      state->SourceA[0] = GL_PREVIOUS;
+      break;
+      
+   default:
+      state->SourceRGB[0] = GL_PREVIOUS;
+      state->SourceA[0]   = GL_PREVIOUS;
+      state->ModeRGB      = GL_REPLACE;
+      state->ModeA        = GL_REPLACE;
+      ASSERT(0);
+      return;
+   }
+
+   switch( mode ) {
+   case GL_REPLACE:
+   case GL_MODULATE:
+      mode_rgb = (tex_base_format == GL_ALPHA) ? GL_REPLACE : mode;
+      mode_a   = mode;
+      break;
+   
+   case GL_DECAL:
+      mode_rgb = GL_INTERPOLATE;
+      mode_a   = GL_REPLACE;
+
+      state->SourceA[0] = GL_PREVIOUS;
+
+      /* Having alpha / luminance / intensity textures replace using the
+       * incoming fragment color matches the definition in NV_texture_shader.
+       * The 1.5 spec simply marks these as "undefined".
+       */
+      switch( tex_base_format ) {
+      case GL_ALPHA:
+      case GL_LUMINANCE:
+      case GL_LUMINANCE_ALPHA:
+      case GL_INTENSITY:
+        state->SourceRGB[0] = GL_PREVIOUS;
+        break;
+      case GL_RGB:
+      case GL_YCBCR_MESA:
+        mode_rgb = GL_REPLACE;
+        break;
+      case GL_RGBA:
+        state->SourceRGB[2] = GL_TEXTURE;
+        break;
+      }
+      break;
+
+   case GL_BLEND:
+      mode_rgb = GL_INTERPOLATE;
+      mode_a   = GL_MODULATE;
+
+      switch( tex_base_format ) {
+      case GL_ALPHA:
+        mode_rgb = GL_REPLACE;
+        break;
+      case GL_INTENSITY:
+        mode_a = GL_INTERPOLATE;
+        /* FALLTHROUGH */
+      case GL_LUMINANCE:
+      case GL_RGB:
+      case GL_LUMINANCE_ALPHA:
+      case GL_RGBA:
+      case GL_YCBCR_MESA:
+        state->SourceRGB[2] = GL_TEXTURE;
+        state->SourceA[2]   = GL_TEXTURE;
+        state->SourceRGB[0] = GL_CONSTANT;
+        state->OperandRGB[2] = GL_SRC_COLOR;
+        break;
+      }
+      break;
+
+   case GL_ADD:
+      mode_rgb = (tex_base_format == GL_ALPHA) ? GL_REPLACE : GL_ADD;
+      mode_a   = (tex_base_format == GL_INTENSITY) ? GL_ADD : GL_MODULATE;
+      break;
+
+   default:
+      mode_rgb = GL_REPLACE;
+      mode_a   = GL_REPLACE;
+      ASSERT(0);
+      break;
+   }
+   
+   state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS)
+       ? mode_rgb : GL_REPLACE;
+   state->ModeA   = (state->SourceA[0]   != GL_PREVIOUS)
+       ? mode_a   : GL_REPLACE;
+}
 
 void GLAPIENTRY
 _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
@@ -179,6 +317,18 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
                   return;
                FLUSH_VERTICES(ctx, _NEW_TEXTURE);
                texUnit->EnvMode = mode;
+
+              /* FIXME: Is this needed here or is having it in
+               * FIXME: update_texture_state enough?
+               */
+              if ( mode == GL_COMBINE ) {
+                 texUnit->_CurrentCombine = & texUnit->Combine;
+              }
+              else if ( texUnit->_Current != NULL ) {
+                 calculate_derived_texenv( & texUnit->_EnvMode, mode,
+                                            texUnit->_Current->Image[0][0]->Format );
+                 texUnit->_CurrentCombine = & texUnit->_EnvMode;
+              }
             }
             else {
                TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
@@ -243,10 +393,10 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
                TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
               return;
            }
-           if (texUnit->CombineModeRGB == mode)
+           if (texUnit->Combine.ModeRGB == mode)
               return;
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-           texUnit->CombineModeRGB = mode;
+           texUnit->Combine.ModeRGB = mode;
         }
         else {
             TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
@@ -284,10 +434,10 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
               return;
            }
 
-           if (texUnit->CombineModeA == mode)
+           if (texUnit->Combine.ModeA == mode)
                return;
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-           texUnit->CombineModeA = mode;
+           texUnit->Combine.ModeA = mode;
         }
         else {
             TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
@@ -311,10 +461,10 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
                 (ctx->Extensions.ATI_texture_env_combine3 &&
                  (source == GL_ZERO || source == GL_ONE))) {
                /* legal */
-               if (texUnit->CombineSourceRGB[s] == source)
+               if (texUnit->Combine.SourceRGB[s] == source)
                   return;
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-              texUnit->CombineSourceRGB[s] = source;
+              texUnit->Combine.SourceRGB[s] = source;
             }
             else {
                TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
@@ -343,10 +493,10 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
                (ctx->Extensions.ATI_texture_env_combine3 &&
                  (source == GL_ZERO || source == GL_ONE))) {
                /* legal */
-              if (texUnit->CombineSourceA[s] == source)
+              if (texUnit->Combine.SourceA[s] == source)
                   return;
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-              texUnit->CombineSourceA[s] = source;
+              texUnit->Combine.SourceA[s] = source;
             }
             else {
                TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
@@ -369,10 +519,10 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
            case GL_ONE_MINUS_SRC_COLOR:
            case GL_SRC_ALPHA:
            case GL_ONE_MINUS_SRC_ALPHA:
-              if (texUnit->CombineOperandRGB[s] == operand)
+              if (texUnit->Combine.OperandRGB[s] == operand)
                  return;
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-              texUnit->CombineOperandRGB[s] = operand;
+              texUnit->Combine.OperandRGB[s] = operand;
               break;
            default:
                TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
@@ -392,11 +542,11 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
            switch (operand) {
            case GL_SRC_ALPHA:
            case GL_ONE_MINUS_SRC_ALPHA:
-              if (texUnit->CombineOperandA[pname-GL_OPERAND0_ALPHA] ==
+              if (texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] ==
                   operand)
                  return;
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-              texUnit->CombineOperandA[pname-GL_OPERAND0_ALPHA] = operand;
+              texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] = operand;
               break;
            default:
                TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
@@ -417,10 +567,10 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
            case GL_ONE_MINUS_SRC_COLOR: /* ARB combine only */
            case GL_SRC_ALPHA:
            case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
-              if (texUnit->CombineOperandRGB[2] == operand)
+              if (texUnit->Combine.OperandRGB[2] == operand)
                  return;
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-              texUnit->CombineOperandRGB[2] = operand;
+              texUnit->Combine.OperandRGB[2] = operand;
                break;
            default:
                TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
@@ -439,10 +589,10 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
            switch (operand) {
            case GL_SRC_ALPHA:
            case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
-              if (texUnit->CombineOperandA[2] == operand)
+              if (texUnit->Combine.OperandA[2] == operand)
                  return;
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-              texUnit->CombineOperandA[2] = operand;
+              texUnit->Combine.OperandA[2] = operand;
               break;
            default:
                TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
@@ -472,10 +622,10 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
                             "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" );
               return;
            }
-           if (texUnit->CombineScaleShiftRGB == newshift)
+           if (texUnit->Combine.ScaleShiftRGB == newshift)
               return;
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-           texUnit->CombineScaleShiftRGB = newshift;
+           texUnit->Combine.ScaleShiftRGB = newshift;
         }
         else {
             TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
@@ -500,10 +650,10 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
                             "glTexEnv(GL_ALPHA_SCALE not 1, 2 or 4)" );
               return;
            }
-           if (texUnit->CombineScaleShiftA == newshift)
+           if (texUnit->Combine.ScaleShiftA == newshift)
               return;
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-           texUnit->CombineScaleShiftA = newshift;
+           texUnit->Combine.ScaleShiftA = newshift;
         }
         else {
             TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
@@ -634,7 +784,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
          case GL_COMBINE_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLfloat) texUnit->CombineModeRGB;
+               *params = (GLfloat) texUnit->Combine.ModeRGB;
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
@@ -643,7 +793,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
          case GL_COMBINE_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLfloat) texUnit->CombineModeA;
+               *params = (GLfloat) texUnit->Combine.ModeA;
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
@@ -652,7 +802,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
          case GL_SOURCE0_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLfloat) texUnit->CombineSourceRGB[0];
+               *params = (GLfloat) texUnit->Combine.SourceRGB[0];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
@@ -661,7 +811,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
          case GL_SOURCE1_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLfloat) texUnit->CombineSourceRGB[1];
+               *params = (GLfloat) texUnit->Combine.SourceRGB[1];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
@@ -670,7 +820,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
          case GL_SOURCE2_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLfloat) texUnit->CombineSourceRGB[2];
+               *params = (GLfloat) texUnit->Combine.SourceRGB[2];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
@@ -679,7 +829,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
          case GL_SOURCE0_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLfloat) texUnit->CombineSourceA[0];
+               *params = (GLfloat) texUnit->Combine.SourceA[0];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
@@ -688,7 +838,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
          case GL_SOURCE1_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLfloat) texUnit->CombineSourceA[1];
+               *params = (GLfloat) texUnit->Combine.SourceA[1];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
@@ -697,7 +847,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
          case GL_SOURCE2_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLfloat) texUnit->CombineSourceA[2];
+               *params = (GLfloat) texUnit->Combine.SourceA[2];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
@@ -706,7 +856,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
          case GL_OPERAND0_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLfloat) texUnit->CombineOperandRGB[0];
+               *params = (GLfloat) texUnit->Combine.OperandRGB[0];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
@@ -715,7 +865,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
          case GL_OPERAND1_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLfloat) texUnit->CombineOperandRGB[1];
+               *params = (GLfloat) texUnit->Combine.OperandRGB[1];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
@@ -724,7 +874,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
          case GL_OPERAND2_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLfloat) texUnit->CombineOperandRGB[2];
+               *params = (GLfloat) texUnit->Combine.OperandRGB[2];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
@@ -733,7 +883,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
          case GL_OPERAND0_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLfloat) texUnit->CombineOperandA[0];
+               *params = (GLfloat) texUnit->Combine.OperandA[0];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
@@ -742,7 +892,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
          case GL_OPERAND1_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLfloat) texUnit->CombineOperandA[1];
+               *params = (GLfloat) texUnit->Combine.OperandA[1];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
@@ -751,7 +901,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
          case GL_OPERAND2_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLfloat) texUnit->CombineOperandA[2];
+               *params = (GLfloat) texUnit->Combine.OperandA[2];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
@@ -760,9 +910,9 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
          case GL_RGB_SCALE:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               if (texUnit->CombineScaleShiftRGB == 0)
+               if (texUnit->Combine.ScaleShiftRGB == 0)
                   *params = 1.0;
-               else if (texUnit->CombineScaleShiftRGB == 1)
+               else if (texUnit->Combine.ScaleShiftRGB == 1)
                   *params = 2.0;
                else
                   *params = 4.0;
@@ -775,9 +925,9 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
          case GL_ALPHA_SCALE:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               if (texUnit->CombineScaleShiftA == 0)
+               if (texUnit->Combine.ScaleShiftA == 0)
                   *params = 1.0;
-               else if (texUnit->CombineScaleShiftA == 1)
+               else if (texUnit->Combine.ScaleShiftA == 1)
                   *params = 2.0;
                else
                   *params = 4.0;
@@ -848,7 +998,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
          case GL_COMBINE_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLint) texUnit->CombineModeRGB;
+               *params = (GLint) texUnit->Combine.ModeRGB;
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
@@ -857,7 +1007,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
          case GL_COMBINE_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLint) texUnit->CombineModeA;
+               *params = (GLint) texUnit->Combine.ModeA;
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
@@ -866,7 +1016,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
          case GL_SOURCE0_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLint) texUnit->CombineSourceRGB[0];
+               *params = (GLint) texUnit->Combine.SourceRGB[0];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
@@ -875,7 +1025,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
          case GL_SOURCE1_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLint) texUnit->CombineSourceRGB[1];
+               *params = (GLint) texUnit->Combine.SourceRGB[1];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
@@ -884,7 +1034,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
          case GL_SOURCE2_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLint) texUnit->CombineSourceRGB[2];
+               *params = (GLint) texUnit->Combine.SourceRGB[2];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
@@ -893,7 +1043,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
          case GL_SOURCE0_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLint) texUnit->CombineSourceA[0];
+               *params = (GLint) texUnit->Combine.SourceA[0];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
@@ -902,7 +1052,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
          case GL_SOURCE1_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLint) texUnit->CombineSourceA[1];
+               *params = (GLint) texUnit->Combine.SourceA[1];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
@@ -911,7 +1061,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
          case GL_SOURCE2_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLint) texUnit->CombineSourceA[2];
+               *params = (GLint) texUnit->Combine.SourceA[2];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
@@ -920,7 +1070,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
          case GL_OPERAND0_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLint) texUnit->CombineOperandRGB[0];
+               *params = (GLint) texUnit->Combine.OperandRGB[0];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
@@ -929,7 +1079,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
          case GL_OPERAND1_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLint) texUnit->CombineOperandRGB[1];
+               *params = (GLint) texUnit->Combine.OperandRGB[1];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
@@ -938,7 +1088,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
          case GL_OPERAND2_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLint) texUnit->CombineOperandRGB[2];
+               *params = (GLint) texUnit->Combine.OperandRGB[2];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
@@ -947,7 +1097,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
          case GL_OPERAND0_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLint) texUnit->CombineOperandA[0];
+               *params = (GLint) texUnit->Combine.OperandA[0];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
@@ -956,7 +1106,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
          case GL_OPERAND1_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLint) texUnit->CombineOperandA[1];
+               *params = (GLint) texUnit->Combine.OperandA[1];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
@@ -965,7 +1115,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
          case GL_OPERAND2_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               *params = (GLint) texUnit->CombineOperandA[2];
+               *params = (GLint) texUnit->Combine.OperandA[2];
             }
             else {
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
@@ -974,9 +1124,9 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
          case GL_RGB_SCALE:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               if (texUnit->CombineScaleShiftRGB == 0)
+               if (texUnit->Combine.ScaleShiftRGB == 0)
                   *params = 1;
-               else if (texUnit->CombineScaleShiftRGB == 1)
+               else if (texUnit->Combine.ScaleShiftRGB == 1)
                   *params = 2;
                else
                   *params = 4;
@@ -989,9 +1139,9 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
          case GL_ALPHA_SCALE:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
-               if (texUnit->CombineScaleShiftA == 0)
+               if (texUnit->Combine.ScaleShiftA == 0)
                   *params = 1;
-               else if (texUnit->CombineScaleShiftA == 1)
+               else if (texUnit->Combine.ScaleShiftA == 1)
                   *params = 2;
                else
                   *params = 4;
@@ -2800,6 +2950,64 @@ update_texture_state( GLcontext *ctx )
       if (texUnit->_ReallyEnabled)
          ctx->Texture._EnabledUnits |= (1 << unit);
 
+      if ( texUnit->EnvMode == GL_COMBINE ) {
+        texUnit->_CurrentCombine = & texUnit->Combine;
+      }
+      else {
+        calculate_derived_texenv( & texUnit->_EnvMode, 
+                                   texUnit->EnvMode,
+                                   texUnit->_Current->Image[0][0]->Format );
+        texUnit->_CurrentCombine = & texUnit->_EnvMode;
+      }
+
+      switch (texUnit->_CurrentCombine->ModeRGB) {
+      case GL_REPLACE:
+        texUnit->_CurrentCombine->_NumArgsRGB = 1;
+        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:
+        texUnit->_CurrentCombine->_NumArgsRGB = 2;
+        break;
+      case GL_INTERPOLATE:
+      case GL_MODULATE_ADD_ATI:
+      case GL_MODULATE_SIGNED_ADD_ATI:
+      case GL_MODULATE_SUBTRACT_ATI:
+        texUnit->_CurrentCombine->_NumArgsRGB = 3;
+        break;
+      default:
+        texUnit->_CurrentCombine->_NumArgsRGB = 0;
+        ASSERT(0);
+        break;
+      }
+
+      switch (texUnit->_CurrentCombine->ModeA) {
+      case GL_REPLACE:
+        texUnit->_CurrentCombine->_NumArgsA = 1;
+        break;
+      case GL_MODULATE:
+      case GL_ADD:
+      case GL_ADD_SIGNED:
+      case GL_SUBTRACT:
+        texUnit->_CurrentCombine->_NumArgsA = 2;
+        break;
+      case GL_INTERPOLATE:
+      case GL_MODULATE_ADD_ATI:
+      case GL_MODULATE_SIGNED_ADD_ATI:
+      case GL_MODULATE_SUBTRACT_ATI:
+        texUnit->_CurrentCombine->_NumArgsA = 3;
+        break;
+      default:
+        texUnit->_CurrentCombine->_NumArgsA = 0;
+        ASSERT(0);
+        break;
+      }
+
       if (texUnit->TexGenEnabled) {
         if (texUnit->TexGenEnabled & S_BIT) {
            texUnit->_GenFlags |= texUnit->_GenBitS;
@@ -2910,22 +3118,9 @@ init_texture_unit( GLcontext *ctx, GLuint unit )
    texUnit->EnvMode = GL_MODULATE;
    ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
 
-   texUnit->CombineModeRGB = GL_MODULATE;
-   texUnit->CombineModeA = GL_MODULATE;
-   texUnit->CombineSourceRGB[0] = GL_TEXTURE;
-   texUnit->CombineSourceRGB[1] = GL_PREVIOUS_EXT;
-   texUnit->CombineSourceRGB[2] = GL_CONSTANT_EXT;
-   texUnit->CombineSourceA[0] = GL_TEXTURE;
-   texUnit->CombineSourceA[1] = GL_PREVIOUS_EXT;
-   texUnit->CombineSourceA[2] = GL_CONSTANT_EXT;
-   texUnit->CombineOperandRGB[0] = GL_SRC_COLOR;
-   texUnit->CombineOperandRGB[1] = GL_SRC_COLOR;
-   texUnit->CombineOperandRGB[2] = GL_SRC_ALPHA;
-   texUnit->CombineOperandA[0] = GL_SRC_ALPHA;
-   texUnit->CombineOperandA[1] = GL_SRC_ALPHA;
-   texUnit->CombineOperandA[2] = GL_SRC_ALPHA;
-   texUnit->CombineScaleShiftRGB = 0;
-   texUnit->CombineScaleShiftA = 0;
+   texUnit->Combine = default_combine_state;
+   texUnit->_EnvMode = default_combine_state;
+   texUnit->_CurrentCombine = & texUnit->_EnvMode;
 
    texUnit->TexGenEnabled = 0;
    texUnit->GenModeS = GL_EYE_LINEAR;
index 3e73de2..9704048 100644 (file)
@@ -1425,9 +1425,9 @@ do_row(const struct gl_texture_format *format, GLint srcWidth,
             const GLint rowAb1 = (rowA[k] >> 11) & 0x1f;
             const GLint rowBb0 = (rowB[j] >> 11) & 0x1f;
             const GLint rowBb1 = (rowB[k] >> 11) & 0x1f;
-            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4;
-            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4;
-            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4;
+            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
+            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
+            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
             dst[i] = (blue << 11) | (green << 5) | red;
          }
       }
@@ -1456,10 +1456,10 @@ do_row(const struct gl_texture_format *format, GLint srcWidth,
             const GLint rowAa1 = (rowA[k] >> 12) & 0xf;
             const GLint rowBa0 = (rowB[j] >> 12) & 0xf;
             const GLint rowBa1 = (rowB[k] >> 12) & 0xf;
-            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4;
-            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4;
-            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4;
-            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 4;
+            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
+            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
+            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
+            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
             dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
          }
       }
@@ -1488,10 +1488,10 @@ do_row(const struct gl_texture_format *format, GLint srcWidth,
             const GLint rowAa1 = (rowA[k] >> 15) & 0x1;
             const GLint rowBa0 = (rowB[j] >> 15) & 0x1;
             const GLint rowBa1 = (rowB[k] >> 15) & 0x1;
-            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4;
-            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4;
-            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4;
-            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 4;
+            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
+            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
+            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
+            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
             dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
          }
       }
@@ -1531,9 +1531,9 @@ do_row(const struct gl_texture_format *format, GLint srcWidth,
             const GLint rowAb1 = (rowA[k] >> 5) & 0x7;
             const GLint rowBb0 = (rowB[j] >> 5) & 0x7;
             const GLint rowBb1 = (rowB[k] >> 5) & 0x7;
-            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4;
-            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4;
-            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4;
+            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
+            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
+            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
             dst[i] = (blue << 5) | (green << 2) | red;
          }
       }
index 37e8ea8..496812f 100644 (file)
@@ -3113,7 +3113,9 @@ _swrast_choose_texture_sample_func( GLcontext *ctx,
 /**
  * Do texture application for GL_ARB/EXT_texture_env_combine.
  * This function also supports GL_{EXT,ARB}_texture_env_dot3 and
- * GL_ATI_texture_env_combine3
+ * GL_ATI_texture_env_combine3.  Since "classic" texture environments are
+ * implemented using GL_ARB_texture_env_combine-like state, this same function
+ * is used for classic texture environment application as well.
  *
  * \param ctx          rendering context
  * \param textureUnit  the texture unit to apply
@@ -3132,8 +3134,8 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
    const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]);
    const GLchan (*argRGB [3])[4];
    const GLchan (*argA [3])[4];
-   const GLuint RGBshift = textureUnit->CombineScaleShiftRGB;
-   const GLuint Ashift   = textureUnit->CombineScaleShiftA;
+   const GLuint RGBshift = textureUnit->_CurrentCombine->ScaleShiftRGB;
+   const GLuint Ashift   = textureUnit->_CurrentCombine->ScaleShiftA;
 #if CHAN_TYPE == GL_FLOAT
    const GLchan RGBmult = (GLfloat) (1 << RGBshift);
    const GLchan Amult = (GLfloat) (1 << Ashift);
@@ -3159,67 +3161,22 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
 
    /*
    printf("modeRGB 0x%x  modeA 0x%x  srcRGB1 0x%x  srcA1 0x%x  srcRGB2 0x%x  srcA2 0x%x\n",
-          textureUnit->CombineModeRGB,
-          textureUnit->CombineModeA,
-          textureUnit->CombineSourceRGB[0],
-          textureUnit->CombineSourceA[0],
-          textureUnit->CombineSourceRGB[1],
-          textureUnit->CombineSourceA[1]);
+          textureUnit->_CurrentCombine->ModeRGB,
+          textureUnit->_CurrentCombine->ModeA,
+          textureUnit->_CurrentCombine->SourceRGB[0],
+          textureUnit->_CurrentCombine->SourceA[0],
+          textureUnit->_CurrentCombine->SourceRGB[1],
+          textureUnit->_CurrentCombine->SourceA[1]);
    */
 
    /*
     * Do operand setup for up to 3 operands.  Loop over the terms.
     */
-   switch (textureUnit->CombineModeRGB) {
-      case GL_REPLACE:
-        numColorArgs = 1;
-        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;
-        break;
-      case GL_INTERPOLATE:
-      case GL_MODULATE_ADD_ATI:
-      case GL_MODULATE_SIGNED_ADD_ATI:
-      case GL_MODULATE_SUBTRACT_ATI:
-        numColorArgs = 3;
-        break;
-      default:
-        numColorArgs = 0;
-        ASSERT(0);
-        break;
-   }
-
-   switch (textureUnit->CombineModeA) {
-      case GL_REPLACE:
-        numAlphaArgs = 1;
-        break;
-      case GL_MODULATE:
-      case GL_ADD:
-      case GL_ADD_SIGNED:
-      case GL_SUBTRACT:
-        numAlphaArgs = 2;
-        break;
-      case GL_INTERPOLATE:
-      case GL_MODULATE_ADD_ATI:
-      case GL_MODULATE_SIGNED_ADD_ATI:
-      case GL_MODULATE_SUBTRACT_ATI:
-        numAlphaArgs = 3;
-        break;
-      default:
-        numAlphaArgs = 0;
-        ASSERT(0);
-        break;
-   }
+   numColorArgs = textureUnit->_CurrentCombine->_NumArgsRGB;
+   numAlphaArgs = textureUnit->_CurrentCombine->_NumArgsA;
 
    for (j = 0; j < numColorArgs; j++) {
-      const GLenum srcRGB = textureUnit->CombineSourceRGB[j];
+      const GLenum srcRGB = textureUnit->_CurrentCombine->SourceRGB[j];
 
 
       switch (srcRGB) {
@@ -3270,21 +3227,21 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
             }
       }
 
-      if (textureUnit->CombineOperandRGB[j] != GL_SRC_COLOR) {
+      if (textureUnit->_CurrentCombine->OperandRGB[j] != GL_SRC_COLOR) {
          const GLchan (*src)[4] = argRGB[j];
          GLchan (*dst)[4] = ccolor[j];
 
          /* point to new arg[j] storage */
          argRGB[j] = (const GLchan (*)[4]) ccolor[j];
 
-         if (textureUnit->CombineOperandRGB[j] == GL_ONE_MINUS_SRC_COLOR) {
+         if (textureUnit->_CurrentCombine->OperandRGB[j] == GL_ONE_MINUS_SRC_COLOR) {
             for (i = 0; i < n; i++) {
                dst[i][RCOMP] = CHAN_MAX - src[i][RCOMP];
                dst[i][GCOMP] = CHAN_MAX - src[i][GCOMP];
                dst[i][BCOMP] = CHAN_MAX - src[i][BCOMP];
             }
          }
-         else if (textureUnit->CombineOperandRGB[j] == GL_SRC_ALPHA) {
+         else if (textureUnit->_CurrentCombine->OperandRGB[j] == GL_SRC_ALPHA) {
             for (i = 0; i < n; i++) {
                dst[i][RCOMP] = src[i][ACOMP];
                dst[i][GCOMP] = src[i][ACOMP];
@@ -3292,7 +3249,7 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
             }
          }
          else {
-            ASSERT(textureUnit->CombineOperandRGB[j] ==GL_ONE_MINUS_SRC_ALPHA);
+            ASSERT(textureUnit->_CurrentCombine->OperandRGB[j] ==GL_ONE_MINUS_SRC_ALPHA);
             for (i = 0; i < n; i++) {
                dst[i][RCOMP] = CHAN_MAX - src[i][ACOMP];
                dst[i][GCOMP] = CHAN_MAX - src[i][ACOMP];
@@ -3304,7 +3261,7 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
 
 
    for (j = 0; j < numAlphaArgs; j++) {
-      const GLenum srcA = textureUnit->CombineSourceA[j];
+      const GLenum srcA = textureUnit->_CurrentCombine->SourceA[j];
 
       switch (srcA) {
          case GL_TEXTURE:
@@ -3346,7 +3303,7 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
             }
       }
 
-      if (textureUnit->CombineOperandA[j] == GL_ONE_MINUS_SRC_ALPHA) {
+      if (textureUnit->_CurrentCombine->OperandA[j] == GL_ONE_MINUS_SRC_ALPHA) {
          const GLchan (*src)[4] = argA[j];
          GLchan (*dst)[4] = ccolor[j];
          argA[j] = (const GLchan (*)[4]) ccolor[j];
@@ -3359,7 +3316,7 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
    /*
     * Do the texture combine.
     */
-   switch (textureUnit->CombineModeRGB) {
+   switch (textureUnit->_CurrentCombine->ModeRGB) {
       case GL_REPLACE:
          {
             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
@@ -3651,7 +3608,7 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
          _mesa_problem(ctx, "invalid combine mode");
    }
 
-   switch (textureUnit->CombineModeA) {
+   switch (textureUnit->_CurrentCombine->ModeA) {
       case GL_REPLACE:
          {
             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
@@ -3823,8 +3780,8 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
     * were written such that the GL_COMBINE_ALPHA value could be set to
     * GL_DOT3.
     */
-   if (textureUnit->CombineModeRGB == GL_DOT3_RGBA_EXT ||
-       textureUnit->CombineModeRGB == GL_DOT3_RGBA) {
+   if (textureUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT ||
+       textureUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) {
       for (i = 0; i < n; i++) {
         rgba[i][ACOMP] = rgba[i][RCOMP];
       }
@@ -3835,20 +3792,6 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
 
 
 /**
- * Implement NVIDIA's GL_NV_texture_env_combine4 extension when
- * texUnit->EnvMode == GL_COMBINE4_NV.
- */
-static INLINE void
-texture_combine4( const GLcontext *ctx, GLuint unit, GLuint n,
-                  CONST GLchan (*primary_rgba)[4],
-                  CONST GLchan *texelBuffer,
-                  GLchan (*rgba)[4] )
-{
-}
-
-
-
-/**
  * Apply a conventional OpenGL texture env mode (REPLACE, ADD, BLEND,
  * MODULATE, or DECAL) to an array of fragments.
  * Input:  textureUnit - pointer to texture unit to apply
@@ -4276,20 +4219,12 @@ _swrast_texture_span( GLcontext *ctx, struct sw_span *span )
    for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
       if (ctx->Texture.Unit[unit]._ReallyEnabled) {
          const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
-         if (texUnit->EnvMode == GL_COMBINE) {
-            /* GL_ARB/EXT_texture_env_combine */
+         if (texUnit->_CurrentCombine != &texUnit->_EnvMode ) {
             texture_combine( ctx, unit, span->end,
                              (CONST GLchan (*)[4]) primary_rgba,
                              swrast->TexelBuffer,
                              span->array->rgba );
          }
-         else if (texUnit->EnvMode == GL_COMBINE4_NV) {
-            /* GL_NV_texture_env_combine4 */
-            texture_combine4( ctx, unit, span->end,
-                              (CONST GLchan (*)[4]) primary_rgba,
-                              swrast->TexelBuffer,
-                              span->array->rgba );
-         }
          else {
             /* conventional texture blend */
             const GLchan (*texels)[4] = (const GLchan (*)[4])