From 40bd9d0b190e11d39350d1b08d2c2b28e3040bca Mon Sep 17 00:00:00 2001 From: Daniel Borca Date: Wed, 29 Oct 2003 14:35:31 +0000 Subject: texture compression --- src/mesa/main/dd.h | 11 +++++++++ src/mesa/main/texcompress.c | 17 ++++++++++++++ src/mesa/main/texformat.c | 54 +++++++++++++++++++++++++++++++++++++++++-- src/mesa/main/texformat.h | 4 ++++ src/mesa/main/texformat_tmp.h | 21 +++++++++++++++++ src/mesa/main/teximage.c | 31 ++++++++++++++++++++----- 6 files changed, 130 insertions(+), 8 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index a4aa534510..9942227354 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -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 ); /*@}*/ /** diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c index e6a9695722..1b9daac1e6 100644 --- a/src/mesa/main/texcompress.c +++ b/src/mesa/main/texcompress.c @@ -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; diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c index b5c721f211..0000767f4c 100644 --- a/src/mesa/main/texformat.c +++ b/src/mesa/main/texformat.c @@ -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) diff --git a/src/mesa/main/texformat.h b/src/mesa/main/texformat.h index 07fa2adb75..c43da46d7b 100644 --- a/src/mesa/main/texformat.h +++ b/src/mesa/main/texformat.h @@ -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; diff --git a/src/mesa/main/texformat_tmp.h b/src/mesa/main/texformat_tmp.h index 840fcd2549..b0af8b879b 100644 --- a/src/mesa/main/texformat_tmp.h +++ b/src/mesa/main/texformat_tmp.h @@ -361,6 +361,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 ) diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index cf199ddf4d..efe197e13e 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -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) -- cgit v1.2.3