mesa: replace gl_texture_format with gl_format
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_texture.c
index 4aa081ca347c45f13ddbed71a2f7a0d152e6abc2..0378b3c9fcd560020f5c3fb6c060c401cf7b7431 100644 (file)
@@ -38,6 +38,7 @@
 #include "main/texstore.h"
 #include "main/teximage.h"
 #include "main/texobj.h"
+#include "main/texgetimage.h"
 
 #include "xmlpool.h"           /* for symbolic values of enum-type options */
 
@@ -131,6 +132,25 @@ void radeon_teximage_unmap(radeon_texture_image *image)
        }
 }
 
+static void map_override(GLcontext *ctx, radeonTexObj *t)
+{
+       radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
+
+       radeon_bo_map(t->bo, GL_FALSE);
+
+       img->base.Data = t->bo->ptr;
+       _mesa_set_fetch_functions(&img->base, 2);
+}
+
+static void unmap_override(GLcontext *ctx, radeonTexObj *t)
+{
+       radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
+
+       radeon_bo_unmap(t->bo);
+
+       img->base.Data = NULL;
+}
+
 /**
  * Map a validated texture for reading during software rendering.
  */
@@ -139,9 +159,15 @@ void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
        radeonTexObj* t = radeon_tex_obj(texObj);
        int face, level;
 
+       if (!radeon_validate_texture_miptree(ctx, texObj))
+         return;
+
        /* for r100 3D sw fallbacks don't have mt */
+       if (t->image_override && t->bo)
+               map_override(ctx, t);
+
        if (!t->mt)
-         return;
+               return;
 
        radeon_bo_map(t->mt->bo, GL_FALSE);
        for(face = 0; face < t->mt->faces; ++face) {
@@ -155,6 +181,8 @@ void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
        radeonTexObj* t = radeon_tex_obj(texObj);
        int face, level;
 
+       if (t->image_override && t->bo)
+               unmap_override(ctx, t);
        /* for r100 3D sw fallbacks don't have mt */
        if (!t->mt)
          return;
@@ -228,41 +256,52 @@ void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_objec
 
 
 /* try to find a format which will only need a memcopy */
-static const struct gl_texture_format *radeonChoose8888TexFormat(radeonContextPtr rmesa,
-                                                                GLenum srcFormat,
-                                                                GLenum srcType)
+static gl_format radeonChoose8888TexFormat(radeonContextPtr rmesa,
+                                          GLenum srcFormat,
+                                          GLenum srcType, GLboolean fbo)
 {
        const GLuint ui = 1;
        const GLubyte littleEndian = *((const GLubyte *)&ui);
 
        /* r100 can only do this */
-       if (IS_R100_CLASS(rmesa->radeonScreen))
+       if (IS_R100_CLASS(rmesa->radeonScreen) || fbo)
          return _dri_texformat_argb8888;
 
        if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
            (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
            (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
            (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
-               return &_mesa_texformat_rgba8888;
+               return MESA_FORMAT_RGBA8888;
        } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
                   (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
                   (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
                   (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
-               return &_mesa_texformat_rgba8888_rev;
+               return MESA_FORMAT_RGBA8888_REV;
+       } else if (IS_R200_CLASS(rmesa->radeonScreen)) {
+               return _dri_texformat_argb8888;
        } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
                                            srcType == GL_UNSIGNED_INT_8_8_8_8)) {
-               return &_mesa_texformat_argb8888_rev;
+               return MESA_FORMAT_ARGB8888_REV;
        } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
                                            srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
-               return &_mesa_texformat_argb8888;
+               return MESA_FORMAT_ARGB8888;
        } else
                return _dri_texformat_argb8888;
 }
 
-const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
-                                                         GLint internalFormat,
-                                                         GLenum format,
-                                                         GLenum type)
+gl_format radeonChooseTextureFormat_mesa(GLcontext * ctx,
+                                        GLint internalFormat,
+                                        GLenum format,
+                                        GLenum type)
+{
+       return radeonChooseTextureFormat(ctx, internalFormat, format,
+                                        type, 0);
+}
+
+gl_format radeonChooseTextureFormat(GLcontext * ctx,
+                                   GLint internalFormat,
+                                   GLenum format,
+                                   GLenum type, GLboolean fbo)
 {
        radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
        const GLboolean do32bpt =
@@ -294,7 +333,7 @@ const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
                case GL_UNSIGNED_SHORT_1_5_5_5_REV:
                        return _dri_texformat_argb1555;
                default:
-                       return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type) :
+                       return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type, fbo) :
                            _dri_texformat_argb4444;
                }
 
@@ -321,7 +360,7 @@ const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
        case GL_RGBA12:
        case GL_RGBA16:
                return !force16bpt ?
-                       radeonChoose8888TexFormat(rmesa, format,type) :
+                       radeonChoose8888TexFormat(rmesa, format, type, fbo) :
                        _dri_texformat_argb4444;
 
        case GL_RGBA4:
@@ -349,8 +388,12 @@ const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
        case GL_ALPHA12:
        case GL_ALPHA16:
        case GL_COMPRESSED_ALPHA:
-               return _dri_texformat_a8;
-
+               /* r200: can't use a8 format since interpreting hw I8 as a8 would result
+                  in wrong rgb values (same as alpha value instead of 0). */
+               if (IS_R200_CLASS(rmesa->radeonScreen))
+                       return _dri_texformat_al88;
+               else
+                       return _dri_texformat_a8;
        case 1:
        case GL_LUMINANCE:
        case GL_LUMINANCE4:
@@ -382,78 +425,86 @@ const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
        case GL_YCBCR_MESA:
                if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
                    type == GL_UNSIGNED_BYTE)
-                       return &_mesa_texformat_ycbcr;
+                       return MESA_FORMAT_YCBCR;
                else
-                       return &_mesa_texformat_ycbcr_rev;
+                       return MESA_FORMAT_YCBCR_REV;
 
        case GL_RGB_S3TC:
        case GL_RGB4_S3TC:
        case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-               return &_mesa_texformat_rgb_dxt1;
+               return MESA_FORMAT_RGB_DXT1;
 
        case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-               return &_mesa_texformat_rgba_dxt1;
+               return MESA_FORMAT_RGBA_DXT1;
 
        case GL_RGBA_S3TC:
        case GL_RGBA4_S3TC:
        case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-               return &_mesa_texformat_rgba_dxt3;
+               return MESA_FORMAT_RGBA_DXT3;
 
        case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-               return &_mesa_texformat_rgba_dxt5;
+               return MESA_FORMAT_RGBA_DXT5;
 
        case GL_ALPHA16F_ARB:
-               return &_mesa_texformat_alpha_float16;
+               return MESA_FORMAT_ALPHA_FLOAT16;
        case GL_ALPHA32F_ARB:
-               return &_mesa_texformat_alpha_float32;
+               return MESA_FORMAT_ALPHA_FLOAT32;
        case GL_LUMINANCE16F_ARB:
-               return &_mesa_texformat_luminance_float16;
+               return MESA_FORMAT_LUMINANCE_FLOAT16;
        case GL_LUMINANCE32F_ARB:
-               return &_mesa_texformat_luminance_float32;
+               return MESA_FORMAT_LUMINANCE_FLOAT32;
        case GL_LUMINANCE_ALPHA16F_ARB:
-               return &_mesa_texformat_luminance_alpha_float16;
+               return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16;
        case GL_LUMINANCE_ALPHA32F_ARB:
-               return &_mesa_texformat_luminance_alpha_float32;
+               return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32;
        case GL_INTENSITY16F_ARB:
-               return &_mesa_texformat_intensity_float16;
+               return MESA_FORMAT_INTENSITY_FLOAT16;
        case GL_INTENSITY32F_ARB:
-               return &_mesa_texformat_intensity_float32;
+               return MESA_FORMAT_INTENSITY_FLOAT32;
        case GL_RGB16F_ARB:
-               return &_mesa_texformat_rgba_float16;
+               return MESA_FORMAT_RGBA_FLOAT16;
        case GL_RGB32F_ARB:
-               return &_mesa_texformat_rgba_float32;
+               return MESA_FORMAT_RGBA_FLOAT32;
        case GL_RGBA16F_ARB:
-               return &_mesa_texformat_rgba_float16;
+               return MESA_FORMAT_RGBA_FLOAT16;
        case GL_RGBA32F_ARB:
-               return &_mesa_texformat_rgba_float32;
+               return MESA_FORMAT_RGBA_FLOAT32;
 
        case GL_DEPTH_COMPONENT:
        case GL_DEPTH_COMPONENT16:
        case GL_DEPTH_COMPONENT24:
        case GL_DEPTH_COMPONENT32:
-#if 0
-               switch (type) {
-               case GL_UNSIGNED_BYTE:
-               case GL_UNSIGNED_SHORT:
-                       return &_mesa_texformat_z16;
-               case GL_UNSIGNED_INT:
-                       return &_mesa_texformat_z32;
-               case GL_UNSIGNED_INT_24_8_EXT:
-               default:
-                       return &_mesa_texformat_z24_s8;
-               }
-#else
-               return &_mesa_texformat_z16;
-#endif
+       case GL_DEPTH_STENCIL_EXT:
+       case GL_DEPTH24_STENCIL8_EXT:
+               return MESA_FORMAT_S8_Z24;
+
+       /* EXT_texture_sRGB */
+       case GL_SRGB:
+       case GL_SRGB8:
+       case GL_SRGB_ALPHA:
+       case GL_SRGB8_ALPHA8:
+       case GL_COMPRESSED_SRGB:
+       case GL_COMPRESSED_SRGB_ALPHA:
+               return MESA_FORMAT_SRGBA8;
+
+       case GL_SLUMINANCE:
+       case GL_SLUMINANCE8:
+       case GL_COMPRESSED_SLUMINANCE:
+               return MESA_FORMAT_SL8;
+
+       case GL_SLUMINANCE_ALPHA:
+       case GL_SLUMINANCE8_ALPHA8:
+       case GL_COMPRESSED_SLUMINANCE_ALPHA:
+               return MESA_FORMAT_SLA8;
 
        default:
                _mesa_problem(ctx,
-                             "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
-                             (int)internalFormat);
-               return NULL;
+                             "unexpected internalFormat 0x%x in %s",
+                             (int)internalFormat, __func__);
+               return MESA_FORMAT_NONE;
        }
 
-       return NULL;            /* never get here */
+       return MESA_FORMAT_NONE;                /* never get here */
 }
 
 /**
@@ -461,7 +512,7 @@ const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
  */
 static void radeon_teximage(
        GLcontext *ctx, int dims,
-       GLint face, GLint level,
+       GLenum target, GLint level,
        GLint internalFormat,
        GLint width, GLint height, GLint depth,
        GLsizei imageSize,
@@ -478,6 +529,7 @@ static void radeon_teximage(
        GLint postConvWidth = width;
        GLint postConvHeight = height;
        GLuint texelBytes;
+       GLuint face = radeon_face_for_target(target);
 
        radeon_firevertices(rmesa);
 
@@ -489,21 +541,21 @@ static void radeon_teximage(
        }
 
        /* Choose and fill in the texture format for this image */
-       texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type);
+       texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type, 0);
        _mesa_set_fetch_functions(texImage, dims);
 
-       if (texImage->TexFormat->TexelBytes == 0) {
+       if (_mesa_is_format_compressed(texImage->TexFormat)) {
                texelBytes = 0;
                texImage->IsCompressed = GL_TRUE;
                texImage->CompressedSize =
                        ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
                                           texImage->Height, texImage->Depth,
-                                          texImage->TexFormat->MesaFormat);
+                                          texImage->TexFormat);
        } else {
                texImage->IsCompressed = GL_FALSE;
                texImage->CompressedSize = 0;
 
-               texelBytes = texImage->TexFormat->TexelBytes;
+               texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
                /* Minimum pitch of 32 bytes */
                if (postConvWidth * texelBytes < 32) {
                  postConvWidth = 32 / texelBytes;
@@ -517,8 +569,17 @@ static void radeon_teximage(
        /* Allocate memory for image */
        radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */
 
+       if (t->mt &&
+           t->mt->firstLevel == level &&
+           t->mt->lastLevel == level &&
+           t->mt->target != GL_TEXTURE_CUBE_MAP_ARB &&
+           !radeon_miptree_matches_image(t->mt, texImage, face, level)) {
+         radeon_miptree_unreference(t->mt);
+         t->mt = NULL;
+       }
+
        if (!t->mt)
-               radeon_try_alloc_miptree(rmesa, t, texImage, face, level);
+               radeon_try_alloc_miptree(rmesa, t, image, face, level);
        if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) {
                radeon_mipmap_level *lvl;
                image->mt = t->mt;
@@ -532,7 +593,7 @@ static void radeon_teximage(
                if (texImage->IsCompressed) {
                        size = texImage->CompressedSize;
                } else {
-                       size = texImage->Width * texImage->Height * texImage->Depth * texImage->TexFormat->TexelBytes;
+                       size = texImage->Width * texImage->Height * texImage->Depth * _mesa_get_format_bytes(texImage->TexFormat);
                }
                texImage->Data = _mesa_alloc_texmemory(size);
        }
@@ -549,34 +610,56 @@ static void radeon_teximage(
 
        if (pixels) {
                radeon_teximage_map(image, GL_TRUE);
-
                if (compressed) {
-                       memcpy(texImage->Data, pixels, imageSize);
+                       if (image->mt) {
+                               uint32_t srcRowStride, bytesPerRow, rows;
+                               srcRowStride = _mesa_compressed_row_stride(texImage->TexFormat, width);
+                               bytesPerRow = srcRowStride;
+                               rows = (height + 3) / 4;
+                               copy_rows(texImage->Data, image->mt->levels[level].rowstride,
+                                         pixels, srcRowStride, rows, bytesPerRow);
+                       } else {
+                               memcpy(texImage->Data, pixels, imageSize);
+                       }
                } else {
                        GLuint dstRowStride;
+                       GLuint *dstImageOffsets;
+
                        if (image->mt) {
                                radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
                                dstRowStride = lvl->rowstride;
                        } else {
-                               dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
+                               dstRowStride = texImage->Width * _mesa_get_format_bytes(texImage->TexFormat);
                        }
 
-                       if (!texImage->TexFormat->StoreImage(ctx, dims,
-                                               texImage->_BaseFormat,
-                                               texImage->TexFormat,
-                                               texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
-                                               dstRowStride,
-                                               texImage->ImageOffsets,
-                                               width, height, depth,
-                                               format, type, pixels, packing))
-                               _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
-               }
+                       if (dims == 3) {
+                               int i;
 
-       }
+                               dstImageOffsets = _mesa_malloc(depth * sizeof(GLuint)) ;
+                               if (!dstImageOffsets)
+                                       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+
+                               for (i = 0; i < depth; ++i) {
+                                       dstImageOffsets[i] = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat) * height * i;
+                               }
+                       } else {
+                               dstImageOffsets = texImage->ImageOffsets;
+                       }
+
+                       if (!_mesa_texstore(ctx, dims,
+                                           texImage->_BaseFormat,
+                                           texImage->TexFormat,
+                                           texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
+                                           dstRowStride,
+                                           dstImageOffsets,
+                                           width, height, depth,
+                                           format, type, pixels, packing)) {
+                               _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+                       }
 
-       /* SGIS_generate_mipmap */
-       if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-               radeon_generate_mipmap(ctx, texObj->Target, texObj);
+                       if (dims == 3)
+                               _mesa_free(dstImageOffsets);
+               }
        }
 
        _mesa_unmap_teximage_pbo(ctx, packing);
@@ -595,7 +678,7 @@ void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
                      struct gl_texture_object *texObj,
                      struct gl_texture_image *texImage)
 {
-       radeon_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1,
+       radeon_teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
                0, format, type, pixels, packing, texObj, texImage, 0);
 }
 
@@ -608,9 +691,7 @@ void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level,
                           struct gl_texture_image *texImage)
 
 {
-       GLuint face = radeon_face_for_target(target);
-
-       radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
+       radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
                0, format, type, pixels, packing, texObj, texImage, 0);
 }
 
@@ -621,9 +702,7 @@ void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
                                     struct gl_texture_object *texObj,
                                     struct gl_texture_image *texImage)
 {
-       GLuint face = radeon_face_for_target(target);
-
-       radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
+       radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
                imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
 }
 
@@ -636,14 +715,14 @@ void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
                      struct gl_texture_object *texObj,
                      struct gl_texture_image *texImage)
 {
-       radeon_teximage(ctx, 3, 0, level, internalFormat, width, height, depth,
+       radeon_teximage(ctx, 3, target, level, internalFormat, width, height, depth,
                0, format, type, pixels, packing, texObj, texImage, 0);
 }
 
 /**
  * Update a subregion of the given texture image.
  */
-static void radeon_texsubimage(GLcontext* ctx, int dims, int level,
+static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int level,
                GLint xoffset, GLint yoffset, GLint zoffset,
                GLsizei width, GLsizei height, GLsizei depth,
                GLsizei imageSize,
@@ -677,36 +756,42 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, int level,
                        radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
                        dstRowStride = lvl->rowstride;
                } else {
-                       dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
+                       dstRowStride = texImage->RowStride * _mesa_get_format_bytes(texImage->TexFormat);
                }
 
                if (compressed) {
-                       uint32_t srcRowStride, bytesPerRow, rows; 
-                       dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, texImage->Width);
-                       srcRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
+                       uint32_t srcRowStride, bytesPerRow, rows;
+                       GLubyte *img_start;
+                       if (!image->mt) {
+                               dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat, texImage->Width);
+                               img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
+                                                                          texImage->TexFormat,
+                                                                          texImage->Width, texImage->Data);
+                       }
+                       else {
+                               uint32_t blocks_x = dstRowStride / (image->mt->bpp * 4);
+                               img_start = texImage->Data + image->mt->bpp * 4 * (blocks_x * (yoffset / 4) + xoffset / 4);
+                       }
+                       srcRowStride = _mesa_compressed_row_stride(texImage->TexFormat, width);
                        bytesPerRow = srcRowStride;
-                       rows = height / 4;
+                       rows = (height + 3) / 4;
 
-                       copy_rows(texImage->Data, dstRowStride,  image->base.Data, srcRowStride, rows,
-                                 bytesPerRow);
+                       copy_rows(img_start, dstRowStride,  pixels, srcRowStride, rows,  bytesPerRow);
                        
-               } else {
-                       if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
-                                                            texImage->TexFormat, texImage->Data,
-                                                            xoffset, yoffset, zoffset,
-                                                            dstRowStride,
-                                                            texImage->ImageOffsets,
-                                                            width, height, depth,
-                                                            format, type, pixels, packing))
+               }
+               else {
+                       if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
+                                           texImage->TexFormat, texImage->Data,
+                                           xoffset, yoffset, zoffset,
+                                           dstRowStride,
+                                           texImage->ImageOffsets,
+                                           width, height, depth,
+                                           format, type, pixels, packing)) {
                                _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
+                       }
                }
-
        }
 
-       /* GL_SGIS_generate_mipmap */
-       if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-               radeon_generate_mipmap(ctx, texObj->Target, texObj);
-       }
        radeon_teximage_unmap(image);
 
        _mesa_unmap_teximage_pbo(ctx, packing);
@@ -723,7 +808,7 @@ void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
                         struct gl_texture_object *texObj,
                         struct gl_texture_image *texImage)
 {
-       radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1, 0,
+       radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0,
                format, type, pixels, packing, texObj, texImage, 0);
 }
 
@@ -736,7 +821,7 @@ void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
                         struct gl_texture_object *texObj,
                         struct gl_texture_image *texImage)
 {
-       radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
+       radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
                           0, format, type, pixels, packing, texObj, texImage,
                           0);
 }
@@ -749,7 +834,7 @@ void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
                                   struct gl_texture_object *texObj,
                                   struct gl_texture_image *texImage)
 {
-       radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
+       radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
                imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1);
 }
 
@@ -763,7 +848,7 @@ void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
                         struct gl_texture_object *texObj,
                         struct gl_texture_image *texImage)
 {
-       radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth, 0,
+       radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0,
                format, type, pixels, packing, texObj, texImage, 0);
 }
 
@@ -791,7 +876,7 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_imag
                 * In fact, that memcpy() could be done by the hardware in many
                 * cases, provided that we have a proper memory manager.
                 */
-               radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
+               radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel-image->mt->firstLevel];
 
                assert(srclvl->size == dstlvl->size);
                assert(srclvl->rowstride == dstlvl->rowstride);
@@ -809,11 +894,11 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_imag
                uint32_t height;
                /* need to confirm this value is correct */
                if (mt->compressed) {
-                       height = image->base.Height / 4;
-                       srcrowstride = image->base.RowStride * mt->bpp;
+                       height = (image->base.Height + 3) / 4;
+                       srcrowstride = _mesa_compressed_row_stride(image->base.TexFormat, image->base.Width);
                } else {
                        height = image->base.Height * image->base.Depth;
-                       srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
+                       srcrowstride = image->base.Width * _mesa_get_format_bytes(image->base.TexFormat);
                }
 
 //             if (mt->tilebits)
@@ -844,7 +929,7 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
        if (t->validated || t->image_override)
                return GL_TRUE;
 
-       if (RADEON_DEBUG & DEBUG_TEXTURE)
+       if (RADEON_DEBUG & RADEON_TEXTURE)
                fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj);
 
        if (baseimage->base.Border > 0)
@@ -872,11 +957,11 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
        }
 
        if (!t->mt) {
-               if (RADEON_DEBUG & DEBUG_TEXTURE)
+               if (RADEON_DEBUG & RADEON_TEXTURE)
                        fprintf(stderr, " Allocate new miptree\n");
-               radeon_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel);
+               radeon_try_alloc_miptree(rmesa, t, baseimage, 0, texObj->BaseLevel);
                if (!t->mt) {
-                       _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree");
+                       _mesa_problem(ctx, "radeon_validate_texture failed to alloc miptree");
                        return GL_FALSE;
                }
        }
@@ -885,15 +970,16 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
        for(face = 0; face < t->mt->faces; ++face) {
                for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) {
                        radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]);
-                       if (RADEON_DEBUG & DEBUG_TEXTURE)
+                       if (RADEON_DEBUG & RADEON_TEXTURE)
                                fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt);
                        if (t->mt == image->mt) {
-                               if (RADEON_DEBUG & DEBUG_TEXTURE)
+                               if (RADEON_DEBUG & RADEON_TEXTURE)
                                        fprintf(stderr, "OK\n");
+
                                continue;
                        }
 
-                       if (RADEON_DEBUG & DEBUG_TEXTURE)
+                       if (RADEON_DEBUG & RADEON_TEXTURE)
                                fprintf(stderr, "migrating\n");
                        migrate_image_to_miptree(t->mt, image, face, level);
                }
@@ -924,6 +1010,8 @@ radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
        }
 
        if (compressed) {
+               /* FIXME: this can't work for small textures (mips) which
+                        use different hw stride */
                _mesa_get_compressed_teximage(ctx, target, level, pixels,
                                              texObj, texImage);
        } else {