added a few more fallbackStrings (Andreas Stenglein)
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_texstate.c
index 6dccd311800ba303969e9139bd327f9feac20598..43fe509fb4e90d568c1d32d38a85c768950fdca3 100644 (file)
@@ -50,19 +50,29 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "radeon_tcl.h"
 
 
+#define RADEON_TXFORMAT_A8        RADEON_TXFORMAT_I8
+#define RADEON_TXFORMAT_L8        RADEON_TXFORMAT_I8
 #define RADEON_TXFORMAT_AL88      RADEON_TXFORMAT_AI88
 #define RADEON_TXFORMAT_YCBCR     RADEON_TXFORMAT_YVYU422
 #define RADEON_TXFORMAT_YCBCR_REV RADEON_TXFORMAT_VYUY422
+#define RADEON_TXFORMAT_RGB_DXT1  RADEON_TXFORMAT_DXT1
+#define RADEON_TXFORMAT_RGBA_DXT1 RADEON_TXFORMAT_DXT1
+#define RADEON_TXFORMAT_RGBA_DXT3 RADEON_TXFORMAT_DXT23
+#define RADEON_TXFORMAT_RGBA_DXT5 RADEON_TXFORMAT_DXT45
 
 #define _COLOR(f) \
     [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, 0 }
+#define _COLOR_REV(f) \
+    [ MESA_FORMAT_ ## f ## _REV ] = { RADEON_TXFORMAT_ ## f, 0 }
 #define _ALPHA(f) \
     [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 }
+#define _ALPHA_REV(f) \
+    [ MESA_FORMAT_ ## f ## _REV ] = { RADEON_TXFORMAT_ ## f | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 }
 #define _YUV(f) \
    [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, RADEON_YUV_TO_RGB }
 #define _INVALID(f) \
     [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
-#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_YCBCR_REV) \
+#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \
                             && (tx_table[f].format != 0xffffffff) )
 
 static const struct {
@@ -71,18 +81,30 @@ static const struct {
 tx_table[] =
 {
    _ALPHA(RGBA8888),
+   _ALPHA_REV(RGBA8888),
    _ALPHA(ARGB8888),
+   _ALPHA_REV(ARGB8888),
    _INVALID(RGB888),
    _COLOR(RGB565),
+   _COLOR_REV(RGB565),
    _ALPHA(ARGB4444),
+   _ALPHA_REV(ARGB4444),
    _ALPHA(ARGB1555),
+   _ALPHA_REV(ARGB1555),
    _ALPHA(AL88),
-   _INVALID(A8),
-   _INVALID(L8),
-   _COLOR(I8),
+   _ALPHA_REV(AL88),
+   _ALPHA(A8),
+   _COLOR(L8),
+   _ALPHA(I8),
    _INVALID(CI8),
    _YUV(YCBCR),
    _YUV(YCBCR_REV),
+   _INVALID(RGB_FXT1),
+   _INVALID(RGBA_FXT1),
+   _COLOR(RGB_DXT1),
+   _ALPHA(RGBA_DXT1),
+   _ALPHA(RGBA_DXT3),
+   _ALPHA(RGBA_DXT5),
 };
 
 #undef _COLOR
@@ -104,10 +126,10 @@ static void radeonSetTexImages( radeonContextPtr rmesa,
                                struct gl_texture_object *tObj )
 {
    radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData;
-   const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel];
-   GLint curOffset;
-   GLint i;
-   GLint firstLevel=0, lastLevel=0, numLevels;
+   const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
+   GLint curOffset, blitWidth;
+   GLint i, texelBytes;
+   GLint numLevels;
    GLint log2Width, log2Height, log2Depth;
 
    /* Set the hardware texture format
@@ -126,41 +148,17 @@ static void radeonSetTexImages( radeonContextPtr rmesa,
       return;
    }
 
-
+   texelBytes = baseImage->TexFormat->TexelBytes;
 
    /* Compute which mipmap levels we really want to send to the hardware.
-    * This depends on the base image size, GL_TEXTURE_MIN_LOD,
-    * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
-    * Yes, this looks overly complicated, but it's all needed.
     */
-   switch (tObj->Target) {
-   case GL_TEXTURE_1D:
-   case GL_TEXTURE_2D:
-      firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5);
-      firstLevel = MAX2(firstLevel, tObj->BaseLevel);
-      lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5);
-      lastLevel = MAX2(lastLevel, tObj->BaseLevel);
-      lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
-      lastLevel = MIN2(lastLevel, tObj->MaxLevel);
-      lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
-      log2Width = tObj->Image[firstLevel]->WidthLog2;
-      log2Height = tObj->Image[firstLevel]->HeightLog2;
-      log2Depth = 0;
-      break;
-   case GL_TEXTURE_RECTANGLE_NV:
-      firstLevel = lastLevel = 0;
-      log2Width = log2Height = 1; /* ? */
-      log2Depth = 0;
-      break;
-   default:
-      return;
-   }
 
-   /* save these values */
-   t->base.firstLevel = firstLevel;
-   t->base.lastLevel = lastLevel;
+   driCalculateTextureFirstLastLevel( (driTextureObject *) t );
+   log2Width  = tObj->Image[0][t->base.firstLevel]->WidthLog2;
+   log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
+   log2Depth  = tObj->Image[0][t->base.firstLevel]->DepthLog2;
 
-   numLevels = lastLevel - firstLevel + 1;
+   numLevels = t->base.lastLevel - t->base.firstLevel + 1;
 
    assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS);
 
@@ -169,40 +167,100 @@ static void radeonSetTexImages( radeonContextPtr rmesa,
     * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
     */
    curOffset = 0;
+   blitWidth = BLIT_WIDTH_BYTES;
+   t->tile_bits = 0;
+
+   /* figure out if this texture is suitable for tiling. */
+   if (texelBytes && (tObj->Target != GL_TEXTURE_RECTANGLE_NV)) {
+      if (rmesa->texmicrotile && (baseImage->Height > 1)) {
+        /* allow 32 (bytes) x 1 mip (which will use two times the space
+           the non-tiled version would use) max if base texture is large enough */
+        if ((numLevels == 1) ||
+          (((baseImage->Width * texelBytes / baseImage->Height) <= 32) &&
+              (baseImage->Width * texelBytes > 64)) ||
+           ((baseImage->Width * texelBytes / baseImage->Height) <= 16)) {
+           /* R100 has two microtile bits (only the txoffset reg, not the blitter)
+              weird: X2 + OPT: 32bit correct, 16bit completely hosed
+                     X2: 32bit correct, 16bit correct
+                     OPT: 32bit large mips correct, small mips hosed, 16bit completely hosed */
+           t->tile_bits |= RADEON_TXO_MICRO_TILE_X2 /*| RADEON_TXO_MICRO_TILE_OPT*/;
+        }
+      }
+      if ((baseImage->Width * texelBytes >= 256) && (baseImage->Height >= 16)) {
+        /* R100 disables macro tiling only if mip width is smaller than 256 bytes, and not
+           in the case if height is smaller than 16 (not 100% sure), as does the r200,
+           so need to disable macro tiling in that case */
+        if ((numLevels == 1) || ((baseImage->Width * texelBytes / baseImage->Height) <= 4)) {
+           t->tile_bits |= RADEON_TXO_MACRO_TILE;
+        }
+      }
+   }
 
    for (i = 0; i < numLevels; i++) {
       const struct gl_texture_image *texImage;
       GLuint size;
 
-      texImage = tObj->Image[i + firstLevel];
+      texImage = tObj->Image[0][i + t->base.firstLevel];
       if ( !texImage )
         break;
 
       /* find image size in bytes */
       if (texImage->IsCompressed) {
-         size = texImage->CompressedSize;
+      /* need to calculate the size AFTER padding even though the texture is
+         submitted without padding.
+         Only handle pot textures currently - don't know if npot is even possible,
+         size calculation would certainly need (trivial) adjustments.
+         Align (and later pad) to 32byte, not sure what that 64byte blit width is
+         good for? */
+         if ((t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK) == RADEON_TXFORMAT_DXT1) {
+            /* RGB_DXT1/RGBA_DXT1, 8 bytes per block */
+            if ((texImage->Width + 3) < 8) /* width one block */
+               size = texImage->CompressedSize * 4;
+            else if ((texImage->Width + 3) < 16)
+               size = texImage->CompressedSize * 2;
+            else size = texImage->CompressedSize;
+         }
+         else /* DXT3/5, 16 bytes per block */
+            if ((texImage->Width + 3) < 8)
+               size = texImage->CompressedSize * 2;
+            else size = texImage->CompressedSize;
       }
       else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
-        size = ((texImage->Width * texImage->TexFormat->TexelBytes + 63)
-                & ~63) * texImage->Height;
+        size = ((texImage->Width * texelBytes + 63) & ~63) * texImage->Height;
+      }
+      else if (t->tile_bits & RADEON_TXO_MICRO_TILE_X2) {
+        /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
+           though the actual offset may be different (if texture is less than
+           32 bytes width) to the untiled case */
+        int w = (texImage->Width * texelBytes * 2 + 31) & ~31;
+        size = (w * ((texImage->Height + 1) / 2)) * texImage->Depth;
+        blitWidth = MAX2(texImage->Width, 64 / texelBytes);
       }
       else {
-         int w = texImage->Width * texImage->TexFormat->TexelBytes;
-         if (w < 32)
-            w = 32;
-         size = w * texImage->Height * texImage->Depth;
+        int w = (texImage->Width * texelBytes + 31) & ~31;
+        size = w * texImage->Height * texImage->Depth;
+        blitWidth = MAX2(texImage->Width, 64 / texelBytes);
       }
       assert(size > 0);
 
-      if (curOffset & 0x1f) {
-         /* align to 32-byte offset */
-         curOffset = (curOffset + 0x1f) & ~0x1f;
-      }
+      /* Align to 32-byte offset.  It is faster to do this unconditionally
+       * (no branch penalty).
+       */
+
+      curOffset = (curOffset + 0x1f) & ~0x1f;
 
-      t->image[0][i].x = curOffset % BLIT_WIDTH_BYTES;
-      t->image[0][i].y = curOffset / BLIT_WIDTH_BYTES;
-      t->image[0][i].width  = MIN2(size, BLIT_WIDTH_BYTES);
-      t->image[0][i].height = size / t->image[0][i].width;
+      if (texelBytes) {
+        t->image[0][i].x = curOffset; /* fix x and y coords up later together with offset */
+        t->image[0][i].y = 0;
+        t->image[0][i].width = MIN2(size / texelBytes, blitWidth);
+        t->image[0][i].height = (size / texelBytes) / t->image[0][i].width;
+      }
+      else {
+         t->image[0][i].x = curOffset % BLIT_WIDTH_BYTES;
+         t->image[0][i].y = curOffset / BLIT_WIDTH_BYTES;
+         t->image[0][i].width  = MIN2(size, BLIT_WIDTH_BYTES);
+         t->image[0][i].height = size / t->image[0][i].width;     
+      }
 
 #if 0
       /* for debugging only and only  applicable to non-rectangle targets */
@@ -237,17 +295,17 @@ static void radeonSetTexImages( radeonContextPtr rmesa,
    t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) |
                      (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT));
 
-   t->pp_txsize = (((tObj->Image[firstLevel]->Width - 1) << 0) |
-                   ((tObj->Image[firstLevel]->Height - 1) << 16));
+   t->pp_txsize = (((tObj->Image[0][t->base.firstLevel]->Width - 1) << 0) |
+                   ((tObj->Image[0][t->base.firstLevel]->Height - 1) << 16));
 
    /* Only need to round to nearest 32 for textures, but the blitter
     * requires 64-byte aligned pitches, and we may/may not need the
     * blitter.   NPOT only!
     */
    if (baseImage->IsCompressed)
-      t->pp_txpitch = (tObj->Image[firstLevel]->Width + 63) & ~(63);
+      t->pp_txpitch = (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63);
    else
-      t->pp_txpitch = ((tObj->Image[firstLevel]->Width * baseImage->TexFormat->TexelBytes) + 63) & ~(63);
+      t->pp_txpitch = ((tObj->Image[0][t->base.firstLevel]->Width * texelBytes) + 63) & ~(63);
    t->pp_txpitch -= 32;
 
    t->dirty_state = TEX_ALL;
@@ -261,375 +319,6 @@ static void radeonSetTexImages( radeonContextPtr rmesa,
  * Texture combine functions
  */
 
-#define RADEON_DISABLE         0
-#define RADEON_REPLACE         1
-#define RADEON_MODULATE                2
-#define RADEON_DECAL           3
-#define RADEON_BLEND           4
-#define RADEON_ADD             5
-#define RADEON_MAX_COMBFUNC    6
-
-static GLuint radeon_color_combine[][RADEON_MAX_COMBFUNC] =
-{
-   /* Unit 0:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (RADEON_COLOR_ARG_A_ZERO |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_CURRENT_COLOR |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_REPLACE = 0x00802800
-       */
-      (RADEON_COLOR_ARG_A_ZERO |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_T0_COLOR |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_MODULATE = 0x00800142
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_T0_COLOR |
-       RADEON_COLOR_ARG_C_ZERO |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_DECAL = 0x008c2d42
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_T0_COLOR |
-       RADEON_COLOR_ARG_C_T0_ALPHA |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_BLEND = 0x008c2902
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_TFACTOR_COLOR |
-       RADEON_COLOR_ARG_C_T0_COLOR |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_ADD = 0x00812802
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_T0_COLOR |
-       RADEON_COMP_ARG_B |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-   },
-
-   /* Unit 1:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (RADEON_COLOR_ARG_A_ZERO |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_CURRENT_COLOR |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_REPLACE = 0x00803000
-       */
-      (RADEON_COLOR_ARG_A_ZERO |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_T1_COLOR |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_MODULATE = 0x00800182
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_T1_COLOR |
-       RADEON_COLOR_ARG_C_ZERO |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_DECAL = 0x008c3582
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_T1_COLOR |
-       RADEON_COLOR_ARG_C_T1_ALPHA |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_BLEND = 0x008c3102
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_TFACTOR_COLOR |
-       RADEON_COLOR_ARG_C_T1_COLOR |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_ADD = 0x00813002
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_T1_COLOR |
-       RADEON_COMP_ARG_B |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-   },
-
-   /* Unit 2:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (RADEON_COLOR_ARG_A_ZERO |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_CURRENT_COLOR |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_REPLACE = 0x00803800
-       */
-      (RADEON_COLOR_ARG_A_ZERO |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_T2_COLOR |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_MODULATE = 0x008001c2
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_T2_COLOR |
-       RADEON_COLOR_ARG_C_ZERO |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_DECAL = 0x008c3dc2
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_T2_COLOR |
-       RADEON_COLOR_ARG_C_T2_ALPHA |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_BLEND = 0x008c3902
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_TFACTOR_COLOR |
-       RADEON_COLOR_ARG_C_T2_COLOR |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_ADD = 0x00813802
-       */
-      (RADEON_COLOR_ARG_A_CURRENT_COLOR |
-       RADEON_COLOR_ARG_B_ZERO |
-       RADEON_COLOR_ARG_C_T2_COLOR |
-       RADEON_COMP_ARG_B |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-   }
-};
-
-static GLuint radeon_alpha_combine[][RADEON_MAX_COMBFUNC] =
-{
-   /* Unit 0:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_REPLACE = 0x00800500
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_T0_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_MODULATE = 0x00800051
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_T0_ALPHA |
-       RADEON_ALPHA_ARG_C_ZERO |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_DECAL = 0x00800100
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_BLEND = 0x00800051
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
-       RADEON_ALPHA_ARG_C_T0_ALPHA |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_ADD = 0x00800051
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_T0_ALPHA |
-       RADEON_COMP_ARG_B |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-   },
-
-   /* Unit 1:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_REPLACE = 0x00800600
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_T1_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_MODULATE = 0x00800061
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_T1_ALPHA |
-       RADEON_ALPHA_ARG_C_ZERO |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_DECAL = 0x00800100
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_BLEND = 0x00800061
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
-       RADEON_ALPHA_ARG_C_T1_ALPHA |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_ADD = 0x00800061
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_T1_ALPHA |
-       RADEON_COMP_ARG_B |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-   },
-
-   /* Unit 2:
-    */
-   {
-      /* Disable combiner stage
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_REPLACE = 0x00800700
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_T2_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_MODULATE = 0x00800071
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_T2_ALPHA |
-       RADEON_ALPHA_ARG_C_ZERO |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_DECAL = 0x00800100
-       */
-      (RADEON_ALPHA_ARG_A_ZERO |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_BLEND = 0x00800071
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
-       RADEON_ALPHA_ARG_C_T2_ALPHA |
-       RADEON_BLEND_CTL_BLEND |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-
-      /* GL_ADD = 0x00800021
-       */
-      (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
-       RADEON_ALPHA_ARG_B_ZERO |
-       RADEON_ALPHA_ARG_C_T2_ALPHA |
-       RADEON_COMP_ARG_B |
-       RADEON_BLEND_CTL_ADD |
-       RADEON_SCALE_1X |
-       RADEON_CLAMP_TX),
-   }
-};
-
-
 /* GL_ARB_texture_env_combine support
  */
 
@@ -775,6 +464,13 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
    radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
    GLuint color_combine, alpha_combine;
+   const GLuint color_combine0 = RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO
+         | RADEON_COLOR_ARG_C_CURRENT_COLOR | RADEON_BLEND_CTL_ADD
+         | RADEON_SCALE_1X | RADEON_CLAMP_TX;
+   const GLuint alpha_combine0 = RADEON_ALPHA_ARG_A_ZERO | RADEON_ALPHA_ARG_B_ZERO
+         | RADEON_ALPHA_ARG_C_CURRENT_ALPHA | RADEON_BLEND_CTL_ADD
+         | RADEON_SCALE_1X | RADEON_CLAMP_TX;
+
 
    /* texUnit->_Current can be NULL if and only if the texture unit is
     * not actually enabled.
@@ -783,7 +479,7 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
           || (texUnit->_Current != NULL) );
 
    if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
-      fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, ctx, unit );
+      fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx, unit );
    }
 
    /* Set the texture environment state.  Isn't this nice and clean?
@@ -792,446 +488,290 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
     * reduces the amount of special-casing we have to do, alpha-only
     * textures being a notable exception.
     */
+    /* Don't cache these results.
+    */
+   rmesa->state.texture.unit[unit].format = 0;
+   rmesa->state.texture.unit[unit].envMode = 0;
+
    if ( !texUnit->_ReallyEnabled ) {
-      /* Don't cache these results.
-       */
-      rmesa->state.texture.unit[unit].format = 0;
-      rmesa->state.texture.unit[unit].envMode = 0;
-      color_combine = radeon_color_combine[unit][RADEON_DISABLE];
-      alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
+      color_combine = color_combine0;
+      alpha_combine = alpha_combine0;
    }
    else {
-      const struct gl_texture_object *tObj = texUnit->_Current;
-      const GLenum format = tObj->Image[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 i;
+      const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
+      const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
+      GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB;
+      GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA;
 
-      switch ( texUnit->EnvMode ) {
-      case GL_REPLACE:
-         switch ( format ) {
-        case GL_RGBA:
-         case GL_LUMINANCE_ALPHA:
-         case GL_INTENSITY:
-           color_combine = radeon_color_combine[unit][RADEON_REPLACE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE];
+
+      /* Step 1:
+       * Extract the color and alpha combine function arguments.
+       */
+      for ( i = 0 ; i < numColorArgs ; i++ ) {
+        const GLint op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR;
+        const GLuint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i];
+        assert(op >= 0);
+        assert(op <= 3);
+        switch ( srcRGBi ) {
+        case GL_TEXTURE:
+           color_arg[i] = radeon_texture_color[op][unit];
            break;
-        case GL_ALPHA:
-           color_combine = radeon_color_combine[unit][RADEON_DISABLE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE];
+        case GL_CONSTANT:
+           color_arg[i] = radeon_tfactor_color[op];
            break;
-        case GL_LUMINANCE:
-        case GL_RGB:
-        case GL_YCBCR_MESA:
-           color_combine = radeon_color_combine[unit][RADEON_REPLACE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
+        case GL_PRIMARY_COLOR:
+           color_arg[i] = radeon_primary_color[op];
            break;
-        case GL_COLOR_INDEX:
-        default:
-           return GL_FALSE;
-        }
-        break;
-
-      case GL_MODULATE:
-        switch ( format ) {
-        case GL_RGBA:
-        case GL_LUMINANCE_ALPHA:
-        case GL_INTENSITY:
-           color_combine = radeon_color_combine[unit][RADEON_MODULATE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+        case GL_PREVIOUS:
+           color_arg[i] = radeon_previous_color[op];
            break;
-        case GL_ALPHA:
-           color_combine = radeon_color_combine[unit][RADEON_DISABLE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+        case GL_ZERO:
+           color_arg[i] = radeon_zero_color[op];
            break;
-        case GL_RGB:
-        case GL_LUMINANCE:
-        case GL_YCBCR_MESA:
-           color_combine = radeon_color_combine[unit][RADEON_MODULATE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
+        case GL_ONE:
+           color_arg[i] = radeon_zero_color[op+1];
            break;
-        case GL_COLOR_INDEX:
+        case GL_TEXTURE0:
+        case GL_TEXTURE1:
+        case GL_TEXTURE2:
+        /* implement ogl 1.4/1.5 core spec here, not specification of
+         * GL_ARB_texture_env_crossbar (which would require disabling blending
+         * instead of undefined results when referencing not enabled texunit) */
+          color_arg[i] = radeon_texture_color[op][srcRGBi - GL_TEXTURE0];
+          break;
         default:
            return GL_FALSE;
         }
-        break;
+      }
 
-      case GL_DECAL:
-        switch ( format ) {
-        case GL_RGBA:
-        case GL_RGB:
-        case GL_YCBCR_MESA:
-           color_combine = radeon_color_combine[unit][RADEON_DECAL];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
+      for ( i = 0 ; i < numAlphaArgs ; i++ ) {
+        const GLint op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA;
+        const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i];
+        assert(op >= 0);
+        assert(op <= 1);
+        switch ( srcAi ) {
+        case GL_TEXTURE:
+           alpha_arg[i] = radeon_texture_alpha[op][unit];
            break;
-        case GL_ALPHA:
-        case GL_LUMINANCE:
-        case GL_LUMINANCE_ALPHA:
-        case GL_INTENSITY:
-           color_combine = radeon_color_combine[unit][RADEON_DISABLE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
+        case GL_CONSTANT:
+           alpha_arg[i] = radeon_tfactor_alpha[op];
            break;
-        case GL_COLOR_INDEX:
-        default:
-           return GL_FALSE;
-        }
-        break;
-
-      case GL_BLEND:
-        switch ( format ) {
-        case GL_RGBA:
-        case GL_RGB:
-        case GL_LUMINANCE:
-        case GL_LUMINANCE_ALPHA:
-        case GL_YCBCR_MESA:
-           color_combine = radeon_color_combine[unit][RADEON_BLEND];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+        case GL_PRIMARY_COLOR:
+           alpha_arg[i] = radeon_primary_alpha[op];
            break;
-        case GL_ALPHA:
-           color_combine = radeon_color_combine[unit][RADEON_DISABLE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+        case GL_PREVIOUS:
+           alpha_arg[i] = radeon_previous_alpha[op];
            break;
-        case GL_INTENSITY:
-           color_combine = radeon_color_combine[unit][RADEON_BLEND];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_BLEND];
+        case GL_ZERO:
+           alpha_arg[i] = radeon_zero_alpha[op];
            break;
-        case GL_COLOR_INDEX:
+        case GL_ONE:
+           alpha_arg[i] = radeon_zero_alpha[op+1];
+           break;
+        case GL_TEXTURE0:
+        case GL_TEXTURE1:
+        case GL_TEXTURE2:
+          alpha_arg[i] = radeon_texture_alpha[op][srcAi - GL_TEXTURE0];
+          break;
         default:
            return GL_FALSE;
         }
-        break;
+      }
 
+      /* Step 2:
+       * Build up the color and alpha combine functions.
+       */
+      switch ( texUnit->_CurrentCombine->ModeRGB ) {
+      case GL_REPLACE:
+        color_combine = (RADEON_COLOR_ARG_A_ZERO |
+                         RADEON_COLOR_ARG_B_ZERO |
+                         RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, C );
+        break;
+      case GL_MODULATE:
+        color_combine = (RADEON_COLOR_ARG_C_ZERO |
+                         RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, B );
+        break;
       case GL_ADD:
-        switch ( format ) {
-        case GL_RGBA:
-        case GL_RGB:
-        case GL_LUMINANCE:
-        case GL_LUMINANCE_ALPHA:
-        case GL_YCBCR_MESA:
-           color_combine = radeon_color_combine[unit][RADEON_ADD];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
-           break;
-        case GL_ALPHA:
-           color_combine = radeon_color_combine[unit][RADEON_DISABLE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
-           break;
-        case GL_INTENSITY:
-           color_combine = radeon_color_combine[unit][RADEON_ADD];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_ADD];
-           break;
-        case GL_COLOR_INDEX:
-        default:
-           return GL_FALSE;
-        }
+        color_combine = (RADEON_COLOR_ARG_B_ZERO |
+                         RADEON_COMP_ARG_B |
+                         RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, C );
+        break;
+      case GL_ADD_SIGNED:
+        color_combine = (RADEON_COLOR_ARG_B_ZERO |
+                         RADEON_COMP_ARG_B |
+                         RADEON_BLEND_CTL_ADDSIGNED |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, C );
+        break;
+      case GL_SUBTRACT:
+        color_combine = (RADEON_COLOR_ARG_B_ZERO |
+                         RADEON_COMP_ARG_B |
+                         RADEON_BLEND_CTL_SUBTRACT |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, C );
+        break;
+      case GL_INTERPOLATE:
+        color_combine = (RADEON_BLEND_CTL_BLEND |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, B );
+        RADEON_COLOR_ARG( 1, A );
+        RADEON_COLOR_ARG( 2, C );
         break;
 
-      case GL_COMBINE:
-        /* Don't cache these results.
+      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.
          */
-        rmesa->state.texture.unit[unit].format = 0;
-        rmesa->state.texture.unit[unit].envMode = 0;
+        RGBshift = 0;
+        /* FALLTHROUGH */
 
-        /* Step 0:
-         * Calculate how many arguments we need to process.
+      case GL_DOT3_RGB:
+      case GL_DOT3_RGBA:
+        /* The R100 / RV200 only support a 1X multiplier in hardware
+         * w/the ARB version.
          */
-        switch ( texUnit->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:
-           return GL_FALSE;
-        }
-
-        switch ( texUnit->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:
+        if ( RGBshift != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) {
            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] = radeon_texture_color[op][unit];
-              break;
-           case GL_CONSTANT:
-              color_arg[i] = radeon_tfactor_color[op];
-              break;
-           case GL_PRIMARY_COLOR:
-              color_arg[i] = radeon_primary_color[op];
-              break;
-           case GL_PREVIOUS:
-              color_arg[i] = radeon_previous_color[op];
-              break;
-           case GL_ZERO:
-              color_arg[i] = radeon_zero_color[op];
-              break;
-           case GL_ONE:
-              color_arg[i] = radeon_zero_color[op+1];
-              break;
-           default:
-              return GL_FALSE;
-           }
-        }
-
-        for ( i = 0 ; i < numAlphaArgs ; i++ ) {
-           const GLuint op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA;
-           assert(op >= 0);
-           assert(op <= 1);
-           switch ( texUnit->CombineSourceA[i] ) {
-           case GL_TEXTURE:
-              alpha_arg[i] = radeon_texture_alpha[op][unit];
-              break;
-           case GL_CONSTANT:
-              alpha_arg[i] = radeon_tfactor_alpha[op];
-              break;
-           case GL_PRIMARY_COLOR:
-              alpha_arg[i] = radeon_primary_alpha[op];
-              break;
-           case GL_PREVIOUS:
-              alpha_arg[i] = radeon_previous_alpha[op];
-              break;
-           case GL_ZERO:
-              alpha_arg[i] = radeon_zero_alpha[op];
-              break;
-           case GL_ONE:
-              alpha_arg[i] = radeon_zero_alpha[op+1];
-              break;
-           default:
-              return GL_FALSE;
-           }
-        }
-
-        /* Step 2:
-         * Build up the color and alpha combine functions.
-         */
-        switch ( texUnit->CombineModeRGB ) {
-        case GL_REPLACE:
-           color_combine = (RADEON_COLOR_ARG_A_ZERO |
-                            RADEON_COLOR_ARG_B_ZERO |
-                            RADEON_BLEND_CTL_ADD |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, C );
-           break;
-        case GL_MODULATE:
-           color_combine = (RADEON_COLOR_ARG_C_ZERO |
-                            RADEON_BLEND_CTL_ADD |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, A );
-           RADEON_COLOR_ARG( 1, B );
-           break;
-        case GL_ADD:
-           color_combine = (RADEON_COLOR_ARG_B_ZERO |
-                            RADEON_COMP_ARG_B |
-                            RADEON_BLEND_CTL_ADD |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, A );
-           RADEON_COLOR_ARG( 1, C );
-           break;
-        case GL_ADD_SIGNED:
-           color_combine = (RADEON_COLOR_ARG_B_ZERO |
-                            RADEON_COMP_ARG_B |
-                            RADEON_BLEND_CTL_ADDSIGNED |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, A );
-           RADEON_COLOR_ARG( 1, C );
-           break;
-        case GL_SUBTRACT:
-           color_combine = (RADEON_COLOR_ARG_B_ZERO |
-                            RADEON_COMP_ARG_B |
-                            RADEON_BLEND_CTL_SUBTRACT |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, A );
-           RADEON_COLOR_ARG( 1, C );
-           break;
-        case GL_INTERPOLATE:
-           color_combine = (RADEON_BLEND_CTL_BLEND |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, B );
-           RADEON_COLOR_ARG( 1, A );
-           RADEON_COLOR_ARG( 2, C );
-           break;
-
-        case GL_DOT3_RGB_EXT:
-        case GL_DOT3_RGBA_EXT:
-           /* The EXT version of the DOT3 extension does not support the
-            * scale factor, but the ARB version (and the version in OpenGL
-            * 1.3) does.
-            */
-           RGBshift = 0;
-           Ashift = 0;
-           /* FALLTHROUGH */
-
-        case GL_DOT3_RGB:
-        case GL_DOT3_RGBA:
-           /* The R100 / RV200 only support a 1X multiplier in hardware
-            * w/the ARB version.
-            */
-           if ( RGBshift != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) {
-              return GL_FALSE;
-           }
-
-           RGBshift += 2;
+        RGBshift += 2;
+        if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT)
+           || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) {
+            /* is it necessary to set this or will it be ignored anyway? */
            Ashift = RGBshift;
-
-           color_combine = (RADEON_COLOR_ARG_C_ZERO |
-                            RADEON_BLEND_CTL_DOT3 |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, A );
-           RADEON_COLOR_ARG( 1, B );
-           break;
-
-        case GL_MODULATE_ADD_ATI:
-           color_combine = (RADEON_BLEND_CTL_ADD |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, A );
-           RADEON_COLOR_ARG( 1, C );
-           RADEON_COLOR_ARG( 2, B );
-           break;
-        case GL_MODULATE_SIGNED_ADD_ATI:
-           color_combine = (RADEON_BLEND_CTL_ADDSIGNED |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, A );
-           RADEON_COLOR_ARG( 1, C );
-           RADEON_COLOR_ARG( 2, B );
-           break;
-        case GL_MODULATE_SUBTRACT_ATI:
-           color_combine = (RADEON_BLEND_CTL_SUBTRACT |
-                            RADEON_CLAMP_TX);
-           RADEON_COLOR_ARG( 0, A );
-           RADEON_COLOR_ARG( 1, C );
-           RADEON_COLOR_ARG( 2, B );
-           break;
-        default:
-           return GL_FALSE;
-        }
-
-        switch ( texUnit->CombineModeA ) {
-        case GL_REPLACE:
-           alpha_combine = (RADEON_ALPHA_ARG_A_ZERO |
-                            RADEON_ALPHA_ARG_B_ZERO |
-                            RADEON_BLEND_CTL_ADD |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, C );
-           break;
-        case GL_MODULATE:
-           alpha_combine = (RADEON_ALPHA_ARG_C_ZERO |
-                            RADEON_BLEND_CTL_ADD |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, A );
-           RADEON_ALPHA_ARG( 1, B );
-           break;
-        case GL_ADD:
-           alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
-                            RADEON_COMP_ARG_B |
-                            RADEON_BLEND_CTL_ADD |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, A );
-           RADEON_ALPHA_ARG( 1, C );
-           break;
-        case GL_ADD_SIGNED:
-           alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
-                            RADEON_COMP_ARG_B |
-                            RADEON_BLEND_CTL_ADDSIGNED |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, A );
-           RADEON_ALPHA_ARG( 1, C );
-           break;
-        case GL_SUBTRACT:
-           alpha_combine = (RADEON_COLOR_ARG_B_ZERO |
-                            RADEON_COMP_ARG_B |
-                            RADEON_BLEND_CTL_SUBTRACT |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, A );
-           RADEON_ALPHA_ARG( 1, C );
-           break;
-        case GL_INTERPOLATE:
-           alpha_combine = (RADEON_BLEND_CTL_BLEND |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, B );
-           RADEON_ALPHA_ARG( 1, A );
-           RADEON_ALPHA_ARG( 2, C );
-           break;
-
-        case GL_MODULATE_ADD_ATI:
-           alpha_combine = (RADEON_BLEND_CTL_ADD |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, A );
-           RADEON_ALPHA_ARG( 1, C );
-           RADEON_ALPHA_ARG( 2, B );
-           break;
-        case GL_MODULATE_SIGNED_ADD_ATI:
-           alpha_combine = (RADEON_BLEND_CTL_ADDSIGNED |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, A );
-           RADEON_ALPHA_ARG( 1, C );
-           RADEON_ALPHA_ARG( 2, B );
-           break;
-        case GL_MODULATE_SUBTRACT_ATI:
-           alpha_combine = (RADEON_BLEND_CTL_SUBTRACT |
-                            RADEON_CLAMP_TX);
-           RADEON_ALPHA_ARG( 0, A );
-           RADEON_ALPHA_ARG( 1, C );
-           RADEON_ALPHA_ARG( 2, B );
-           break;
-        default:
-           return GL_FALSE;
         }
 
-        if ( (texUnit->CombineModeRGB == GL_DOT3_RGB_EXT)
-             || (texUnit->CombineModeRGB == GL_DOT3_RGB) ) {
-           alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
-        }
+        color_combine = (RADEON_COLOR_ARG_C_ZERO |
+                         RADEON_BLEND_CTL_DOT3 |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, B );
+        break;
 
-        /* Step 3:
-         * Apply the scale factor.
-         */
-        color_combine |= (RGBshift << RADEON_SCALE_SHIFT);
-        alpha_combine |= (Ashift   << RADEON_SCALE_SHIFT);
+      case GL_MODULATE_ADD_ATI:
+        color_combine = (RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, C );
+        RADEON_COLOR_ARG( 2, B );
+        break;
+      case GL_MODULATE_SIGNED_ADD_ATI:
+        color_combine = (RADEON_BLEND_CTL_ADDSIGNED |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, C );
+        RADEON_COLOR_ARG( 2, B );
+        break;
+      case GL_MODULATE_SUBTRACT_ATI:
+        color_combine = (RADEON_BLEND_CTL_SUBTRACT |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, C );
+        RADEON_COLOR_ARG( 2, B );
+        break;
+      default:
+        return GL_FALSE;
+      }
 
-        /* All done!
-         */
+      switch ( texUnit->_CurrentCombine->ModeA ) {
+      case GL_REPLACE:
+        alpha_combine = (RADEON_ALPHA_ARG_A_ZERO |
+                         RADEON_ALPHA_ARG_B_ZERO |
+                         RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, C );
+        break;
+      case GL_MODULATE:
+        alpha_combine = (RADEON_ALPHA_ARG_C_ZERO |
+                         RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, A );
+        RADEON_ALPHA_ARG( 1, B );
+        break;
+      case GL_ADD:
+        alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
+                         RADEON_COMP_ARG_B |
+                         RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, A );
+        RADEON_ALPHA_ARG( 1, C );
+        break;
+      case GL_ADD_SIGNED:
+        alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
+                         RADEON_COMP_ARG_B |
+                         RADEON_BLEND_CTL_ADDSIGNED |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, A );
+        RADEON_ALPHA_ARG( 1, C );
+        break;
+      case GL_SUBTRACT:
+        alpha_combine = (RADEON_COLOR_ARG_B_ZERO |
+                         RADEON_COMP_ARG_B |
+                         RADEON_BLEND_CTL_SUBTRACT |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, A );
+        RADEON_ALPHA_ARG( 1, C );
+        break;
+      case GL_INTERPOLATE:
+        alpha_combine = (RADEON_BLEND_CTL_BLEND |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, B );
+        RADEON_ALPHA_ARG( 1, A );
+        RADEON_ALPHA_ARG( 2, C );
         break;
 
+      case GL_MODULATE_ADD_ATI:
+        alpha_combine = (RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, A );
+        RADEON_ALPHA_ARG( 1, C );
+        RADEON_ALPHA_ARG( 2, B );
+        break;
+      case GL_MODULATE_SIGNED_ADD_ATI:
+        alpha_combine = (RADEON_BLEND_CTL_ADDSIGNED |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, A );
+        RADEON_ALPHA_ARG( 1, C );
+        RADEON_ALPHA_ARG( 2, B );
+        break;
+      case GL_MODULATE_SUBTRACT_ATI:
+        alpha_combine = (RADEON_BLEND_CTL_SUBTRACT |
+                         RADEON_CLAMP_TX);
+        RADEON_ALPHA_ARG( 0, A );
+        RADEON_ALPHA_ARG( 1, C );
+        RADEON_ALPHA_ARG( 2, B );
+        break;
       default:
         return GL_FALSE;
       }
+
+      if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB_EXT)
+          || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB) ) {
+        alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
+      }
+
+      /* Step 3:
+       * Apply the scale factor.
+       */
+      color_combine |= (RGBshift << RADEON_SCALE_SHIFT);
+      alpha_combine |= (Ashift   << RADEON_SCALE_SHIFT);
+
+      /* All done!
+       */
    }
 
    if ( rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] != color_combine ||
@@ -1341,14 +881,16 @@ static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit )
       /* Very easy to do this, in fact would remove a fallback case
        * elsewhere, but I haven't done it yet...  Fallback: 
        */
-      fprintf(stderr, "fallback Q_BIT\n");
+      if (RADEON_DEBUG & DEBUG_FALLBACKS) 
+       fprintf(stderr, "fallback Q_BIT\n");
       return GL_FALSE;
    }
    else if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) != (S_BIT|T_BIT) ||
            texUnit->GenModeS != texUnit->GenModeT) {
       /* Mixed modes, fallback:
        */
-      /* fprintf(stderr, "fallback mixed texgen\n"); */
+      if (RADEON_DEBUG & DEBUG_FALLBACKS) 
+        fprintf(stderr, "fallback mixed texgen\n");
       return GL_FALSE;
    }
    else
@@ -1383,7 +925,8 @@ static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit )
    default:
       /* Unsupported mode, fallback:
        */
-      /*  fprintf(stderr, "fallback unsupported texgen\n"); */
+      if (RADEON_DEBUG & DEBUG_FALLBACKS) 
+        fprintf(stderr, "fallback GL_SPHERE_MAP\n");
       return GL_FALSE;
    }
 
@@ -1500,7 +1043,7 @@ static GLboolean enable_tex_rect( GLcontext *ctx, int unit )
       RADEON_FIREVERTICES( rmesa );
       radeonSetTexImages( rmesa, tObj );
       radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 );
-      if ( !t->base.memBlock /* && !rmesa->prefer_agp_client_texturing  FIXME */ ) {
+      if ( !t->base.memBlock /* && !rmesa->prefer_gart_client_texturing  FIXME */ ) {
         fprintf(stderr, "%s: upload failed\n", __FUNCTION__);
         return GL_FALSE;
       }
@@ -1519,7 +1062,7 @@ static GLboolean update_tex_common( GLcontext *ctx, int unit )
    GLenum format;
 
    /* Fallback if there's a texture border */
-   if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) {
+   if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) {
       fprintf(stderr, "%s: border\n", __FUNCTION__);
       return GL_FALSE;
    }
@@ -1572,7 +1115,7 @@ static GLboolean update_tex_common( GLcontext *ctx, int unit )
       rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
    }
 
-   format = tObj->Image[tObj->BaseLevel]->Format;
+   format = tObj->Image[0][tObj->BaseLevel]->Format;
    if ( rmesa->state.texture.unit[unit].format != format ||
        rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode ) {
       rmesa->state.texture.unit[unit].format = format;