i965: Mostly fix glsl-max-varyings.
[mesa.git] / src / mesa / drivers / dri / r300 / r300_texstate.c
index 33673fa0b9c4b62c0437778d412205d51378862a..4ba6740e3d921ad7078a9b52b7ddad888fe1b9fc 100644 (file)
@@ -39,27 +39,16 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/imports.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 "main/simple_list.h"
 
 #include "r300_context.h"
-#include "r300_state.h"
-#include "r300_ioctl.h"
-#include "radeon_ioctl.h"
-#include "r300_mipmap_tree.h"
+#include "radeon_mipmap_tree.h"
 #include "r300_tex.h"
 #include "r300_reg.h"
 
-#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5                        \
-                          || ((f) >= MESA_FORMAT_RGBA_FLOAT32 &&       \
-                              (f) <= MESA_FORMAT_INTENSITY_FLOAT16))   \
-                         && tx_table[f].flag )
-
-#define _ASSIGN(entry, format)                         \
-       [ MESA_FORMAT_ ## entry ] = { format, 0, 1}
-
 /*
  * Note that the _REV formats are the same as the non-REV formats.  This is
  * because the REV and non-REV formats are identical as a byte string, but
@@ -69,61 +58,119 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  * identically.  -- paulus
  */
 
-static const struct tx_table {
-       GLuint format, filter, flag;
-} tx_table[] = {
-       /* *INDENT-OFF* */
+int32_t r300TranslateTexFormat(gl_format mesaFormat)
+{
+       switch (mesaFormat)
+       {
 #ifdef MESA_LITTLE_ENDIAN
-       _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
-       _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
-       _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
-       _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
+               case MESA_FORMAT_RGBA8888:
+                       return R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8);
+               case MESA_FORMAT_RGBA8888_REV:
+                       return R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8);
+               case MESA_FORMAT_ARGB8888:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
+               case MESA_FORMAT_ARGB8888_REV:
+                       return R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8);
 #else
-       _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
-       _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
-       _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
-       _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
+               case MESA_FORMAT_RGBA8888:
+                       return R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8);
+               case MESA_FORMAT_RGBA8888_REV:
+                       return R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8);
+               case MESA_FORMAT_ARGB8888:
+                       return R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8);
+               case MESA_FORMAT_ARGB8888_REV:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
 #endif
-       _ASSIGN(RGB888, R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)),
-       _ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
-       _ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
-       _ASSIGN(ARGB4444, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
-       _ASSIGN(ARGB4444_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
-       _ASSIGN(ARGB1555, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
-       _ASSIGN(ARGB1555_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
-       _ASSIGN(AL88, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
-       _ASSIGN(AL88_REV, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
-       _ASSIGN(RGB332, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z3Y3X2)),
-       _ASSIGN(A8, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8)),
-       _ASSIGN(L8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8)),
-       _ASSIGN(I8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
-       _ASSIGN(CI8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
-       _ASSIGN(YCBCR, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE),
-       _ASSIGN(YCBCR_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE),
-       _ASSIGN(RGB_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1)),
-       _ASSIGN(RGBA_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1)),
-       _ASSIGN(RGBA_DXT3, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3)),
-       _ASSIGN(RGBA_DXT5, R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5)),
-       _ASSIGN(RGBA_FLOAT32, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R32G32B32A32)),
-       _ASSIGN(RGBA_FLOAT16, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R16G16B16A16)),
-       _ASSIGN(RGB_FLOAT32, 0xffffffff),
-       _ASSIGN(RGB_FLOAT16, 0xffffffff),
-       _ASSIGN(ALPHA_FLOAT32, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I32)),
-       _ASSIGN(ALPHA_FLOAT16, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I16)),
-       _ASSIGN(LUMINANCE_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I32)),
-       _ASSIGN(LUMINANCE_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I16)),
-       _ASSIGN(LUMINANCE_ALPHA_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I32A32)),
-       _ASSIGN(LUMINANCE_ALPHA_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16)),
-       _ASSIGN(INTENSITY_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, X, FL_I32)),
-       _ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)),
-       _ASSIGN(Z16, R300_EASY_TX_FORMAT(X, X, X, X, X16)),
-       _ASSIGN(Z24_S8, R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8)),
-       _ASSIGN(Z32, R300_EASY_TX_FORMAT(X, X, X, X, X32)),
-       /* *INDENT-ON* */
+               case MESA_FORMAT_XRGB8888:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
+               case MESA_FORMAT_RGB888:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
+               case MESA_FORMAT_RGB565:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
+               case MESA_FORMAT_RGB565_REV:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
+               case MESA_FORMAT_ARGB4444:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4);
+               case MESA_FORMAT_ARGB4444_REV:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4);
+               case MESA_FORMAT_ARGB1555:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5);
+               case MESA_FORMAT_ARGB1555_REV:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5);
+               case MESA_FORMAT_AL88:
+                       return R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8);
+               case MESA_FORMAT_AL88_REV:
+                       return R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8);
+               case MESA_FORMAT_RGB332:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z3Y3X2);
+               case MESA_FORMAT_A8:
+                       return R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8);
+               case MESA_FORMAT_L8:
+                       return R300_EASY_TX_FORMAT(X, X, X, ONE, X8);
+               case MESA_FORMAT_I8:
+                       return R300_EASY_TX_FORMAT(X, X, X, X, X8);
+               case MESA_FORMAT_CI8:
+                       return R300_EASY_TX_FORMAT(X, X, X, X, X8);
+               case MESA_FORMAT_YCBCR:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE;
+               case MESA_FORMAT_YCBCR_REV:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE;
+               case MESA_FORMAT_RGB_DXT1:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1);
+               case MESA_FORMAT_RGBA_DXT1:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1);
+               case MESA_FORMAT_RGBA_DXT3:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3);
+               case MESA_FORMAT_RGBA_DXT5:
+                       return R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5);
+               case MESA_FORMAT_RGBA_FLOAT32:
+                       return R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R32G32B32A32);
+               case MESA_FORMAT_RGBA_FLOAT16:
+                       return R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R16G16B16A16);
+               case MESA_FORMAT_ALPHA_FLOAT32:
+                       return R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I32);
+               case MESA_FORMAT_ALPHA_FLOAT16:
+                       return R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I16);
+               case MESA_FORMAT_LUMINANCE_FLOAT32:
+                       return R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I32);
+               case MESA_FORMAT_LUMINANCE_FLOAT16:
+                       return R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I16);
+               case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
+                       return R300_EASY_TX_FORMAT(X, X, X, Y, FL_I32A32);
+               case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
+                       return R300_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16);
+               case MESA_FORMAT_INTENSITY_FLOAT32:
+                       return R300_EASY_TX_FORMAT(X, X, X, X, FL_I32);
+               case MESA_FORMAT_INTENSITY_FLOAT16:
+                       return R300_EASY_TX_FORMAT(X, X, X, X, FL_I16);
+               case MESA_FORMAT_Z16:
+                       return R300_EASY_TX_FORMAT(X, X, X, X, X16);
+               case MESA_FORMAT_Z24_S8:
+                       return R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8);
+               case MESA_FORMAT_S8_Z24:
+                       return R300_EASY_TX_FORMAT(Y, Y, Y, Y, X24_Y8);
+               case MESA_FORMAT_Z32:
+                       return R300_EASY_TX_FORMAT(X, X, X, X, X32);
+               /* EXT_texture_sRGB */
+               case MESA_FORMAT_SRGBA8:
+                       return R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8) | R300_TX_FORMAT_GAMMA;
+               case MESA_FORMAT_SLA8:
+                       return R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8) | R300_TX_FORMAT_GAMMA;
+               case MESA_FORMAT_SL8:
+                       return R300_EASY_TX_FORMAT(X, X, X, ONE, X8) | R300_TX_FORMAT_GAMMA;
+               case MESA_FORMAT_SRGB_DXT1:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1) | R300_TX_FORMAT_GAMMA;
+               case MESA_FORMAT_SRGBA_DXT1:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1) | R300_TX_FORMAT_GAMMA;
+               case MESA_FORMAT_SRGBA_DXT3:
+                       return R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3) | R300_TX_FORMAT_GAMMA;
+               case MESA_FORMAT_SRGBA_DXT5:
+                       return R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5) | R300_TX_FORMAT_GAMMA;
+               default:
+                       return -1;
+       }
 };
 
-#undef _ASSIGN
-
 void r300SetDepthTexMode(struct gl_texture_object *tObj)
 {
        static const GLuint formats[3][3] = {
@@ -133,9 +180,9 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj)
                        R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X16),
                },
                {
-                       R300_EASY_TX_FORMAT(X, X, X, ONE, X24_Y8),
-                       R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8),
-                       R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X24_Y8),
+                       R300_EASY_TX_FORMAT(Y, Y, Y, ONE, X24_Y8),
+                       R300_EASY_TX_FORMAT(Y, Y, Y, Y, X24_Y8),
+                       R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, Y, X24_Y8),
                },
                {
                        R300_EASY_TX_FORMAT(X, X, X, ONE, X32),
@@ -144,18 +191,18 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj)
                },
        };
        const GLuint *format;
-       r300TexObjPtr t;
+       radeonTexObjPtr t;
 
        if (!tObj)
                return;
 
-       t = r300_tex_obj(tObj);
+       t = radeon_tex_obj(tObj);
 
-       switch (tObj->Image[0][tObj->BaseLevel]->TexFormat->MesaFormat) {
+       switch (tObj->Image[0][tObj->BaseLevel]->TexFormat) {
        case MESA_FORMAT_Z16:
                format = formats[0];
                break;
-       case MESA_FORMAT_Z24_S8:
+       case MESA_FORMAT_S8_Z24:
                format = formats[1];
                break;
        case MESA_FORMAT_Z32:
@@ -171,13 +218,13 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj)
 
        switch (tObj->DepthMode) {
        case GL_LUMINANCE:
-               t->format = format[0];
+               t->pp_txformat = format[0];
                break;
        case GL_INTENSITY:
-               t->format = format[1];
+               t->pp_txformat = format[1];
                break;
        case GL_ALPHA:
-               t->format = format[2];
+               t->pp_txformat = format[2];
                break;
        default:
                /* Error...which should have already been caught by higher
@@ -195,127 +242,60 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj)
  * \param rmesa Context pointer
  * \param t the r300 texture object
  */
-static void setup_hardware_state(r300ContextPtr rmesa, r300TexObj *t)
+static void setup_hardware_state(r300ContextPtr rmesa, radeonTexObj *t)
 {
-       const struct gl_texture_image *firstImage =
-           t->base.Image[0][t->mt->firstLevel];
+       const struct gl_texture_image *firstImage;
+       firstImage = t->base.Image[0][t->minLod];
 
-       if (!t->image_override
-           && VALID_FORMAT(firstImage->TexFormat->MesaFormat)) {
-               if (firstImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) {
+       if (!t->image_override) {
+               if (firstImage->_BaseFormat == GL_DEPTH_COMPONENT) {
                        r300SetDepthTexMode(&t->base);
                } else {
-                       t->format = tx_table[firstImage->TexFormat->MesaFormat].format;
+                       int32_t txformat = r300TranslateTexFormat(firstImage->TexFormat);
+                       if (txformat < 0) {
+                               _mesa_problem(rmesa->radeon.glCtx, "%s: Invalid format %s",
+                                                         __FUNCTION__, _mesa_get_format_name(firstImage->TexFormat));
+                               exit(1);
+                       }
+                       t->pp_txformat = (uint32_t) txformat;
                }
+       }
 
-               t->filter |= tx_table[firstImage->TexFormat->MesaFormat].filter;
-       } else if (!t->image_override) {
-               _mesa_problem(NULL, "unexpected texture format in %s",
-                             __FUNCTION__);
+       if (t->image_override && t->bo)
                return;
-       }
+
+       t->pp_txsize = (((R300_TX_WIDTHMASK_MASK & ((firstImage->Width - 1) << R300_TX_WIDTHMASK_SHIFT)))
+                       | ((R300_TX_HEIGHTMASK_MASK & ((firstImage->Height - 1) << R300_TX_HEIGHTMASK_SHIFT)))
+                       | ((R300_TX_DEPTHMASK_MASK & ((firstImage->DepthLog2) << R300_TX_DEPTHMASK_SHIFT)))
+                       | ((R300_TX_MAX_MIP_LEVEL_MASK & ((t->maxLod - t->minLod) << R300_TX_MAX_MIP_LEVEL_SHIFT))));
 
        t->tile_bits = 0;
 
        if (t->base.Target == GL_TEXTURE_CUBE_MAP)
-               t->format |= R300_TX_FORMAT_CUBIC_MAP;
+               t->pp_txformat |= R300_TX_FORMAT_CUBIC_MAP;
        if (t->base.Target == GL_TEXTURE_3D)
-               t->format |= R300_TX_FORMAT_3D;
+               t->pp_txformat |= R300_TX_FORMAT_3D;
 
-       t->size = (((firstImage->Width - 1) << R300_TX_WIDTHMASK_SHIFT)
-               | ((firstImage->Height - 1) << R300_TX_HEIGHTMASK_SHIFT))
-               | ((t->mt->lastLevel - t->mt->firstLevel) << R300_TX_MAX_MIP_LEVEL_SHIFT);
 
        if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
-               unsigned int align = (64 / t->mt->bpp) - 1;
-               t->size |= R300_TX_SIZE_TXPITCH_EN;
+               unsigned int align = (64 / _mesa_get_format_bytes(firstImage->TexFormat)) - 1;
+               t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN;
                if (!t->image_override)
-                       t->pitch_reg = ((firstImage->Width + align) & ~align) - 1;
+                       t->pp_txpitch = ((firstImage->Width + align) & ~align) - 1;
        }
 
        if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
            if (firstImage->Width > 2048)
-               t->pitch_reg |= R500_TXWIDTH_BIT11;
+               t->pp_txpitch |= R500_TXWIDTH_BIT11;
+            else
+               t->pp_txpitch &= ~R500_TXWIDTH_BIT11;
            if (firstImage->Height > 2048)
-               t->pitch_reg |= R500_TXHEIGHT_BIT11;
-       }
-}
-
-
-static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
-       GLuint numrows, GLuint rowsize)
-{
-       assert(rowsize <= dststride);
-       assert(rowsize <= srcstride);
-
-       if (rowsize == srcstride && rowsize == dststride) {
-               memcpy(dst, src, numrows*rowsize);
-       } else {
-               GLuint i;
-               for(i = 0; i < numrows; ++i) {
-                       memcpy(dst, src, rowsize);
-                       dst += dststride;
-                       src += srcstride;
-               }
+               t->pp_txpitch |= R500_TXHEIGHT_BIT11;
+            else
+               t->pp_txpitch &= ~R500_TXHEIGHT_BIT11;
        }
 }
 
-
-/**
- * Ensure that the given image is stored in the given miptree from now on.
- */
-static void migrate_image_to_miptree(r300_mipmap_tree *mt, r300_texture_image *image, int face, int level)
-{
-       r300_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel];
-       unsigned char *dest;
-
-       assert(image->mt != mt);
-       assert(dstlvl->width == image->base.Width);
-       assert(dstlvl->height == image->base.Height);
-       assert(dstlvl->depth == image->base.Depth);
-
-       radeon_bo_map(mt->bo, GL_TRUE);
-       dest = mt->bo->ptr + dstlvl->faces[face].offset;
-
-       if (image->mt) {
-               /* Format etc. should match, so we really just need a memcpy().
-                * In fact, that memcpy() could be done by the hardware in many
-                * cases, provided that we have a proper memory manager.
-                */
-               r300_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
-
-               assert(srclvl->size == dstlvl->size);
-               assert(srclvl->rowstride == dstlvl->rowstride);
-
-               radeon_bo_map(image->mt->bo, GL_FALSE);
-               memcpy(dest,
-                       image->mt->bo->ptr + srclvl->faces[face].offset,
-                       dstlvl->size);
-               radeon_bo_unmap(image->mt->bo);
-
-               r300_miptree_unreference(image->mt);
-       } else {
-               uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
-
-               if (mt->tilebits)
-                       WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
-
-               copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
-                       image->base.Height * image->base.Depth, srcrowstride);
-
-               _mesa_free_texmemory(image->base.Data);
-               image->base.Data = 0;
-       }
-
-       radeon_bo_unmap(mt->bo);
-
-       image->mt = mt;
-       image->mtface = face;
-       image->mtlevel = level;
-       r300_miptree_reference(image->mt);
-}
-
-
 /**
  * Ensure the given texture is ready for rendering.
  *
@@ -324,68 +304,11 @@ static void migrate_image_to_miptree(r300_mipmap_tree *mt, r300_texture_image *i
 static GLboolean r300_validate_texture(GLcontext * ctx, struct gl_texture_object *texObj)
 {
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
-       r300TexObj *t = r300_tex_obj(texObj);
-       r300_texture_image *baseimage = get_r300_texture_image(texObj->Image[0][texObj->BaseLevel]);
-       int face, level;
-
-       if (t->validated)
-               return GL_TRUE;
+       radeonTexObj *t = radeon_tex_obj(texObj);
 
-       if (RADEON_DEBUG & DEBUG_TEXTURE)
-               fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj);
-
-       if (baseimage->base.Border > 0)
+       if (!radeon_validate_texture_miptree(ctx, texObj))
                return GL_FALSE;
 
-       /* Ensure a matching miptree exists.
-        *
-        * Differing mipmap trees can result when the app uses TexImage to
-        * change texture dimensions.
-        *
-        * Prefer to use base image's miptree if it
-        * exists, since that most likely contains more valid data (remember
-        * that the base level is usually significantly larger than the rest
-        * of the miptree, so cubemaps are the only possible exception).
-        */
-       if (baseimage->mt &&
-           baseimage->mt != t->mt &&
-           r300_miptree_matches_texture(baseimage->mt, &t->base)) {
-               r300_miptree_unreference(t->mt);
-               t->mt = baseimage->mt;
-               r300_miptree_reference(t->mt);
-       } else if (t->mt && !r300_miptree_matches_texture(t->mt, &t->base)) {
-               r300_miptree_unreference(t->mt);
-               t->mt = 0;
-       }
-
-       if (!t->mt) {
-               if (RADEON_DEBUG & DEBUG_TEXTURE)
-                       fprintf(stderr, " Allocate new miptree\n");
-               r300_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel);
-               if (!t->mt) {
-                       _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree");
-                       return GL_FALSE;
-               }
-       }
-
-       /* Ensure all images are stored in the single main miptree */
-       for(face = 0; face < t->mt->faces; ++face) {
-               for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) {
-                       r300_texture_image *image = get_r300_texture_image(texObj->Image[face][level]);
-                       if (RADEON_DEBUG & DEBUG_TEXTURE)
-                               fprintf(stderr, " face %i, level %i... ", face, level);
-                       if (t->mt == image->mt) {
-                               if (RADEON_DEBUG & DEBUG_TEXTURE)
-                                       fprintf(stderr, "OK\n");
-                               continue;
-                       }
-
-                       if (RADEON_DEBUG & DEBUG_TEXTURE)
-                               fprintf(stderr, "migrating\n");
-                       migrate_image_to_miptree(t->mt, image, face, level);
-               }
-       }
-
        /* Configure the hardware registers (more precisely, the cached version
         * of the hardware registers). */
        setup_hardware_state(rmesa, t);
@@ -394,15 +317,37 @@ static GLboolean r300_validate_texture(GLcontext * ctx, struct gl_texture_object
        return GL_TRUE;
 }
 
-
 /**
- * Ensure all enabled and complete textures are uploaded.
+ * Ensure all enabled and complete textures are uploaded along with any buffers being used.
  */
-void r300ValidateTextures(GLcontext * ctx)
+GLboolean r300ValidateBuffers(GLcontext * ctx)
 {
+       r300ContextPtr rmesa = R300_CONTEXT(ctx);
+       struct radeon_renderbuffer *rrb;
        int i;
+       int ret;
 
+       radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
+
+       rrb = radeon_get_colorbuffer(&rmesa->radeon);
+       /* color buffer */
+       if (rrb && rrb->bo) {
+               radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
+                                                 rrb->bo, 0,
+                                                 RADEON_GEM_DOMAIN_VRAM);
+       }
+
+       /* depth buffer */
+       rrb = radeon_get_depthbuffer(&rmesa->radeon);
+       if (rrb && rrb->bo) {
+               radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
+                                                 rrb->bo, 0,
+                                                 RADEON_GEM_DOMAIN_VRAM);
+       }
+       
        for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
+               radeonTexObj *t;
+
                if (!ctx->Texture.Unit[i]._ReallyEnabled)
                        continue;
 
@@ -411,7 +356,21 @@ void r300ValidateTextures(GLcontext * ctx)
                                      "failed to validate texture for unit %d.\n",
                                      i);
                }
+               t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
+               if (t->image_override && t->bo)
+                       radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
+                                                         t->bo,
+                                                         RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+               else if (t->mt->bo)
+                       radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
+                                                         t->mt->bo,
+                                                         RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
        }
+
+       ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
+       if (ret)
+               return GL_FALSE;
+       return GL_TRUE;
 }
 
 void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
@@ -420,7 +379,7 @@ void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
        r300ContextPtr rmesa = pDRICtx->driverPrivate;
        struct gl_texture_object *tObj =
            _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
-       r300TexObjPtr t = r300_tex_obj(tObj);
+       radeonTexObjPtr t = radeon_tex_obj(tObj);
        uint32_t pitch_val;
 
        if (!tObj)
@@ -431,29 +390,135 @@ void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
        if (!offset)
                return;
 
+       t->bo = NULL;
        t->override_offset = offset;
-       t->pitch_reg &= (1 << 13) -1;
+       t->pp_txpitch &= (1 << 13) -1;
        pitch_val = pitch;
 
        switch (depth) {
        case 32:
-               t->format = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
-               t->filter |= tx_table[2].filter;
+               t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
                pitch_val /= 4;
                break;
        case 24:
        default:
-               t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
-               t->filter |= tx_table[4].filter;
+               t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
                pitch_val /= 4;
                break;
        case 16:
-               t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
-               t->filter |= tx_table[5].filter;
+               t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
+               pitch_val /= 2;
+               break;
+       }
+       pitch_val--;
+
+       t->pp_txpitch |= pitch_val;
+}
+
+void r300SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint 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;
+       r300ContextPtr rmesa;
+       struct radeon_framebuffer *rfb;
+       radeonTexObjPtr t;
+       uint32_t pitch_val;
+       uint32_t internalFormat, type, format;
+
+       type = GL_BGRA;
+       format = GL_UNSIGNED_BYTE;
+       internalFormat = (texture_format == __DRI_TEXTURE_FORMAT_RGB ? 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, GL_TRUE);
+       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;
+       }
+
+       radeon_miptree_unreference(&t->mt);
+       radeon_miptree_unreference(&rImage->mt);
+
+       _mesa_init_teximage_fields(radeon->glCtx, target, texImage,
+                                  rb->base.Width, rb->base.Height, 1, 0, rb->cpp);
+       texImage->RowStride = rb->pitch / rb->cpp;
+       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)
+                       t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
+               else
+                       t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
+               pitch_val /= 4;
+               break;
+       case 3:
+       default:
+               t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
+               pitch_val /= 4;
+               break;
+       case 2:
+               t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
                pitch_val /= 2;
                break;
        }
        pitch_val--;
+       t->pp_txsize = (((R300_TX_WIDTHMASK_MASK & ((rb->base.Width - 1) << R300_TX_WIDTHMASK_SHIFT)))
+                       | ((R300_TX_HEIGHTMASK_MASK & ((rb->base.Height - 1) << R300_TX_HEIGHTMASK_SHIFT))));
+       t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN;
+       t->pp_txpitch |= pitch_val;
+
+       if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
+           if (rb->base.Width > 2048)
+               t->pp_txpitch |= R500_TXWIDTH_BIT11;
+            else
+               t->pp_txpitch &= ~R500_TXWIDTH_BIT11;
+           if (rb->base.Height > 2048)
+               t->pp_txpitch |= R500_TXHEIGHT_BIT11;
+            else
+               t->pp_txpitch &= ~R500_TXHEIGHT_BIT11;
+       }
+       t->validated = GL_TRUE;
+       _mesa_unlock_texture(radeon->glCtx, texObj);
+       return;
+}
 
-       t->pitch_reg |= pitch_val;
+void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
+{
+        r300SetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
 }