radeon: stupid mesa extension fail
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_texstate.c
index 6dccd311800ba303969e9139bd327f9feac20598..78e2a08559ba19ae3ab78b7017aa37f8f5e59773 100644 (file)
@@ -1,4 +1,3 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c,v 1.6 2002/12/16 16:18:59 dawes Exp $ */
 /**************************************************************************
 
 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
@@ -34,15 +33,18 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *   Gareth Hughes <gareth@valinux.com>
  */
 
-#include "glheader.h"
-#include "imports.h"
-#include "colormac.h"
-#include "context.h"
-#include "macros.h"
-#include "texformat.h"
-#include "enums.h"
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/colormac.h"
+#include "main/context.h"
+#include "main/macros.h"
+#include "main/texformat.h"
+#include "main/teximage.h"
+#include "main/texobj.h"
+#include "main/enums.h"
 
 #include "radeon_context.h"
+#include "radeon_mipmap_tree.h"
 #include "radeon_state.h"
 #include "radeon_ioctl.h"
 #include "radeon_swtcl.h"
@@ -50,586 +52,72 @@ 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 {
+struct tx_table {
    GLuint format, filter;
-}
-tx_table[] =
+};
+
+static const struct tx_table tx_table[] =
 {
    _ALPHA(RGBA8888),
+   _ALPHA_REV(RGBA8888),
    _ALPHA(ARGB8888),
-   _INVALID(RGB888),
+   _ALPHA_REV(ARGB8888),
+   [ MESA_FORMAT_RGB888 ] = { RADEON_TXFORMAT_ARGB8888, 0 },
    _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
 #undef _ALPHA
 #undef _INVALID
 
-/**
- * This function computes the number of bytes of storage needed for
- * the given texture object (all mipmap levels, all cube faces).
- * The \c image[face][level].x/y/width/height parameters for upload/blitting
- * are computed here.  \c pp_txfilter, \c pp_txformat, etc. will be set here
- * too.
- * 
- * \param rmesa Context pointer
- * \param tObj GL texture object whose images are to be posted to
- *                 hardware state.
- */
-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;
-   GLint log2Width, log2Height, log2Depth;
-
-   /* Set the hardware texture format
-    */
-
-   t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK |
-                      RADEON_TXFORMAT_ALPHA_IN_MAP);
-   t->pp_txfilter &= ~RADEON_YUV_TO_RGB;
-
-   if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) {
-      t->pp_txformat |= tx_table[ baseImage->TexFormat->MesaFormat ].format;
-      t->pp_txfilter |= tx_table[ baseImage->TexFormat->MesaFormat ].filter;
-   }
-   else {
-      _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__);
-      return;
-   }
-
-
-
-   /* 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;
-
-   numLevels = lastLevel - firstLevel + 1;
-
-   assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS);
-
-   /* Calculate mipmap offsets and dimensions for blitting (uploading)
-    * The idea is that we lay out the mipmap levels within a block of
-    * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
-    */
-   curOffset = 0;
-
-   for (i = 0; i < numLevels; i++) {
-      const struct gl_texture_image *texImage;
-      GLuint size;
-
-      texImage = tObj->Image[i + firstLevel];
-      if ( !texImage )
-        break;
-
-      /* find image size in bytes */
-      if (texImage->IsCompressed) {
-         size = texImage->CompressedSize;
-      }
-      else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
-        size = ((texImage->Width * texImage->TexFormat->TexelBytes + 63)
-                & ~63) * texImage->Height;
-      }
-      else {
-         int w = texImage->Width * texImage->TexFormat->TexelBytes;
-         if (w < 32)
-            w = 32;
-         size = w * texImage->Height * texImage->Depth;
-      }
-      assert(size > 0);
-
-      if (curOffset & 0x1f) {
-         /* align to 32-byte offset */
-         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 0
-      /* for debugging only and only  applicable to non-rectangle targets */
-      assert(size % t->image[0][i].width == 0);
-      assert(t->image[0][i].x == 0
-             || (size < BLIT_WIDTH_BYTES && t->image[0][i].height == 1));
-#endif
-
-      if (0)
-         fprintf(stderr,
-                 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
-                 i, texImage->Width, texImage->Height,
-                 t->image[0][i].x, t->image[0][i].y,
-                 t->image[0][i].width, t->image[0][i].height, size, curOffset);
-
-      curOffset += size;
-
-   }
-
-   /* Align the total size of texture memory block.
-    */
-   t->base.totalSize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
-
-   /* Hardware state:
-    */
-   t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK;
-   t->pp_txfilter |= (numLevels - 1) << RADEON_MAX_MIP_LEVEL_SHIFT;
-
-   t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
-                      RADEON_TXFORMAT_HEIGHT_MASK |
-                       RADEON_TXFORMAT_CUBIC_MAP_ENABLE);
-   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));
-
-   /* 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);
-   else
-      t->pp_txpitch = ((tObj->Image[firstLevel]->Width * baseImage->TexFormat->TexelBytes) + 63) & ~(63);
-   t->pp_txpitch -= 32;
-
-   t->dirty_state = TEX_ALL;
-
-   /* FYI: radeonUploadTexImages( rmesa, t ); used to be called here */
-}
-
-
-
 /* ================================================================
  * 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
  */
 
@@ -772,9 +260,16 @@ do {                                                       \
 
 static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
 {
-   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+   r100ContextPtr rmesa = R100_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,455 +278,316 @@ 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?
     * The chip will automagically set the texture alpha to 0xff when
-    * the texture format does not include an alpha component.  This
+    * the texture format does not include an alpha component. This
     * reduces the amount of special-casing we have to do, alpha-only
-    * textures being a notable exception.
+    * textures being a notable exception. Doesn't work for luminance
+    * textures realized with I8 and ALPHA_IN_MAP not set neither (on r100).
+    */
+    /* 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];
-           break;
-        case GL_ALPHA:
-           color_combine = radeon_color_combine[unit][RADEON_DISABLE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE];
-           break;
-        case GL_LUMINANCE:
-        case GL_RGB:
-        case GL_YCBCR_MESA:
-           color_combine = radeon_color_combine[unit][RADEON_REPLACE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
-           break;
-        case GL_COLOR_INDEX:
-        default:
-           return GL_FALSE;
-        }
-        break;
 
-      case GL_MODULATE:
-        switch ( format ) {
-        case GL_RGBA:
-        case GL_LUMINANCE_ALPHA:
-        case GL_INTENSITY:
-           color_combine = radeon_color_combine[unit][RADEON_MODULATE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
-           break;
-        case GL_ALPHA:
-           color_combine = radeon_color_combine[unit][RADEON_DISABLE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+      /* 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:
+           if (texUnit->_Current->Image[0][0]->_BaseFormat == GL_ALPHA)
+              color_arg[i] = radeon_zero_color[op];
+           else
+              color_arg[i] = radeon_texture_color[op][unit];
            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_CONSTANT:
+           color_arg[i] = radeon_tfactor_color[op];
            break;
-        case GL_COLOR_INDEX:
-        default:
-           return GL_FALSE;
-        }
-        break;
-
-      case GL_DECAL:
-        switch ( format ) {
-        case GL_RGBA:
-        case GL_RGB:
-        case GL_YCBCR_MESA:
-           color_combine = radeon_color_combine[unit][RADEON_DECAL];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
+        case GL_PRIMARY_COLOR:
+           color_arg[i] = radeon_primary_color[op];
            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_PREVIOUS:
+           color_arg[i] = radeon_previous_color[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_ZERO:
+           color_arg[i] = radeon_zero_color[op];
            break;
-        case GL_ALPHA:
-           color_combine = radeon_color_combine[unit][RADEON_DISABLE];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+        case GL_ONE:
+           color_arg[i] = radeon_zero_color[op+1];
            break;
-        case GL_INTENSITY:
-           color_combine = radeon_color_combine[unit][RADEON_BLEND];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_BLEND];
+        case GL_TEXTURE0:
+        case GL_TEXTURE1:
+        case GL_TEXTURE2: {
+           GLuint txunit = srcRGBi - GL_TEXTURE0;
+           if (ctx->Texture.Unit[txunit]._Current->Image[0][0]->_BaseFormat == GL_ALPHA)
+              color_arg[i] = radeon_zero_color[op];
+           else
+        /* 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][txunit];
+           }
            break;
-        case GL_COLOR_INDEX:
         default:
            return GL_FALSE;
         }
-        break;
+      }
 
-      case GL_ADD:
-        switch ( format ) {
-        case GL_RGBA:
-        case GL_RGB:
-        case GL_LUMINANCE:
-        case GL_LUMINANCE_ALPHA:
-        case GL_YCBCR_MESA:
-           color_combine = radeon_color_combine[unit][RADEON_ADD];
-           alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
-           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];
+      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:
+           if (texUnit->_Current->Image[0][0]->_BaseFormat == GL_LUMINANCE)
+              alpha_arg[i] = radeon_zero_alpha[op+1];
+           else
+              alpha_arg[i] = radeon_texture_alpha[op][unit];
            break;
-        case GL_COLOR_INDEX:
-        default:
-           return GL_FALSE;
-        }
-        break;
-
-      case GL_COMBINE:
-        /* Don't cache these results.
-         */
-        rmesa->state.texture.unit[unit].format = 0;
-        rmesa->state.texture.unit[unit].envMode = 0;
-
-        /* Step 0:
-         * Calculate how many arguments we need to process.
-         */
-        switch ( texUnit->CombineModeRGB ) {
-        case GL_REPLACE:
-           numColorArgs = 1;
+        case GL_CONSTANT:
+           alpha_arg[i] = radeon_tfactor_alpha[op];
            break;
-        case GL_MODULATE:
-        case GL_ADD:
-        case GL_ADD_SIGNED:
-        case GL_SUBTRACT:
-        case GL_DOT3_RGB:
-        case GL_DOT3_RGBA:
-        case GL_DOT3_RGB_EXT:
-        case GL_DOT3_RGBA_EXT:
-           numColorArgs = 2;
+        case GL_PRIMARY_COLOR:
+           alpha_arg[i] = radeon_primary_alpha[op];
            break;
-        case GL_INTERPOLATE:
-        case GL_MODULATE_ADD_ATI:
-        case GL_MODULATE_SIGNED_ADD_ATI:
-        case GL_MODULATE_SUBTRACT_ATI:
-           numColorArgs = 3;
+        case GL_PREVIOUS:
+           alpha_arg[i] = radeon_previous_alpha[op];
            break;
-        default:
-           return GL_FALSE;
-        }
-
-        switch ( texUnit->CombineModeA ) {
-        case GL_REPLACE:
-           numAlphaArgs = 1;
+        case GL_ZERO:
+           alpha_arg[i] = radeon_zero_alpha[op];
            break;
-        case GL_MODULATE:
-        case GL_ADD:
-        case GL_ADD_SIGNED:
-        case GL_SUBTRACT:
-           numAlphaArgs = 2;
+        case GL_ONE:
+           alpha_arg[i] = radeon_zero_alpha[op+1];
            break;
-        case GL_INTERPOLATE:
-        case GL_MODULATE_ADD_ATI:
-        case GL_MODULATE_SIGNED_ADD_ATI:
-        case GL_MODULATE_SUBTRACT_ATI:
-           numAlphaArgs = 3;
+        case GL_TEXTURE0:
+        case GL_TEXTURE1:
+        case GL_TEXTURE2: {    
+           GLuint txunit = srcAi - GL_TEXTURE0;
+           if (ctx->Texture.Unit[txunit]._Current->Image[0][0]->_BaseFormat == GL_LUMINANCE)
+              alpha_arg[i] = radeon_zero_alpha[op+1];
+           else
+              alpha_arg[i] = radeon_texture_alpha[op][txunit];
+           }
            break;
         default:
            return GL_FALSE;
         }
+      }
 
-        /* Step 1:
-         * Extract the color and alpha combine function arguments.
-         */
-        for ( i = 0 ; i < numColorArgs ; i++ ) {
-           const GLuint op = texUnit->CombineOperandRGB[i] - GL_SRC_COLOR;
-           assert(op >= 0);
-           assert(op <= 3);
-           switch ( texUnit->CombineSourceRGB[i] ) {
-           case GL_TEXTURE:
-              color_arg[i] = 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->_CurrentCombine->ModeRGB ) {
+      case GL_REPLACE:
+        color_combine = (RADEON_COLOR_ARG_A_ZERO |
+                         RADEON_COLOR_ARG_B_ZERO |
+                         RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, C );
+        break;
+      case GL_MODULATE:
+        color_combine = (RADEON_COLOR_ARG_C_ZERO |
+                         RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, B );
+        break;
+      case GL_ADD:
+        color_combine = (RADEON_COLOR_ARG_B_ZERO |
+                         RADEON_COMP_ARG_B |
+                         RADEON_BLEND_CTL_ADD |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, C );
+        break;
+      case GL_ADD_SIGNED:
+        color_combine = (RADEON_COLOR_ARG_B_ZERO |
+                         RADEON_COMP_ARG_B |
+                         RADEON_BLEND_CTL_ADDSIGNED |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, C );
+        break;
+      case GL_SUBTRACT:
+        color_combine = (RADEON_COLOR_ARG_B_ZERO |
+                         RADEON_COMP_ARG_B |
+                         RADEON_BLEND_CTL_SUBTRACT |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, A );
+        RADEON_COLOR_ARG( 1, C );
+        break;
+      case GL_INTERPOLATE:
+        color_combine = (RADEON_BLEND_CTL_BLEND |
+                         RADEON_CLAMP_TX);
+        RADEON_COLOR_ARG( 0, B );
+        RADEON_COLOR_ARG( 1, A );
+        RADEON_COLOR_ARG( 2, C );
+        break;
 
-        /* Step 2:
-         * Build up the color and alpha combine functions.
+      case GL_DOT3_RGB_EXT:
+      case GL_DOT3_RGBA_EXT:
+        /* The EXT version of the DOT3 extension does not support the
+         * scale factor, but the ARB version (and the version in OpenGL
+         * 1.3) does.
          */
-        switch ( texUnit->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;
-           Ashift = RGBshift;
+        RGBshift = 0;
+        /* FALLTHROUGH */
 
-           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:
+      case GL_DOT3_RGB:
+      case GL_DOT3_RGBA:
+        /* The R100 / RV200 only support a 1X multiplier in hardware
+         * w/the ARB version.
+         */
+        if ( RGBshift != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) {
            return GL_FALSE;
         }
 
-        switch ( texUnit->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;
+        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;
         }
 
-        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 ||
@@ -1244,6 +600,158 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
    return GL_TRUE;
 }
 
+void radeonSetTexOffset(__DRIcontext * pDRICtx, GLint texname,
+                        unsigned long long offset, GLint depth, GLuint pitch)
+{
+       r100ContextPtr rmesa = pDRICtx->driverPrivate;
+       struct gl_texture_object *tObj =
+           _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
+       radeonTexObjPtr t = radeon_tex_obj(tObj);
+
+       if (tObj == NULL)
+               return;
+
+       t->image_override = GL_TRUE;
+
+       if (!offset)
+               return;
+       
+       t->bo = NULL;
+       t->override_offset = offset;
+       t->pp_txpitch = pitch - 32;
+
+       switch (depth) {
+       case 32:
+               t->pp_txformat = tx_table[MESA_FORMAT_ARGB8888].format;
+               t->pp_txfilter |= tx_table[MESA_FORMAT_ARGB8888].filter;
+               break;
+       case 24:
+       default:
+               t->pp_txformat = tx_table[MESA_FORMAT_RGB888].format;
+               t->pp_txfilter |= tx_table[MESA_FORMAT_RGB888].filter;
+               break;
+       case 16:
+               t->pp_txformat = tx_table[MESA_FORMAT_RGB565].format;
+               t->pp_txfilter |= tx_table[MESA_FORMAT_RGB565].filter;
+               break;
+       }
+}
+
+void radeonSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_format,
+                        __DRIdrawable *dPriv)
+{
+       struct gl_texture_unit *texUnit;
+       struct gl_texture_object *texObj;
+       struct gl_texture_image *texImage;
+       struct radeon_renderbuffer *rb;
+       radeon_texture_image *rImage;
+       radeonContextPtr radeon;
+       r100ContextPtr rmesa;
+       struct radeon_framebuffer *rfb;
+       radeonTexObjPtr t;
+       uint32_t pitch_val;
+       uint32_t internalFormat, type, format;
+
+       type = GL_BGRA;
+       format = GL_UNSIGNED_BYTE;
+       internalFormat = (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT ? 3 : 4);
+
+       radeon = pDRICtx->driverPrivate;
+       rmesa = pDRICtx->driverPrivate;
+
+       rfb = dPriv->driverPrivate;
+        texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit];
+       texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target);
+        texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0);
+
+       rImage = get_radeon_texture_image(texImage);
+       t = radeon_tex_obj(texObj);
+        if (t == NULL) {
+           return;
+       }
+
+       radeon_update_renderbuffers(pDRICtx, dPriv);
+       /* back & depth buffer are useless free them right away */
+       rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
+       if (rb && rb->bo) {
+               radeon_bo_unref(rb->bo);
+        rb->bo = NULL;
+       }
+       rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+       if (rb && rb->bo) {
+               radeon_bo_unref(rb->bo);
+               rb->bo = NULL;
+       }
+       rb = rfb->color_rb[0];
+       if (rb->bo == NULL) {
+               /* Failed to BO for the buffer */
+               return;
+       }
+       
+       _mesa_lock_texture(radeon->glCtx, texObj);
+       if (t->bo) {
+               radeon_bo_unref(t->bo);
+               t->bo = NULL;
+       }
+       if (rImage->bo) {
+               radeon_bo_unref(rImage->bo);
+               rImage->bo = NULL;
+       }
+       if (t->mt) {
+               radeon_miptree_unreference(t->mt);
+               t->mt = NULL;
+       }
+       if (rImage->mt) {
+               radeon_miptree_unreference(rImage->mt);
+               rImage->mt = NULL;
+       }
+       _mesa_init_teximage_fields(radeon->glCtx, target, texImage,
+                                  rb->width, rb->height, 1, 0, rb->cpp);
+       texImage->TexFormat = radeonChooseTextureFormat(radeon->glCtx,
+                                                       internalFormat,
+                                                       type, format);
+       rImage->bo = rb->bo;
+       radeon_bo_ref(rImage->bo);
+       t->bo = rb->bo;
+       radeon_bo_ref(t->bo);
+       t->tile_bits = 0;
+       t->image_override = GL_TRUE;
+       t->override_offset = 0;
+       t->pp_txpitch &= (1 << 13) -1;
+       pitch_val = rb->pitch;
+       switch (rb->cpp) {
+       case 4:
+               t->pp_txformat = tx_table[MESA_FORMAT_ARGB8888].format;
+               t->pp_txfilter |= tx_table[MESA_FORMAT_ARGB8888].filter;
+               break;
+       case 3:
+       default:
+               t->pp_txformat = tx_table[MESA_FORMAT_RGB888].format;
+               t->pp_txfilter |= tx_table[MESA_FORMAT_RGB888].filter;
+               break;
+       case 2:
+               t->pp_txformat = tx_table[MESA_FORMAT_RGB565].format;
+               t->pp_txfilter |= tx_table[MESA_FORMAT_RGB565].filter;
+               break;
+       }
+        t->pp_txsize = ((rb->width - 1) << RADEON_TEX_USIZE_SHIFT)
+                  | ((rb->height - 1) << RADEON_TEX_VSIZE_SHIFT);
+        t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2;
+       t->pp_txpitch = pitch_val;
+        t->pp_txpitch -= 32;
+
+       t->validated = GL_TRUE;
+       _mesa_unlock_texture(radeon->glCtx, texObj);
+       return;
+}
+
+
+void radeonSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
+{
+        radeonSetTexBuffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv);
+}
+
+
 #define TEXOBJ_TXFILTER_MASK (RADEON_MAX_MIP_LEVEL_MASK |      \
                              RADEON_MIN_FILTER_MASK |          \
                              RADEON_MAG_FILTER_MASK |          \
@@ -1264,365 +772,415 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
                               RADEON_TXFORMAT_NON_POWER2)
 
 
-static void import_tex_obj_state( radeonContextPtr rmesa,
+static void disable_tex_obj_state( r100ContextPtr rmesa, 
+                                  int unit )
+{
+   /* do not use RADEON_DB_STATE to avoid stale texture caches */
+   uint32_t *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
+   GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT];
+   GLuint *txr_cmd = RADEON_DB_STATE( txr[unit] );
+
+   RADEON_STATECHANGE( rmesa, tex[unit] );
+
+   RADEON_STATECHANGE( rmesa, tcl );
+   rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_ST_BIT(unit) |
+                                            RADEON_Q_BIT(unit));
+   
+   if (rmesa->radeon.TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<<unit)) {
+     TCL_FALLBACK( rmesa->radeon.glCtx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
+     rmesa->recheck_texgen[unit] = GL_TRUE;
+   }
+
+   if (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) {
+     /* this seems to be a genuine (r100 only?) hw bug. Need to remove the
+       cubic_map bit on unit 2 when the unit is disabled, otherwise every
+       2nd (2d) mipmap on unit 0 will be broken (may not be needed for other
+       units, better be safe than sorry though).*/
+     RADEON_STATECHANGE( rmesa, tex[unit] );
+     rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &= ~RADEON_TXFORMAT_CUBIC_MAP_ENABLE;
+   }
+
+   {
+      GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
+      GLuint tmp = rmesa->TexGenEnabled;
+
+      rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
+      rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
+      rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
+      rmesa->TexGenNeedNormals[unit] = 0;
+      rmesa->TexGenEnabled |= 
+       (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
+
+      if (tmp != rmesa->TexGenEnabled) {
+       rmesa->recheck_texgen[unit] = GL_TRUE;
+       rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
+      }
+   }
+}
+
+static void import_tex_obj_state( r100ContextPtr rmesa,
                                  int unit,
                                  radeonTexObjPtr texobj )
 {
-   GLuint *cmd = RADEON_DB_STATE( tex[unit] );
+/* do not use RADEON_DB_STATE to avoid stale texture caches */
+   uint32_t *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
+   GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT];
+
+   RADEON_STATECHANGE( rmesa, tex[unit] );
 
    cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK;
    cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK;
    cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
    cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK;
-   cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset;
    cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
-   RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tex[unit] );
 
-   if (texobj->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
+   if (texobj->base.Target == GL_TEXTURE_RECTANGLE_NV) {
       GLuint *txr_cmd = RADEON_DB_STATE( txr[unit] );
       txr_cmd[TXR_PP_TEX_SIZE] = texobj->pp_txsize; /* NPOT only! */
       txr_cmd[TXR_PP_TEX_PITCH] = texobj->pp_txpitch; /* NPOT only! */
       RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.txr[unit] );
+      se_coord_fmt |= RADEON_VTX_ST0_NONPARAMETRIC << unit;
    }
+   else {
+      se_coord_fmt &= ~(RADEON_VTX_ST0_NONPARAMETRIC << unit);
 
-   texobj->dirty_state &= ~(1<<unit);
-}
+      if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) {
+        uint32_t *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
+
+        RADEON_STATECHANGE( rmesa, cube[unit] );
+        cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
+        /* state filled out in the cube_emit */
+      }
+   }
 
+   if (se_coord_fmt != rmesa->hw.set.cmd[SET_SE_COORDFMT]) {
+      RADEON_STATECHANGE( rmesa, set );
+      rmesa->hw.set.cmd[SET_SE_COORDFMT] = se_coord_fmt;
+   }
 
+   rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
+}
 
 
-static void set_texgen_matrix( radeonContextPtr rmesa, 
+static void set_texgen_matrix( r100ContextPtr rmesa, 
                               GLuint unit,
                               const GLfloat *s_plane,
-                              const GLfloat *t_plane )
+                              const GLfloat *t_plane,
+                              const GLfloat *r_plane,
+                              const GLfloat *q_plane )
 {
-   static const GLfloat scale_identity[4] = { 1,1,1,1 };
-
-   if (!TEST_EQ_4V( s_plane, scale_identity) ||
-       !TEST_EQ_4V( t_plane, scale_identity)) {
-      rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE<<unit;
-      rmesa->TexGenMatrix[unit].m[0]  = s_plane[0];
-      rmesa->TexGenMatrix[unit].m[4]  = s_plane[1];
-      rmesa->TexGenMatrix[unit].m[8]  = s_plane[2];
-      rmesa->TexGenMatrix[unit].m[12] = s_plane[3];
-
-      rmesa->TexGenMatrix[unit].m[1]  = t_plane[0];
-      rmesa->TexGenMatrix[unit].m[5]  = t_plane[1];
-      rmesa->TexGenMatrix[unit].m[9]  = t_plane[2];
-      rmesa->TexGenMatrix[unit].m[13] = t_plane[3];
-      rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
-   }
+   rmesa->TexGenMatrix[unit].m[0]  = s_plane[0];
+   rmesa->TexGenMatrix[unit].m[4]  = s_plane[1];
+   rmesa->TexGenMatrix[unit].m[8]  = s_plane[2];
+   rmesa->TexGenMatrix[unit].m[12] = s_plane[3];
+
+   rmesa->TexGenMatrix[unit].m[1]  = t_plane[0];
+   rmesa->TexGenMatrix[unit].m[5]  = t_plane[1];
+   rmesa->TexGenMatrix[unit].m[9]  = t_plane[2];
+   rmesa->TexGenMatrix[unit].m[13] = t_plane[3];
+
+   rmesa->TexGenMatrix[unit].m[2]  = r_plane[0];
+   rmesa->TexGenMatrix[unit].m[6]  = r_plane[1];
+   rmesa->TexGenMatrix[unit].m[10] = r_plane[2];
+   rmesa->TexGenMatrix[unit].m[14] = r_plane[3];
+
+   rmesa->TexGenMatrix[unit].m[3]  = q_plane[0];
+   rmesa->TexGenMatrix[unit].m[7]  = q_plane[1];
+   rmesa->TexGenMatrix[unit].m[11] = q_plane[2];
+   rmesa->TexGenMatrix[unit].m[15] = q_plane[3];
+
+   rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE << unit;
+   rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
 }
 
-/* Ignoring the Q texcoord for now.
- *
- * Returns GL_FALSE if fallback required.  
+/* Returns GL_FALSE if fallback required.
  */
 static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit )
-{  
-   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+{
+   r100ContextPtr rmesa = R100_CONTEXT(ctx);
    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
    GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
    GLuint tmp = rmesa->TexGenEnabled;
-
-   rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
-   rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
-   rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
+   static const GLfloat reflect[16] = {
+      -1,  0,  0,  0,
+       0, -1,  0,  0,
+       0,  0,  -1, 0,
+       0,  0,  0,  1 };
+
+   rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE << unit);
+   rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE << unit);
+   rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK << inputshift);
    rmesa->TexGenNeedNormals[unit] = 0;
 
-   if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) == 0) {
+   if ((texUnit->TexGenEnabled & (S_BIT|T_BIT|R_BIT|Q_BIT)) == 0) {
       /* Disabled, no fallback:
        */
-      rmesa->TexGenEnabled |= 
-        (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
+      rmesa->TexGenEnabled |=
+        (RADEON_TEXGEN_INPUT_TEXCOORD_0 + unit) << inputshift;
       return GL_TRUE;
    }
-   else if (texUnit->TexGenEnabled & Q_BIT) {
-      /* 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");
-      return GL_FALSE;
+   /* the r100 cannot do texgen for some coords and not for others
+    * we do not detect such cases (certainly can't do it here) and just
+    * ASSUME that when S and T are texgen enabled we do not need other
+    * non-texgen enabled coords, no matter if the R and Q bits are texgen
+    * enabled. Still check for mixed mode texgen for all coords.
+    */
+   else if ( (texUnit->TexGenEnabled & S_BIT) &&
+            (texUnit->TexGenEnabled & T_BIT) &&
+            (texUnit->GenS.Mode == texUnit->GenT.Mode) ) {
+      if ( ((texUnit->TexGenEnabled & R_BIT) &&
+           (texUnit->GenS.Mode != texUnit->GenR.Mode)) ||
+          ((texUnit->TexGenEnabled & Q_BIT) &&
+           (texUnit->GenS.Mode != texUnit->GenQ.Mode)) ) {
+        /* Mixed modes, fallback:
+         */
+        if (RADEON_DEBUG & DEBUG_FALLBACKS)
+           fprintf(stderr, "fallback mixed texgen\n");
+        return GL_FALSE;
+      }
+      rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit;
    }
-   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"); */
+   else {
+   /* some texgen mode not including both S and T bits */
+      if (RADEON_DEBUG & DEBUG_FALLBACKS)
+        fprintf(stderr, "fallback mixed texgen/nontexgen\n");
       return GL_FALSE;
    }
-   else
-      rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit;
 
-   switch (texUnit->GenModeS) {
+   if ((texUnit->TexGenEnabled & (R_BIT | Q_BIT)) != 0) {
+      /* need this here for vtxfmt presumably. Argh we need to set
+         this from way too many places, would be much easier if we could leave
+         tcl q coord always enabled as on r200) */
+      RADEON_STATECHANGE( rmesa, tcl );
+      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_Q_BIT(unit);
+   }
+
+   switch (texUnit->GenS.Mode) {
    case GL_OBJECT_LINEAR:
       rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_OBJ << inputshift;
-      set_texgen_matrix( rmesa, unit, 
-                        texUnit->ObjectPlaneS,
-                        texUnit->ObjectPlaneT);
+      set_texgen_matrix( rmesa, unit,
+                        texUnit->GenS.ObjectPlane,
+                        texUnit->GenT.ObjectPlane,
+                        texUnit->GenR.ObjectPlane,
+                        texUnit->GenQ.ObjectPlane);
       break;
 
    case GL_EYE_LINEAR:
       rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE << inputshift;
-      set_texgen_matrix( rmesa, unit, 
-                        texUnit->EyePlaneS,
-                        texUnit->EyePlaneT);
+      set_texgen_matrix( rmesa, unit,
+                        texUnit->GenS.EyePlane,
+                        texUnit->GenT.EyePlane,
+                        texUnit->GenR.EyePlane,
+                        texUnit->GenQ.EyePlane);
       break;
 
    case GL_REFLECTION_MAP_NV:
       rmesa->TexGenNeedNormals[unit] = GL_TRUE;
-      rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT<<inputshift;
+      rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT << inputshift;
+      /* TODO: unknown if this is needed/correct */
+      set_texgen_matrix( rmesa, unit, reflect, reflect + 4,
+                       reflect + 8, reflect + 12 );
       break;
 
    case GL_NORMAL_MAP_NV:
       rmesa->TexGenNeedNormals[unit] = GL_TRUE;
-      rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL<<inputshift;
+      rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL << inputshift;
       break;
 
    case GL_SPHERE_MAP:
+      /* the mode which everyone uses :-( */
    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;
    }
 
    if (tmp != rmesa->TexGenEnabled) {
-      rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
+      rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
    }
 
    return GL_TRUE;
 }
 
-
-static void disable_tex( GLcontext *ctx, int unit )
+/**
+ * Compute the cached hardware register values for the given texture object.
+ *
+ * \param rmesa Context pointer
+ * \param t the r300 texture object
+ */
+static GLboolean setup_hardware_state(r100ContextPtr rmesa, radeonTexObj *t, int unit)
 {
-   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
-   if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit)) {
-      /* Texture unit disabled */
-      if ( rmesa->state.texture.unit[unit].texobj != NULL ) {
-        /* The old texture is no longer bound to this texture unit.
-         * Mark it as such.
-         */
-
-        rmesa->state.texture.unit[unit].texobj->base.bound &= ~(1UL << unit);
-        rmesa->state.texture.unit[unit].texobj = NULL;
-      }
-
-      RADEON_STATECHANGE( rmesa, ctx );
-      rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= 
-         ~((RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit);
-
-      RADEON_STATECHANGE( rmesa, tcl );
-      switch (unit) {
-      case 0:
-        rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_TCL_VTX_ST0 |
-                                                  RADEON_TCL_VTX_Q0);
-           break;
-      case 1:
-        rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_TCL_VTX_ST1 |
-                                                  RADEON_TCL_VTX_Q1);
-        break;
-      default:
-        break;
-      }
-
-
-      if (rmesa->TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<<unit)) {
-        TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
-        rmesa->recheck_texgen[unit] = GL_TRUE;
-      }
-
+   const struct gl_texture_image *firstImage;
+   GLint log2Width, log2Height, log2Depth, texelBytes;
 
+   if ( t->bo ) {
+       return GL_TRUE;
+   }
 
-      {
-        GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
-        GLuint tmp = rmesa->TexGenEnabled;
+   firstImage = t->base.Image[0][t->mt->firstLevel];   
 
-        rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
-        rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
-        rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
-        rmesa->TexGenNeedNormals[unit] = 0;
-        rmesa->TexGenEnabled |= 
-            (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
+   if (firstImage->Border > 0) {
+      fprintf(stderr, "%s: border\n", __FUNCTION__);
+      return GL_FALSE;
+   }
 
-        if (tmp != rmesa->TexGenEnabled) {
-           rmesa->recheck_texgen[unit] = GL_TRUE;
-           rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
-        }
+   log2Width  = firstImage->WidthLog2;
+   log2Height = firstImage->HeightLog2;
+   log2Depth  = firstImage->DepthLog2;
+   texelBytes = firstImage->TexFormat->TexelBytes;
+
+   if (!t->image_override) {
+      if (VALID_FORMAT(firstImage->TexFormat->MesaFormat)) {
+       const struct tx_table *table = tx_table;
+
+        t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK |
+                            RADEON_TXFORMAT_ALPHA_IN_MAP);
+        t->pp_txfilter &= ~RADEON_YUV_TO_RGB;   
+        
+        t->pp_txformat |= table[ firstImage->TexFormat->MesaFormat ].format;
+        t->pp_txfilter |= table[ firstImage->TexFormat->MesaFormat ].filter;
+      } else {
+        _mesa_problem(NULL, "unexpected texture format in %s",
+                      __FUNCTION__);
+        return GL_FALSE;
       }
    }
-}
-
-static GLboolean enable_tex_2d( GLcontext *ctx, int unit )
-{
-   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
-   struct gl_texture_object *tObj = texUnit->_Current;
-   radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
-
-   /* Need to load the 2d images associated with this unit.
-    */
-   if (t->pp_txformat & RADEON_TXFORMAT_NON_POWER2) {
-      t->pp_txformat &= ~RADEON_TXFORMAT_NON_POWER2;
-      t->base.dirty_images[0] = ~0;
+   
+   t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK;
+   t->pp_txfilter |= (t->mt->lastLevel - t->mt->firstLevel) << RADEON_MAX_MIP_LEVEL_SHIFT;
+       
+   t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
+                      RADEON_TXFORMAT_HEIGHT_MASK |
+                      RADEON_TXFORMAT_CUBIC_MAP_ENABLE |
+                      RADEON_TXFORMAT_F5_WIDTH_MASK |
+                      RADEON_TXFORMAT_F5_HEIGHT_MASK);
+   t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) |
+                     (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT));
+   
+   t->tile_bits = 0;
+   
+   if (t->base.Target == GL_TEXTURE_CUBE_MAP) {
+      ASSERT(log2Width == log2Height);
+      t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_F5_WIDTH_SHIFT) |
+                        (log2Height << RADEON_TXFORMAT_F5_HEIGHT_SHIFT) |
+                        /* don't think we need this bit, if it exists at all - fglrx does not set it */
+                        (RADEON_TXFORMAT_CUBIC_MAP_ENABLE));
+      t->pp_cubic_faces = ((log2Width << RADEON_FACE_WIDTH_1_SHIFT) |
+                           (log2Height << RADEON_FACE_HEIGHT_1_SHIFT) |
+                           (log2Width << RADEON_FACE_WIDTH_2_SHIFT) |
+                           (log2Height << RADEON_FACE_HEIGHT_2_SHIFT) |
+                           (log2Width << RADEON_FACE_WIDTH_3_SHIFT) |
+                           (log2Height << RADEON_FACE_HEIGHT_3_SHIFT) |
+                           (log2Width << RADEON_FACE_WIDTH_4_SHIFT) |
+                           (log2Height << RADEON_FACE_HEIGHT_4_SHIFT));
    }
 
-   ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D);
+   t->pp_txsize = (((firstImage->Width - 1) << RADEON_TEX_USIZE_SHIFT)
+                  | ((firstImage->Height - 1) << RADEON_TEX_VSIZE_SHIFT));
 
-   if ( t->base.dirty_images[0] ) {
-      RADEON_FIREVERTICES( rmesa );
-      radeonSetTexImages( rmesa, tObj );
-      radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 );
-      if ( !t->base.memBlock ) 
-       return GL_FALSE;
+   if ( !t->image_override ) {
+      if (firstImage->IsCompressed)
+         t->pp_txpitch = (firstImage->Width + 63) & ~(63);
+      else
+         t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63);
+      t->pp_txpitch -= 32;
    }
 
-   return GL_TRUE;
-}
-
-static GLboolean enable_tex_rect( GLcontext *ctx, int unit )
-{
-   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
-   struct gl_texture_object *tObj = texUnit->_Current;
-   radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
-
-   if (!(t->pp_txformat & RADEON_TXFORMAT_NON_POWER2)) {
+   if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
       t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2;
-      t->base.dirty_images[0] = ~0;
-   }
-
-   ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);
-
-   if ( t->base.dirty_images[0] ) {
-      RADEON_FIREVERTICES( rmesa );
-      radeonSetTexImages( rmesa, tObj );
-      radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 );
-      if ( !t->base.memBlock /* && !rmesa->prefer_agp_client_texturing  FIXME */ ) {
-        fprintf(stderr, "%s: upload failed\n", __FUNCTION__);
-        return GL_FALSE;
-      }
    }
 
    return GL_TRUE;
 }
 
-
-static GLboolean update_tex_common( GLcontext *ctx, int unit )
+static GLboolean radeon_validate_texture(GLcontext *ctx, struct gl_texture_object *texObj, int unit)
 {
-   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
-   struct gl_texture_object *tObj = texUnit->_Current;
-   radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
-   GLenum format;
+   r100ContextPtr rmesa = R100_CONTEXT(ctx);
+   radeonTexObj *t = radeon_tex_obj(texObj);
+   int ret;
 
-   /* Fallback if there's a texture border */
-   if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) {
-      fprintf(stderr, "%s: border\n", __FUNCTION__);
+   if (!radeon_validate_texture_miptree(ctx, texObj))
       return GL_FALSE;
-   }
-
-   /* Update state if this is a different texture object to last
-    * time.
-    */
-   if ( rmesa->state.texture.unit[unit].texobj != t ) {
-      if ( rmesa->state.texture.unit[unit].texobj != NULL ) {
-        /* The old texture is no longer bound to this texture unit.
-         * Mark it as such.
-         */
 
-        rmesa->state.texture.unit[unit].texobj->base.bound &= 
-            ~(1UL << unit);
-      }
-
-      rmesa->state.texture.unit[unit].texobj = t;
-      t->base.bound |= (1UL << unit);
-      t->dirty_state |= 1<<unit;
-      driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */
-   }
+   ret = setup_hardware_state(rmesa, t, unit);
+   if (ret == GL_FALSE)
+     return GL_FALSE;
 
+   /* yuv conversion only works in first unit */
+   if (unit != 0 && (t->pp_txfilter & RADEON_YUV_TO_RGB))
+      return GL_FALSE;
 
-   /* Newly enabled?
-    */
-   if ( !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit))) {
-      RADEON_STATECHANGE( rmesa, ctx );
-      rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= 
-         (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit;
-
-      RADEON_STATECHANGE( rmesa, tcl );
+   RADEON_STATECHANGE( rmesa, ctx );
+   rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= 
+     (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit;
 
-      if (unit == 0)
-         rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST0;
-      else 
-         rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST1;
+   RADEON_STATECHANGE( rmesa, tcl );
+   rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_ST_BIT(unit);
 
-      rmesa->recheck_texgen[unit] = GL_TRUE;
-   }
+   rmesa->recheck_texgen[unit] = GL_TRUE;
 
-   if (t->dirty_state & (1<<unit)) {
-      import_tex_obj_state( rmesa, unit, t );
-   }
+   import_tex_obj_state( rmesa, unit, t );
 
    if (rmesa->recheck_texgen[unit]) {
       GLboolean fallback = !radeon_validate_texgen( ctx, unit );
       TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
       rmesa->recheck_texgen[unit] = 0;
-      rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
+      rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
    }
 
-   format = tObj->Image[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;
-      rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode;
-      if ( ! radeonUpdateTextureEnv( ctx, unit ) ) {
-        return GL_FALSE;
-      }
+   if ( ! radeonUpdateTextureEnv( ctx, unit ) ) {
+     return GL_FALSE;
    }
-
    FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback );
+
+   t->validated = GL_TRUE;
    return !t->border_fallback;
 }
 
-
-
 static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit )
 {
+   r100ContextPtr rmesa = R100_CONTEXT(ctx);
    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
 
-   TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_TEXRECT_0 << unit, 0 );
 
-   if ( texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT) ) {
-      TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_TEXRECT_0 << unit, 1 );
-
-      return (enable_tex_rect( ctx, unit ) &&
-             update_tex_common( ctx, unit ));
-   }
-   else if ( texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) {
-      return (enable_tex_2d( ctx, unit ) &&
-             update_tex_common( ctx, unit ));
+   if (ctx->Texture.Unit[unit]._ReallyEnabled & TEXTURE_3D_BIT) {
+     return GL_FALSE;
    }
-   else if ( texUnit->_ReallyEnabled ) {
-      return GL_FALSE;
+
+   if (!ctx->Texture.Unit[unit]._ReallyEnabled) {
+     /* disable the unit */
+     disable_tex_obj_state(rmesa, unit);
+     return GL_TRUE;
    }
-   else {
-      disable_tex( ctx, unit );
-      return GL_TRUE;
+
+   if (!radeon_validate_texture(ctx, ctx->Texture.Unit[unit]._Current, unit)) {
+    _mesa_warning(ctx,
+                 "failed to validate texture for unit %d.\n",
+                 unit);
+    rmesa->state.texture.unit[unit].texobj = NULL;
+    return GL_FALSE;
    }
+   rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
+   return GL_TRUE;
 }
 
 void radeonUpdateTextureState( GLcontext *ctx )
 {
-   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+   r100ContextPtr rmesa = R100_CONTEXT(ctx);
    GLboolean ok;
 
+   /* set the ctx all textures off */
+   RADEON_STATECHANGE( rmesa, ctx );
+   rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~((RADEON_TEX_ENABLE_MASK) | (RADEON_TEX_BLEND_ENABLE_MASK));
+
    ok = (radeonUpdateTextureUnit( ctx, 0 ) &&
-        radeonUpdateTextureUnit( ctx, 1 ));
+        radeonUpdateTextureUnit( ctx, 1 ) &&
+        radeonUpdateTextureUnit( ctx, 2 ));
 
    FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, !ok );
 
-   if (rmesa->TclFallback)
+   if (rmesa->radeon.TclFallback)
       radeonChooseVertexState( ctx );
 }