diff options
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/mtypes.h | 3 | ||||
-rw-r--r-- | src/mesa/main/texcompress_s3tc.c | 137 |
2 files changed, 119 insertions, 21 deletions
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 07119a2fb6e..4086ef94bed 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2455,6 +2455,9 @@ struct __GLcontextRec { /** Dither disable via MESA_NO_DITHER env var */ GLboolean NoDither; + /** software compression/decompression supported or not */ + GLboolean Mesa_DXTn; + /** Core tnl module support */ struct gl_tnl_module TnlModule; diff --git a/src/mesa/main/texcompress_s3tc.c b/src/mesa/main/texcompress_s3tc.c index 572cdd25614..a797c2edf9b 100644 --- a/src/mesa/main/texcompress_s3tc.c +++ b/src/mesa/main/texcompress_s3tc.c @@ -28,6 +28,9 @@ * GL_EXT_texture_compression_s3tc support. */ +#ifndef USE_EXTERNAL_DXTN_LIB +#define USE_EXTERNAL_DXTN_LIB 0 +#endif #include "glheader.h" #include "imports.h" @@ -39,16 +42,79 @@ #include "texformat.h" #include "texstore.h" +#if USE_EXTERNAL_DXTN_LIB +#include <dlfcn.h> +#endif + +typedef void (*dxtFetchTexelFuncExt)( GLint srcRowstride, GLubyte *pixdata, GLint col, GLint row, GLvoid *texelOut ); +dxtFetchTexelFuncExt fetch_ext_rgb_dxt1; +dxtFetchTexelFuncExt fetch_ext_rgba_dxt1; +dxtFetchTexelFuncExt fetch_ext_rgba_dxt3; +dxtFetchTexelFuncExt fetch_ext_rgba_dxt5; + +typedef void (*dxtCompressTexFuncExt)(GLint srccomps, GLint width, GLint height, const GLubyte *srcPixData, GLenum destformat, GLubyte *dest); +dxtCompressTexFuncExt ext_tx_compress_dxtn; +void *dxtlibhandle = NULL; void _mesa_init_texture_s3tc( GLcontext *ctx ) { /* called during context initialization */ + ctx->Mesa_DXTn = GL_FALSE; +#if USE_EXTERNAL_DXTN_LIB + if (!dxtlibhandle) { + char *error; + + dxtlibhandle = dlopen ("libtxc_dxtn.so", RTLD_LAZY | RTLD_GLOBAL); + if (!dxtlibhandle) { + _mesa_warning(ctx, "couldn't open libtxc_dxtn.so, software DXTn" + "compression/decompression unavailable\n"); + } + else { + /* the fetch functions are not per context! Might be problematic... */ + fetch_ext_rgb_dxt1 = dlsym(dxtlibhandle, "fetch_2d_texel_rgb_dxt1"); + error = dlerror(); + if (error == NULL) { + fetch_ext_rgba_dxt1 = dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt1"); + error = dlerror(); + } + if (error == NULL) { + fetch_ext_rgba_dxt3 = dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt3"); + error = dlerror(); + } + if (error == NULL) { + fetch_ext_rgba_dxt5 = dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt5"); + error = dlerror(); + } + if (error == NULL) { + ext_tx_compress_dxtn = dlsym(dxtlibhandle, "tx_compress_dxtn"); + error = dlerror(); + } + + if (error) { + _mesa_warning(ctx, "couldn't reference all symbols in " + "libtxc_dxtn.so, software DXTn compression/decompression " + "unavailable\n"); + fetch_ext_rgb_dxt1 = NULL; + fetch_ext_rgba_dxt1 = NULL; + fetch_ext_rgba_dxt3 = NULL; + fetch_ext_rgba_dxt5 = NULL; + ext_tx_compress_dxtn = NULL; + dlclose(dxtlibhandle); + dxtlibhandle = NULL; + } + } + } + if (dxtlibhandle) { + ctx->Mesa_DXTn = GL_TRUE; + _mesa_warning(ctx, "software DXTn compression/decompression available\n"); + } +#else (void) ctx; +#endif } - /** * Called via TexFormat->StoreImage to store an RGB_DXT1 texture. */ @@ -95,10 +161,12 @@ texstore_rgb_dxt1(STORE_PARAMS) GL_COMPRESSED_RGB_S3TC_DXT1_EXT, texWidth, (GLubyte *) dstAddr); -#if 0 - compress_dxt1(ctx, srcWidth, srcHeight, srcFormat, pixels, srcRowStride, - dst, dstRowStride); -#endif + if (ext_tx_compress_dxtn) { + (*ext_tx_compress_dxtn)(3, srcWidth, srcHeight, pixels, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, dst); + } + else { + _mesa_problem(ctx, "external dxt library not available"); + } if (tempImage) _mesa_free((void *) tempImage); @@ -152,10 +220,13 @@ texstore_rgba_dxt1(STORE_PARAMS) dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, texWidth, (GLubyte *) dstAddr); -#if 0 - compress_dxt1(ctx, srcWidth, srcHeight, srcFormat, pixels, srcRowStride, - dst, dstRowStride); -#endif + if (ext_tx_compress_dxtn) { + (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, dst); + } + else { + _mesa_problem(ctx, "external dxt library not available"); + } + if (tempImage) _mesa_free((void*) tempImage); @@ -207,10 +278,13 @@ texstore_rgba_dxt3(STORE_PARAMS) dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, texWidth, (GLubyte *) dstAddr); -#if 0 - compress_rgba_dxt3(ctx, srcWidth, srcHeight, pixels, - srcRowStride, dst, dstRowStride); -#endif + if (ext_tx_compress_dxtn) { + (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, dst); + } + else { + _mesa_problem(ctx, "external dxt library not available"); + } + if (tempImage) _mesa_free((void *) tempImage); @@ -262,10 +336,13 @@ texstore_rgba_dxt5(STORE_PARAMS) dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, texWidth, (GLubyte *) dstAddr); -#if 0 - compress_rgba_dxt5(ctx, srcWidth, srcHeight, pixels, - srcRowStride, dst, dstRowStride); -#endif + if (ext_tx_compress_dxtn) { + (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, dst); + } + else { + _mesa_problem(ctx, "external dxt library not available"); + } + if (tempImage) _mesa_free((void *) tempImage); @@ -277,7 +354,12 @@ static void fetch_texel_2d_rgb_dxt1( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - (void) texImage; (void) i; (void) j; (void) k; (void) texel; + (void) k; + if (fetch_ext_rgb_dxt1) { + ASSERT (sizeof(GLchan) == sizeof(GLubyte)); + (*fetch_ext_rgb_dxt1)((texImage)->RowStride, (GLubyte *)(texImage)->Data, i, j, texel); + } + else _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n"); } @@ -299,7 +381,11 @@ static void fetch_texel_2d_rgba_dxt1( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - (void) texImage; (void) i; (void) j; (void) k; (void) texel; + (void) k; + if (fetch_ext_rgba_dxt1) { + (*fetch_ext_rgba_dxt1)((texImage)->RowStride, (GLubyte *)(texImage)->Data, i, j, texel); + } + else _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n"); } @@ -321,7 +407,12 @@ static void fetch_texel_2d_rgba_dxt3( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - (void) texImage; (void) i; (void) j; (void) k; (void) texel; + (void) k; + if (fetch_ext_rgba_dxt3) { + ASSERT (sizeof(GLchan) == sizeof(GLubyte)); + (*fetch_ext_rgba_dxt3)((texImage)->RowStride, (GLubyte *)(texImage)->Data, i, j, texel); + } + else _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n"); } @@ -343,7 +434,11 @@ static void fetch_texel_2d_rgba_dxt5( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - (void) texImage; (void) i; (void) j; (void) k; (void) texel; + (void) k; + if (fetch_ext_rgba_dxt5) { + (*fetch_ext_rgba_dxt5)((texImage)->RowStride, (GLubyte *)(texImage)->Data, i, j, texel); + } + else _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n"); } |