texture compression
authorDaniel Borca <dborca@users.sourceforge.net>
Wed, 29 Oct 2003 14:35:31 +0000 (14:35 +0000)
committerDaniel Borca <dborca@users.sourceforge.net>
Wed, 29 Oct 2003 14:35:31 +0000 (14:35 +0000)
src/mesa/main/dd.h
src/mesa/main/texcompress.c
src/mesa/main/texformat.c
src/mesa/main/texformat.h
src/mesa/main/texformat_tmp.h
src/mesa/main/teximage.c

index a4aa534..9942227 100644 (file)
@@ -480,6 +480,17 @@ struct dd_function_table {
                                    GLsizei imageSize, const GLvoid *data,
                                    struct gl_texture_object *texObj,
                                    struct gl_texture_image *texImage);
+   /**
+    * Called to validate a certain compressed format.
+    */
+   GLboolean (*IsCompressedFormat)( GLcontext *ctx, GLenum internalFormat );
+   /**
+    * Called to get bytes of storage needed for the given texture size and
+    * compressed format.
+    */
+   GLuint (*CompressedTextureSize)( GLcontext *ctx,
+                                    GLsizei width, GLsizei height, GLsizei depth,
+                                    GLenum format );
    /*@}*/
 
    /**
index e6a9695..1b9daac 100644 (file)
@@ -96,11 +96,20 @@ _mesa_compressed_texture_size( GLcontext *ctx,
 {
    GLuint size;
 
+   if (ctx->Driver.CompressedTextureSize) {
+      return ctx->Driver.CompressedTextureSize(ctx, width, height, depth, format);
+   }
+
    switch (format) {
    case GL_COMPRESSED_RGB_FXT1_3DFX:
    case GL_COMPRESSED_RGBA_FXT1_3DFX:
       /* round up to multiple of 4 */
       size = ((width + 7) / 8) * ((height + 3) / 4) * 16;
+      /* Textures smaller than 4x4 will effectively be made into 4x4 and
+       * take 8 bytes.
+       */
+      if (size < 16)
+         size = 16;
       return size;
    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
@@ -150,6 +159,10 @@ _mesa_compressed_row_stride(GLenum format, GLsizei width)
    GLint bytesPerTile, stride;
 
    switch (format) {
+   case GL_COMPRESSED_RGB_FXT1_3DFX:
+   case GL_COMPRESSED_RGBA_FXT1_3DFX:
+      bytesPerTile = 8;
+      break;
    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
       bytesPerTile = 8;
@@ -193,6 +206,10 @@ _mesa_compressed_image_address(GLint col, GLint row, GLint img,
    (void) img;
 
    switch (format) {
+   case GL_COMPRESSED_RGB_FXT1_3DFX:
+   case GL_COMPRESSED_RGBA_FXT1_3DFX:
+      bytesPerTile = 8;
+      break;
    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
       bytesPerTile = 8;
index b5c721f..0000767 100644 (file)
@@ -453,6 +453,40 @@ const struct gl_texture_format _mesa_texformat_ycbcr_rev = {
    fetch_3d_texel_ycbcr_rev,           /* FetchTexel3D */
 };
 
+const struct gl_texture_format _mesa_texformat_rgb_fxt1 = {
+   MESA_FORMAT_RGB_FXT1,               /* 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_fxt1,            /* FetchTexel2D */
+   NULL, /*impossible*/                /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_rgba_fxt1 = {
+   MESA_FORMAT_RGBA_FXT1,              /* 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_fxt1,           /* FetchTexel2D */
+   NULL, /*impossible*/                /* FetchTexel3D */
+};
+
 const struct gl_texture_format _mesa_texformat_rgb_dxt1 = {
    MESA_FORMAT_RGB_DXT1,               /* MesaFormat */
    GL_RGB,                             /* BaseFormat */
@@ -838,13 +872,17 @@ _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)
+      if (ctx->Extensions.TDFX_texture_compression_FXT1)
+         return &_mesa_texformat_rgb_fxt1;
+      else 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)
+      if (ctx->Extensions.TDFX_texture_compression_FXT1)
+         return &_mesa_texformat_rgba_fxt1;
+      else if (ctx->Extensions.EXT_texture_compression_s3tc)
          return &_mesa_texformat_rgba_dxt3;  /* Not rgba_dxt1!  See the spec */
       return &_mesa_texformat_rgba;
 
@@ -855,6 +893,18 @@ _mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat,
       else
          return &_mesa_texformat_ycbcr_rev;
 
+   /* GL_3DFX_texture_compression_FXT1 */
+   case GL_COMPRESSED_RGB_FXT1_3DFX:
+      if (ctx->Extensions.TDFX_texture_compression_FXT1)
+         return &_mesa_texformat_rgb_fxt1;
+      else
+         return NULL;
+   case GL_COMPRESSED_RGBA_FXT1_3DFX:
+      if (ctx->Extensions.TDFX_texture_compression_FXT1)
+         return &_mesa_texformat_rgba_fxt1;
+      else
+         return NULL;
+
    /* GL_EXT_texture_compression_s3tc */
    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
       if (ctx->Extensions.EXT_texture_compression_s3tc)
index 07fa2ad..c43da46 100644 (file)
@@ -75,6 +75,8 @@ enum _format {
    MESA_FORMAT_YCBCR_REV,      /*                     UorV UorV YYYY YYYY */
    /*@}*/
 
+   MESA_FORMAT_RGB_FXT1,
+   MESA_FORMAT_RGBA_FXT1,
    MESA_FORMAT_RGB_DXT1,
    MESA_FORMAT_RGBA_DXT1,
    MESA_FORMAT_RGBA_DXT3,
@@ -162,6 +164,8 @@ 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_fxt1;
+extern const struct gl_texture_format _mesa_texformat_rgba_fxt1;
 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;
index 840fcd2..b0af8b8 100644 (file)
@@ -362,6 +362,27 @@ static void FETCH(ycbcr_rev)( const struct gl_texture_image *texImage,
 
 
 #if DIM == 2
+static void FETCH(rgb_fxt1)( 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_fxt1)( 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(rgb_dxt1)( const struct gl_texture_image *texImage,
                              GLint i, GLint j, GLint k, GLvoid *texel )
 {
index cf199dd..efe197e 100644 (file)
@@ -262,6 +262,18 @@ _mesa_base_tex_format( GLcontext *ctx, GLint format )
             return GL_RGBA;
          else
             return -1;
+      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+         if (ctx->Extensions.EXT_texture_compression_s3tc)
+            return GL_RGB;
+         else
+            return -1;
+      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+         if (ctx->Extensions.EXT_texture_compression_s3tc)
+            return GL_RGBA;
+         else
+            return -1;
 
       case GL_YCBCR_MESA:
          if (ctx->Extensions.MESA_ycbcr_texture)
@@ -366,13 +378,20 @@ is_index_format(GLenum format)
  * are supported.
  */
 static GLboolean
-is_compressed_format(GLenum internalFormat)
+is_compressed_format(GLcontext *ctx, GLenum internalFormat)
 {
    switch (internalFormat) {
       case GL_COMPRESSED_RGB_FXT1_3DFX:
       case GL_COMPRESSED_RGBA_FXT1_3DFX:
+      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
          return GL_TRUE;
       default:
+         if (ctx->Driver.IsCompressedFormat) {
+            return ctx->Driver.IsCompressedFormat(ctx, internalFormat);
+         }
          return GL_FALSE;
    }
 }
@@ -916,7 +935,7 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
    img->Height2 = height - 2 * border; /*1 << img->HeightLog2;*/
    img->Depth2 = depth - 2 * border; /*1 << img->DepthLog2;*/
    img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
-   img->IsCompressed = is_compressed_format(internalFormat);
+   img->IsCompressed = is_compressed_format(ctx, internalFormat);
    if (img->IsCompressed)
       img->CompressedSize = _mesa_compressed_texture_size(ctx, width, height,
                                                        depth, internalFormat);
@@ -1236,7 +1255,7 @@ texture_error_check( GLcontext *ctx, GLenum target,
       }
    }
 
-   if (is_compressed_format(internalFormat)) {
+   if (is_compressed_format(ctx, internalFormat)) {
       if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
          /* OK */
       }
@@ -1569,7 +1588,7 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
       return GL_TRUE;
    }
 
-   if (is_compressed_format(internalFormat)) {
+   if (is_compressed_format(ctx, internalFormat)) {
       if (target != GL_TEXTURE_2D) {
          _mesa_error(ctx, GL_INVALID_ENUM,
                      "glCopyTexImage%d(target)", dimensions);
@@ -2612,7 +2631,7 @@ compressed_texture_error_check(GLcontext *ctx, GLint dimensions,
 
    maxTextureSize = 1 << (maxLevels - 1);
 
-   if (!is_compressed_format(internalFormat))
+   if (!is_compressed_format(ctx, internalFormat))
       return GL_INVALID_ENUM;
 
    if (border != 0)
@@ -2701,7 +2720,7 @@ compressed_subtexture_error_check(GLcontext *ctx, GLint dimensions,
 
    maxTextureSize = 1 << (maxLevels - 1);
 
-   if (!is_compressed_format(format))
+   if (!is_compressed_format(ctx, format))
       return GL_INVALID_ENUM;
 
    if (width < 1 || width > maxTextureSize)