radeon: more fixes for compressed textures
authorRoland Scheidegger <sroland@vmware.com>
Mon, 3 Aug 2009 22:21:07 +0000 (00:21 +0200)
committerRoland Scheidegger <sroland@vmware.com>
Mon, 3 Aug 2009 22:21:07 +0000 (00:21 +0200)
- fix not respecting required hardware stride with compressedTexImage -
  this fixes #22615.
- make sure correct stride is used in various places
- fix stored miptree never matching with a TexImage call with compressed
  texture
- don't always store data with compressedtexsubimage at offset 0,
  and actually use the supplied pixel data... (untested)
- make sure rows for compressed texture handling are rounded up not down

Note that trying to access stored compressed textures in hardware miptrees
from core mesa (get_compressed_teximage, swrast fallbacks) can't work correctly,
since RowStride isn't really set to anything useful, plus some places (at least
get_compressed_teximage) assume this data has native stride and no padding.

src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
src/mesa/drivers/dri/radeon/radeon_texture.c

index 071a18e7d86e878de5c0fd2b0ac841f5b19c8b4b..02e0dc7774af86ae3112e7fd91c05dfc3eeba058 100644 (file)
@@ -366,8 +366,8 @@ GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_textu
                mt->width0 == firstImage->Width &&
                mt->height0 == firstImage->Height &&
                mt->depth0 == firstImage->Depth &&
-               mt->bpp == firstImage->TexFormat->TexelBytes &&
-               mt->compressed == compressed);
+               mt->compressed == compressed &&
+               (!mt->compressed ? (mt->bpp == firstImage->TexFormat->TexelBytes) : 1));
 }
 
 
index 6a065f046884ebc2a1205fe695e1fe6c8b5c12d7..fa16f44c18e85c92804082660d7caaea75727be2 100644 (file)
@@ -610,9 +610,17 @@ 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->MesaFormat, 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;
@@ -756,14 +764,23 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int leve
                }
 
                if (compressed) {
-                       uint32_t srcRowStride, bytesPerRow, rows; 
-                       dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, texImage->Width);
+                       uint32_t srcRowStride, bytesPerRow, rows;
+                       GLubyte *img_start;
+                       if (!image->mt) {
+                               dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, texImage->Width);
+                               img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
+                                                                          texImage->TexFormat->MesaFormat,
+                                                                          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->MesaFormat, 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,
@@ -884,8 +901,8 @@ 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->MesaFormat, image->base.Width);
                } else {
                        height = image->base.Height * image->base.Depth;
                        srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
@@ -1000,6 +1017,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 {