Mesa (master): mesa/st: fix generate mipmap for signed compressed formats.

Dave Airlie airlied at kemper.freedesktop.org
Wed Mar 2 05:26:27 UTC 2011


Module: Mesa
Branch: master
Commit: 64f19b90d777ab21f8053eddcce83369754592a6
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=64f19b90d777ab21f8053eddcce83369754592a6

Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Mar  2 15:28:32 2011 +1000

mesa/st: fix generate mipmap for signed compressed formats.

This was always converting to 8-bit per channel unsigned formats,
which isn't suitable for RGTC signed formats, this special cases
those two formats and converts to floats for those.

Signed-off-by: Dave Airlie <airlied at redhat.com>

---

 src/mesa/state_tracker/st_gen_mipmap.c |   95 +++++++++++++++++++++-----------
 1 files changed, 63 insertions(+), 32 deletions(-)

diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c
index 4bf6828..2ec8431 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -103,52 +103,78 @@ st_render_mipmap(struct st_context *st,
  * image with stride==width.
  */
 static void
-decompress_image(enum pipe_format format,
-                 const uint8_t *src, uint8_t *dst,
+decompress_image(enum pipe_format format, int datatype,
+                 const uint8_t *src, void *dst,
                  unsigned width, unsigned height, unsigned src_stride)
 {
    const struct util_format_description *desc = util_format_description(format);
    const uint bw = util_format_get_blockwidth(format);
    const uint bh = util_format_get_blockheight(format);
-   const uint dst_stride = 4 * MAX2(width, bw);
-
-   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];
-            }
-         }
+   uint dst_stride = 4 * MAX2(width, bw);
+
+   if (datatype == GL_FLOAT) {
+      desc->unpack_rgba_float((float *)dst, dst_stride * sizeof(GLfloat), src, src_stride, width, height);
+      if (width < bw || height < bh) {
+	 float *dst_p = (float *)dst;
+	 /* 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[p + 0] = dst_p[0];
+		  dst_p[p + 1] = dst_p[1];
+		  dst_p[p + 2] = dst_p[2];
+		  dst_p[p + 3] = dst_p[3];
+	       }
+	    }
+	 }
+      }
+   } else {
+      desc->unpack_rgba_8unorm((uint8_t *)dst, dst_stride, src, src_stride, width, height);
+      if (width < bw || height < bh) {
+	 uint8_t *dst_p = (uint8_t *)dst;
+	 /* 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[p + 0] = dst_p[0];
+		  dst_p[p + 1] = dst_p[1];
+		  dst_p[p + 2] = dst_p[2];
+		  dst_p[p + 3] = dst_p[3];
+	       }
+	    }
+	 }
       }
    }
 }
 
-
 /**
  * Helper function to compress an image.  The source is a 32-bpp RGBA image
  * with stride==width.
  */
 static void
-compress_image(enum pipe_format format,
-               const uint8_t *src, uint8_t *dst,
+compress_image(enum pipe_format format, int datatype,
+               const void *src, uint8_t *dst,
                unsigned width, unsigned height, unsigned dst_stride)
 {
    const struct util_format_description *desc = util_format_description(format);
    const uint src_stride = 4 * width;
 
-   desc->pack_rgba_8unorm(dst, dst_stride, src, src_stride, width, height);
+   if (datatype == GL_FLOAT)
+      desc->pack_rgba_float(dst, dst_stride, (GLfloat *)src, src_stride * sizeof(GLfloat), width, height);
+   else
+      desc->pack_rgba_8unorm(dst, dst_stride, (uint8_t *)src, src_stride, width, height);
 }
 
 
@@ -178,7 +204,12 @@ fallback_generate_mipmap(struct gl_context *ctx, GLenum target,
       _mesa_is_format_compressed(texObj->Image[face][baseLevel]->TexFormat);
 
    if (compressed) {
-      datatype = GL_UNSIGNED_BYTE;
+      if (texObj->Image[face][baseLevel]->TexFormat == MESA_FORMAT_SIGNED_RED_RGTC1 ||
+	  texObj->Image[face][baseLevel]->TexFormat == MESA_FORMAT_SIGNED_RG_RGTC2)
+         datatype = GL_FLOAT;
+      else
+         datatype = GL_UNSIGNED_BYTE;
+      
       comps = 4;
    }
    else {
@@ -230,11 +261,11 @@ fallback_generate_mipmap(struct gl_context *ctx, GLenum target,
 
          assert(comps == 4);
 
-         srcTemp = malloc(srcWidth2 * srcHeight2 * comps + 000);
-         dstTemp = malloc(dstWidth2 * dstHeight2 * comps + 000);
+         srcTemp = malloc(srcWidth2 * srcHeight2 * comps * (datatype == GL_FLOAT ? 4 : 1));
+         dstTemp = malloc(dstWidth2 * dstHeight2 * comps * (datatype == GL_FLOAT ? 4 : 1));
 
          /* decompress the src image: srcData -> srcTemp */
-         decompress_image(format, srcData, srcTemp, srcWidth, srcHeight, srcTrans->stride);
+         decompress_image(format, datatype, srcData, srcTemp, srcWidth, srcHeight, srcTrans->stride);
 
          _mesa_generate_mipmap_level(target, datatype, comps,
                                      0 /*border*/,
@@ -246,7 +277,7 @@ fallback_generate_mipmap(struct gl_context *ctx, GLenum target,
                                      dstWidth2); /* stride in texels */
 
          /* compress the new image: dstTemp -> dstData */
-         compress_image(format, dstTemp, dstData, dstWidth, dstHeight, dstTrans->stride);
+         compress_image(format, datatype, dstTemp, dstData, dstWidth, dstHeight, dstTrans->stride);
 
          free(srcTemp);
          free(dstTemp);




More information about the mesa-commit mailing list