some texture compression odds & ends
authorBrian Paul <brian.paul@tungstengraphics.com>
Thu, 3 Apr 2003 20:57:49 +0000 (20:57 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Thu, 3 Apr 2003 20:57:49 +0000 (20:57 +0000)
src/mesa/main/texcompress.c
src/mesa/main/texformat.c
src/mesa/main/texformat.h
src/mesa/main/texformat_tmp.h

index 81938854c277abe36f27a6333847c6c06ca7ec44..01425f33a56a2fff735d6d80d4ace7a2693b0f08 100644 (file)
@@ -1,5 +1,3 @@
-/* $Id: texcompress.c,v 1.4 2003/03/24 20:00:09 brianp Exp $ */
-
 /*
  * Mesa 3-D graphics library
  * Version:  5.1
@@ -52,6 +50,21 @@ _mesa_get_compressed_formats( GLcontext *ctx, GLint *formats )
             n += 2;
          }
       }
+      if (ctx->Extensions.EXT_texture_compression_s3tc) {
+         if (formats) {
+            formats[n++] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
+            /* Skip this one because it has a restriction (all transparent
+             * pixels become black).  See the texture compressions spec for
+             * a detailed explanation.  This is what NVIDIA does.
+            formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+            */
+            formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+            formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+         }
+         else {
+            n += 3;
+         }
+      }
    }
    return n;
 }
@@ -61,8 +74,8 @@ _mesa_get_compressed_formats( GLcontext *ctx, GLint *formats )
 /**
  * Return bytes of storage needed for the given texture size and compressed
  * format.
- * \param width, height, depth - texture size in texels
- * \param texFormat - one of the compressed format enums
+ * \param width, height, depth  the texture size in texels
+ * \param texFormat   one of the specific compressed format enums
  * \return size in bytes, or zero if bad texFormat
  */
 GLuint
@@ -78,6 +91,34 @@ _mesa_compressed_texture_size( GLcontext *ctx,
       /* round up to multiple of 4 */
       size = ((width + 7) / 8) * ((height + 3) / 4) * 16;
       return size;
+   case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+   case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+      /* round up width, height to next multiple of 4 */
+      width = (width + 3) & ~3;
+      height = (height + 3) & ~3;
+      ASSERT(depth == 1);
+      /* 8 bytes per 4x4 tile of RGB[A] texels */
+      size = (width * height * 8) / 16;
+      /* Textures smaller than 4x4 will effectively be made into 4x4 and
+       * take 8 bytes.
+       */
+      if (size < 8)
+         size = 8;
+      return size;
+   case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+   case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+      /* round up width, height to next multiple of 4 */
+      width = (width + 3) & ~3;
+      height = (height + 3) & ~3;
+      ASSERT(depth == 1);
+      /* 16 bytes per 4x4 tile of RGBA texels */
+      size = width * height; /* simple! */
+      /* Textures smaller than 4x4 will effectively be made into 4x4 and
+       * take 16 bytes.
+       */
+      if (size < 16)
+         size = 16;
+      return size;
    default:
       _mesa_problem(ctx, "bad texformat in compressed_texture_size");
       return 0;
@@ -85,8 +126,12 @@ _mesa_compressed_texture_size( GLcontext *ctx,
 }
 
 
-/*
+/**
  * Compute the bytes per row in a compressed texture image.
+ * We use this for computing the destination address for sub-texture updates.
+ * \param format  one of the specific texture compression formats
+ * \param width  image width in pixels
+ * \return stride, in bytes, between rows for compressed image
  */
 GLint
 _mesa_compressed_row_stride(GLenum format, GLsizei width)
@@ -94,6 +139,14 @@ _mesa_compressed_row_stride(GLenum format, GLsizei width)
    GLint bytesPerTile, stride;
 
    switch (format) {
+   case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+   case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+      bytesPerTile = 8;
+      break;
+   case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+   case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+      bytesPerTile = 16;
+      break;
    default:
       return 0;
    }
@@ -103,7 +156,7 @@ _mesa_compressed_row_stride(GLenum format, GLsizei width)
 }
 
 
-/*
+/**
  * Return the address of the pixel at (col, row, img) in a
  * compressed texture image.
  * \param col, row, img - image position (3D)
@@ -125,6 +178,14 @@ _mesa_compressed_image_address(GLint col, GLint row, GLint img,
    (void) img;
 
    switch (format) {
+   case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+   case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+      bytesPerTile = 8;
+      break;
+   case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+   case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+      bytesPerTile = 16;
+      break;
    default:
       return 0;
    }
index c529031f9f125aa838399c7e01bf07ce1c5a7f18..e92572242f76a74912f4d4ff4378b697e92e4b71 100644 (file)
@@ -1,5 +1,3 @@
-/* $Id: texformat.c,v 1.19 2003/03/01 01:50:22 brianp Exp $ */
-
 /*
  * Mesa 3-D graphics library
  * Version:  5.1
@@ -428,7 +426,6 @@ const struct gl_texture_format _mesa_texformat_ycbcr = {
    fetch_3d_texel_ycbcr,               /* FetchTexel3D */
 };
 
-
 const struct gl_texture_format _mesa_texformat_ycbcr_rev = {
    MESA_FORMAT_YCBCR_REV,              /* MesaFormat */
    GL_YCBCR_MESA,                      /* BaseFormat */
@@ -446,6 +443,74 @@ const struct gl_texture_format _mesa_texformat_ycbcr_rev = {
    fetch_3d_texel_ycbcr_rev,           /* FetchTexel3D */
 };
 
+const struct gl_texture_format _mesa_texformat_rgb_dxt1 = {
+   MESA_FORMAT_RGB_DXT1,               /* MesaFormat */
+   GL_RGB,                             /* BaseFormat */
+   4, /*approx*/                       /* RedBits */
+   4, /*approx*/                       /* GreenBits */
+   4, /*approx*/                       /* BlueBits */
+   0,                                  /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   0,                                  /* TexelBytes */
+   NULL, /*impossible*/                /* FetchTexel1D */
+   fetch_2d_texel_rgb_dxt1,            /* FetchTexel2D */
+   NULL, /*impossible*/                /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_rgba_dxt1 = {
+   MESA_FORMAT_RGBA_DXT1,              /* MesaFormat */
+   GL_RGBA,                            /* BaseFormat */
+   4, /*approx*/                       /* RedBits */
+   4, /*approx*/                       /* GreenBits */
+   4, /*approx*/                       /* BlueBits */
+   1, /*approx*/                       /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   0,                                  /* TexelBytes */
+   NULL, /*impossible*/                /* FetchTexel1D */
+   fetch_2d_texel_rgba_dxt1,           /* FetchTexel2D */
+   NULL, /*impossible*/                /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_rgba_dxt3 = {
+   MESA_FORMAT_RGBA_DXT3,              /* MesaFormat */
+   GL_RGBA,                            /* BaseFormat */
+   4, /*approx*/                       /* RedBits */
+   4, /*approx*/                       /* GreenBits */
+   4, /*approx*/                       /* BlueBits */
+   4, /*approx*/                       /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   0,                                  /* TexelBytes */
+   NULL, /*impossible*/                /* FetchTexel1D */
+   fetch_2d_texel_rgba_dxt3,           /* FetchTexel2D */
+   NULL, /*impossible*/                /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_rgba_dxt5 = {
+   MESA_FORMAT_RGBA_DXT5,              /* MesaFormat */
+   GL_RGBA,                            /* BaseFormat */
+   4,/*approx*/                                /* RedBits */
+   4,/*approx*/                                /* GreenBits */
+   4,/*approx*/                                /* BlueBits */
+   4,/*approx*/                                /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   0,                                  /* TexelBytes */
+   NULL, /*impossible*/                /* FetchTexel1D */
+   fetch_2d_texel_rgba_dxt5,           /* FetchTexel2D */
+   NULL, /*impossible*/                /* FetchTexel3D */
+};
+
 
 /* Big-endian */
 #if 0
@@ -738,10 +803,14 @@ _mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat,
    case GL_COMPRESSED_RGB_ARB:
       if (!ctx->Extensions.ARB_texture_compression)
         _mesa_problem(ctx, "texture compression extension not enabled");
+      if (ctx->Extensions.EXT_texture_compression_s3tc)
+         return &_mesa_texformat_rgb_dxt1;
       return &_mesa_texformat_rgb;
    case GL_COMPRESSED_RGBA_ARB:
       if (!ctx->Extensions.ARB_texture_compression)
         _mesa_problem(ctx, "texture compression extension not enabled");
+      if (ctx->Extensions.EXT_texture_compression_s3tc)
+         return &_mesa_texformat_rgba_dxt3;  /* Not rgba_dxt1!  See the spec */
       return &_mesa_texformat_rgba;
 
    /* GL_MESA_ycrcr_texture */
@@ -751,6 +820,28 @@ _mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat,
       else
          return &_mesa_texformat_ycbcr_rev;
 
+   /* GL_EXT_texture_compression_s3tc */
+   case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+      if (ctx->Extensions.EXT_texture_compression_s3tc)
+         return &_mesa_texformat_rgb_dxt1;
+      else
+         return NULL;
+   case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+      if (ctx->Extensions.EXT_texture_compression_s3tc)
+         return &_mesa_texformat_rgba_dxt1;
+      else
+         return NULL;
+   case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+      if (ctx->Extensions.EXT_texture_compression_s3tc)
+         return &_mesa_texformat_rgba_dxt3;
+      else
+         return NULL;
+   case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+      if (ctx->Extensions.EXT_texture_compression_s3tc)
+         return &_mesa_texformat_rgba_dxt5;
+      else
+         return NULL;
+
    default:
       _mesa_problem(ctx, "unexpected format in _mesa_choose_tex_format()");
       return NULL;
index 9f4d03616108b28a426e80c3acc7a3bfb8417902..6f19aac7bcf26f792aa5e2a31ef46a47e5e08a3b 100644 (file)
@@ -1,10 +1,8 @@
-/* $Id: texformat.h,v 1.13 2002/10/29 20:28:49 brianp Exp $ */
-
 /*
  * Mesa 3-D graphics library
- * Version:  4.1
+ * Version:  5.1
  *
- * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -67,6 +65,11 @@ enum _format {
    MESA_FORMAT_YCBCR,          /*                     YYYY YYYY UorV UorV */
    MESA_FORMAT_YCBCR_REV,      /*                     UorV UorV YYYY YYYY */
 
+   MESA_FORMAT_RGB_DXT1,
+   MESA_FORMAT_RGBA_DXT1,
+   MESA_FORMAT_RGBA_DXT3,
+   MESA_FORMAT_RGBA_DXT5,
+
 #if 0
    /* upcoming little-endian formats: */
 
@@ -141,6 +144,10 @@ extern const struct gl_texture_format _mesa_texformat_i8;
 extern const struct gl_texture_format _mesa_texformat_ci8;
 extern const struct gl_texture_format _mesa_texformat_ycbcr;
 extern const struct gl_texture_format _mesa_texformat_ycbcr_rev;
+extern const struct gl_texture_format _mesa_texformat_rgb_dxt1;
+extern const struct gl_texture_format _mesa_texformat_rgba_dxt1;
+extern const struct gl_texture_format _mesa_texformat_rgba_dxt3;
+extern const struct gl_texture_format _mesa_texformat_rgba_dxt5;
 
 /* The null format:
  */
index 0c50c2db1dc2ff4d6c5b83e1e818244cfa7c7748..83715d3fdb3f5410b9c09675cd6dedc4d0b50aa5 100644 (file)
@@ -1,10 +1,8 @@
-/* $Id: texformat_tmp.h,v 1.10 2002/10/29 20:28:50 brianp Exp $ */
-
 /*
  * Mesa 3-D graphics library
- * Version:  4.1
+ * Version:  5.1
  *
- * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -356,6 +354,48 @@ static void FETCH(ycbcr_rev)( const struct gl_texture_image *texImage,
 }
 
 
+#if DIM == 2
+static void FETCH(rgb_dxt1)( const struct gl_texture_image *texImage,
+                             GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   /* Extract the (i,j) pixel from texImage->Data and return it
+    * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
+    */
+}
+#endif
+
+#if DIM == 2
+static void FETCH(rgba_dxt1)( const struct gl_texture_image *texImage,
+                              GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   /* Extract the (i,j) pixel from texImage->Data and return it
+    * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
+    */
+}
+#endif
+
+#if DIM == 2
+static void FETCH(rgba_dxt3)( const struct gl_texture_image *texImage,
+                              GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   /* Extract the (i,j) pixel from texImage->Data and return it
+    * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
+    */
+}
+#endif
+
+#if DIM == 2
+static void FETCH(rgba_dxt5)( const struct gl_texture_image *texImage,
+                              GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   /* Extract the (i,j) pixel from texImage->Data and return it
+    * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
+    */
+}
+#endif
+
+
+
 /* big-endian */
 
 #if 0