Mesa (master): mesa: add EXT_texture_compression_latc

Marek Olšák mareko at kemper.freedesktop.org
Tue Mar 8 23:16:28 UTC 2011


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

Author: Marek Olšák <maraeo at gmail.com>
Date:   Mon Mar  7 02:03:52 2011 +0100

mesa: add EXT_texture_compression_latc

The encoding/decoding algorithms are shared with RGTC.
Thanks to some magic with the base format, the RGTC texstore functions work
for LATC too.

swrast passes the related piglit tests besides two things:
- The alpha channel is wrong (it's always 1), however the incorrect alpha
  channel makes some other tests fail too, so I guess it's unrelated to LATC.
- Signed LATC fetches aren't correct yet (signed values are clamped to [0,1]),
  however RGTC has the same problem.

Further testing (with other of my patches) shows that hardware drivers
and softpipe work.

BTW, ETQW uses this extension.

---

 src/mesa/main/extensions.c       |    2 +
 src/mesa/main/formats.c          |   40 ++++++++++++++++++++++
 src/mesa/main/formats.h          |    8 ++++
 src/mesa/main/image.c            |    9 +++++
 src/mesa/main/mipmap.c           |    9 ++++-
 src/mesa/main/mtypes.h           |    1 +
 src/mesa/main/texcompress.c      |   18 ++++++++++
 src/mesa/main/texcompress_rgtc.c |   68 +++++++++++++++++++++++++++++++++++--
 src/mesa/main/texcompress_rgtc.h |   17 +++++++++
 src/mesa/main/texfetch.c         |   28 +++++++++++++++
 src/mesa/main/texformat.c        |   19 ++++++++++
 src/mesa/main/teximage.c         |   13 +++++++
 src/mesa/main/texstore.c         |    9 ++++-
 13 files changed, 234 insertions(+), 7 deletions(-)

diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 3840cdc..519e94f 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -181,6 +181,7 @@ static const struct extension extension_table[] = {
    { "GL_EXT_texture3D",                           o(EXT_texture3D),                           GL             },
    { "GL_EXT_texture_array",                       o(EXT_texture_array),                       GL             },
    { "GL_EXT_texture_compression_dxt1",            o(EXT_texture_compression_s3tc),            GL | ES1 | ES2 },
+   { "GL_EXT_texture_compression_latc",            o(EXT_texture_compression_latc),            GL             },
    { "GL_EXT_texture_compression_rgtc",            o(ARB_texture_compression_rgtc),            GL             },
    { "GL_EXT_texture_compression_s3tc",            o(EXT_texture_compression_s3tc),            GL             },
    { "GL_EXT_texture_cube_map",                    o(ARB_texture_cube_map),                    GL             },
@@ -483,6 +484,7 @@ _mesa_enable_sw_extensions(struct gl_context *ctx)
    ctx->Extensions.EXT_stencil_wrap = GL_TRUE;
    ctx->Extensions.EXT_stencil_two_side = GL_TRUE;
    ctx->Extensions.EXT_texture_array = GL_TRUE;
+   ctx->Extensions.EXT_texture_compression_latc = GL_TRUE;
    ctx->Extensions.EXT_texture_env_add = GL_TRUE;
    ctx->Extensions.EXT_texture_env_combine = GL_TRUE;
    ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE;
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
index 947db84..db10c9b 100644
--- a/src/mesa/main/formats.c
+++ b/src/mesa/main/formats.c
@@ -927,6 +927,42 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] =
      0, 0, 0, 0, 0,
      4, 4, 16                     /* 16 bytes per 4x4 block */
    },
+   {
+     MESA_FORMAT_L_LATC1,
+     "MESA_FORMAT_L_LATC1",
+     GL_LUMINANCE,
+     GL_UNSIGNED_NORMALIZED,
+     0, 0, 0, 0,
+     4, 0, 0, 0, 0,
+     4, 4, 8                     /* 8 bytes per 4x4 block */
+   },
+   {
+     MESA_FORMAT_SIGNED_L_LATC1,
+     "MESA_FORMAT_SIGNED_L_LATC1",
+     GL_LUMINANCE,
+     GL_SIGNED_NORMALIZED,
+     0, 0, 0, 0,
+     4, 0, 0, 0, 0,
+     4, 4, 8                     /* 8 bytes per 4x4 block */
+   },
+   {
+     MESA_FORMAT_LA_LATC2,
+     "MESA_FORMAT_LA_LATC2",
+     GL_LUMINANCE_ALPHA,
+     GL_UNSIGNED_NORMALIZED,
+     0, 0, 0, 4,
+     4, 0, 0, 0, 0,
+     4, 4, 16                     /* 16 bytes per 4x4 block */
+   },
+   {
+     MESA_FORMAT_SIGNED_LA_LATC2,
+     "MESA_FORMAT_SIGNED_LA_LATC2",
+     GL_LUMINANCE_ALPHA,
+     GL_SIGNED_NORMALIZED,
+     0, 0, 0, 4,
+     4, 0, 0, 0, 0,
+     4, 4, 16                     /* 16 bytes per 4x4 block */
+   },
 };
 
 
@@ -1570,6 +1606,10 @@ _mesa_format_to_type_and_comps(gl_format format,
    case MESA_FORMAT_SIGNED_RED_RGTC1:
    case MESA_FORMAT_RG_RGTC2:
    case MESA_FORMAT_SIGNED_RG_RGTC2:
+   case MESA_FORMAT_L_LATC1:
+   case MESA_FORMAT_SIGNED_L_LATC1:
+   case MESA_FORMAT_LA_LATC2:
+   case MESA_FORMAT_SIGNED_LA_LATC2:
       /* XXX generate error instead? */
       *datatype = GL_UNSIGNED_BYTE;
       *comps = 0;
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
index e21967e..04a1893 100644
--- a/src/mesa/main/formats.h
+++ b/src/mesa/main/formats.h
@@ -185,6 +185,14 @@ typedef enum
    MESA_FORMAT_RG_RGTC2,
    MESA_FORMAT_SIGNED_RG_RGTC2,
    /*@}*/
+
+   /*@{*/
+   MESA_FORMAT_L_LATC1,
+   MESA_FORMAT_SIGNED_L_LATC1,
+   MESA_FORMAT_LA_LATC2,
+   MESA_FORMAT_SIGNED_LA_LATC2,
+   /*@}*/
+
    MESA_FORMAT_COUNT
 } gl_format;
 
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c
index 6393613..18abf28 100644
--- a/src/mesa/main/image.c
+++ b/src/mesa/main/image.c
@@ -743,6 +743,10 @@ _mesa_is_color_format(GLenum format)
       case GL_COMPRESSED_SIGNED_RED_RGTC1:
       case GL_COMPRESSED_RG_RGTC2:
       case GL_COMPRESSED_SIGNED_RG_RGTC2:
+      case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
+      case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
+      case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
+      case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
       /* signed, normalized texture formats */
       case GL_RGBA_SNORM:
       case GL_RGBA8_SNORM:
@@ -1025,6 +1029,11 @@ _mesa_is_compressed_format(struct gl_context *ctx, GLenum format)
    case GL_COMPRESSED_RG_RGTC2:
    case GL_COMPRESSED_SIGNED_RG_RGTC2:
       return ctx->Extensions.ARB_texture_compression_rgtc;
+   case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
+   case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
+   case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
+   case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
+      return ctx->Extensions.EXT_texture_compression_latc;
    default:
       return GL_FALSE;
    }
diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c
index 0727e18..e594160 100644
--- a/src/mesa/main/mipmap.c
+++ b/src/mesa/main/mipmap.c
@@ -1764,8 +1764,13 @@ _mesa_generate_mipmap(struct gl_context *ctx, GLenum target,
       } else if (srcImage->_BaseFormat == GL_RGBA) {
          convertFormat = MESA_FORMAT_RGBA8888;
          components = 4;
-      }
-      else {
+      } else if (srcImage->_BaseFormat == GL_LUMINANCE) {
+         convertFormat = MESA_FORMAT_L8;
+         components = 1;
+      } else if (srcImage->_BaseFormat == GL_LUMINANCE_ALPHA) {
+         convertFormat = MESA_FORMAT_AL88;
+         components = 2;
+      } else {
          _mesa_problem(ctx, "bad srcImage->_BaseFormat in _mesa_generate_mipmaps");
          return;
       }
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 49ecea5..d10bb05 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2802,6 +2802,7 @@ struct gl_extensions
    GLboolean EXT_texture_object;
    GLboolean EXT_texture3D;
    GLboolean EXT_texture_array;
+   GLboolean EXT_texture_compression_latc;
    GLboolean EXT_texture_compression_s3tc;
    GLboolean EXT_texture_env_add;
    GLboolean EXT_texture_env_combine;
diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c
index 82d02ed..942d996 100644
--- a/src/mesa/main/texcompress.c
+++ b/src/mesa/main/texcompress.c
@@ -173,6 +173,15 @@ _mesa_glenum_to_compressed_format(GLenum format)
    case GL_COMPRESSED_SIGNED_RG_RGTC2:
       return MESA_FORMAT_SIGNED_RG_RGTC2;
 
+   case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
+      return MESA_FORMAT_L_LATC1;
+   case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
+      return MESA_FORMAT_SIGNED_L_LATC1;
+   case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
+      return MESA_FORMAT_LA_LATC2;
+   case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
+      return MESA_FORMAT_SIGNED_LA_LATC2;
+
    default:
       return MESA_FORMAT_NONE;
    }
@@ -229,6 +238,15 @@ _mesa_compressed_format_to_glenum(struct gl_context *ctx, GLuint mesaFormat)
    case MESA_FORMAT_SIGNED_RG_RGTC2:
       return GL_COMPRESSED_SIGNED_RG_RGTC2;
 
+   case MESA_FORMAT_L_LATC1:
+      return GL_COMPRESSED_LUMINANCE_LATC1_EXT;
+   case MESA_FORMAT_SIGNED_L_LATC1:
+      return GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT;
+   case MESA_FORMAT_LA_LATC2:
+      return GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT;
+   case MESA_FORMAT_SIGNED_LA_LATC2:
+      return GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT;
+
    default:
       _mesa_problem(ctx, "Unexpected mesa texture format in"
                     " _mesa_compressed_format_to_glenum()");
diff --git a/src/mesa/main/texcompress_rgtc.c b/src/mesa/main/texcompress_rgtc.c
index 26dca2d..c50df19 100644
--- a/src/mesa/main/texcompress_rgtc.c
+++ b/src/mesa/main/texcompress_rgtc.c
@@ -98,7 +98,8 @@ _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS)
    GLubyte srcpixels[4][4];
    GLubyte *blkaddr;
    GLint dstRowDiff;
-   ASSERT(dstFormat == MESA_FORMAT_RED_RGTC1);
+   ASSERT(dstFormat == MESA_FORMAT_RED_RGTC1 ||
+          dstFormat == MESA_FORMAT_L_LATC1);
    ASSERT(dstXoffset % 4 == 0);
    ASSERT(dstYoffset % 4 == 0);
    ASSERT(dstZoffset % 4 == 0);
@@ -153,7 +154,8 @@ _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS)
    GLbyte srcpixels[4][4];
    GLbyte *blkaddr;
    GLint dstRowDiff;
-   ASSERT(dstFormat == MESA_FORMAT_SIGNED_RED_RGTC1);
+   ASSERT(dstFormat == MESA_FORMAT_SIGNED_RED_RGTC1 ||
+          dstFormat == MESA_FORMAT_SIGNED_L_LATC1);
    ASSERT(dstXoffset % 4 == 0);
    ASSERT(dstYoffset % 4 == 0);
    ASSERT(dstZoffset % 4 == 0);
@@ -208,7 +210,8 @@ _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS)
    GLubyte *blkaddr;
    GLint dstRowDiff;
 
-   ASSERT(dstFormat == MESA_FORMAT_RG_RGTC2);
+   ASSERT(dstFormat == MESA_FORMAT_RG_RGTC2 ||
+          dstFormat == MESA_FORMAT_LA_LATC2);
    ASSERT(dstXoffset % 4 == 0);
    ASSERT(dstYoffset % 4 == 0);
    ASSERT(dstZoffset % 4 == 0);
@@ -269,7 +272,8 @@ _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS)
    GLbyte *blkaddr;
    GLint dstRowDiff;
 
-   ASSERT(dstFormat == MESA_FORMAT_SIGNED_RG_RGTC2);
+   ASSERT(dstFormat == MESA_FORMAT_SIGNED_RG_RGTC2 ||
+          dstFormat == MESA_FORMAT_SIGNED_LA_LATC2);
    ASSERT(dstXoffset % 4 == 0);
    ASSERT(dstYoffset % 4 == 0);
    ASSERT(dstZoffset % 4 == 0);
@@ -374,6 +378,62 @@ _mesa_fetch_texel_2d_f_signed_rg_rgtc2(const struct gl_texture_image *texImage,
    texel[ACOMP] = 1.0;
 }
 
+void
+_mesa_fetch_texel_2d_f_l_latc1(const struct gl_texture_image *texImage,
+                                 GLint i, GLint j, GLint k, GLfloat *texel)
+{
+   GLubyte red;
+   unsigned_fetch_texel_rgtc(texImage->RowStride, (GLubyte *)(texImage->Data),
+                       i, j, &red, 1);
+   texel[RCOMP] =
+   texel[GCOMP] =
+   texel[BCOMP] = UBYTE_TO_FLOAT(red);
+   texel[ACOMP] = 1.0;
+}
+
+void
+_mesa_fetch_texel_2d_f_signed_l_latc1(const struct gl_texture_image *texImage,
+                                        GLint i, GLint j, GLint k, GLfloat *texel)
+{
+   GLbyte red;
+   signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data),
+                       i, j, &red, 1);
+   texel[RCOMP] =
+   texel[GCOMP] =
+   texel[BCOMP] = BYTE_TO_FLOAT_TEX(red);
+   texel[ACOMP] = 1.0;
+}
+
+void
+_mesa_fetch_texel_2d_f_la_latc2(const struct gl_texture_image *texImage,
+                                 GLint i, GLint j, GLint k, GLfloat *texel)
+{
+   GLubyte red, green;
+   unsigned_fetch_texel_rgtc(texImage->RowStride, (GLubyte *)(texImage->Data),
+                     i, j, &red, 2);
+   unsigned_fetch_texel_rgtc(texImage->RowStride, (GLubyte *)(texImage->Data) + 8,
+                     i, j, &green, 2);
+   texel[RCOMP] =
+   texel[GCOMP] =
+   texel[BCOMP] = UBYTE_TO_FLOAT(red);
+   texel[ACOMP] = UBYTE_TO_FLOAT(green);
+}
+
+void
+_mesa_fetch_texel_2d_f_signed_la_latc2(const struct gl_texture_image *texImage,
+                                       GLint i, GLint j, GLint k, GLfloat *texel)
+{
+   GLbyte red, green;
+   signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data),
+                     i, j, &red, 2);
+   signed_fetch_texel_rgtc(texImage->RowStride, (GLbyte *)(texImage->Data) + 8,
+                     i, j, &green, 2);
+   texel[RCOMP] =
+   texel[GCOMP] =
+   texel[BCOMP] = BYTE_TO_FLOAT_TEX(red);
+   texel[ACOMP] = BYTE_TO_FLOAT_TEX(green);
+}
+
 #define TAG(x) unsigned_##x
 
 #define TYPE GLubyte
diff --git a/src/mesa/main/texcompress_rgtc.h b/src/mesa/main/texcompress_rgtc.h
index 424edc4..1876677 100644
--- a/src/mesa/main/texcompress_rgtc.h
+++ b/src/mesa/main/texcompress_rgtc.h
@@ -57,4 +57,21 @@ _mesa_fetch_texel_2d_f_rg_rgtc2(const struct gl_texture_image *texImage,
 extern void
 _mesa_fetch_texel_2d_f_signed_rg_rgtc2(const struct gl_texture_image *texImage,
 				       GLint i, GLint j, GLint k, GLfloat *texel);
+
+extern void
+_mesa_fetch_texel_2d_f_l_latc1(const struct gl_texture_image *texImage,
+                                 GLint i, GLint j, GLint k, GLfloat *texel);
+
+extern void
+_mesa_fetch_texel_2d_f_signed_l_latc1(const struct gl_texture_image *texImage,
+                                        GLint i, GLint j, GLint k, GLfloat *texel);
+
+extern void
+_mesa_fetch_texel_2d_f_la_latc2(const struct gl_texture_image *texImage,
+                                 GLint i, GLint j, GLint k, GLfloat *texel);
+
+extern void
+_mesa_fetch_texel_2d_f_signed_la_latc2(const struct gl_texture_image *texImage,
+                                       GLint i, GLint j, GLint k, GLfloat *texel);
+
 #endif
diff --git a/src/mesa/main/texfetch.c b/src/mesa/main/texfetch.c
index 550597e..988a7e0 100644
--- a/src/mesa/main/texfetch.c
+++ b/src/mesa/main/texfetch.c
@@ -786,6 +786,34 @@ texfetch_funcs[MESA_FORMAT_COUNT] =
       NULL,
       NULL
    },
+   {
+      MESA_FORMAT_L_LATC1,
+      NULL,
+      _mesa_fetch_texel_2d_f_l_latc1,
+      NULL,
+      NULL
+   },
+   {
+      MESA_FORMAT_SIGNED_L_LATC1,
+      NULL,
+      _mesa_fetch_texel_2d_f_signed_l_latc1,
+      NULL,
+      NULL
+   },
+   {
+      MESA_FORMAT_LA_LATC2,
+      NULL,
+      _mesa_fetch_texel_2d_f_la_latc2,
+      NULL,
+      NULL
+   },
+   {
+      MESA_FORMAT_SIGNED_LA_LATC2,
+      NULL,
+      _mesa_fetch_texel_2d_f_signed_la_latc2,
+      NULL,
+      NULL
+   },
 };
 
 
diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c
index 72025cf..521b9a0 100644
--- a/src/mesa/main/texformat.c
+++ b/src/mesa/main/texformat.c
@@ -621,6 +621,25 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat,
       }
    }
 
+   if (ctx->Extensions.EXT_texture_compression_latc) {
+      switch (internalFormat) {
+         case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
+            RETURN_IF_SUPPORTED(MESA_FORMAT_L_LATC1);
+            break;
+         case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
+            RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_L_LATC1);
+            break;
+         case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
+            RETURN_IF_SUPPORTED(MESA_FORMAT_LA_LATC2);
+            break;
+         case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
+            RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_LA_LATC2);
+            break;
+         default:
+            ; /* fallthrough */
+      }
+   }
+
    _mesa_problem(ctx, "unexpected format in _mesa_choose_tex_format()");
    return MESA_FORMAT_NONE;
 }
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index d4ae6dd..6ec6610 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -509,6 +509,19 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
       }
    }
 
+   if (ctx->Extensions.EXT_texture_compression_latc) {
+      switch (internalFormat) {
+      case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
+      case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
+         return GL_LUMINANCE;
+      case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
+      case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
+         return GL_LUMINANCE_ALPHA;
+      default:
+         ; /* fallthrough */
+      }
+   }
+
    return -1; /* error */
 }
 
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index cd30fa0..760cdfa 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -4135,7 +4135,14 @@ texstore_funcs[MESA_FORMAT_COUNT] =
    { MESA_FORMAT_RED_RGTC1, _mesa_texstore_red_rgtc1 },
    { MESA_FORMAT_SIGNED_RED_RGTC1, _mesa_texstore_signed_red_rgtc1 },
    { MESA_FORMAT_RG_RGTC2, _mesa_texstore_rg_rgtc2 },
-   { MESA_FORMAT_SIGNED_RG_RGTC2, _mesa_texstore_signed_rg_rgtc2 }
+   { MESA_FORMAT_SIGNED_RG_RGTC2, _mesa_texstore_signed_rg_rgtc2 },
+
+   /* Re-use the R/RG texstore functions.
+    * The code is generic enough to handle LATC too. */
+   { MESA_FORMAT_L_LATC1, _mesa_texstore_red_rgtc1 },
+   { MESA_FORMAT_SIGNED_L_LATC1, _mesa_texstore_signed_red_rgtc1 },
+   { MESA_FORMAT_LA_LATC2, _mesa_texstore_rg_rgtc2 },
+   { MESA_FORMAT_SIGNED_LA_LATC2, _mesa_texstore_signed_rg_rgtc2 }
 };
 
 




More information about the mesa-commit mailing list