From 78233887446a8f5fe66d674caf1b7ee838647ac1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Apr 2003 20:57:49 +0000 Subject: [PATCH] some texture compression odds & ends --- src/mesa/main/texcompress.c | 73 +++++++++++++++++++++++--- src/mesa/main/texformat.c | 97 +++++++++++++++++++++++++++++++++-- src/mesa/main/texformat.h | 15 ++++-- src/mesa/main/texformat_tmp.h | 48 +++++++++++++++-- 4 files changed, 216 insertions(+), 17 deletions(-) diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c index 81938854c27..01425f33a56 100644 --- a/src/mesa/main/texcompress.c +++ b/src/mesa/main/texcompress.c @@ -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; } diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c index c529031f9f1..e92572242f7 100644 --- a/src/mesa/main/texformat.c +++ b/src/mesa/main/texformat.c @@ -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; diff --git a/src/mesa/main/texformat.h b/src/mesa/main/texformat.h index 9f4d0361610..6f19aac7bcf 100644 --- a/src/mesa/main/texformat.h +++ b/src/mesa/main/texformat.h @@ -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: */ diff --git a/src/mesa/main/texformat_tmp.h b/src/mesa/main/texformat_tmp.h index 0c50c2db1dc..83715d3fdb3 100644 --- a/src/mesa/main/texformat_tmp.h +++ b/src/mesa/main/texformat_tmp.h @@ -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 -- 2.30.2