GL_ATI_texture_env_combine3 extension
diff --git a/docs/RELNOTES-5.1 b/docs/RELNOTES-5.1
index 09786e0..a1ad947 100644
--- a/docs/RELNOTES-5.1
+++ b/docs/RELNOTES-5.1
@@ -18,6 +18,9 @@
 New Features in Mesa 5.1
 ------------------------
 
+GL_ATI_texture_env_combine3 extension
+   This adds a few new texture combine modes.
+   Contributed by Ian Romanick.
 
 
 
@@ -49,4 +52,4 @@
 
 
 ----------------------------------------------------------------------
-$Id: RELNOTES-5.1,v 1.1 2002/12/18 14:57:34 brianp Exp $
+$Id: RELNOTES-5.1,v 1.2 2003/01/21 15:50:24 brianp Exp $
diff --git a/docs/VERSIONS b/docs/VERSIONS
index e1a8399..953485d 100644
--- a/docs/VERSIONS
+++ b/docs/VERSIONS
@@ -1,4 +1,4 @@
-$Id: VERSIONS,v 1.120 2002/12/18 14:56:59 brianp Exp $
+$Id: VERSIONS,v 1.121 2003/01/21 15:50:24 brianp Exp $
 
 
 Mesa Version History
@@ -1084,10 +1084,11 @@
 
 5.1  Month day, 2003
     New:
-	-
+	- GL_ATI_texture_env_combine3 extension (Ian Romanick)
     Bug fixes:
 	- really enable OpenGL 1.4 features in DOS driver.
 	- glAreProgramsResidentNV was slightly incorrect
+	- fixed issues in glDrawPixels and glCopyPixels for very wide images
     Changes:
 	- dropped API trace feature (src/Trace/)
 
diff --git a/include/GL/glext.h b/include/GL/glext.h
index 245f100..7d1f396 100644
--- a/include/GL/glext.h
+++ b/include/GL/glext.h
@@ -2423,6 +2423,11 @@
 #define GL_ACTIVE_STENCIL_FACE_EXT        0x8911
 #endif
 
+#ifndef GL_ATI_texture_env_combine3
+#define GL_MODULATE_ADD_ATI               0x8744
+#define GL_MODULATE_SIGNED_ADD_ATI        0x8745
+#define GL_MODULATE_SUBTRACT_ATI          0x8746
+#endif
 
 /*************************************************************/
 
@@ -5016,6 +5021,9 @@
 typedef void (APIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face);
 #endif
 
+#ifndef GL_ATI_texture_env_combine3
+#define GL_ATI_texture_env_combine3 1
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/src/mesa/main/enums.c b/src/mesa/main/enums.c
index 7a080e9..1f95dec 100644
--- a/src/mesa/main/enums.c
+++ b/src/mesa/main/enums.c
@@ -1,4 +1,4 @@
-/* $Id: enums.c,v 1.24 2002/10/29 20:28:45 brianp Exp $ */
+/* $Id: enums.c,v 1.25 2003/01/21 15:49:13 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -837,11 +837,16 @@
    { "GL_DOT3_RGBA_EXT", 0x8741 },
 
    /* GL_ARB_texture_env_dot3 */
-   { "GL_DOT3_RGB_EXT", 0x86ae },
-   { "GL_DOT3_RGBA_EXT", 0x86af },
+   { "GL_DOT3_RGB_ARB", 0x86ae },
+   { "GL_DOT3_RGBA_ARB", 0x86af },
 
    /* GL_ARB_texture_border_clamp */
    { "GL_CLAMP_TO_BORDER_ARB", 0x812D },
+
+   /* GL_ATI_texture_env_combine3 */
+   { "GL_MODULATE_ADD_ATI", 0x8744 },
+   { "GL_MODULATE_SIGNED_ADD_ATI", 0x8745 },
+   { "GL_MODULATE_SUBTRACT_ATI", 0x8746 },
 };
 
 #define Elements(x) sizeof(x)/sizeof(*x)
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 8362164..296308c 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -1,4 +1,4 @@
-/* $Id: extensions.c,v 1.86 2003/01/14 04:55:45 brianp Exp $ */
+/* $Id: extensions.c,v 1.87 2003/01/21 15:49:14 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -69,6 +69,7 @@
    { ON,  "GL_ARB_transpose_matrix",           0 },
    { ON,  "GL_ARB_window_pos",                 F(ARB_window_pos) },
    { OFF, "GL_ATI_texture_mirror_once",        F(ATI_texture_mirror_once)},
+   { OFF, "GL_ATI_texture_env_combine3",       F(ATI_texture_env_combine3)},
    { ON,  "GL_EXT_abgr",                       0 },
    { ON,  "GL_EXT_bgra",                       0 },
    { OFF, "GL_EXT_blend_color",                F(EXT_blend_color) },
@@ -157,6 +158,7 @@
       "GL_ARB_texture_env_crossbar",
       "GL_ARB_texture_env_dot3",
       "GL_ARB_texture_mirrored_repeat",
+      "GL_ATI_texture_env_combine3",
       "GL_ATI_texture_mirror_once",
       "GL_EXT_blend_color",
       "GL_EXT_blend_func_separate",
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index dfb3f12..353dc0d 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1,4 +1,4 @@
-/* $Id: mtypes.h,v 1.98 2003/01/14 04:55:45 brianp Exp $ */
+/* $Id: mtypes.h,v 1.99 2003/01/21 15:49:15 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -1348,6 +1348,7 @@
    GLboolean ARB_texture_mirrored_repeat;
    GLboolean ARB_window_pos;
    GLboolean ATI_texture_mirror_once;
+   GLboolean ATI_texture_env_combine3;
    GLboolean EXT_blend_color;
    GLboolean EXT_blend_func_separate;
    GLboolean EXT_blend_logic_op;
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index b511b1a..6762ee9 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -1,4 +1,4 @@
-/* $Id: texstate.c,v 1.91 2003/01/16 15:22:13 brianp Exp $ */
+/* $Id: texstate.c,v 1.92 2003/01/21 15:49:17 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -171,7 +171,7 @@
                 mode == GL_DECAL ||
                 mode == GL_REPLACE ||
                 (mode == GL_ADD && ctx->Extensions.EXT_texture_env_add) ||
-                (mode == GL_COMBINE_EXT &&
+                (mode == GL_COMBINE &&
                  (ctx->Extensions.EXT_texture_env_combine ||
                   ctx->Extensions.ARB_texture_env_combine))) {
                /* legal */
@@ -199,7 +199,7 @@
             COPY_4FV(texUnit->EnvColor, tmp);
          }
          break;
-      case GL_COMBINE_RGB_EXT:
+      case GL_COMBINE_RGB:
 	 if (ctx->Extensions.EXT_texture_env_combine ||
              ctx->Extensions.ARB_texture_env_combine) {
 	    const GLenum mode = (GLenum) (GLint) *param;
@@ -207,11 +207,11 @@
 	    case GL_REPLACE:
 	    case GL_MODULATE:
 	    case GL_ADD:
-	    case GL_ADD_SIGNED_EXT:
-	    case GL_INTERPOLATE_EXT:
+	    case GL_ADD_SIGNED:
+	    case GL_INTERPOLATE:
                /* OK */
 	       break;
-            case GL_SUBTRACT_ARB:
+            case GL_SUBTRACT:
                if (!ctx->Extensions.ARB_texture_env_combine) {
                   TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
                   return;
@@ -224,13 +224,21 @@
 		  return;
 	       }
 	       break;
-	    case GL_DOT3_RGB_ARB:
-	    case GL_DOT3_RGBA_ARB:
+	    case GL_DOT3_RGB:
+	    case GL_DOT3_RGBA:
 	       if (!ctx->Extensions.ARB_texture_env_dot3) {
                   TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
 		  return;
 	       }
 	       break;
+	    case GL_MODULATE_ADD_ATI:
+	    case GL_MODULATE_SIGNED_ADD_ATI:
+	    case GL_MODULATE_SUBTRACT_ATI:
+	       if (!ctx->Extensions.ATI_texture_env_combine3) {
+                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
+		  return;
+	       }
+	       break;
 	    default:
                TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
 	       return;
@@ -245,47 +253,63 @@
 	    return;
 	 }
          break;
-      case GL_COMBINE_ALPHA_EXT:
+      case GL_COMBINE_ALPHA:
 	 if (ctx->Extensions.EXT_texture_env_combine ||
              ctx->Extensions.ARB_texture_env_combine) {
 	    const GLenum mode = (GLenum) (GLint) *param;
-            if (mode == GL_REPLACE ||
-                mode == GL_MODULATE ||
-                mode == GL_ADD ||
-                mode == GL_ADD_SIGNED_EXT ||
-                mode == GL_INTERPOLATE_EXT ||
-                (mode == GL_SUBTRACT_ARB &&
-                 ctx->Extensions.ARB_texture_env_combine)) {
-               /* legal */
-               if (texUnit->CombineModeA == mode)
-                  return;
-               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-               texUnit->CombineModeA = mode;
-            }
-            else {
-               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
+            switch (mode) {
+	    case GL_REPLACE:
+	    case GL_MODULATE:
+	    case GL_ADD:
+	    case GL_ADD_SIGNED:
+	    case GL_INTERPOLATE:
+	       /* OK */
+	       break;
+	    case GL_SUBTRACT:
+	       if (!ctx->Extensions.ARB_texture_env_combine) {
+		  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
+		  return;
+	       }
+	       break;
+	    case GL_MODULATE_ADD_ATI:
+	    case GL_MODULATE_SIGNED_ADD_ATI:
+	    case GL_MODULATE_SUBTRACT_ATI:
+	       if (!ctx->Extensions.ATI_texture_env_combine3) {
+                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
+		  return;
+	       }
+	       break;
+	    default:
+	       TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
 	       return;
 	    }
+
+	    if (texUnit->CombineModeA == mode)
+		return;
+	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+	    texUnit->CombineModeA = mode;
 	 }
 	 else {
             TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
 	    return;
 	 }
 	 break;
-      case GL_SOURCE0_RGB_EXT:
-      case GL_SOURCE1_RGB_EXT:
-      case GL_SOURCE2_RGB_EXT:
+      case GL_SOURCE0_RGB:
+      case GL_SOURCE1_RGB:
+      case GL_SOURCE2_RGB:
 	 if (ctx->Extensions.EXT_texture_env_combine ||
 	     ctx->Extensions.ARB_texture_env_combine) {
 	    const GLenum source = (GLenum) (GLint) *param;
-	    const GLuint s = pname - GL_SOURCE0_RGB_EXT;
+	    const GLuint s = pname - GL_SOURCE0_RGB;
             if (source == GL_TEXTURE ||
-                source == GL_CONSTANT_EXT ||
-                source == GL_PRIMARY_COLOR_EXT ||
-                source == GL_PREVIOUS_EXT ||
+                source == GL_CONSTANT ||
+                source == GL_PRIMARY_COLOR ||
+                source == GL_PREVIOUS ||
                 (ctx->Extensions.ARB_texture_env_crossbar &&
-                 source >= GL_TEXTURE0_ARB &&
-                 source < GL_TEXTURE0_ARB + ctx->Const.MaxTextureUnits)) {
+                 source >= GL_TEXTURE0 &&
+                 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
+                (ctx->Extensions.ATI_texture_env_combine3 &&
+                 (source == GL_ZERO || source == GL_ONE))) {
                /* legal */
                if (texUnit->CombineSourceRGB[s] == source)
                   return;
@@ -302,20 +326,22 @@
 	    return;
 	 }
 	 break;
-      case GL_SOURCE0_ALPHA_EXT:
-      case GL_SOURCE1_ALPHA_EXT:
-      case GL_SOURCE2_ALPHA_EXT:
+      case GL_SOURCE0_ALPHA:
+      case GL_SOURCE1_ALPHA:
+      case GL_SOURCE2_ALPHA:
 	 if (ctx->Extensions.EXT_texture_env_combine ||
              ctx->Extensions.ARB_texture_env_combine) {
 	    const GLenum source = (GLenum) (GLint) *param;
-	    const GLuint s = pname - GL_SOURCE0_ALPHA_EXT;
+	    const GLuint s = pname - GL_SOURCE0_ALPHA;
             if (source == GL_TEXTURE ||
-                source == GL_CONSTANT_EXT ||
-                source == GL_PRIMARY_COLOR_EXT ||
-                source == GL_PREVIOUS_EXT ||
+                source == GL_CONSTANT ||
+                source == GL_PRIMARY_COLOR ||
+                source == GL_PREVIOUS ||
                 (ctx->Extensions.ARB_texture_env_crossbar &&
-                 source >= GL_TEXTURE0_ARB &&
-                 source < GL_TEXTURE0_ARB + ctx->Const.MaxTextureUnits)) {
+                 source >= GL_TEXTURE0 &&
+                 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
+		(ctx->Extensions.ATI_texture_env_combine3 &&
+                 (source == GL_ZERO || source == GL_ONE))) {
                /* legal */
 	       if (texUnit->CombineSourceA[s] == source)
                   return;
@@ -332,12 +358,12 @@
 	    return;
 	 }
 	 break;
-      case GL_OPERAND0_RGB_EXT:
-      case GL_OPERAND1_RGB_EXT:
+      case GL_OPERAND0_RGB:
+      case GL_OPERAND1_RGB:
 	 if (ctx->Extensions.EXT_texture_env_combine ||
 	     ctx->Extensions.ARB_texture_env_combine) {
 	    const GLenum operand = (GLenum) (GLint) *param;
-	    const GLuint s = pname - GL_OPERAND0_RGB_EXT;
+	    const GLuint s = pname - GL_OPERAND0_RGB;
 	    switch (operand) {
 	    case GL_SRC_COLOR:
 	    case GL_ONE_MINUS_SRC_COLOR:
@@ -358,19 +384,19 @@
 	    return;
 	 }
 	 break;
-      case GL_OPERAND0_ALPHA_EXT:
-      case GL_OPERAND1_ALPHA_EXT:
+      case GL_OPERAND0_ALPHA:
+      case GL_OPERAND1_ALPHA:
 	 if (ctx->Extensions.EXT_texture_env_combine ||
              ctx->Extensions.ARB_texture_env_combine) {
 	    const GLenum operand = (GLenum) (GLint) *param;
 	    switch (operand) {
 	    case GL_SRC_ALPHA:
 	    case GL_ONE_MINUS_SRC_ALPHA:
-	       if (texUnit->CombineOperandA[pname-GL_OPERAND0_ALPHA_EXT] ==
+	       if (texUnit->CombineOperandA[pname-GL_OPERAND0_ALPHA] ==
 		   operand)
 		  return;
 	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-	       texUnit->CombineOperandA[pname-GL_OPERAND0_ALPHA_EXT] = operand;
+	       texUnit->CombineOperandA[pname-GL_OPERAND0_ALPHA] = operand;
 	       break;
 	    default:
                TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
@@ -382,7 +408,7 @@
 	    return;
 	 }
 	 break;
-      case GL_OPERAND2_RGB_EXT:
+      case GL_OPERAND2_RGB:
 	 if (ctx->Extensions.EXT_texture_env_combine ||
              ctx->Extensions.ARB_texture_env_combine) {
 	    const GLenum operand = (GLenum) (GLint) *param;
@@ -405,7 +431,7 @@
 	    return;
 	 }
 	 break;
-      case GL_OPERAND2_ALPHA_EXT:
+      case GL_OPERAND2_ALPHA:
 	 if (ctx->Extensions.EXT_texture_env_combine ||
              ctx->Extensions.ARB_texture_env_combine) {
 	    const GLenum operand = (GLenum) (GLint) *param;
@@ -427,7 +453,7 @@
 	    return;
 	 }
 	 break;
-      case GL_RGB_SCALE_EXT:
+      case GL_RGB_SCALE:
 	 if (ctx->Extensions.EXT_texture_env_combine ||
              ctx->Extensions.ARB_texture_env_combine) {
 	    GLuint newshift;
@@ -604,7 +630,7 @@
          case GL_TEXTURE_ENV_COLOR:
             COPY_4FV( params, texUnit->EnvColor );
             break;
-         case GL_COMBINE_RGB_EXT:
+         case GL_COMBINE_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLfloat) texUnit->CombineModeRGB;
@@ -613,7 +639,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
             }
             break;
-         case GL_COMBINE_ALPHA_EXT:
+         case GL_COMBINE_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLfloat) texUnit->CombineModeA;
@@ -622,7 +648,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
             }
             break;
-         case GL_SOURCE0_RGB_EXT:
+         case GL_SOURCE0_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLfloat) texUnit->CombineSourceRGB[0];
@@ -631,7 +657,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
             }
             break;
-         case GL_SOURCE1_RGB_EXT:
+         case GL_SOURCE1_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLfloat) texUnit->CombineSourceRGB[1];
@@ -640,7 +666,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
             }
             break;
-         case GL_SOURCE2_RGB_EXT:
+         case GL_SOURCE2_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLfloat) texUnit->CombineSourceRGB[2];
@@ -649,7 +675,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
             }
             break;
-         case GL_SOURCE0_ALPHA_EXT:
+         case GL_SOURCE0_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLfloat) texUnit->CombineSourceA[0];
@@ -658,7 +684,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
             }
             break;
-         case GL_SOURCE1_ALPHA_EXT:
+         case GL_SOURCE1_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLfloat) texUnit->CombineSourceA[1];
@@ -667,7 +693,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
             }
             break;
-         case GL_SOURCE2_ALPHA_EXT:
+         case GL_SOURCE2_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLfloat) texUnit->CombineSourceA[2];
@@ -676,7 +702,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
             }
             break;
-         case GL_OPERAND0_RGB_EXT:
+         case GL_OPERAND0_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLfloat) texUnit->CombineOperandRGB[0];
@@ -685,7 +711,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
             }
             break;
-         case GL_OPERAND1_RGB_EXT:
+         case GL_OPERAND1_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLfloat) texUnit->CombineOperandRGB[1];
@@ -694,7 +720,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
             }
             break;
-         case GL_OPERAND2_RGB_EXT:
+         case GL_OPERAND2_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLfloat) texUnit->CombineOperandRGB[2];
@@ -703,7 +729,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
             }
             break;
-         case GL_OPERAND0_ALPHA_EXT:
+         case GL_OPERAND0_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLfloat) texUnit->CombineOperandA[0];
@@ -712,7 +738,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
             }
             break;
-         case GL_OPERAND1_ALPHA_EXT:
+         case GL_OPERAND1_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLfloat) texUnit->CombineOperandA[1];
@@ -721,7 +747,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
             }
             break;
-         case GL_OPERAND2_ALPHA_EXT:
+         case GL_OPERAND2_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLfloat) texUnit->CombineOperandA[2];
@@ -730,7 +756,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
             }
             break;
-         case GL_RGB_SCALE_EXT:
+         case GL_RGB_SCALE:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                if (texUnit->CombineScaleShiftRGB == 0)
@@ -817,7 +843,7 @@
             params[2] = FLOAT_TO_INT( texUnit->EnvColor[2] );
             params[3] = FLOAT_TO_INT( texUnit->EnvColor[3] );
             break;
-         case GL_COMBINE_RGB_EXT:
+         case GL_COMBINE_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLint) texUnit->CombineModeRGB;
@@ -826,7 +852,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
             }
             break;
-         case GL_COMBINE_ALPHA_EXT:
+         case GL_COMBINE_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLint) texUnit->CombineModeA;
@@ -835,7 +861,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
             }
             break;
-         case GL_SOURCE0_RGB_EXT:
+         case GL_SOURCE0_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLint) texUnit->CombineSourceRGB[0];
@@ -844,7 +870,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
             }
             break;
-         case GL_SOURCE1_RGB_EXT:
+         case GL_SOURCE1_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLint) texUnit->CombineSourceRGB[1];
@@ -853,7 +879,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
             }
             break;
-         case GL_SOURCE2_RGB_EXT:
+         case GL_SOURCE2_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLint) texUnit->CombineSourceRGB[2];
@@ -862,7 +888,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
             }
             break;
-         case GL_SOURCE0_ALPHA_EXT:
+         case GL_SOURCE0_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLint) texUnit->CombineSourceA[0];
@@ -871,7 +897,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
             }
             break;
-         case GL_SOURCE1_ALPHA_EXT:
+         case GL_SOURCE1_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLint) texUnit->CombineSourceA[1];
@@ -880,7 +906,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
             }
             break;
-         case GL_SOURCE2_ALPHA_EXT:
+         case GL_SOURCE2_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLint) texUnit->CombineSourceA[2];
@@ -889,7 +915,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
             }
             break;
-         case GL_OPERAND0_RGB_EXT:
+         case GL_OPERAND0_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLint) texUnit->CombineOperandRGB[0];
@@ -898,7 +924,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
             }
             break;
-         case GL_OPERAND1_RGB_EXT:
+         case GL_OPERAND1_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLint) texUnit->CombineOperandRGB[1];
@@ -907,7 +933,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
             }
             break;
-         case GL_OPERAND2_RGB_EXT:
+         case GL_OPERAND2_RGB:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLint) texUnit->CombineOperandRGB[2];
@@ -916,7 +942,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
             }
             break;
-         case GL_OPERAND0_ALPHA_EXT:
+         case GL_OPERAND0_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLint) texUnit->CombineOperandA[0];
@@ -925,7 +951,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
             }
             break;
-         case GL_OPERAND1_ALPHA_EXT:
+         case GL_OPERAND1_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLint) texUnit->CombineOperandA[1];
@@ -934,7 +960,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
             }
             break;
-         case GL_OPERAND2_ALPHA_EXT:
+         case GL_OPERAND2_ALPHA:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                *params = (GLint) texUnit->CombineOperandA[2];
@@ -943,7 +969,7 @@
                _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
             }
             break;
-         case GL_RGB_SCALE_EXT:
+         case GL_RGB_SCALE:
             if (ctx->Extensions.EXT_texture_env_combine ||
                 ctx->Extensions.ARB_texture_env_combine) {
                if (texUnit->CombineScaleShiftRGB == 0)
@@ -1049,10 +1075,10 @@
       case GL_TEXTURE_2D:
          texObj = texUnit->Current2D;
          break;
-      case GL_TEXTURE_3D_EXT:
+      case GL_TEXTURE_3D:
          texObj = texUnit->Current3D;
          break;
-      case GL_TEXTURE_CUBE_MAP_ARB:
+      case GL_TEXTURE_CUBE_MAP:
          if (!ctx->Extensions.ARB_texture_cube_map) {
             _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
             return;
@@ -1111,7 +1137,7 @@
          if (texObj->WrapS == eparam)
             return;
          if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE ||
-             (eparam == GL_CLAMP_TO_BORDER_ARB &&
+             (eparam == GL_CLAMP_TO_BORDER &&
               ctx->Extensions.ARB_texture_border_clamp)) {
             /* any texture target */
             FLUSH_VERTICES(ctx, _NEW_TEXTURE);
@@ -1119,7 +1145,7 @@
          }
          else if (texObj->Target != GL_TEXTURE_RECTANGLE_NV &&
                   (eparam == GL_REPEAT ||
-                   (eparam == GL_MIRRORED_REPEAT_ARB &&
+                   (eparam == GL_MIRRORED_REPEAT &&
                     ctx->Extensions.ARB_texture_mirrored_repeat) ||
                    (eparam == GL_MIRROR_CLAMP_ATI &&
                     ctx->Extensions.ATI_texture_mirror_once) ||
@@ -1138,7 +1164,7 @@
          if (texObj->WrapT == eparam)
             return;
          if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE ||
-             (eparam == GL_CLAMP_TO_BORDER_ARB &&
+             (eparam == GL_CLAMP_TO_BORDER &&
               ctx->Extensions.ARB_texture_border_clamp)) {
             /* any texture target */
             FLUSH_VERTICES(ctx, _NEW_TEXTURE);
@@ -1146,7 +1172,7 @@
          }
          else if (texObj->Target != GL_TEXTURE_RECTANGLE_NV &&
                   (eparam == GL_REPEAT ||
-                   (eparam == GL_MIRRORED_REPEAT_ARB &&
+                   (eparam == GL_MIRRORED_REPEAT &&
                     ctx->Extensions.ARB_texture_mirrored_repeat) ||
                    (eparam == GL_MIRROR_CLAMP_ATI &&
                     ctx->Extensions.ATI_texture_mirror_once) ||
@@ -1161,11 +1187,11 @@
             return;
          }
          break;
-      case GL_TEXTURE_WRAP_R_EXT:
+      case GL_TEXTURE_WRAP_R:
          if (texObj->WrapR == eparam)
             return;
          if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE ||
-             (eparam == GL_CLAMP_TO_BORDER_ARB &&
+             (eparam == GL_CLAMP_TO_BORDER &&
               ctx->Extensions.ARB_texture_border_clamp)) {
             /* any texture target */
             FLUSH_VERTICES(ctx, _NEW_TEXTURE);
@@ -1173,7 +1199,7 @@
          }
          else if (texObj->Target != GL_TEXTURE_RECTANGLE_NV &&
                   (eparam == GL_REPEAT ||
-                   (eparam == GL_MIRRORED_REPEAT_ARB &&
+                   (eparam == GL_MIRRORED_REPEAT &&
                     ctx->Extensions.ARB_texture_mirrored_repeat) ||
                    (eparam == GL_MIRROR_CLAMP_ATI &&
                     ctx->Extensions.ATI_texture_mirror_once) ||
@@ -1433,14 +1459,14 @@
       case GL_TEXTURE_3D:
       case GL_PROXY_TEXTURE_3D:
          return 3;
-      case GL_TEXTURE_CUBE_MAP_ARB:
-      case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
-      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
-      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+      case GL_TEXTURE_CUBE_MAP:
+      case GL_PROXY_TEXTURE_CUBE_MAP:
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
          return ctx->Extensions.ARB_texture_cube_map ? 2 : 0;
       case GL_TEXTURE_RECTANGLE_NV:
       case GL_PROXY_TEXTURE_RECTANGLE_NV:
@@ -1482,13 +1508,13 @@
    case GL_PROXY_TEXTURE_3D:
       maxLevels = ctx->Const.Max3DTextureLevels;
       break;
-   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
-   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
-   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
-   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
-   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
-   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
-   case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
+   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+   case GL_PROXY_TEXTURE_CUBE_MAP:
       maxLevels = ctx->Const.MaxCubeTextureLevels;
       break;
    case GL_TEXTURE_RECTANGLE_NV:
@@ -1518,7 +1544,7 @@
    isProxy = (target == GL_PROXY_TEXTURE_1D) ||
              (target == GL_PROXY_TEXTURE_2D) ||
              (target == GL_PROXY_TEXTURE_3D) ||
-             (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) ||
+             (target == GL_PROXY_TEXTURE_CUBE_MAP) ||
              (target == GL_PROXY_TEXTURE_RECTANGLE_NV);
 
    switch (pname) {
@@ -1597,7 +1623,7 @@
          return;
 
       /* GL_ARB_texture_compression */
-      case GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB:
+      case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
          if (ctx->Extensions.ARB_texture_compression) {
             if (img->IsCompressed && !isProxy)
                *params = img->CompressedSize;
@@ -1610,7 +1636,7 @@
                         "glGetTexLevelParameter[if]v(pname)");
          }
          return;
-      case GL_TEXTURE_COMPRESSED_ARB:
+      case GL_TEXTURE_COMPRESSED:
          if (ctx->Extensions.ARB_texture_compression) {
             *params = (GLint) img->IsCompressed;
          }
@@ -1655,7 +1681,7 @@
       case GL_TEXTURE_WRAP_T:
          *params = ENUM_TO_FLOAT(obj->WrapT);
          return;
-      case GL_TEXTURE_WRAP_R_EXT:
+      case GL_TEXTURE_WRAP_R:
          *params = ENUM_TO_FLOAT(obj->WrapR);
          return;
       case GL_TEXTURE_BORDER_COLOR:
@@ -1772,7 +1798,7 @@
       case GL_TEXTURE_WRAP_T:
          *params = (GLint) obj->WrapT;
          return;
-      case GL_TEXTURE_WRAP_R_EXT:
+      case GL_TEXTURE_WRAP_R:
          *params = (GLint) obj->WrapR;
          return;
       case GL_TEXTURE_BORDER_COLOR:
@@ -2420,7 +2446,7 @@
 _mesa_ActiveTextureARB( GLenum target )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLuint texUnit = target - GL_TEXTURE0_ARB;
+   GLuint texUnit = target - GL_TEXTURE0;
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
@@ -2429,7 +2455,7 @@
 
    /* Cater for texture unit 0 is first, therefore use >= */
    if (texUnit >= ctx->Const.MaxTextureUnits) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTextureARB(target)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(target)");
       return;
    }
 
@@ -2452,11 +2478,11 @@
 _mesa_ClientActiveTextureARB( GLenum target )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLuint texUnit = target - GL_TEXTURE0_ARB;
+   GLuint texUnit = target - GL_TEXTURE0;
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
    if (texUnit > ctx->Const.MaxTextureUnits) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTextureARB(target)");
+      _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(target)");
       return;
    }
 
diff --git a/src/mesa/swrast/s_texture.c b/src/mesa/swrast/s_texture.c
index 60091e3..cd86c76 100644
--- a/src/mesa/swrast/s_texture.c
+++ b/src/mesa/swrast/s_texture.c
@@ -1,4 +1,4 @@
-/* $Id: s_texture.c,v 1.75 2002/11/12 19:27:24 brianp Exp $ */
+/* $Id: s_texture.c,v 1.76 2003/01/21 15:49:19 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -49,7 +49,7 @@
 /*
  * Used to compute texel locations for linear sampling.
  * Input:
- *    wrapMode = GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER_ARB
+ *    wrapMode = GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER
  *    S = texcoord in [0,1]
  *    SIZE = width (or height or depth) of texture
  * Output:
@@ -78,7 +78,7 @@
       if (I1 >= (GLint) SIZE)						\
          I1 = SIZE - 1;							\
    }									\
-   else  if (wrapMode == GL_CLAMP_TO_BORDER_ARB) {			\
+   else  if (wrapMode == GL_CLAMP_TO_BORDER) {			\
       const GLfloat min = -1.0F / (2.0F * SIZE);			\
       const GLfloat max = 1.0F - min;					\
       if (S <= min)							\
@@ -91,7 +91,7 @@
       I0 = IFLOOR(U);							\
       I1 = I0 + 1;							\
    }									\
-   else if (wrapMode == GL_MIRRORED_REPEAT_ARB) {			\
+   else if (wrapMode == GL_MIRRORED_REPEAT) {			\
       const GLint flr = IFLOOR(S);					\
       if (flr & 1)							\
          U = 1.0F - (S - (GLfloat) flr);	/* flr is odd */	\
@@ -167,7 +167,7 @@
       else								\
          I = IFLOOR(S * SIZE);						\
    }									\
-   else if (wrapMode == GL_CLAMP_TO_BORDER_ARB) {			\
+   else if (wrapMode == GL_CLAMP_TO_BORDER) {			\
       /* s limited to [min,max] */					\
       /* i limited to [-1, size] */					\
       const GLfloat min = -1.0F / (2.0F * SIZE);			\
@@ -179,7 +179,7 @@
       else								\
          I = IFLOOR(S * SIZE);						\
    }									\
-   else if (wrapMode == GL_MIRRORED_REPEAT_ARB) {			\
+   else if (wrapMode == GL_MIRRORED_REPEAT) {			\
       const GLfloat min = 1.0F / (2.0F * SIZE);				\
       const GLfloat max = 1.0F - min;					\
       const GLint flr = IFLOOR(S);					\
@@ -465,7 +465,7 @@
    i += img->Border;
 
    if (i < 0 || i >= (GLint) img->Width) {
-      /* Need this test for GL_CLAMP_TO_BORDER_ARB mode */
+      /* Need this test for GL_CLAMP_TO_BORDER mode */
       COPY_CHAN4(rgba, tObj->_BorderChan);
    }
    else {
@@ -794,7 +794,7 @@
    j += img->Border;
 
    if (i < 0 || i >= (GLint) img->Width || j < 0 || j >= (GLint) img->Height) {
-      /* Need this test for GL_CLAMP_TO_BORDER_ARB mode */
+      /* Need this test for GL_CLAMP_TO_BORDER mode */
       COPY_CHAN4(rgba, tObj->_BorderChan);
    }
    else {
@@ -1382,7 +1382,7 @@
    if (i < 0 || i >= (GLint) img->Width ||
        j < 0 || j >= (GLint) img->Height ||
        k < 0 || k >= (GLint) img->Depth) {
-      /* Need this test for GL_CLAMP_TO_BORDER_ARB mode */
+      /* Need this test for GL_CLAMP_TO_BORDER mode */
       COPY_CHAN4(rgba, tObj->_BorderChan);
    }
    else {
@@ -2089,10 +2089,10 @@
 
    ASSERT(tObj->WrapS == GL_CLAMP ||
           tObj->WrapS == GL_CLAMP_TO_EDGE ||
-          tObj->WrapS == GL_CLAMP_TO_BORDER_ARB);
+          tObj->WrapS == GL_CLAMP_TO_BORDER);
    ASSERT(tObj->WrapT == GL_CLAMP ||
           tObj->WrapT == GL_CLAMP_TO_EDGE ||
-          tObj->WrapT == GL_CLAMP_TO_BORDER_ARB);
+          tObj->WrapT == GL_CLAMP_TO_BORDER);
    ASSERT(img->Format != GL_COLOR_INDEX);
 
    /* XXX move Wrap mode tests outside of loops for common cases */
@@ -2144,10 +2144,10 @@
 
    ASSERT(tObj->WrapS == GL_CLAMP ||
           tObj->WrapS == GL_CLAMP_TO_EDGE ||
-          tObj->WrapS == GL_CLAMP_TO_BORDER_ARB);
+          tObj->WrapS == GL_CLAMP_TO_BORDER);
    ASSERT(tObj->WrapT == GL_CLAMP ||
           tObj->WrapT == GL_CLAMP_TO_EDGE ||
-          tObj->WrapT == GL_CLAMP_TO_BORDER_ARB);
+          tObj->WrapT == GL_CLAMP_TO_BORDER);
    ASSERT(img->Format != GL_COLOR_INDEX);
 
    /* XXX lots of opportunity for optimization in this loop */
@@ -2736,7 +2736,7 @@
                swrast->TextureSample[texUnit] = sample_nearest_3d;
             }
             break;
-         case GL_TEXTURE_CUBE_MAP_ARB:
+         case GL_TEXTURE_CUBE_MAP:
             if (needLambda) {
                swrast->TextureSample[texUnit] = sample_lambda_cube;
             }
@@ -2773,14 +2773,16 @@
 
 /**
  * Do texture application for GL_ARB/EXT_texture_env_combine.
- * Input:
- *     ctx - rendering context
- *     textureUnit - the texture unit to apply
- *     n - number of fragments to process (span width)
- *     primary_rgba - incoming fragment color array
- *     texelBuffer - pointer to texel colors for all texture units
- * Input/Output:
- *     rgba - incoming colors, which get modified here
+ * This function also supports GL_{EXT,ARB}_texture_env_dot3 and
+ * GL_ATI_texture_env_combine3
+ *
+ * \param ctx          rendering context
+ * \param textureUnit  the texture unit to apply
+ * \param n            number of fragments to process (span width)
+ * \param primary_rgba incoming fragment color array
+ * \param texelBuffer  pointer to texel colors for all texture units
+ * 
+ * \param rgba         incoming colors, which get modified here
  */
 static INLINE void
 texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
@@ -2796,10 +2798,16 @@
 #if CHAN_TYPE == GL_FLOAT
    const GLchan RGBmult = (GLfloat) (1 << RGBshift);
    const GLchan Amult = (GLfloat) (1 << Ashift);
+   static const GLchan one[4] = { 1.0, 1.0, 1.0, 1.0 };
+   static const GLchan zero[4] = { 0.0, 0.0, 0.0, 0.0 };
 #else
    const GLint half = (CHAN_MAX + 1) / 2;
+   static const GLchan one[4] = { CHAN_MAX, CHAN_MAX, CHAN_MAX, CHAN_MAX };
+   static const GLchan zero[4] = { 0, 0, 0, 0 };
 #endif
    GLuint i, j;
+   GLuint numColorArgs;
+   GLuint numAlphaArgs;
 
    /* GLchan ccolor[3][4]; */
    DEFMNARRAY(GLchan, ccolor, 3, 3 * MAX_WIDTH, 4);  /* mac 32k limitation */
@@ -2823,54 +2831,70 @@
    /*
     * Do operand setup for up to 3 operands.  Loop over the terms.
     */
-   for (j = 0; j < 3; j++) {
-      const GLenum srcA = textureUnit->CombineSourceA[j];
+   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;
+   }
+
+   for (j = 0; j < numColorArgs; j++) {
       const GLenum srcRGB = textureUnit->CombineSourceRGB[j];
 
-      switch (srcA) {
-         case GL_TEXTURE:
-            argA[j] = (const GLchan (*)[4])
-               (texelBuffer + unit * (n * 4 * sizeof(GLchan)));
-            break;
-         case GL_PRIMARY_COLOR_EXT:
-            argA[j] = primary_rgba;
-            break;
-         case GL_PREVIOUS_EXT:
-            argA[j] = (const GLchan (*)[4]) rgba;
-            break;
-         case GL_CONSTANT_EXT:
-            {
-               GLchan alpha, (*c)[4] = ccolor[j];
-               UNCLAMPED_FLOAT_TO_CHAN(alpha, textureUnit->EnvColor[3]);
-               for (i = 0; i < n; i++)
-                  c[i][ACOMP] = alpha;
-               argA[j] = (const GLchan (*)[4]) ccolor[j];
-            }
-            break;
-         default:
-            /* ARB_texture_env_crossbar source */
-            {
-               const GLuint srcUnit = srcA - GL_TEXTURE0_ARB;
-               ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
-               if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
-                  return;
-               argA[j] = (const GLchan (*)[4])
-                  (texelBuffer + srcUnit * (n * 4 * sizeof(GLchan)));
-            }
-      }
 
       switch (srcRGB) {
          case GL_TEXTURE:
             argRGB[j] = (const GLchan (*)[4])
                (texelBuffer + unit * (n * 4 * sizeof(GLchan)));
             break;
-         case GL_PRIMARY_COLOR_EXT:
+         case GL_PRIMARY_COLOR:
             argRGB[j] = primary_rgba;
             break;
-         case GL_PREVIOUS_EXT:
+         case GL_PREVIOUS:
             argRGB[j] = (const GLchan (*)[4]) rgba;
             break;
-         case GL_CONSTANT_EXT:
+         case GL_CONSTANT:
             {
                GLchan (*c)[4] = ccolor[j];
                GLchan red, green, blue, alpha;
@@ -2887,10 +2911,18 @@
                argRGB[j] = (const GLchan (*)[4]) ccolor[j];
             }
             break;
+	 /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources.
+	  */
+	 case GL_ZERO:
+            argRGB[j] = & zero;
+            break;
+	 case GL_ONE:
+            argRGB[j] = & one;
+            break;
          default:
             /* ARB_texture_env_crossbar source */
             {
-               const GLuint srcUnit = srcRGB - GL_TEXTURE0_ARB;
+               const GLuint srcUnit = srcRGB - GL_TEXTURE0;
                ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
                if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
                   return;
@@ -2929,6 +2961,51 @@
             }
          }
       }
+   }
+
+
+   for (j = 0; j < numAlphaArgs; j++) {
+      const GLenum srcA = textureUnit->CombineSourceA[j];
+
+      switch (srcA) {
+         case GL_TEXTURE:
+            argA[j] = (const GLchan (*)[4])
+               (texelBuffer + unit * (n * 4 * sizeof(GLchan)));
+            break;
+         case GL_PRIMARY_COLOR:
+            argA[j] = primary_rgba;
+            break;
+         case GL_PREVIOUS:
+            argA[j] = (const GLchan (*)[4]) rgba;
+            break;
+         case GL_CONSTANT:
+            {
+               GLchan alpha, (*c)[4] = ccolor[j];
+               UNCLAMPED_FLOAT_TO_CHAN(alpha, textureUnit->EnvColor[3]);
+               for (i = 0; i < n; i++)
+                  c[i][ACOMP] = alpha;
+               argA[j] = (const GLchan (*)[4]) ccolor[j];
+            }
+            break;
+	 /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources.
+	  */
+	 case GL_ZERO:
+            argA[j] = & zero;
+            break;
+	 case GL_ONE:
+            argA[j] = & one;
+            break;
+         default:
+            /* ARB_texture_env_crossbar source */
+            {
+               const GLuint srcUnit = srcA - GL_TEXTURE0;
+               ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
+               if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
+                  return;
+               argA[j] = (const GLchan (*)[4])
+                  (texelBuffer + srcUnit * (n * 4 * sizeof(GLchan)));
+            }
+      }
 
       if (textureUnit->CombineOperandA[j] == GL_ONE_MINUS_SRC_ALPHA) {
          const GLchan (*src)[4] = argA[j];
@@ -2938,17 +3015,6 @@
             dst[i][ACOMP] = CHAN_MAX - src[i][ACOMP];
          }
       }
-
-      if (textureUnit->CombineModeRGB == GL_REPLACE &&
-          textureUnit->CombineModeA == GL_REPLACE) {
-         break;      /*  done, we need only arg0  */
-      }
-
-      if (j == 1 &&
-          textureUnit->CombineModeRGB != GL_INTERPOLATE_EXT &&
-          textureUnit->CombineModeA != GL_INTERPOLATE_EXT) {
-         break;      /*  arg0 and arg1 are done. we don't need arg2. */
-      }
    }
 
    /*
@@ -3026,7 +3092,7 @@
             }
          }
          break;
-      case GL_ADD_SIGNED_EXT:
+      case GL_ADD_SIGNED:
          {
             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
@@ -3049,7 +3115,7 @@
             }
          }
          break;
-      case GL_INTERPOLATE_EXT:
+      case GL_INTERPOLATE:
          {
             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
@@ -3082,7 +3148,7 @@
             }
          }
          break;
-      case GL_SUBTRACT_ARB:
+      case GL_SUBTRACT:
          {
             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
@@ -3128,8 +3194,8 @@
             }
          }
          break;
-      case GL_DOT3_RGB_ARB:
-      case GL_DOT3_RGBA_ARB:
+      case GL_DOT3_RGB:
+      case GL_DOT3_RGBA:
          {
             /* DO scale the result by 1 2 or 4 */
             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
@@ -3155,6 +3221,93 @@
             }
          }
          break;
+      case GL_MODULATE_ADD_ATI:
+         {
+            const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
+            const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
+            const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2];
+#if CHAN_TYPE != GL_FLOAT
+            const GLint shift = CHAN_BITS - RGBshift;
+#endif
+            for (i = 0; i < n; i++) {
+#if CHAN_TYPE == GL_FLOAT
+               rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + arg1[i][RCOMP]) * RGBmult;
+               rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + arg1[i][GCOMP]) * RGBmult;
+               rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + arg1[i][BCOMP]) * RGBmult;
+#else
+               GLuint r = (PROD(arg0[i][RCOMP], arg2[i][RCOMP])
+                           + ((GLuint) arg1[i][RCOMP] << CHAN_BITS)) >> shift;
+               GLuint g = (PROD(arg0[i][GCOMP], arg2[i][GCOMP])
+                           + ((GLuint) arg1[i][GCOMP] << CHAN_BITS)) >> shift;
+               GLuint b = (PROD(arg0[i][BCOMP], arg2[i][BCOMP])
+                           + ((GLuint) arg1[i][BCOMP] << CHAN_BITS)) >> shift;
+               rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
+               rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
+               rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
+#endif
+            }
+	 }
+         break;
+      case GL_MODULATE_SIGNED_ADD_ATI:
+         {
+            const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
+            const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
+            const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2];
+#if CHAN_TYPE != GL_FLOAT
+            const GLint shift = CHAN_BITS - RGBshift;
+#endif
+            for (i = 0; i < n; i++) {
+#if CHAN_TYPE == GL_FLOAT
+               rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + arg1[i][RCOMP] - 0.5) * RGBmult;
+               rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + arg1[i][GCOMP] - 0.5) * RGBmult;
+               rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + arg1[i][BCOMP] - 0.5) * RGBmult;
+#else
+               GLint r = (S_PROD(arg0[i][RCOMP], arg2[i][RCOMP])
+			  + (((GLint) arg1[i][RCOMP] - half) << CHAN_BITS))
+		    >> shift;
+               GLint g = (S_PROD(arg0[i][GCOMP], arg2[i][GCOMP])
+			  + (((GLint) arg1[i][GCOMP] - half) << CHAN_BITS))
+		    >> shift;
+               GLint b = (S_PROD(arg0[i][BCOMP], arg2[i][BCOMP])
+			  + (((GLint) arg1[i][BCOMP] - half) << CHAN_BITS))
+		    >> shift;
+               rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX);
+               rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX);
+               rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX);
+#endif
+            }
+	 }
+         break;
+      case GL_MODULATE_SUBTRACT_ATI:
+         {
+            const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
+            const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
+            const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2];
+#if CHAN_TYPE != GL_FLOAT
+            const GLint shift = CHAN_BITS - RGBshift;
+#endif
+            for (i = 0; i < n; i++) {
+#if CHAN_TYPE == GL_FLOAT
+               rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) - arg1[i][RCOMP]) * RGBmult;
+               rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) - arg1[i][GCOMP]) * RGBmult;
+               rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) - arg1[i][BCOMP]) * RGBmult;
+#else
+               GLint r = (S_PROD(arg0[i][RCOMP], arg2[i][RCOMP])
+			  - ((GLint) arg1[i][RCOMP] << CHAN_BITS))
+		    >> shift;
+               GLint g = (S_PROD(arg0[i][GCOMP], arg2[i][GCOMP])
+			  - ((GLint) arg1[i][GCOMP] << CHAN_BITS))
+		    >> shift;
+               GLint b = (S_PROD(arg0[i][BCOMP], arg2[i][BCOMP])
+			  - ((GLint) arg1[i][BCOMP] << CHAN_BITS))
+		    >> shift;
+               rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX);
+               rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX);
+               rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX);
+#endif
+            }
+	 }
+         break;
       default:
          _mesa_problem(ctx, "invalid combine mode");
    }
@@ -3211,7 +3364,7 @@
             }
          }
          break;
-      case GL_ADD_SIGNED_EXT:
+      case GL_ADD_SIGNED:
          {
             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
@@ -3226,7 +3379,7 @@
             }
          }
          break;
-      case GL_INTERPOLATE_EXT:
+      case GL_INTERPOLATE:
          {
             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
@@ -3248,7 +3401,7 @@
             }
          }
          break;
-      case GL_SUBTRACT_ARB:
+      case GL_SUBTRACT:
          {
             const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
             const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
@@ -3262,7 +3415,66 @@
             }
          }
          break;
-
+      case GL_MODULATE_ADD_ATI:
+         {
+            const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
+            const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
+            const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2];
+#if CHAN_TYPE != GL_FLOAT
+            const GLint shift = CHAN_BITS - Ashift;
+#endif
+            for (i = 0; i < n; i++) {
+#if CHAN_TYPE == GL_FLOAT
+               rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + arg1[i][ACOMP]) * Amult;
+#else
+               GLuint a = (PROD(arg0[i][ACOMP], arg2[i][ACOMP])
+			   + ((GLuint) arg1[i][ACOMP] << CHAN_BITS))
+		    >> shift;
+               rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
+#endif
+            }
+         }
+         break;
+      case GL_MODULATE_SIGNED_ADD_ATI:
+         {
+            const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
+            const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
+            const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2];
+#if CHAN_TYPE != GL_FLOAT
+            const GLint shift = CHAN_BITS - Ashift;
+#endif
+            for (i = 0; i < n; i++) {
+#if CHAN_TYPE == GL_FLOAT
+               rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + arg1[i][ACOMP] - 0.5F) * Amult;
+#else
+               GLint a = (S_PROD(arg0[i][ACOMP], arg2[i][ACOMP])
+			  + (((GLint) arg1[i][ACOMP] - half) << CHAN_BITS))
+		    >> shift;
+               rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
+#endif
+            }
+         }
+         break;
+      case GL_MODULATE_SUBTRACT_ATI:
+         {
+            const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
+            const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
+            const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2];
+#if CHAN_TYPE != GL_FLOAT
+            const GLint shift = CHAN_BITS - Ashift;
+#endif
+            for (i = 0; i < n; i++) {
+#if CHAN_TYPE == GL_FLOAT
+               rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) - arg1[i][ACOMP]) * Amult;
+#else
+               GLint a = (S_PROD(arg0[i][ACOMP], arg2[i][ACOMP]) 
+			  - ((GLint) arg1[i][ACOMP] << CHAN_BITS))
+		    >> shift;
+               rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
+#endif
+            }
+         }
+         break;
       default:
          _mesa_problem(ctx, "invalid combine mode");
    }
@@ -3273,7 +3485,7 @@
     * GL_DOT3.
     */
    if (textureUnit->CombineModeRGB == GL_DOT3_RGBA_EXT ||
-       textureUnit->CombineModeRGB == GL_DOT3_RGBA_ARB) {
+       textureUnit->CombineModeRGB == GL_DOT3_RGBA) {
       for (i = 0; i < n; i++) {
 	 rgba[i][ACOMP] = rgba[i][RCOMP];
       }
@@ -3715,7 +3927,7 @@
    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_EXT) {
+         if (texUnit->EnvMode == GL_COMBINE) {
             /* GL_ARB/EXT_texture_env_combine */
             texture_combine( ctx, unit, span->end,
                              (CONST GLchan (*)[4]) primary_rgba,