st/mesa: fix compressed mipmap generation for small image sizes
authorBrian Paul <brianp@vmware.com>
Thu, 6 May 2010 20:24:45 +0000 (14:24 -0600)
committerBrian Paul <brianp@vmware.com>
Thu, 6 May 2010 20:26:58 +0000 (14:26 -0600)
When the mipmap level is smaller than the compression block width, height
we need to fill in / replicate pixels so that we don't get garbage values.

Fixes piglit gen-compressed-teximage test.

src/mesa/state_tracker/st_gen_mipmap.c

index 8acf6160494b87056628af6ded6e3d6de8f70dbe..701c8e54e6d9314fdbde941dd8d692965c75404c 100644 (file)
@@ -105,10 +105,32 @@ decompress_image(enum pipe_format format,
                  unsigned width, unsigned height)
 {
    const struct util_format_description *desc = util_format_description(format);
-   const uint dst_stride = 4 * width;
+   const uint bw = util_format_get_blockwidth(format);
+   const uint bh = util_format_get_blockheight(format);
+   const uint dst_stride = 4 * MAX2(width, bw);
    const uint src_stride = util_format_get_stride(format, width);
 
    desc->unpack_rgba_8unorm(dst, dst_stride, src, src_stride, width, height);
+
+   if (width < bw || height < bh) {
+      /* We're decompressing an image smaller than the compression
+       * block size.  We don't want garbage pixel values in the region
+       * outside (width x height) so replicate pixels from the (width
+       * x height) region to fill out the (bw x bh) block size.
+       */
+      uint x, y;
+      for (y = 0; y < bh; y++) {
+         for (x = 0; x < bw; x++) {
+            if (x >= width || y >= height) {
+               uint p = (y * bw + x) * 4;
+               dst[p + 0] = dst[0];
+               dst[p + 1] = dst[1];
+               dst[p + 2] = dst[2];
+               dst[p + 3] = dst[3];
+            }
+         }
+      }
+   }
 }
 
 
@@ -222,7 +244,7 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target,
                                      dstWidth2); /* stride in texels */
 
          /* compress the new image: dstTemp -> dstData */
-         compress_image(format, dstTemp, dstData, dstWidth2, dstHeight2);
+         compress_image(format, dstTemp, dstData, dstWidth, dstHeight);
 
          free(srcTemp);
          free(dstTemp);