X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Ftexcompress.c;h=c1b8c7675a27be612bf0d81451381efa68807941;hb=9b70c33e735ff060ddad7d0b501d19c670f41618;hp=d18b1d0b418fc6afba44813eb3c6a7c5e2c18538;hpb=a0c85249244e1af8dac88076d5f384cf4bd01236;p=mesa.git diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c index d18b1d0b418..c1b8c7675a2 100644 --- a/src/mesa/main/texcompress.c +++ b/src/mesa/main/texcompress.c @@ -1,8 +1,9 @@ /* * Mesa 3-D graphics library - * Version: 6.1 + * Version: 6.5.1 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (c) 2008 VMware, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -34,59 +35,80 @@ #include "colormac.h" #include "context.h" #include "image.h" +#include "mipmap.h" #include "texcompress.h" #include "texformat.h" #include "texstore.h" + /** - * Get the list of supported internal compression formats. + * Return list of (and count of) all specific texture compression + * formats that are supported. * - * \param ctx GL context. - * \param formats the resulting format list (may be NULL). + * \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( GLcontext *ctx, GLint *formats ) +_mesa_get_compressed_formats(GLcontext *ctx, GLint *formats, GLboolean all) { GLuint n = 0; - if (ctx->Extensions.ARB_texture_compression) { - if (ctx->Extensions.TDFX_texture_compression_FXT1) { - if (formats) { - formats[n++] = GL_COMPRESSED_RGB_FXT1_3DFX; - formats[n++] = GL_COMPRESSED_RGBA_FXT1_3DFX; - } - else { - n += 2; - } + if (ctx->Extensions.TDFX_texture_compression_FXT1) { + if (formats) { + formats[n++] = GL_COMPRESSED_RGB_FXT1_3DFX; + formats[n++] = GL_COMPRESSED_RGBA_FXT1_3DFX; + } + else { + n += 2; + } + } + 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.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; - } + } + if (ctx->Extensions.S3_s3tc) { + if (formats) { + formats[n++] = GL_RGB_S3TC; + formats[n++] = GL_RGB4_S3TC; + formats[n++] = GL_RGBA_S3TC; + formats[n++] = GL_RGBA4_S3TC; } - if (ctx->Extensions.S3_s3tc) { - if (formats) { - formats[n++] = GL_RGB_S3TC; - formats[n++] = GL_RGB4_S3TC; - formats[n++] = GL_RGBA_S3TC; - formats[n++] = GL_RGBA4_S3TC; - } - else { - n += 4; - } + else { + n += 4; } } +#if FEATURE_EXT_texture_sRGB + if (ctx->Extensions.EXT_texture_sRGB) { + 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; + } + else { + n += 4; + } + } +#endif /* FEATURE_EXT_texture_sRGB */ return n; } @@ -101,23 +123,25 @@ _mesa_get_compressed_formats( GLcontext *ctx, GLint *formats ) * \param width texture width in texels. * \param height texture height in texels. * \param depth texture depth in texels. - * \param format - one of the specific compressed texture formats + * \param mesaFormat one of the MESA_FORMAT_* compressed formats * * \return size in bytes, or zero if bad format */ GLuint _mesa_compressed_texture_size( GLcontext *ctx, GLsizei width, GLsizei height, GLsizei depth, - GLenum format ) + GLuint mesaFormat ) { GLuint size; ASSERT(depth == 1); (void) depth; + (void) size; - switch (format) { - case GL_COMPRESSED_RGB_FXT1_3DFX: - case GL_COMPRESSED_RGBA_FXT1_3DFX: + switch (mesaFormat) { +#if FEATURE_texture_fxt1 + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: /* round up width to next multiple of 8, height to next multiple of 4 */ width = (width + 7) & ~7; height = (height + 3) & ~3; @@ -126,13 +150,15 @@ _mesa_compressed_texture_size( GLcontext *ctx, /* Textures smaller than 8x4 will effectively be made into 8x4 and * take 16 bytes. */ - if (size < 16) - size = 16; return size; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_RGB_S3TC: - case GL_RGB4_S3TC: +#endif +#if FEATURE_texture_s3tc + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_RGBA_DXT1: +#if FEATURE_EXT_texture_sRGB + case MESA_FORMAT_SRGB_DXT1: + case MESA_FORMAT_SRGBA_DXT1: +#endif /* round up width, height to next multiple of 4 */ width = (width + 3) & ~3; height = (height + 3) & ~3; @@ -141,13 +167,13 @@ _mesa_compressed_texture_size( GLcontext *ctx, /* 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: - case GL_RGBA_S3TC: - case GL_RGBA4_S3TC: + case MESA_FORMAT_RGBA_DXT3: + case MESA_FORMAT_RGBA_DXT5: +#if FEATURE_EXT_texture_sRGB + case MESA_FORMAT_SRGBA_DXT3: + case MESA_FORMAT_SRGBA_DXT5: +#endif /* round up width, height to next multiple of 4 */ width = (width + 3) & ~3; height = (height + 3) & ~3; @@ -156,46 +182,119 @@ _mesa_compressed_texture_size( GLcontext *ctx, /* Textures smaller than 4x4 will effectively be made into 4x4 and * take 16 bytes. */ - if (size < 16) - size = 16; return size; +#endif default: - _mesa_problem(ctx, "bad texformat in compressed_texture_size"); + _mesa_problem(ctx, "bad mesaFormat in _mesa_compressed_texture_size"); return 0; } } +/** + * As above, but format is specified by a GLenum (GL_COMPRESSED_*) token. + * + * Note: This function CAN NOT return a padded hardware texture size. + * That's why we don't call the ctx->Driver.CompressedTextureSize() function. + * + * We use this function to validate the parameter + * of glCompressedTex[Sub]Image1/2/3D(), which must be an exact match. + */ +GLuint +_mesa_compressed_texture_size_glenum(GLcontext *ctx, + GLsizei width, GLsizei height, + GLsizei depth, GLenum glformat) +{ + GLuint mesaFormat; + + switch (glformat) { +#if FEATURE_texture_fxt1 + case GL_COMPRESSED_RGB_FXT1_3DFX: + mesaFormat = MESA_FORMAT_RGB_FXT1; + break; + case GL_COMPRESSED_RGBA_FXT1_3DFX: + mesaFormat = MESA_FORMAT_RGBA_FXT1; + break; +#endif +#if FEATURE_texture_s3tc + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_RGB_S3TC: + mesaFormat = MESA_FORMAT_RGB_DXT1; + break; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_RGB4_S3TC: + mesaFormat = MESA_FORMAT_RGBA_DXT1; + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_RGBA_S3TC: + mesaFormat = MESA_FORMAT_RGBA_DXT3; + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_RGBA4_S3TC: + mesaFormat = MESA_FORMAT_RGBA_DXT5; + break; +#if FEATURE_EXT_texture_sRGB + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + mesaFormat = MESA_FORMAT_SRGB_DXT1; + break; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + mesaFormat = MESA_FORMAT_SRGBA_DXT1; + break; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + mesaFormat = MESA_FORMAT_SRGBA_DXT3; + break; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + mesaFormat = MESA_FORMAT_SRGBA_DXT5; + break; +#endif +#endif + default: + return 0; + } + + return _mesa_compressed_texture_size(ctx, width, height, depth, mesaFormat); +} + + /* * 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 mesaFormat one of the MESA_FORMAT_* compressed 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) +_mesa_compressed_row_stride(GLuint mesaFormat, GLsizei width) { GLint stride; - switch (format) { - case GL_COMPRESSED_RGB_FXT1_3DFX: - case GL_COMPRESSED_RGBA_FXT1_3DFX: + switch (mesaFormat) { +#if FEATURE_texture_fxt1 + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: stride = ((width + 7) / 8) * 16; /* 16 bytes per 8x4 tile */ break; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_RGB_S3TC: - case GL_RGB4_S3TC: +#endif +#if FEATURE_texture_s3tc + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_RGBA_DXT1: +#if FEATURE_EXT_texture_sRGB + case MESA_FORMAT_SRGB_DXT1: + case MESA_FORMAT_SRGBA_DXT1: +#endif stride = ((width + 3) / 4) * 8; /* 8 bytes per 4x4 tile */ break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - case GL_RGBA_S3TC: - case GL_RGBA4_S3TC: + case MESA_FORMAT_RGBA_DXT3: + case MESA_FORMAT_RGBA_DXT5: +#if FEATURE_EXT_texture_sRGB + case MESA_FORMAT_SRGBA_DXT3: + case MESA_FORMAT_SRGBA_DXT5: +#endif stride = ((width + 3) / 4) * 16; /* 16 bytes per 4x4 tile */ break; +#endif default: + _mesa_problem(NULL, "bad mesaFormat in _mesa_compressed_row_stride"); return 0; } @@ -214,7 +313,7 @@ _mesa_compressed_row_stride(GLenum format, GLsizei width) */ GLubyte * _mesa_compressed_image_address(GLint col, GLint row, GLint img, - GLenum format, + GLuint mesaFormat, GLsizei width, const GLubyte *image) { GLubyte *addr; @@ -229,25 +328,34 @@ _mesa_compressed_image_address(GLint col, GLint row, GLint img, * offset = Z * (((width + X - 1) / X) * (row / Y) + col / X); */ - switch (format) { - case GL_COMPRESSED_RGB_FXT1_3DFX: - case GL_COMPRESSED_RGBA_FXT1_3DFX: + switch (mesaFormat) { +#if FEATURE_texture_fxt1 + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: addr = (GLubyte *) image + 16 * (((width + 7) / 8) * (row / 4) + col / 8); break; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_RGB_S3TC: - case GL_RGB4_S3TC: +#endif +#if FEATURE_texture_s3tc + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_RGBA_DXT1: +#if FEATURE_EXT_texture_sRGB + case MESA_FORMAT_SRGB_DXT1: + case MESA_FORMAT_SRGBA_DXT1: +#endif addr = (GLubyte *) image + 8 * (((width + 3) / 4) * (row / 4) + col / 4); break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - case GL_RGBA_S3TC: - case GL_RGBA4_S3TC: + case MESA_FORMAT_RGBA_DXT3: + case MESA_FORMAT_RGBA_DXT5: +#if FEATURE_EXT_texture_sRGB + case MESA_FORMAT_SRGBA_DXT3: + case MESA_FORMAT_SRGBA_DXT5: +#endif addr = (GLubyte *) image + 16 * (((width + 3) / 4) * (row / 4) + col / 4); break; +#endif default: - return NULL; + _mesa_problem(NULL, "bad mesaFormat in _mesa_compressed_image_address"); + addr = NULL; } return addr;