X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Ftexcompress.c;h=957cc6df66124058a3e8820e821686f9c27b2cee;hb=c73245882c7ff1277b190b97f093f7b423a22f10;hp=d820ae92747c5f7a2135a301a25b697285ee597f;hpb=69f16accd0aa3b8d414092a5e52ccc99649da01a;p=mesa.git diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c index d820ae92747..957cc6df661 100644 --- a/src/mesa/main/texcompress.c +++ b/src/mesa/main/texcompress.c @@ -37,22 +37,201 @@ #include "mfeatures.h" #include "mtypes.h" #include "texcompress.h" +#include "texcompress_fxt1.h" +#include "texcompress_rgtc.h" +#include "texcompress_s3tc.h" +#include "texcompress_etc.h" +#include "swrast/s_context.h" +/** + * Get the GL base format of a specified GL compressed texture format + * + * From page 232 of the OpenGL 3.3 (Compatiblity Profile) spec: + * + * "Compressed Internal Format Base Internal Format Type + * --------------------------- -------------------- --------- + * COMPRESSED_ALPHA ALPHA Generic + * COMPRESSED_LUMINANCE LUMINANCE Generic + * COMPRESSED_LUMINANCE_ALPHA LUMINANCE_ALPHA Generic + * COMPRESSED_INTENSITY INTENSITY Generic + * COMPRESSED_RED RED Generic + * COMPRESSED_RG RG Generic + * COMPRESSED_RGB RGB Generic + * COMPRESSED_RGBA RGBA Generic + * COMPRESSED_SRGB RGB Generic + * COMPRESSED_SRGB_ALPHA RGBA Generic + * COMPRESSED_SLUMINANCE LUMINANCE Generic + * COMPRESSED_SLUMINANCE_ALPHA LUMINANCE_ALPHA Generic + * COMPRESSED_RED_RGTC1 RED Specific + * COMPRESSED_SIGNED_RED_RGTC1 RED Specific + * COMPRESSED_RG_RGTC2 RG Specific + * COMPRESSED_SIGNED_RG_RGTC2 RG Specific" + * + * \return + * The base format of \c format if \c format is a compressed format (either + * generic or specific. Otherwise 0 is returned. + */ +GLenum +_mesa_gl_compressed_format_base_format(GLenum format) +{ + switch (format) { + case GL_COMPRESSED_RED: + case GL_COMPRESSED_RED_RGTC1: + case GL_COMPRESSED_SIGNED_RED_RGTC1: + return GL_RED; + + case GL_COMPRESSED_RG: + case GL_COMPRESSED_RG_RGTC2: + case GL_COMPRESSED_SIGNED_RG_RGTC2: + return GL_RG; + + case GL_COMPRESSED_RGB: + case GL_COMPRESSED_SRGB: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGB_FXT1_3DFX: + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_ETC1_RGB8_OES: + return GL_RGB; + + case GL_COMPRESSED_RGBA: + case GL_COMPRESSED_SRGB_ALPHA: + case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB: + case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_COMPRESSED_RGBA_FXT1_3DFX: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + return GL_RGBA; + + case GL_COMPRESSED_ALPHA: + return GL_ALPHA; + + case GL_COMPRESSED_LUMINANCE: + case GL_COMPRESSED_SLUMINANCE: + case GL_COMPRESSED_LUMINANCE_LATC1_EXT: + case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT: + return GL_LUMINANCE; + + case GL_COMPRESSED_LUMINANCE_ALPHA: + case GL_COMPRESSED_SLUMINANCE_ALPHA: + case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT: + case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT: + case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI: + return GL_LUMINANCE_ALPHA; + + case GL_COMPRESSED_INTENSITY: + return GL_INTENSITY; + + default: + return 0; + } +} + /** * Return list of (and count of) all specific texture compression * formats that are supported. * + * Some formats are \b not returned by this function. The + * \c GL_COMPRESSED_TEXTURE_FORMATS query only returns formats that are + * "suitable for general-purpose usage." All texture compression extensions + * have taken this to mean either linear RGB or linear RGBA. + * + * The GL_ARB_texture_compress_rgtc spec says: + * + * "19) Should the GL_NUM_COMPRESSED_TEXTURE_FORMATS and + * GL_COMPRESSED_TEXTURE_FORMATS queries return the RGTC formats? + * + * RESOLVED: No. + * + * The OpenGL 2.1 specification says "The only values returned + * by this query [GL_COMPRESSED_TEXTURE_FORMATS"] are those + * corresponding to formats suitable for general-purpose usage. + * The renderer will not enumerate formats with restrictions that + * need to be specifically understood prior to use." + * + * Compressed textures with just red or red-green components are + * not general-purpose so should not be returned by these queries + * because they have restrictions. + * + * Applications that seek to use the RGTC formats should do so + * by looking for this extension's name in the string returned by + * glGetString(GL_EXTENSIONS) rather than + * what GL_NUM_COMPRESSED_TEXTURE_FORMATS and + * GL_COMPRESSED_TEXTURE_FORMATS return." + * + * There is nearly identical wording in the GL_EXT_texture_compression_rgtc + * spec. + * + * The GL_EXT_texture_rRGB spec says: + * + * "22) Should the new COMPRESSED_SRGB_* formats be listed in an + * implementation's GL_COMPRESSED_TEXTURE_FORMATS list? + * + * RESOLVED: No. Section 3.8.1 says formats listed by + * GL_COMPRESSED_TEXTURE_FORMATS are "suitable for general-purpose + * usage." The non-linear distribution of red, green, and + * blue for these sRGB compressed formats makes them not really + * general-purpose." + * + * The GL_EXT_texture_compression_latc spec says: + * + * "16) Should the GL_NUM_COMPRESSED_TEXTURE_FORMATS and + * GL_COMPRESSED_TEXTURE_FORMATS queries return the LATC formats? + * + * RESOLVED: No. + * + * The OpenGL 2.1 specification says "The only values returned + * by this query [GL_COMPRESSED_TEXTURE_FORMATS"] are those + * corresponding to formats suitable for general-purpose usage. + * The renderer will not enumerate formats with restrictions that + * need to be specifically understood prior to use." + * + * Historically, OpenGL implementation have advertised the RGB and + * RGBA versions of the S3TC extensions compressed format tokens + * through this mechanism. + * + * The specification is not sufficiently clear about what "suitable + * for general-purpose usage" means. Historically that seems to mean + * unsigned RGB or unsigned RGBA. The DXT1 format supporting alpha + * (GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) is not exposed in the list (at + * least for NVIDIA drivers) because the alpha is always 1.0 expect + * when it is 0.0 when RGB is required to be black. NVIDIA's even + * limits itself to true linear RGB or RGBA formats, specifically + * not including EXT_texture_sRGB's sRGB S3TC compressed formats. + * + * Adding luminance and luminance-alpha texture formats (and + * certainly signed versions of luminance and luminance-alpha + * formats!) invites potential comptaibility problems with old + * applications using this mechanism since old applications are + * unlikely to expect non-RGB or non-RGBA formats to be advertised + * through this mechanism. However no specific misinteractions + * with old applications is known. + * + * Applications that seek to use the LATC formats should do so + * by looking for this extension's name in the string returned by + * glGetString(GL_EXTENSIONS) rather than + * what GL_NUM_COMPRESSED_TEXTURE_FORMATS and + * GL_COMPRESSED_TEXTURE_FORMATS return." + * + * There is no formal spec for GL_ATI_texture_compression_3dc. Since the + * formats added by this extension are luminance-alpha formats, it is + * reasonable to expect them to follow the same rules as + * GL_EXT_texture_compression_latc. At the very least, Catalyst 11.6 does not + * expose the 3dc formats through this mechanism. + * * \param ctx the GL context * \param formats the resulting format list (may be NULL). - * \param all if true return all formats, even those with some kind - * of restrictions/limitations (See GL_ARB_texture_compression - * spec for more info). * * \return number of formats. */ GLuint -_mesa_get_compressed_formats(struct gl_context *ctx, GLint *formats, GLboolean all) +_mesa_get_compressed_formats(struct gl_context *ctx, GLint *formats) { GLuint n = 0; if (ctx->Extensions.TDFX_texture_compression_FXT1) { @@ -64,24 +243,15 @@ _mesa_get_compressed_formats(struct gl_context *ctx, GLint *formats, GLboolean a n += 2; } } - /* don't return RGTC - ARB_texture_compression_rgtc query 19 */ + if (ctx->Extensions.EXT_texture_compression_s3tc) { if (formats) { formats[n++] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - /* This format has some restrictions/limitations and so should - * not be returned via the GL_COMPRESSED_TEXTURE_FORMATS query. - * Specifically, all transparent pixels become black. NVIDIA - * omits this format too. - */ - if (all) - 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; - if (all) - n += 1; } } if (ctx->Extensions.S3_s3tc) { @@ -95,38 +265,35 @@ _mesa_get_compressed_formats(struct gl_context *ctx, GLint *formats, GLboolean a n += 4; } } -#if FEATURE_EXT_texture_sRGB - if (ctx->Extensions.EXT_texture_sRGB) { + + if (ctx->Extensions.OES_compressed_ETC1_RGB8_texture) { if (formats) { - formats[n++] = GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; - formats[n++] = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; - formats[n++] = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; - formats[n++] = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + formats[n++] = GL_ETC1_RGB8_OES; } else { - n += 4; + n += 1; } } -#endif /* FEATURE_EXT_texture_sRGB */ - return n; -#if FEATURE_ES1 || FEATURE_ES2 - if (formats) { - formats[n++] = GL_PALETTE4_RGB8_OES; - formats[n++] = GL_PALETTE4_RGBA8_OES; - formats[n++] = GL_PALETTE4_R5_G6_B5_OES; - formats[n++] = GL_PALETTE4_RGBA4_OES; - formats[n++] = GL_PALETTE4_RGB5_A1_OES; - formats[n++] = GL_PALETTE8_RGB8_OES; - formats[n++] = GL_PALETTE8_RGBA8_OES; - formats[n++] = GL_PALETTE8_R5_G6_B5_OES; - formats[n++] = GL_PALETTE8_RGBA4_OES; - formats[n++] = GL_PALETTE8_RGB5_A1_OES; - } - else { - n += 10; + if (ctx->API == API_OPENGLES) { + if (formats) { + formats[n++] = GL_PALETTE4_RGB8_OES; + formats[n++] = GL_PALETTE4_RGBA8_OES; + formats[n++] = GL_PALETTE4_R5_G6_B5_OES; + formats[n++] = GL_PALETTE4_RGBA4_OES; + formats[n++] = GL_PALETTE4_RGB5_A1_OES; + formats[n++] = GL_PALETTE8_RGB8_OES; + formats[n++] = GL_PALETTE8_RGBA8_OES; + formats[n++] = GL_PALETTE8_R5_G6_B5_OES; + formats[n++] = GL_PALETTE8_RGBA4_OES; + formats[n++] = GL_PALETTE8_RGB5_A1_OES; + } + else { + n += 10; + } } -#endif + + return n; } @@ -183,6 +350,9 @@ _mesa_glenum_to_compressed_format(GLenum format) case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT: return MESA_FORMAT_SIGNED_LA_LATC2; + case GL_ETC1_RGB8_OES: + return MESA_FORMAT_ETC1_RGB8; + default: return MESA_FORMAT_NONE; } @@ -200,16 +370,13 @@ _mesa_glenum_to_compressed_format(GLenum format) * internal format unchanged. */ GLenum -_mesa_compressed_format_to_glenum(struct gl_context *ctx, GLuint mesaFormat) +_mesa_compressed_format_to_glenum(struct gl_context *ctx, gl_format mesaFormat) { switch (mesaFormat) { -#if FEATURE_texture_fxt1 case MESA_FORMAT_RGB_FXT1: return GL_COMPRESSED_RGB_FXT1_3DFX; case MESA_FORMAT_RGBA_FXT1: return GL_COMPRESSED_RGBA_FXT1_3DFX; -#endif -#if FEATURE_texture_s3tc case MESA_FORMAT_RGB_DXT1: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; case MESA_FORMAT_RGBA_DXT1: @@ -218,7 +385,6 @@ _mesa_compressed_format_to_glenum(struct gl_context *ctx, GLuint mesaFormat) return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; case MESA_FORMAT_RGBA_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; -#if FEATURE_EXT_texture_sRGB case MESA_FORMAT_SRGB_DXT1: return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; case MESA_FORMAT_SRGBA_DXT1: @@ -227,9 +393,6 @@ _mesa_compressed_format_to_glenum(struct gl_context *ctx, GLuint mesaFormat) return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; case MESA_FORMAT_SRGBA_DXT5: return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; -#endif -#endif - case MESA_FORMAT_RED_RGTC1: return GL_COMPRESSED_RED_RGTC1; case MESA_FORMAT_SIGNED_RED_RGTC1: @@ -248,6 +411,9 @@ _mesa_compressed_format_to_glenum(struct gl_context *ctx, GLuint mesaFormat) case MESA_FORMAT_SIGNED_LA_LATC2: return GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT; + case MESA_FORMAT_ETC1_RGB8: + return GL_ETC1_RGB8_OES; + default: _mesa_problem(ctx, "Unexpected mesa texture format in" " _mesa_compressed_format_to_glenum()"); @@ -286,3 +452,101 @@ _mesa_compressed_image_address(GLint col, GLint row, GLint img, return (GLubyte *) image + offset; } + + +/** + * Decompress a compressed texture image, returning a GL_RGBA/GL_FLOAT image. + * \param srcRowStride stride in bytes between rows of blocks in the + * compressed source image. + */ +void +_mesa_decompress_image(gl_format format, GLuint width, GLuint height, + const GLubyte *src, GLint srcRowStride, + GLfloat *dest) +{ + void (*fetch)(const struct swrast_texture_image *texImage, + GLint i, GLint j, GLint k, GLfloat *texel); + struct swrast_texture_image texImage; /* dummy teximage */ + GLuint i, j; + GLuint bytes, bw, bh; + + bytes = _mesa_get_format_bytes(format); + _mesa_get_format_block_size(format, &bw, &bh); + + /* setup dummy texture image info */ + memset(&texImage, 0, sizeof(texImage)); + texImage.Map = (void *) src; + + /* XXX This line is a bit of a hack to adapt to the row stride + * convention used by the texture decompression functions. + */ + texImage.RowStride = srcRowStride * bh / bytes; + + switch (format) { + /* DXT formats */ + case MESA_FORMAT_RGB_DXT1: + fetch = _mesa_fetch_texel_rgb_dxt1; + break; + case MESA_FORMAT_RGBA_DXT1: + fetch = _mesa_fetch_texel_rgba_dxt1; + break; + case MESA_FORMAT_RGBA_DXT3: + fetch = _mesa_fetch_texel_rgba_dxt3; + break; + case MESA_FORMAT_RGBA_DXT5: + fetch = _mesa_fetch_texel_rgba_dxt5; + break; + + /* FXT1 formats */ + case MESA_FORMAT_RGB_FXT1: + fetch = _mesa_fetch_texel_2d_f_rgb_fxt1; + break; + case MESA_FORMAT_RGBA_FXT1: + fetch = _mesa_fetch_texel_2d_f_rgba_fxt1; + break; + + /* Red/RG formats */ + case MESA_FORMAT_RED_RGTC1: + fetch = _mesa_fetch_texel_red_rgtc1; + break; + case MESA_FORMAT_SIGNED_RED_RGTC1: + fetch = _mesa_fetch_texel_signed_red_rgtc1; + break; + case MESA_FORMAT_RG_RGTC2: + fetch = _mesa_fetch_texel_rg_rgtc2; + break; + case MESA_FORMAT_SIGNED_RG_RGTC2: + fetch = _mesa_fetch_texel_signed_rg_rgtc2; + break; + + /* L/LA formats */ + case MESA_FORMAT_L_LATC1: + fetch = _mesa_fetch_texel_l_latc1; + break; + case MESA_FORMAT_SIGNED_L_LATC1: + fetch = _mesa_fetch_texel_signed_l_latc1; + break; + case MESA_FORMAT_LA_LATC2: + fetch = _mesa_fetch_texel_la_latc2; + break; + case MESA_FORMAT_SIGNED_LA_LATC2: + fetch = _mesa_fetch_texel_signed_la_latc2; + break; + + /* ETC1 formats */ + case MESA_FORMAT_ETC1_RGB8: + fetch = _mesa_fetch_texel_2d_f_etc1_rgb8; + break; + + default: + _mesa_problem(NULL, "Unexpected format in _mesa_decompress_image()"); + return; + } + + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + fetch(&texImage, i, j, 0, dest); + dest += 4; + } + } +}