radeon: fix compressed mipmapped textures
authorMaciej Cencora <m.cencora@gmail.com>
Sat, 21 Nov 2009 14:56:23 +0000 (15:56 +0100)
committerMaciej Cencora <m.cencora@gmail.com>
Sat, 21 Nov 2009 15:30:48 +0000 (16:30 +0100)
Tested on r300 only, other cards may require adjusting texture_compressed_row_align.

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

index 2a38c4599c643de3cee4a220a86e9e997e9e9c40..71f70d724b9458b9af7675b4997c626783ef0af0 100644 (file)
@@ -262,7 +262,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
                else
                        radeon->texture_row_align = 32;
                radeon->texture_rect_row_align = 64;
-               radeon->texture_compressed_row_align = 64;
+               radeon->texture_compressed_row_align = 32;
        }
 
        radeon_init_dma(radeon);
index 0497fa7db502f9b375694a4b708ddc1e1881e7ea..a11b5b9979960b107a8e6cd2b0b24ba06c3bad17 100644 (file)
 #include "main/texobj.h"
 #include "radeon_texture.h"
 
-static GLuint radeon_compressed_texture_size(GLcontext *ctx,
-               GLsizei width, GLsizei height, GLsizei depth,
-               gl_format mesaFormat)
+static unsigned get_aligned_compressed_row_stride(
+               gl_format format,
+               unsigned width,
+               unsigned minStride)
 {
-       GLuint size = _mesa_format_image_size(mesaFormat, width, height, depth);
-
-       if (mesaFormat == MESA_FORMAT_RGB_DXT1 ||
-           mesaFormat == MESA_FORMAT_RGBA_DXT1) {
-               if (width + 3 < 8)      /* width one block */
-                       size = size * 4;
-               else if (width + 3 < 16)
-                       size = size * 2;
-       } else {
-               /* DXT3/5, 16 bytes per block */
-         //            WARN_ONCE("DXT 3/5 suffers from multitexturing problems!\n");
-               if (width + 3 < 8)
-                       size = size * 2;
+       const unsigned blockSize = _mesa_get_format_bytes(format);
+       unsigned blockWidth, blockHeight, numXBlocks;
+
+       _mesa_get_format_block_size(format, &blockWidth, &blockHeight);
+       numXBlocks = (width + blockWidth - 1) / blockWidth;
+
+       while (numXBlocks * blockSize < minStride)
+       {
+               ++numXBlocks;
        }
 
-       return size;
+       return numXBlocks * blockSize;
+}
+
+static unsigned get_compressed_image_size(
+               gl_format format,
+               unsigned rowStride,
+               unsigned height)
+{
+       unsigned blockWidth, blockHeight;
+
+       _mesa_get_format_block_size(format, &blockWidth, &blockHeight);
+
+       return rowStride * ((height + blockHeight - 1) / blockHeight);
 }
 
 /**
@@ -74,10 +83,8 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree
 
        /* Find image size in bytes */
        if (_mesa_is_format_compressed(mt->mesaFormat)) {
-               /* TODO: Is this correct? Need test cases for compressed textures! */
-               row_align = rmesa->texture_compressed_row_align - 1;
-               lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align;
-               lvl->size = radeon_compressed_texture_size(rmesa->glCtx, lvl->width, lvl->height, lvl->depth, mt->mesaFormat);
+               lvl->rowstride = get_aligned_compressed_row_stride(mt->mesaFormat, lvl->width, rmesa->texture_compressed_row_align);
+               lvl->size = get_compressed_image_size(mt->mesaFormat, lvl->rowstride, lvl->height);
        } else if (mt->target == GL_TEXTURE_RECTANGLE_NV) {
                row_align = rmesa->texture_rect_row_align - 1;
                lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align;