mesa: add EXT_texture_compression_latc
authorMarek Olšák <maraeo@gmail.com>
Mon, 7 Mar 2011 01:03:52 +0000 (02:03 +0100)
committerMarek Olšák <maraeo@gmail.com>
Tue, 8 Mar 2011 22:52:37 +0000 (23:52 +0100)
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.

13 files changed:
src/mesa/main/extensions.c
src/mesa/main/formats.c
src/mesa/main/formats.h
src/mesa/main/image.c
src/mesa/main/mipmap.c
src/mesa/main/mtypes.h
src/mesa/main/texcompress.c
src/mesa/main/texcompress_rgtc.c
src/mesa/main/texcompress_rgtc.h
src/mesa/main/texfetch.c
src/mesa/main/texformat.c
src/mesa/main/teximage.c
src/mesa/main/texstore.c

index 3840cdc5d365066b65719e434ce63ec379b08395..519e94fec12cc59083c7bdd22b728cabc4186fe6 100644 (file)
@@ -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;
index 947db84a69e1e21ae15aff154c3249408cf7604c..db10c9b4c2e2550d98ddb27a0b8a1c96f5e26860 100644 (file)
@@ -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;
index e21967e2b0c66ab6d1d3db521150fa73f91b9567..04a18930b4e1b53cd5a9710a8d446bb0f885b037 100644 (file)
@@ -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;
 
index 63936132f98bd3e1cacd3de54037f6cbc9516a29..18abf2882af009a8683729c546adc81eafb151f0 100644 (file)
@@ -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;
    }
index 0727e1818f1cc085ada3220977d73dd10d29f184..e594160ad9eee039b651905e18f488a82867369d 100644 (file)
@@ -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;
       }
index 49ecea59d340b491a84b6d31ab568a931dd7d474..d10bb05b9ab12fd1f5aa20003994d56e8d95a938 100644 (file)
@@ -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;
index 82d02ed0ecf0ae55d7c5db95b73417df359e22f6..942d996695e15ddb3aa2df61d3025d8270b1f83c 100644 (file)
@@ -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()");
index 26dca2d760b5dbbb08566c719158fd1194606721..c50df19c5d8426195990c7ea96b8e7767161dc04 100644 (file)
@@ -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
index 424edc4581c0ac3fa89d82984294069f19327251..18766770d747838970334df171a9f4ece717f520 100644 (file)
@@ -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
index 550597e1cdfd9c3dfcccdebf3fc77b80057bec50..988a7e054686491e56d5745a55d2bce847fa8d86 100644 (file)
@@ -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
+   },
 };
 
 
index 72025cf828e8b1b36a5923c0f8496f532cd43cb0..521b9a04b71beae62da1fe42f4a8120c2c7bab4b 100644 (file)
@@ -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;
 }
index d4ae6dd69d83bb1a6ca53e0ba2617bf6b7127a76..6ec66100e7abb64817f48f10af6793bc7cf7949f 100644 (file)
@@ -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 */
 }
 
index cd30fa02149f221416461f2b47bc57150fa8c451..760cdfa85479af494c803c3fce7cf09bd7aa326b 100644 (file)
@@ -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 }
 };