mesa: drop fence type parameter from NewSyncObject()
[mesa.git] / src / mesa / drivers / dri / r200 / r200_texstate.c
index 3f9a2f4ac1bcf11dc18c05c007f6d3ed6d2c688e..dcf211f521e0a4226227e47bb7297a783a99e4f4 100644 (file)
@@ -29,17 +29,20 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 /*
  * Authors:
- *   Keith Whitwell <keith@tungstengraphics.com>
+ *   Keith Whitwell <keithw@vmware.com>
  */
 
 #include "main/glheader.h"
 #include "main/imports.h"
 #include "main/context.h"
 #include "main/macros.h"
-#include "main/texformat.h"
+#include "main/state.h"
+#include "main/teximage.h"
 #include "main/texobj.h"
 #include "main/enums.h"
 
+#include "radeon_common.h"
+#include "radeon_mipmap_tree.h"
 #include "r200_context.h"
 #include "r200_state.h"
 #include "r200_ioctl.h"
@@ -47,348 +50,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "r200_tex.h"
 #include "r200_tcl.h"
 
-
-#define R200_TXFORMAT_A8        R200_TXFORMAT_I8
-#define R200_TXFORMAT_L8        R200_TXFORMAT_I8
-#define R200_TXFORMAT_AL88      R200_TXFORMAT_AI88
-#define R200_TXFORMAT_YCBCR     R200_TXFORMAT_YVYU422
-#define R200_TXFORMAT_YCBCR_REV R200_TXFORMAT_VYUY422
-#define R200_TXFORMAT_RGB_DXT1  R200_TXFORMAT_DXT1
-#define R200_TXFORMAT_RGBA_DXT1 R200_TXFORMAT_DXT1
-#define R200_TXFORMAT_RGBA_DXT3 R200_TXFORMAT_DXT23
-#define R200_TXFORMAT_RGBA_DXT5 R200_TXFORMAT_DXT45
-
-#define _COLOR(f) \
-    [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, 0 }
-#define _COLOR_REV(f) \
-    [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f, 0 }
-#define _ALPHA(f) \
-    [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
-#define _ALPHA_REV(f) \
-    [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
-#define _YUV(f) \
-    [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, R200_YUV_TO_RGB }
-#define _INVALID(f) \
-    [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \
-                            && (tx_table_be[f].format != 0xffffffff) )
-
-struct tx_table {
-   GLuint format, filter;
-};
-
-static const struct tx_table tx_table_be[] =
-{
-   [ MESA_FORMAT_RGBA8888 ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
-   _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),
-   _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),
-};
-
-static const struct tx_table tx_table_le[] =
-{
-   _ALPHA(RGBA8888),
-   [ MESA_FORMAT_RGBA8888_REV ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
-   _ALPHA(ARGB8888),
-   _ALPHA_REV(ARGB8888),
-   [ MESA_FORMAT_RGB888 ] = { R200_TXFORMAT_ARGB8888, 0 },
-   _COLOR(RGB565),
-   _COLOR_REV(RGB565),
-   _ALPHA(ARGB4444),
-   _ALPHA_REV(ARGB4444),
-   _ALPHA(ARGB1555),
-   _ALPHA_REV(ARGB1555),
-   _ALPHA(AL88),
-   _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 r200SetTexImages( r200ContextPtr rmesa,
-                             struct gl_texture_object *tObj )
-{
-   r200TexObjPtr t = (r200TexObjPtr)tObj->DriverData;
-   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
-    */
-   if ( !t->image_override ) {
-      if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) {
-        const struct tx_table *table = _mesa_little_endian() ? tx_table_le :
-                                                               tx_table_be;
-
-         t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK |
-                             R200_TXFORMAT_ALPHA_IN_MAP);
-         t->pp_txfilter &= ~R200_YUV_TO_RGB;
-
-        t->pp_txformat |= table[ baseImage->TexFormat->MesaFormat ].format;
-        t->pp_txfilter |= table[ baseImage->TexFormat->MesaFormat ].filter;
-      }
-      else {
-         _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__);
-         return;
-      }
-   }
-
-   texelBytes = baseImage->TexFormat->TexelBytes;
-
-   /* Compute which mipmap levels we really want to send to the hardware.
-    */
-
-   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 = t->base.lastLevel - t->base.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;
-   blitWidth = BLIT_WIDTH_BYTES;
-   t->tile_bits = 0;
-
-   /* figure out if this texture is suitable for tiling. */
-   if (texelBytes) {
-      if (rmesa->texmicrotile  && (tObj->Target != GL_TEXTURE_RECTANGLE_NV) &&
-      /* texrect might be able to use micro tiling too in theory? */
-        (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)) {
-           t->tile_bits |= R200_TXO_MICRO_TILE;
-        }
-      }
-      if (tObj->Target != GL_TEXTURE_RECTANGLE_NV) {
-        /* we can set macro tiling even for small textures, they will be untiled anyway */
-        t->tile_bits |= R200_TXO_MACRO_TILE;
-      }
-   }
-
-   for (i = 0; i < numLevels; i++) {
-      const struct gl_texture_image *texImage;
-      GLuint size;
-
-      texImage = tObj->Image[0][i + t->base.firstLevel];
-      if ( !texImage )
-        break;
-
-      /* find image size in bytes */
-      if (texImage->IsCompressed) {
-      /* 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 & R200_TXFORMAT_FORMAT_MASK) == R200_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 * texelBytes + 63) & ~63) * texImage->Height;
-      }
-      else if (t->tile_bits & R200_TXO_MICRO_TILE) {
-        /* 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 * texelBytes + 31) & ~31;
-        size = w * texImage->Height * texImage->Depth;
-        blitWidth = MAX2(texImage->Width, 64 / texelBytes);
-      }
-      assert(size > 0);
-
-      /* Align to 32-byte offset.  It is faster to do this unconditionally
-       * (no branch penalty).
-       */
-
-      curOffset = (curOffset + 0x1f) & ~0x1f;
-
-      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 */
-      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;
-
-   /* Setup remaining cube face blits, if needed */
-   if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
-      const GLuint faceSize = t->base.totalSize;
-      GLuint face;
-      /* reuse face 0 x/y/width/height - just update the offset when uploading */
-      for (face = 1; face < 6; face++) {
-         for (i = 0; i < numLevels; i++) {
-            t->image[face][i].x =  t->image[0][i].x;
-            t->image[face][i].y =  t->image[0][i].y;
-            t->image[face][i].width  = t->image[0][i].width;
-            t->image[face][i].height = t->image[0][i].height;
-         }
-      }
-      t->base.totalSize = 6 * faceSize; /* total texmem needed */
-   }
-
-
-   /* Hardware state:
-    */
-   t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK;
-   t->pp_txfilter |= (numLevels - 1) << R200_MAX_MIP_LEVEL_SHIFT;
-
-   t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
-                      R200_TXFORMAT_HEIGHT_MASK |
-                       R200_TXFORMAT_CUBIC_MAP_ENABLE |
-                       R200_TXFORMAT_F5_WIDTH_MASK |
-                       R200_TXFORMAT_F5_HEIGHT_MASK);
-   t->pp_txformat |= ((log2Width << R200_TXFORMAT_WIDTH_SHIFT) |
-                     (log2Height << R200_TXFORMAT_HEIGHT_SHIFT));
-
-   t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK);
-   if (tObj->Target == GL_TEXTURE_3D) {
-      t->pp_txformat_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT);
-      t->pp_txformat_x |= R200_TEXCOORD_VOLUME;
-   }
-   else if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
-      ASSERT(log2Width == log2Height);
-      t->pp_txformat |= ((log2Width << R200_TXFORMAT_F5_WIDTH_SHIFT) |
-                         (log2Height << R200_TXFORMAT_F5_HEIGHT_SHIFT) |
-/* don't think we need this bit, if it exists at all - fglrx does not set it */
-                         (R200_TXFORMAT_CUBIC_MAP_ENABLE));
-      t->pp_txformat_x |= R200_TEXCOORD_CUBIC_ENV;
-      t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) |
-                           (log2Height << R200_FACE_HEIGHT_1_SHIFT) |
-                           (log2Width << R200_FACE_WIDTH_2_SHIFT) |
-                           (log2Height << R200_FACE_HEIGHT_2_SHIFT) |
-                           (log2Width << R200_FACE_WIDTH_3_SHIFT) |
-                           (log2Height << R200_FACE_HEIGHT_3_SHIFT) |
-                           (log2Width << R200_FACE_WIDTH_4_SHIFT) |
-                           (log2Height << R200_FACE_HEIGHT_4_SHIFT));
-   }
-   else {
-      /* If we don't in fact send enough texture coordinates, q will be 1,
-       * making TEXCOORD_PROJ act like TEXCOORD_NONPROJ (Right?)
-       */
-      t->pp_txformat_x |= R200_TEXCOORD_PROJ;
-   }
-
-   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 ( !t->image_override ) {
-      if (baseImage->IsCompressed)
-         t->pp_txpitch = (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63);
-      else
-         t->pp_txpitch = ((tObj->Image[0][t->base.firstLevel]->Width * texelBytes) + 63) & ~(63);
-      t->pp_txpitch -= 32;
-   }
-
-   t->dirty_state = TEX_ALL;
-
-   /* FYI: r200UploadTexImages( rmesa, t ) used to be called here */
-}
-
-
+                             && (tx_table_be[f].format != 0xffffffff) )
 
 /* ================================================================
  * Texture combine functions
@@ -551,7 +214,7 @@ do {                                                        \
  * Texture unit state management
  */
 
-static GLboolean r200UpdateTextureEnv( GLcontext *ctx, int unit, int slot, GLuint replaceargs )
+static GLboolean r200UpdateTextureEnv( struct gl_context *ctx, int unit, int slot, GLuint replaceargs )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
@@ -563,14 +226,8 @@ static GLboolean r200UpdateTextureEnv( GLcontext *ctx, int unit, int slot, GLuin
       ~(R200_TXA_DOT_ALPHA | R200_TXA_SCALE_MASK | R200_TXA_OUTPUT_REG_MASK |
        R200_TXA_TFACTOR_SEL_MASK | R200_TXA_TFACTOR1_SEL_MASK);
 
-   /* texUnit->_Current can be NULL if and only if the texture unit is
-    * not actually enabled.
-    */
-   assert( (texUnit->_ReallyEnabled == 0)
-          || (texUnit->_Current != NULL) );
-
-   if ( R200_DEBUG & DEBUG_TEXTURE ) {
-      fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx, unit );
+   if ( R200_DEBUG & RADEON_TEXTURE ) {
+      fprintf( stderr, "%s( %p, %d )\n", __func__, (void *)ctx, unit );
    }
 
    /* Set the texture environment state.  Isn't this nice and clean?
@@ -587,7 +244,7 @@ static GLboolean r200UpdateTextureEnv( GLcontext *ctx, int unit, int slot, GLuin
                        (unit << R200_TXA_TFACTOR_SEL_SHIFT) |
                        (replaceargs << R200_TXA_TFACTOR1_SEL_SHIFT);
 
-   if ( !texUnit->_ReallyEnabled ) {
+   if ( !texUnit->_Current ) {
       assert( unit == 0);
       color_combine = R200_TXC_ARG_A_ZERO | R200_TXC_ARG_B_ZERO
          | R200_TXC_ARG_C_DIFFUSE_COLOR | R200_TXC_OP_MADD;
@@ -976,48 +633,125 @@ static GLboolean r200UpdateTextureEnv( GLcontext *ctx, int unit, int slot, GLuin
    return GL_TRUE;
 }
 
-void r200SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
-                     unsigned long long offset, GLint depth, GLuint pitch)
+void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint texture_format,
+                      __DRIdrawable *dPriv)
 {
-       r200ContextPtr rmesa = pDRICtx->driverPrivate;
-       struct gl_texture_object *tObj =
-           _mesa_lookup_texture(rmesa->glCtx, texname);
-       r200TexObjPtr t;
-
-       if (!tObj)
+       struct gl_texture_object *texObj;
+       struct gl_texture_image *texImage;
+       struct radeon_renderbuffer *rb;
+       radeon_texture_image *rImage;
+       radeonContextPtr radeon;
+       struct radeon_framebuffer *rfb;
+       radeonTexObjPtr t;
+       uint32_t pitch_val;
+       mesa_format texFormat;
+
+       radeon = pDRICtx->driverPrivate;
+
+       rfb = dPriv->driverPrivate;
+       texObj = _mesa_get_current_tex_object(&radeon->glCtx, 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, GL_TRUE);
+       rb = rfb->color_rb[0];
+       if (rb->bo == NULL) {
+               /* Failed to BO for the buffer */
                return;
+       }
 
-       t = (r200TexObjPtr) tObj->DriverData;
-
-       t->image_override = GL_TRUE;
-
-       if (!offset)
-               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;
+       }
 
-       t->pp_txoffset = offset;
-       t->pp_txpitch = pitch - 32;
+       radeon_miptree_unreference(&t->mt);
+       radeon_miptree_unreference(&rImage->mt);
 
-       switch (depth) {
-       case 32:
-               t->pp_txformat = tx_table_le[MESA_FORMAT_ARGB8888].format;
-               t->pp_txfilter |= tx_table_le[MESA_FORMAT_ARGB8888].filter;
+       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:
+               if (texture_format == __DRI_TEXTURE_FORMAT_RGB) {
+                       texFormat = MESA_FORMAT_BGR_UNORM8;
+                       t->pp_txformat = tx_table_le[MESA_FORMAT_BGR_UNORM8].format;
+               }
+               else {
+                       texFormat = MESA_FORMAT_B8G8R8A8_UNORM;
+                       t->pp_txformat = tx_table_le[MESA_FORMAT_B8G8R8A8_UNORM].format;
+               }
+               t->pp_txfilter |= tx_table_le[MESA_FORMAT_B8G8R8A8_UNORM].filter;
                break;
-       case 24:
+       case 3:
        default:
-               t->pp_txformat = tx_table_le[MESA_FORMAT_RGB888].format;
-               t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB888].filter;
+               texFormat = MESA_FORMAT_BGR_UNORM8;
+               t->pp_txformat = tx_table_le[MESA_FORMAT_BGR_UNORM8].format;
+               t->pp_txfilter |= tx_table_le[MESA_FORMAT_BGR_UNORM8].filter;
                break;
-       case 16:
-               t->pp_txformat = tx_table_le[MESA_FORMAT_RGB565].format;
-               t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB565].filter;
+       case 2:
+               texFormat = MESA_FORMAT_B5G6R5_UNORM;
+               t->pp_txformat = tx_table_le[MESA_FORMAT_B5G6R5_UNORM].format;
+               t->pp_txfilter |= tx_table_le[MESA_FORMAT_B5G6R5_UNORM].filter;
                break;
        }
+
+       _mesa_init_teximage_fields(&radeon->glCtx, texImage,
+                                  rb->base.Base.Width, rb->base.Base.Height,
+                                  1, 0,
+                                  rb->cpp, texFormat);
+       rImage->base.RowStride = rb->pitch / rb->cpp;
+
+
+        t->pp_txsize = ((rb->base.Base.Width - 1) << RADEON_TEX_USIZE_SHIFT)
+                  | ((rb->base.Base.Height - 1) << RADEON_TEX_VSIZE_SHIFT);
+
+       if (target == GL_TEXTURE_RECTANGLE_NV) {
+               t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
+               t->pp_txpitch = pitch_val;
+               t->pp_txpitch -= 32;
+       } else {
+               t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
+                                   R200_TXFORMAT_HEIGHT_MASK |
+                                   R200_TXFORMAT_CUBIC_MAP_ENABLE |
+                                   R200_TXFORMAT_F5_WIDTH_MASK |
+                                   R200_TXFORMAT_F5_HEIGHT_MASK);
+               t->pp_txformat |= ((texImage->WidthLog2 << R200_TXFORMAT_WIDTH_SHIFT) |
+                                  (texImage->HeightLog2 << R200_TXFORMAT_HEIGHT_SHIFT));
+       }
+
+       t->validated = GL_TRUE;
+       _mesa_unlock_texture(&radeon->glCtx, texObj);
+       return;
 }
 
+
+void r200SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
+{
+        r200SetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
+}
+
+
 #define REF_COLOR 1
 #define REF_ALPHA 2
 
-static GLboolean r200UpdateAllTexEnv( GLcontext *ctx )
+static GLboolean r200UpdateAllTexEnv( struct gl_context *ctx )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    GLint i, j, currslot;
@@ -1030,7 +764,7 @@ static GLboolean r200UpdateAllTexEnv( GLcontext *ctx )
 
    /* find highest used unit */
    for ( j = 0; j < R200_MAX_TEXTURE_UNITS; j++) {
-      if (ctx->Texture.Unit[j]._ReallyEnabled) {
+      if (ctx->Texture.Unit[j]._Current) {
         maxunitused = j;
       }
    }
@@ -1059,7 +793,7 @@ static GLboolean r200UpdateAllTexEnv( GLcontext *ctx )
 
          nextunit[j] = currentnext;
 
-         if (!texUnit->_ReallyEnabled) {
+         if (!texUnit->_Current) {
         /* the not enabled stages are referenced "indirectly",
             must not cut off the lower stages */
            stageref[j] = REF_COLOR | REF_ALPHA;
@@ -1131,8 +865,8 @@ static GLboolean r200UpdateAllTexEnv( GLcontext *ctx )
 
    /* don't enable texture sampling for units if the result is not used */
    for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) {
-      if (ctx->Texture.Unit[i]._ReallyEnabled && !texregfree[i])
-        rmesa->state.texture.unit[i].unitneeded = ctx->Texture.Unit[i]._ReallyEnabled;
+      if (ctx->Texture.Unit[i]._Current && !texregfree[i])
+        rmesa->state.texture.unit[i].unitneeded = 1 << _mesa_tex_target_to_index(ctx, ctx->Texture.Unit[i]._Current->Target);
       else rmesa->state.texture.unit[i].unitneeded = 0;
    }
 
@@ -1143,7 +877,7 @@ static GLboolean r200UpdateAllTexEnv( GLcontext *ctx )
    i = 0;
    while ((i <= maxunitused) && (i >= 0)) {
       /* only output instruction if the results are referenced */
-      if (ctx->Texture.Unit[i]._ReallyEnabled && stageref[i+1]) {
+      if (ctx->Texture.Unit[i]._Current && stageref[i+1]) {
          GLuint replaceunit = i;
         /* try to optimize GL_REPLACE away (only one level deep though) */
         if (   (ctx->Texture.Unit[i]._CurrentCombine->ModeRGB == GL_REPLACE) &&
@@ -1203,16 +937,48 @@ static GLboolean r200UpdateAllTexEnv( GLcontext *ctx )
 
 #define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK |         \
                                 R200_TEXCOORD_MASK |           \
+                                R200_MIN_MIP_LEVEL_MASK |      \
                                 R200_CLAMP_Q_MASK |            \
                                 R200_VOLUME_FILTER_MASK)
 
 
+static void disable_tex_obj_state( r200ContextPtr rmesa, 
+                                  int unit )
+{
+   
+   R200_STATECHANGE( rmesa, vtx );
+   rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
+
+   R200_STATECHANGE( rmesa, ctx );
+   rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_0_ENABLE << unit);
+   if (rmesa->radeon.TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<<unit)) {
+      TCL_FALLBACK( &rmesa->radeon.glCtx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
+   }
+
+   /* Actually want to keep all units less than max active texture
+    * enabled, right?  Fix this for >2 texunits.
+    */
+
+   {
+      GLuint tmp = rmesa->TexGenEnabled;
+
+      rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
+      rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
+      rmesa->TexGenNeedNormals[unit] = GL_FALSE;
+      rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
+
+      if (tmp != rmesa->TexGenEnabled) {
+        rmesa->recheck_texgen[unit] = GL_TRUE;
+        rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
+      }
+   }
+}
 static void import_tex_obj_state( r200ContextPtr rmesa,
                                  int unit,
-                                 r200TexObjPtr texobj )
+                                 radeonTexObjPtr texobj )
 {
 /* do not use RADEON_DB_STATE to avoid stale texture caches */
-   int *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
+   GLuint *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
 
    R200_STATECHANGE( rmesa, tex[unit] );
 
@@ -1225,36 +991,19 @@ static void import_tex_obj_state( r200ContextPtr rmesa,
    cmd[TEX_PP_TXSIZE] = texobj->pp_txsize; /* NPOT only! */
    cmd[TEX_PP_TXPITCH] = texobj->pp_txpitch; /* NPOT only! */
    cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
-   if (rmesa->r200Screen->drmSupportsFragShader) {
-      cmd[TEX_PP_TXOFFSET_NEWDRM] = texobj->pp_txoffset;
-   }
-   else {
-      cmd[TEX_PP_TXOFFSET_OLDDRM] = texobj->pp_txoffset;
-   }
 
-   if (texobj->base.tObj->Target == GL_TEXTURE_CUBE_MAP) {
-      int *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
-      GLuint bytesPerFace = texobj->base.totalSize / 6;
-      ASSERT(texobj->base.totalSize % 6 == 0);
+   if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) {
+      GLuint *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
 
       R200_STATECHANGE( rmesa, cube[unit] );
       cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
-      if (rmesa->r200Screen->drmSupportsFragShader) {
-        /* that value is submitted twice. could change cube atom
-           to not include that command when new drm is used */
-        cmd[TEX_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
-      }
-      cube_cmd[CUBE_PP_CUBIC_OFFSET_F1] = texobj->pp_txoffset + 1 * bytesPerFace;
-      cube_cmd[CUBE_PP_CUBIC_OFFSET_F2] = texobj->pp_txoffset + 2 * bytesPerFace;
-      cube_cmd[CUBE_PP_CUBIC_OFFSET_F3] = texobj->pp_txoffset + 3 * bytesPerFace;
-      cube_cmd[CUBE_PP_CUBIC_OFFSET_F4] = texobj->pp_txoffset + 4 * bytesPerFace;
-      cube_cmd[CUBE_PP_CUBIC_OFFSET_F5] = texobj->pp_txoffset + 5 * bytesPerFace;
+      /* that value is submitted twice. could change cube atom
+         to not include that command when new drm is used */
+      cmd[TEX_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
    }
 
-   texobj->dirty_state &= ~(1<<unit);
 }
 
-
 static void set_texgen_matrix( r200ContextPtr rmesa, 
                               GLuint unit,
                               const GLfloat *s_plane,
@@ -1334,7 +1083,7 @@ static GLuint r200_need_dis_texgen(const GLbitfield texGenEnabled,
 /*
  * Returns GL_FALSE if fallback required.  
  */
-static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
+static GLboolean r200_validate_texgen( struct gl_context *ctx, GLuint unit )
 {  
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
@@ -1363,40 +1112,39 @@ static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
                                                    (unit * 4));
 
    if (0) 
-      fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit);
+      fprintf(stderr, "%s unit %d\n", __func__, unit);
 
    if (texUnit->TexGenEnabled & S_BIT) {
-      mode = texUnit->GenModeS;
+      mode = texUnit->GenS.Mode;
    } else {
       tgcm |= R200_TEXGEN_COMP_S << (unit * 4);
    }
 
    if (texUnit->TexGenEnabled & T_BIT) {
-      if (texUnit->GenModeT != mode)
+      if (texUnit->GenT.Mode != mode)
         mixed_fallback = GL_TRUE;
    } else {
       tgcm |= R200_TEXGEN_COMP_T << (unit * 4);
    }
-
    if (texUnit->TexGenEnabled & R_BIT) {
-      if (texUnit->GenModeR != mode)
+      if (texUnit->GenR.Mode != mode)
         mixed_fallback = GL_TRUE;
    } else {
       tgcm |= R200_TEXGEN_COMP_R << (unit * 4);
    }
 
    if (texUnit->TexGenEnabled & Q_BIT) {
-      if (texUnit->GenModeQ != mode)
+      if (texUnit->GenQ.Mode != mode)
         mixed_fallback = GL_TRUE;
    } else {
       tgcm |= R200_TEXGEN_COMP_Q << (unit * 4);
    }
 
    if (mixed_fallback) {
-      if (R200_DEBUG & DEBUG_FALLBACKS)
+      if (R200_DEBUG & RADEON_FALLBACKS)
         fprintf(stderr, "fallback mixed texgen, 0x%x (0x%x 0x%x 0x%x 0x%x)\n",
-                texUnit->TexGenEnabled, texUnit->GenModeS, texUnit->GenModeT,
-                texUnit->GenModeR, texUnit->GenModeQ);
+                texUnit->TexGenEnabled, texUnit->GenS.Mode, texUnit->GenT.Mode,
+                texUnit->GenR.Mode, texUnit->GenQ.Mode);
       return GL_FALSE;
    }
 
@@ -1414,10 +1162,12 @@ static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
    switch (mode) {
    case GL_OBJECT_LINEAR: {
       GLuint needtgenable = r200_need_dis_texgen( texUnit->TexGenEnabled,
-                               texUnit->ObjectPlaneS, texUnit->ObjectPlaneT,
-                               texUnit->ObjectPlaneR, texUnit->ObjectPlaneQ );
+                                                  texUnit->GenS.ObjectPlane,
+                                                  texUnit->GenT.ObjectPlane,
+                                                  texUnit->GenR.ObjectPlane,
+                                                  texUnit->GenQ.ObjectPlane );
       if (needtgenable & (S_BIT | T_BIT)) {
-        if (R200_DEBUG & DEBUG_FALLBACKS)
+        if (R200_DEBUG & RADEON_FALLBACKS)
         fprintf(stderr, "fallback mixed texgen / obj plane, 0x%x\n",
                 texUnit->TexGenEnabled);
         return GL_FALSE;
@@ -1431,19 +1181,21 @@ static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
 
       tgi |= R200_TEXGEN_INPUT_OBJ << inputshift;
       set_texgen_matrix( rmesa, unit, 
-        (texUnit->TexGenEnabled & S_BIT) ? texUnit->ObjectPlaneS : I,
-        (texUnit->TexGenEnabled & T_BIT) ? texUnit->ObjectPlaneT : I + 4,
-        (texUnit->TexGenEnabled & R_BIT) ? texUnit->ObjectPlaneR : I + 8,
-        (texUnit->TexGenEnabled & Q_BIT) ? texUnit->ObjectPlaneQ : I + 12);
+        (texUnit->TexGenEnabled & S_BIT) ? texUnit->GenS.ObjectPlane : I,
+        (texUnit->TexGenEnabled & T_BIT) ? texUnit->GenT.ObjectPlane : I + 4,
+        (texUnit->TexGenEnabled & R_BIT) ? texUnit->GenR.ObjectPlane : I + 8,
+        (texUnit->TexGenEnabled & Q_BIT) ? texUnit->GenQ.ObjectPlane : I + 12);
       }
       break;
 
    case GL_EYE_LINEAR: {
       GLuint needtgenable = r200_need_dis_texgen( texUnit->TexGenEnabled,
-                               texUnit->EyePlaneS, texUnit->EyePlaneT,
-                               texUnit->EyePlaneR, texUnit->EyePlaneQ );
+                                                  texUnit->GenS.EyePlane,
+                                                  texUnit->GenT.EyePlane,
+                                                  texUnit->GenR.EyePlane,
+                                                  texUnit->GenQ.EyePlane );
       if (needtgenable & (S_BIT | T_BIT)) {
-        if (R200_DEBUG & DEBUG_FALLBACKS)
+        if (R200_DEBUG & RADEON_FALLBACKS)
         fprintf(stderr, "fallback mixed texgen / eye plane, 0x%x\n",
                 texUnit->TexGenEnabled);
         return GL_FALSE;
@@ -1456,10 +1208,10 @@ static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
       }
       tgi |= R200_TEXGEN_INPUT_EYE << inputshift;
       set_texgen_matrix( rmesa, unit,
-        (texUnit->TexGenEnabled & S_BIT) ? texUnit->EyePlaneS : I,
-        (texUnit->TexGenEnabled & T_BIT) ? texUnit->EyePlaneT : I + 4,
-        (texUnit->TexGenEnabled & R_BIT) ? texUnit->EyePlaneR : I + 8,
-        (texUnit->TexGenEnabled & Q_BIT) ? texUnit->EyePlaneQ : I + 12);
+        (texUnit->TexGenEnabled & S_BIT) ? texUnit->GenS.EyePlane : I,
+        (texUnit->TexGenEnabled & T_BIT) ? texUnit->GenT.EyePlane : I + 4,
+        (texUnit->TexGenEnabled & R_BIT) ? texUnit->GenR.EyePlane : I + 8,
+        (texUnit->TexGenEnabled & Q_BIT) ? texUnit->GenQ.EyePlane : I + 12);
       }
       break;
 
@@ -1493,9 +1245,9 @@ static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
    default:
       /* Unsupported mode, fallback:
        */
-      if (R200_DEBUG & DEBUG_FALLBACKS)
+      if (R200_DEBUG & RADEON_FALLBACKS)
         fprintf(stderr, "fallback unsupported texgen, %d\n",
-                texUnit->GenModeS);
+                texUnit->GenS.Mode);
       return GL_FALSE;
    }
 
@@ -1513,53 +1265,7 @@ static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
    return GL_TRUE;
 }
 
-
-static void disable_tex( GLcontext *ctx, int unit )
-{
-   r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
-   if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_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;
-      }
-
-      R200_STATECHANGE( rmesa, ctx );
-      rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_0_ENABLE << unit);
-        
-      R200_STATECHANGE( rmesa, vtx );
-      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
-        
-      if (rmesa->TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<<unit)) {
-        TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
-      }
-
-      /* Actually want to keep all units less than max active texture
-       * enabled, right?  Fix this for >2 texunits.
-       */
-
-      {
-        GLuint tmp = rmesa->TexGenEnabled;
-
-        rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
-        rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
-        rmesa->TexGenNeedNormals[unit] = GL_FALSE;
-        rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
-
-        if (tmp != rmesa->TexGenEnabled) {
-           rmesa->recheck_texgen[unit] = GL_TRUE;
-           rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
-        }
-      }
-   }
-}
-
-void set_re_cntl_d3d( GLcontext *ctx, int unit, GLboolean use_d3d )
+void set_re_cntl_d3d( struct gl_context *ctx, int unit, GLboolean use_d3d )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
 
@@ -1575,241 +1281,195 @@ void set_re_cntl_d3d( GLcontext *ctx, int unit, GLboolean use_d3d )
    }
 }
 
-static GLboolean enable_tex_2d( 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 void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t)
 {
-   r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
-   struct gl_texture_object *tObj = texUnit->_Current;
-   r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData;
+   const struct gl_texture_image *firstImage = t->base.Image[0][t->minLod];
+   GLint log2Width, log2Height, log2Depth, texelBytes;
+   uint extra_size = 0;
 
-   /* Need to load the 2d images associated with this unit.
-    */
-   if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) {
-      t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2;
-      t->base.dirty_images[0] = ~0;
+   if ( t->bo ) {
+       return;
    }
 
-   ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D);
+   log2Width  = firstImage->WidthLog2;
+   log2Height = firstImage->HeightLog2;
+   log2Depth  = firstImage->DepthLog2;
+   texelBytes = _mesa_get_format_bytes(firstImage->TexFormat);
 
-   if ( t->base.dirty_images[0] ) {
-      R200_FIREVERTICES( rmesa );
-      r200SetTexImages( rmesa, tObj );
-      r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 );
-      if ( !t->base.memBlock && !t->image_override ) 
-        return GL_FALSE;
-   }
+   radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+       "%s(%p, tex %p) log2(w %d, h %d, d %d), texelBytes %d. format %d\n",
+       __func__, rmesa, t, log2Width, log2Height,
+       log2Depth, texelBytes, firstImage->TexFormat);
 
-   set_re_cntl_d3d( ctx, unit, GL_FALSE );
-
-   return GL_TRUE;
-}
-
-#if ENABLE_HW_3D_TEXTURE
-static GLboolean enable_tex_3d( GLcontext *ctx, int unit )
-{
-   r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
-   struct gl_texture_object *tObj = texUnit->_Current;
-   r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData;
-
-   /* Need to load the 3d images associated with this unit.
-    */
-   if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) {
-      t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2;
-      t->base.dirty_images[0] = ~0;
-   }
+   if (!t->image_override) {
+      if (VALID_FORMAT(firstImage->TexFormat)) {
+        const struct tx_table *table = _mesa_little_endian() ? tx_table_le :
+           tx_table_be;
+        
+        t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK |
+                            R200_TXFORMAT_ALPHA_IN_MAP);
+        t->pp_txfilter &= ~R200_YUV_TO_RGB;
+        
+        t->pp_txformat |= table[ firstImage->TexFormat ].format;
+        t->pp_txfilter |= table[ firstImage->TexFormat ].filter;
 
-   ASSERT(tObj->Target == GL_TEXTURE_3D);
 
-   /* R100 & R200 do not support mipmaps for 3D textures.
-    */
-   if ( (tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR) ) {
-      return GL_FALSE;
-   }
-
-   if ( t->base.dirty_images[0] ) {
-      R200_FIREVERTICES( rmesa );
-      r200SetTexImages( rmesa, tObj );
-      r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 );
-      if ( !t->base.memBlock ) 
-        return GL_FALSE;
+      } else {
+        _mesa_problem(NULL, "unexpected texture format in %s",
+                      __func__);
+        return;
+      }
    }
 
-   set_re_cntl_d3d( ctx, unit, GL_TRUE );
-
-   return GL_TRUE;
-}
-#endif
+   t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK;
+   t->pp_txfilter |= ((t->maxLod) << R200_MAX_MIP_LEVEL_SHIFT)
+          & R200_MAX_MIP_LEVEL_MASK;
+
+   if ( t->pp_txfilter &
+               (R200_MIN_FILTER_NEAREST_MIP_NEAREST
+                | R200_MIN_FILTER_NEAREST_MIP_LINEAR
+                | R200_MIN_FILTER_LINEAR_MIP_NEAREST
+                | R200_MIN_FILTER_LINEAR_MIP_LINEAR
+                | R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST
+                | R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR))
+                extra_size = t->minLod;
 
-static GLboolean enable_tex_cube( GLcontext *ctx, int unit )
-{
-   r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
-   struct gl_texture_object *tObj = texUnit->_Current;
-   r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData;
-   GLuint face;
+   t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
+                      R200_TXFORMAT_HEIGHT_MASK |
+                      R200_TXFORMAT_CUBIC_MAP_ENABLE |
+                      R200_TXFORMAT_F5_WIDTH_MASK |
+                      R200_TXFORMAT_F5_HEIGHT_MASK);
+   t->pp_txformat |= (((log2Width + extra_size) << R200_TXFORMAT_WIDTH_SHIFT) |
+                     ((log2Height + extra_size)<< R200_TXFORMAT_HEIGHT_SHIFT));
+   
+   t->tile_bits = 0;
+   
+   t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK
+                  | R200_MIN_MIP_LEVEL_MASK);
 
-   /* Need to load the 2d images associated with this unit.
-    */
-   if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) {
-      t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2;
-      for (face = 0; face < 6; face++)
-         t->base.dirty_images[face] = ~0;
-   }
+   t->pp_txformat_x |= (t->minLod << R200_MIN_MIP_LEVEL_SHIFT)
+          & R200_MIN_MIP_LEVEL_MASK;
 
-   ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP);
+   if (t->base.Target == GL_TEXTURE_3D) {
+      t->pp_txformat_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT);
+      t->pp_txformat_x |= R200_TEXCOORD_VOLUME;
 
-   if ( t->base.dirty_images[0] || t->base.dirty_images[1] ||
-        t->base.dirty_images[2] || t->base.dirty_images[3] ||
-        t->base.dirty_images[4] || t->base.dirty_images[5] ) {
-      /* flush */
-      R200_FIREVERTICES( rmesa );
-      /* layout memory space, once for all faces */
-      r200SetTexImages( rmesa, tObj );
    }
-
-   /* upload (per face) */
-   for (face = 0; face < 6; face++) {
-      if (t->base.dirty_images[face]) {
-         r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, face );
-      }
+   else if (t->base.Target == GL_TEXTURE_CUBE_MAP) {
+      assert(log2Width == log2Height);
+      t->pp_txformat |= ((log2Width << R200_TXFORMAT_F5_WIDTH_SHIFT) |
+                        (log2Height << R200_TXFORMAT_F5_HEIGHT_SHIFT) |
+                        /* don't think we need this bit, if it exists at all - fglrx does not set it */
+                        (R200_TXFORMAT_CUBIC_MAP_ENABLE));
+      t->pp_txformat_x |= R200_TEXCOORD_CUBIC_ENV;
+      t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) |
+                           (log2Height << R200_FACE_HEIGHT_1_SHIFT) |
+                           (log2Width << R200_FACE_WIDTH_2_SHIFT) |
+                           (log2Height << R200_FACE_HEIGHT_2_SHIFT) |
+                           (log2Width << R200_FACE_WIDTH_3_SHIFT) |
+                           (log2Height << R200_FACE_HEIGHT_3_SHIFT) |
+                           (log2Width << R200_FACE_WIDTH_4_SHIFT) |
+                           (log2Height << R200_FACE_HEIGHT_4_SHIFT));
    }
-      
-   if ( !t->base.memBlock ) {
-      /* texmem alloc failed, use s/w fallback */
-      return GL_FALSE;
+   else {
+      /* If we don't in fact send enough texture coordinates, q will be 1,
+       * making TEXCOORD_PROJ act like TEXCOORD_NONPROJ (Right?)
+       */
+      t->pp_txformat_x |= R200_TEXCOORD_PROJ;
    }
+   /* FIXME: NPOT sizes, is it correct really? */
+   t->pp_txsize = (((firstImage->Width - 1) << R200_PP_TX_WIDTHMASK_SHIFT)
+                  | ((firstImage->Height - 1) << R200_PP_TX_HEIGHTMASK_SHIFT));
 
-   set_re_cntl_d3d( ctx, unit, GL_TRUE );
-
-   return GL_TRUE;
-}
-
-static GLboolean enable_tex_rect( GLcontext *ctx, int unit )
-{
-   r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
-   struct gl_texture_object *tObj = texUnit->_Current;
-   r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData;
-
-   if (!(t->pp_txformat & R200_TXFORMAT_NON_POWER2)) {
-      t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
-      t->base.dirty_images[0] = ~0;
+   if ( !t->image_override ) {
+      if (_mesa_is_format_compressed(firstImage->TexFormat))
+         t->pp_txpitch = (firstImage->Width + 63) & ~(63);
+      else
+         t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63);
+      t->pp_txpitch -= 32;
    }
 
-   ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);
-
-   if ( t->base.dirty_images[0] ) {
-      R200_FIREVERTICES( rmesa );
-      r200SetTexImages( rmesa, tObj );
-      r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 );
-      if ( !t->base.memBlock &&
-           !t->image_override &&
-           !rmesa->prefer_gart_client_texturing ) 
-        return GL_FALSE;
+   if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
+      t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
    }
 
-   set_re_cntl_d3d( ctx, unit, GL_FALSE );
-
-   return GL_TRUE;
 }
 
-
-static GLboolean update_tex_common( GLcontext *ctx, int unit )
+static GLboolean r200_validate_texture(struct gl_context *ctx, struct gl_texture_object *texObj, int unit)
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
-   struct gl_texture_object *tObj = texUnit->_Current;
-   r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData;
-
-   /* Fallback if there's a texture border */
-   if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 )
-       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! */
-   }
-
+   radeonTexObj *t = radeon_tex_obj(texObj);
 
-   /* Newly enabled?
-    */
-   if ( 1|| !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE<<unit))) {
-      R200_STATECHANGE( rmesa, ctx );
-      rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << unit;
-
-      R200_STATECHANGE( rmesa, vtx );
-      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
-      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3);
+   if (!radeon_validate_texture_miptree(ctx, _mesa_get_samplerobj(ctx, unit), texObj))
+      return GL_FALSE;
 
-      rmesa->recheck_texgen[unit] = GL_TRUE;
-   }
+   r200_validate_texgen(ctx, unit);
+   /* Configure the hardware registers (more precisely, the cached version
+    * of the hardware registers). */
+   setup_hardware_state(rmesa, t);
+
+   if (texObj->Target == GL_TEXTURE_RECTANGLE_NV ||
+       texObj->Target == GL_TEXTURE_2D ||
+       texObj->Target == GL_TEXTURE_1D)
+      set_re_cntl_d3d( ctx, unit, GL_FALSE );
+   else
+      set_re_cntl_d3d( ctx, unit, GL_TRUE );
+   R200_STATECHANGE( rmesa, ctx );
+   rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << unit;
+   
+   R200_STATECHANGE( rmesa, vtx );
+   rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
+   rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3);
 
-   if (t->dirty_state & (1<<unit)) {
-      import_tex_obj_state( rmesa, unit, t );
-   }
+   rmesa->recheck_texgen[unit] = GL_TRUE;
+   r200TexUpdateParameters(ctx, unit);
+   import_tex_obj_state( rmesa, unit, t );
 
    if (rmesa->recheck_texgen[unit]) {
       GLboolean fallback = !r200_validate_texgen( ctx, unit );
       TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
       rmesa->recheck_texgen[unit] = 0;
-      rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
+      rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
    }
 
-   FALLBACK( rmesa, R200_FALLBACK_BORDER_MODE, t->border_fallback );
-   return !t->border_fallback;
-}
+   t->validated = GL_TRUE;
 
+   FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback );
 
+   return !t->border_fallback;
+}
 
-static GLboolean r200UpdateTextureUnit( GLcontext *ctx, int unit )
+static GLboolean r200UpdateTextureUnit(struct gl_context *ctx, int unit)
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    GLuint unitneeded = rmesa->state.texture.unit[unit].unitneeded;
 
-   if ( unitneeded & (TEXTURE_RECT_BIT) ) {
-      return (enable_tex_rect( ctx, unit ) &&
-             update_tex_common( ctx, unit ));
-   }
-   else if ( unitneeded & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) {
-      return (enable_tex_2d( ctx, unit ) &&
-             update_tex_common( ctx, unit ));
-   }
-#if ENABLE_HW_3D_TEXTURE
-   else if ( unitneeded & (TEXTURE_3D_BIT) ) {
-      return (enable_tex_3d( ctx, unit ) &&
-             update_tex_common( ctx, unit ));
-   }
-#endif
-   else if ( unitneeded & (TEXTURE_CUBE_BIT) ) {
-      return (enable_tex_cube( ctx, unit ) &&
-             update_tex_common( ctx, unit ));
-   }
-   else if ( unitneeded ) {
-      return GL_FALSE;
-   }
-   else {
-      disable_tex( ctx, unit );
-      return GL_TRUE;
+   if (!unitneeded) {
+      /* disable the unit */
+     disable_tex_obj_state(rmesa, unit);
+     return GL_TRUE;
    }
+
+   if (!r200_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 r200UpdateTextureState( GLcontext *ctx )
+void r200UpdateTextureState( struct gl_context *ctx )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    GLboolean ok;
@@ -1821,10 +1481,13 @@ void r200UpdateTextureState( GLcontext *ctx )
       atoms. */
    R200_NEWPRIM( rmesa );
 
-   if (ctx->ATIFragmentShader._Enabled) {
+   if (_mesa_ati_fragment_shader_enabled(ctx)) {
       GLuint i;
       for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) {
-        rmesa->state.texture.unit[i].unitneeded = ctx->Texture.Unit[i]._ReallyEnabled;
+         if (ctx->Texture.Unit[i]._Current)
+            rmesa->state.texture.unit[i].unitneeded = 1 << _mesa_tex_target_to_index(ctx, ctx->Texture.Unit[i]._Current->Target);
+         else
+            rmesa->state.texture.unit[i].unitneeded = 0;
       }
       ok = GL_TRUE;
    }
@@ -1840,17 +1503,17 @@ void r200UpdateTextureState( GLcontext *ctx )
         r200UpdateTextureUnit( ctx, 5 ));
    }
 
-   if (ok && ctx->ATIFragmentShader._Enabled) {
+   if (ok && _mesa_ati_fragment_shader_enabled(ctx)) {
       r200UpdateFragmentShader(ctx);
    }
 
    FALLBACK( rmesa, R200_FALLBACK_TEXTURE, !ok );
 
-   if (rmesa->TclFallback)
+   if (rmesa->radeon.TclFallback)
       r200ChooseVertexState( ctx );
 
 
-   if (rmesa->r200Screen->chip_family == CHIP_FAMILY_R200) {
+   if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) {
 
       /*
        * T0 hang workaround -------------
@@ -1863,10 +1526,10 @@ void r200UpdateTextureState( GLcontext *ctx )
         R200_STATECHANGE(rmesa, tex[1]);
         rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_1_ENABLE;
         if (!(rmesa->hw.cst.cmd[CST_PP_CNTL_X] & R200_PPX_TEX_1_ENABLE))
-           rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
+          rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
         rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] |= R200_TXFORMAT_LOOKUP_DISABLE;
       }
-      else if (!ctx->ATIFragmentShader._Enabled) {
+      else if (!_mesa_ati_fragment_shader_enabled(ctx)) {
         if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE) &&
            (rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] & R200_TXFORMAT_LOOKUP_DISABLE)) {
            R200_STATECHANGE(rmesa, tex[1]);