diff options
author | Eric Anholt <[email protected]> | 2004-10-07 23:30:29 +0000 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2004-10-07 23:30:29 +0000 |
commit | d09209f5530e8bba78e4e0ec62b2027c588cc8f3 (patch) | |
tree | 0c7bdde2064bcf0c880e8bf259a8ef80dbc933a0 /src/mesa/main/texcompress_s3tc.c | |
parent | 554e5a2eaf4b681b5c43b6aeb66f100a66da4a42 (diff) |
Add Roland Scheidegger's S3TC patch. This patch does not implement the
(patented) S3TC/DXTC algorithms, but adds an option to dlopen a library module
providing functions to do so. Because it uses dlopen, it is only enabled if
USE_EXTERNAL_DXTN_LIB=1 is defined (which is only in linux-dri config, so far).
It adds support for S3TC to several DRI drivers, and adds a DRI config option to
force enabling S3TC even if the software compression/decompression is
unavailable. This may allow people to use apps that require S3TC even though
they don't have a license to implement the patented material themselves, if
those apps use precompressed textures.
Ideally we would get permission from the current holder of the patents to
implement the algorithm in Mesa, at which point the dlopen mess could go away.
Until then, this allows some to run applications they couldn't otherwise, and
hopefully will provide us with more push to get the final step of getting that
permission done.
Diffstat (limited to 'src/mesa/main/texcompress_s3tc.c')
-rw-r--r-- | src/mesa/main/texcompress_s3tc.c | 137 |
1 files changed, 116 insertions, 21 deletions
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"); } |