diff options
Diffstat (limited to 'src')
25 files changed, 627 insertions, 44 deletions
diff --git a/src/mesa/drivers/dri/common/xmlpool.h b/src/mesa/drivers/dri/common/xmlpool.h index 7b8222e0a2..efd13a136a 100644 --- a/src/mesa/drivers/dri/common/xmlpool.h +++ b/src/mesa/drivers/dri/common/xmlpool.h @@ -159,6 +159,12 @@ DRI_CONF_OPT_BEGIN(no_neg_lod_bias,bool,def) \ DRI_CONF_DESC(de,"Verbiete negativen Textur-LOD-Bias") \ DRI_CONF_OPT_END +#define DRI_CONF_FORCE_S3TC_ENABLE(def) \ +DRI_CONF_OPT_BEGIN(force_s3tc_enable,bool,def) \ + DRI_CONF_DESC(en,"enable s3tc even if software support is not available") \ + DRI_CONF_DESC(de,"Benutze s3tc auch ohne Softwareunterstuetzung") \ +DRI_CONF_OPT_END + #define DRI_CONF_COLOR_REDUCTION_ROUND 0 #define DRI_CONF_COLOR_REDUCTION_DITHER 1 #define DRI_CONF_COLOR_REDUCTION(def) \ diff --git a/src/mesa/drivers/dri/i830/i830_context.c b/src/mesa/drivers/dri/i830/i830_context.c index b69f11a0c0..3e6f8a9a1f 100644 --- a/src/mesa/drivers/dri/i830/i830_context.c +++ b/src/mesa/drivers/dri/i830/i830_context.c @@ -73,7 +73,7 @@ int I830_DEBUG = (0); * Mesa's Driver Functions ***************************************/ -#define DRIVER_DATE "20040506" +#define DRIVER_DATE "20041007" static const GLubyte *i830DDGetString( GLcontext *ctx, GLenum name ) @@ -372,6 +372,14 @@ GLboolean i830CreateContext( const __GLcontextModes *mesaVis, driInitExtensions( ctx, card_extensions, GL_TRUE ); + if (imesa->glCtx->Mesa_DXTn) { + _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); + _mesa_enable_extension( ctx, "GL_S3_s3tc" ); + } + else if (driQueryOptionb (&imesa->optionCache, "force_s3tc_enable")) { + _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); + } + _mesa_enable_extension( ctx, "GL_3DFX_texture_compression_FXT1" ); /* XXX these should really go right after _mesa_init_driver_functions() */ diff --git a/src/mesa/drivers/dri/i830/i830_screen.c b/src/mesa/drivers/dri/i830/i830_screen.c index 52aa22d9d1..f323baccbf 100644 --- a/src/mesa/drivers/dri/i830/i830_screen.c +++ b/src/mesa/drivers/dri/i830/i830_screen.c @@ -59,9 +59,10 @@ const char __driConfigOptions[] = DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE DRI_CONF_MAX_TEXTURE_UNITS(4,2,4) + DRI_CONF_FORCE_S3TC_ENABLE(false) DRI_CONF_SECTION_END DRI_CONF_END; -const GLuint __driNConfigOptions = 1; +const GLuint __driNConfigOptions = 2; #ifdef USE_NEW_INTERFACE static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; diff --git a/src/mesa/drivers/dri/i830/i830_tex.c b/src/mesa/drivers/dri/i830/i830_tex.c index 2fb4cc9324..41b5d92933 100644 --- a/src/mesa/drivers/dri/i830/i830_tex.c +++ b/src/mesa/drivers/dri/i830/i830_tex.c @@ -643,6 +643,22 @@ i830ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_COMPRESSED_RGBA_FXT1_3DFX: return &_mesa_texformat_rgba_fxt1; + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return &_mesa_texformat_rgb_dxt1; + + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return &_mesa_texformat_rgba_dxt1; + + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return &_mesa_texformat_rgba_dxt3; + + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return &_mesa_texformat_rgba_dxt5; + default: fprintf(stderr, "unexpected texture format in %s\n", __FUNCTION__); return NULL; diff --git a/src/mesa/drivers/dri/i830/i830_texmem.c b/src/mesa/drivers/dri/i830/i830_texmem.c index 6a30b49655..7faf90874c 100644 --- a/src/mesa/drivers/dri/i830/i830_texmem.c +++ b/src/mesa/drivers/dri/i830/i830_texmem.c @@ -116,6 +116,20 @@ static void i830UploadTexLevel( i830ContextPtr imesa, src += image->Width*2; } } + else if ((t->Setup[I830_TEXREG_TM0S1] & TM0S1_MT_FORMAT_MASK)==MT_COMPRESS_DXT1) + { + for (j = 0 ; j < image->Height/4 ; j++, dst += (t->Pitch)) { + __memcpy(dst, src, (image->Width*2) ); + src += image->Width*2; + } + } + else if (((t->Setup[I830_TEXREG_TM0S1] & TM0S1_MT_FORMAT_MASK)==MT_COMPRESS_DXT2_3) || ((t->Setup[I830_TEXREG_TM0S1] & TM0S1_MT_FORMAT_MASK)==MT_COMPRESS_DXT4_5)) + { + for (j = 0 ; j < image->Height/4 ; j++, dst += (t->Pitch)) { + __memcpy(dst, src, (image->Width*4) ); + src += image->Width*4; + } + } } else if (image->Width * image->TexFormat->TexelBytes == t->Pitch) { GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[0][hwlevel].offset); diff --git a/src/mesa/drivers/dri/i830/i830_texstate.c b/src/mesa/drivers/dri/i830/i830_texstate.c index d5440141bf..358c554f3b 100644 --- a/src/mesa/drivers/dri/i830/i830_texstate.c +++ b/src/mesa/drivers/dri/i830/i830_texstate.c @@ -117,7 +117,24 @@ static void i830SetTexImages( i830ContextPtr imesa, t->texelBytes = 2; textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); break; - + case MESA_FORMAT_RGBA_DXT1: + case MESA_FORMAT_RGB_DXT1: + /* + * DXTn pitches are Width/4 * blocksize in bytes + * for DXT1: blocksize=8 so Width/4*8 = Width * 2 + * for DXT3/5: blocksize=16 so Width/4*16 = Width * 4 + */ + t->texelBytes = 2; + textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); + break; + case MESA_FORMAT_RGBA_DXT3: + t->texelBytes = 4; + textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); + break; + case MESA_FORMAT_RGBA_DXT5: + t->texelBytes = 4; + textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); + break; default: fprintf(stderr, "%s: bad image format\n", __FUNCTION__); free( t ); diff --git a/src/mesa/drivers/dri/i915/i830_texstate.c b/src/mesa/drivers/dri/i915/i830_texstate.c index a393fd1d52..ba452279ba 100644 --- a/src/mesa/drivers/dri/i915/i830_texstate.c +++ b/src/mesa/drivers/dri/i915/i830_texstate.c @@ -125,6 +125,25 @@ static GLboolean i830SetTexImages( i830ContextPtr i830, textureFormat = MAPSURF_COMPRESSED | MT_COMPRESS_FXT1; break; + case MESA_FORMAT_RGBA_DXT1: + case MESA_FORMAT_RGB_DXT1: + /* + * DXTn pitches are Width/4 * blocksize in bytes + * for DXT1: blocksize=8 so Width/4*8 = Width * 2 + * for DXT3/5: blocksize=16 so Width/4*16 = Width * 4 + */ + t->intel.texelBytes = 2; + textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); + break; + case MESA_FORMAT_RGBA_DXT3: + t->intel.texelBytes = 4; + textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); + break; + case MESA_FORMAT_RGBA_DXT5: + t->intel.texelBytes = 4; + textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); + break; + default: fprintf(stderr, "%s: bad image format\n", __FUNCTION__); abort(); diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c index 60ba062952..2f94e6743a 100644 --- a/src/mesa/drivers/dri/i915/i915_texstate.c +++ b/src/mesa/drivers/dri/i915/i915_texstate.c @@ -127,6 +127,24 @@ static void i915SetTexImages( i915ContextPtr i915, t->intel.texelBytes = 2; textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); break; + case MESA_FORMAT_RGBA_DXT1: + case MESA_FORMAT_RGB_DXT1: + /* + * DXTn pitches are Width/4 * blocksize in bytes + * for DXT1: blocksize=8 so Width/4*8 = Width * 2 + * for DXT3/5: blocksize=16 so Width/4*16 = Width * 4 + */ + t->intel.texelBytes = 2; + textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); + break; + case MESA_FORMAT_RGBA_DXT3: + t->intel.texelBytes = 4; + textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); + break; + case MESA_FORMAT_RGBA_DXT5: + t->intel.texelBytes = 4; + textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); + break; default: fprintf(stderr, "%s: bad image format\n", __FUNCTION__); diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index c1559e9567..302ddfa840 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -72,7 +72,7 @@ int prevLockLine; * Mesa's Driver Functions ***************************************/ -#define DRIVER_DATE "20040919" +#define DRIVER_DATE "20041007" const GLubyte *intelGetString( GLcontext *ctx, GLenum name ) { @@ -354,6 +354,14 @@ GLboolean intelInitContext( intelContextPtr intel, driInitExtensions( ctx, card_extensions, GL_TRUE ); + if (intel->ctx.Mesa_DXTn) { + _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); + _mesa_enable_extension( ctx, "GL_S3_s3tc" ); + } + else if (driQueryOptionb (&intelScreen->optionCache, "force_s3tc_enable")) { + _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); + } + /* driInitTextureObjects( ctx, & intel->swapped, */ /* DRI_TEXMGR_DO_TEXTURE_1D | */ /* DRI_TEXMGR_DO_TEXTURE_2D | */ diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h index 839062921b..625e96f580 100644 --- a/src/mesa/drivers/dri/i915/intel_context.h +++ b/src/mesa/drivers/dri/i915/intel_context.h @@ -230,6 +230,11 @@ struct intel_context __DRIscreenPrivate *driScreen; intelScreenPrivate *intelScreen; drmI830Sarea *sarea; + + /** + * Configuration cache + */ + driOptionCache optionCache; }; diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c index e7e9b12915..8007ff48c2 100644 --- a/src/mesa/drivers/dri/i915/intel_screen.c +++ b/src/mesa/drivers/dri/i915/intel_screen.c @@ -30,6 +30,7 @@ #include "matrix.h" #include "simple_list.h" #include "utils.h" +#include "xmlpool.h" #include "intel_screen.h" @@ -43,8 +44,13 @@ #include "i830_dri.h" -const char __driConfigOptions[] = { 0 }; -const GLuint __driNConfigOptions = 0; +const char __driConfigOptions[] = +DRI_CONF_BEGIN + DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_FORCE_S3TC_ENABLE(false) + DRI_CONF_SECTION_END +DRI_CONF_END; +const GLuint __driNConfigOptions = 1; #ifdef USE_NEW_INTERFACE static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; @@ -78,6 +84,9 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv) fprintf(stderr,"\nERROR! Allocating private area failed\n"); return GL_FALSE; } + /* parse information in __driConfigOptions */ + driParseOptionInfo (&intelScreen->optionCache, + __driConfigOptions, __driNConfigOptions); intelScreen->driScrnPriv = sPriv; sPriv->private = (void *)intelScreen; diff --git a/src/mesa/drivers/dri/i915/intel_screen.h b/src/mesa/drivers/dri/i915/intel_screen.h index ffe5e8e50d..f2fb1c6bc9 100644 --- a/src/mesa/drivers/dri/i915/intel_screen.h +++ b/src/mesa/drivers/dri/i915/intel_screen.h @@ -30,7 +30,7 @@ #include <sys/time.h> #include "dri_util.h" - +#include "xmlconfig.h" typedef struct { drm_handle_t handle; @@ -76,6 +76,11 @@ typedef struct int irq_active; int allow_batchbuffer; + + /** + * Configuration cache with default values for all contexts + */ + driOptionCache optionCache; } intelScreenPrivate; diff --git a/src/mesa/drivers/dri/i915/intel_tex.c b/src/mesa/drivers/dri/i915/intel_tex.c index 4e22d7e3f7..b6b8188275 100644 --- a/src/mesa/drivers/dri/i915/intel_tex.c +++ b/src/mesa/drivers/dri/i915/intel_tex.c @@ -554,6 +554,22 @@ intelChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_COMPRESSED_RGBA_FXT1_3DFX: return &_mesa_texformat_rgba_fxt1; + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return &_mesa_texformat_rgb_dxt1; + + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return &_mesa_texformat_rgba_dxt1; + + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return &_mesa_texformat_rgba_dxt3; + + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return &_mesa_texformat_rgba_dxt5; + default: fprintf(stderr, "unexpected texture format in %s\n", __FUNCTION__); return NULL; @@ -628,11 +644,24 @@ static void intelUploadTexImage( intelContextPtr intel, { case GL_COMPRESSED_RGB_FXT1_3DFX: case GL_COMPRESSED_RGBA_FXT1_3DFX: + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: for (j = 0 ; j < image->Height/4 ; j++, dst += (t->Pitch)) { __memcpy(dst, src, row_len ); src += row_len; } break; + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + for (j = 0 ; j < image->Height/4 ; j++, dst += (t->Pitch)) { + __memcpy(dst, src, (image->Width*4) ); + src += image->Width*4; + } + break; default: fprintf(stderr,"Internal Compressed format not supported %d\n", image->IntFormat); break; diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index d5ca2f9b3a..0868febc34 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -62,7 +62,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_vtxfmt.h" #include "r200_maos.h" -#define DRIVER_DATE "20040929" +#define DRIVER_DATE "20041007" #include "vblank.h" #include "utils.h" @@ -401,6 +401,14 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, _math_matrix_set_identity( &rmesa->tmpmat ); driInitExtensions( ctx, card_extensions, GL_TRUE ); + if (rmesa->glCtx->Mesa_DXTn) { + _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); + _mesa_enable_extension( ctx, "GL_S3_s3tc" ); + } + else if (driQueryOptionb (&rmesa->optionCache, "force_s3tc_enable")) { + _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); + } + if (rmesa->r200Screen->drmSupportsCubeMaps) _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" ); if (rmesa->r200Screen->drmSupportsBlendColor) { diff --git a/src/mesa/drivers/dri/r200/r200_screen.c b/src/mesa/drivers/dri/r200/r200_screen.c index e338e5b353..1411394ab5 100644 --- a/src/mesa/drivers/dri/r200/r200_screen.c +++ b/src/mesa/drivers/dri/r200/r200_screen.c @@ -68,6 +68,7 @@ DRI_CONF_BEGIN DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB) DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0") DRI_CONF_NO_NEG_LOD_BIAS(false) + DRI_CONF_FORCE_S3TC_ENABLE(false) DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER) DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC) DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF) @@ -80,7 +81,7 @@ DRI_CONF_BEGIN DRI_CONF_NV_VERTEX_PROGRAM(false) DRI_CONF_SECTION_END DRI_CONF_END; -static const GLuint __driNConfigOptions = 13; +static const GLuint __driNConfigOptions = 14; #if 1 /* Including xf86PciInfo.h introduces a bunch of errors... diff --git a/src/mesa/drivers/dri/r200/r200_tex.c b/src/mesa/drivers/dri/r200/r200_tex.c index 346c27cee0..3d259c2ca6 100644 --- a/src/mesa/drivers/dri/r200/r200_tex.c +++ b/src/mesa/drivers/dri/r200/r200_tex.c @@ -420,6 +420,22 @@ r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, else return &_mesa_texformat_ycbcr_rev; + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return &_mesa_texformat_rgb_dxt1; + + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return &_mesa_texformat_rgba_dxt1; + + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return &_mesa_texformat_rgba_dxt3; + + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return &_mesa_texformat_rgba_dxt5; + default: _mesa_problem(ctx, "unexpected internalFormat 0x%x in r200ChooseTextureFormat", @@ -710,6 +726,116 @@ static void r200TexSubImage2D( GLcontext *ctx, GLenum target, GLint level, } +static void r200CompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + driTextureObject * t = (driTextureObject *) texObj->DriverData; + GLuint face; + + /* which cube face or ordinary 2D image */ + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; + ASSERT(face < 6); + break; + default: + face = 0; + } + + if ( t != NULL ) { + driSwapOutTextureObject( t ); + } + else { + t = (driTextureObject *) r200AllocTexObj( texObj ); + if (!t) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); + return; + } + } + + texImage->IsClientData = GL_FALSE; +/* can't call this, different parameters. Would never evaluate to true anyway currently + if (r200ValidateClientStorage( ctx, target, + internalFormat, + width, height, + format, type, pixels, + packing, texObj, texImage)) { + if (R200_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "%s: Using client storage\n", __FUNCTION__); + } + else */{ + if (R200_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__); + + /* Normal path: copy (to cached memory) and eventually upload + * via another copy to GART memory and then a blit... Could + * eliminate one copy by going straight to (permanent) GART. + * + * Note, this will call r200ChooseTextureFormat. + */ + _mesa_store_compressed_teximage2d(ctx, target, level, internalFormat, width, + height, border, imageSize, data, texObj, texImage); + + t->dirty_images[face] |= (1 << level); + } +} + + +static void r200CompressedTexSubImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + driTextureObject * t = (driTextureObject *) texObj->DriverData; + GLuint face; + + + /* which cube face or ordinary 2D image */ + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; + ASSERT(face < 6); + break; + default: + face = 0; + } + + assert( t ); /* this _should_ be true */ + if ( t ) { + driSwapOutTextureObject( t ); + } + else { + t = (driTextureObject *) r200AllocTexObj( texObj ); + if (!t) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2D"); + return; + } + } + + _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset, yoffset, width, + height, format, imageSize, data, texObj, texImage); + + t->dirty_images[face] |= (1 << level); +} + + #if ENABLE_HW_3D_TEXTURE static void r200TexImage3D( GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, @@ -1036,6 +1162,9 @@ void r200InitTextureFuncs( struct dd_function_table *functions ) functions->TexParameter = r200TexParameter; functions->TexGen = r200TexGen; + functions->CompressedTexImage2D = r200CompressedTexImage2D; + functions->CompressedTexSubImage2D = r200CompressedTexSubImage2D; + driInitTextureFormats(); #if 000 diff --git a/src/mesa/drivers/dri/r200/r200_texmem.c b/src/mesa/drivers/dri/r200/r200_texmem.c index bc937ce6cb..3f8e5d6e7f 100644 --- a/src/mesa/drivers/dri/r200/r200_texmem.c +++ b/src/mesa/drivers/dri/r200/r200_texmem.c @@ -372,10 +372,23 @@ static void uploadSubImage( r200ContextPtr rmesa, r200TexObjPtr t, tex.height = imageHeight; } else { - tex.width = imageWidth; /* compressed */ - tex.height = imageHeight; - if (tex.height < 4) - tex.height = 4; + /* In case of for instance 8x8 texture (2x2 dxt blocks), padding after the first two blocks is + needed (only with dxt1 since 2 dxt3/dxt5 blocks already use 32 Byte). */ + /* set tex.height to 1/4 since 1 "macropixel" (dxt-block) has 4 real pixels. Needed + so the kernel module reads the right amount of data. */ + tex.height = (imageHeight + 3) / 4; + tex.width = (imageWidth + 3) / 4; + switch (t->pp_txformat & R200_TXFORMAT_FORMAT_MASK) { + case R200_TXFORMAT_DXT1: + tex.width *= 8; + break; + case R200_TXFORMAT_DXT23: + case R200_TXFORMAT_DXT45: + tex.width *= 16; + break; + default: + fprintf(stderr, "unknown compressed tex format in uploadSubImage\n"); + } } tex.image = &tmp; diff --git a/src/mesa/drivers/dri/r200/r200_texstate.c b/src/mesa/drivers/dri/r200/r200_texstate.c index 003c1e3e47..f6df2c4f82 100644 --- a/src/mesa/drivers/dri/r200/r200_texstate.c +++ b/src/mesa/drivers/dri/r200/r200_texstate.c @@ -53,6 +53,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define R200_TXFORMAT_AL88 R200_TXFORMAT_AI88 #define R200_TXFORMAT_YCBCR R200_TXFORMAT_YVYU422 #define R200_TXFORMAT_YCBCR_REV R200_TXFORMAT_VYUY422 +#define R200_TXFORMAT_RGB_DXT1 R200_TXFORMAT_DXT1 +#define R200_TXFORMAT_RGBA_DXT1 R200_TXFORMAT_DXT1 +#define R200_TXFORMAT_RGBA_DXT3 R200_TXFORMAT_DXT23 +#define R200_TXFORMAT_RGBA_DXT5 R200_TXFORMAT_DXT45 #define _COLOR(f) \ [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, 0 } @@ -66,7 +70,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, R200_YUV_TO_RGB } #define _INVALID(f) \ [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 } -#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_YCBCR_REV) \ +#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \ && (tx_table[f].format != 0xffffffff) ) static const struct { @@ -93,6 +97,12 @@ tx_table[] = _INVALID(CI8), _YUV(YCBCR), _YUV(YCBCR_REV), + _INVALID(RGB_FXT1), + _INVALID(RGBA_FXT1), + _COLOR(RGB_DXT1), + _ALPHA(RGBA_DXT1), + _ALPHA(RGBA_DXT3), + _ALPHA(RGBA_DXT5), }; #undef _COLOR @@ -165,7 +175,24 @@ static void r200SetTexImages( r200ContextPtr rmesa, /* find image size in bytes */ if (texImage->IsCompressed) { - size = texImage->CompressedSize; + /* need to calculate the size AFTER padding even though the texture is + submitted without padding. + Only handle pot textures currently - don't know if npot is even possible, + size calculation would certainly need (trivial) adjustments. + Align (and later pad) to 32byte, not sure what that 64byte blit width is + good for? */ + if ((t->pp_txformat & R200_TXFORMAT_FORMAT_MASK) == R200_TXFORMAT_DXT1) { + /* RGB_DXT1/RGBA_DXT1, 8 bytes per block */ + if ((texImage->Width + 3) < 8) /* width one block */ + size = texImage->CompressedSize * 4; + else if ((texImage->Width + 3) < 16) + size = texImage->CompressedSize * 2; + else size = texImage->CompressedSize; + } + else /* DXT3/5, 16 bytes per block */ + if ((texImage->Width + 3) < 8) + size = texImage->CompressedSize * 2; + else size = texImage->CompressedSize; } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) { size = ((texImage->Width * texImage->TexFormat->TexelBytes + 63) diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index 5f419347b4..fc69ec1b5b 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -62,7 +62,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_vtxfmt.h" #include "radeon_maos.h" -#define DRIVER_DATE "20040929" +#define DRIVER_DATE "20041007" #include "vblank.h" #include "utils.h" @@ -397,6 +397,13 @@ radeonCreateContext( const __GLcontextModes *glVisual, _math_matrix_set_identity( &rmesa->tmpmat ); driInitExtensions( ctx, card_extensions, GL_TRUE ); + if (rmesa->glCtx->Mesa_DXTn) { + _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); + _mesa_enable_extension( ctx, "GL_S3_s3tc" ); + } + else if (driQueryOptionb (&rmesa->optionCache, "force_s3tc_enable")) { + _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); + } if (rmesa->dri.drmMinor >= 9) _mesa_enable_extension( ctx, "GL_NV_texture_rectangle"); diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index a3b2047bc8..d725d312f4 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -65,6 +65,7 @@ DRI_CONF_BEGIN DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB) DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0") DRI_CONF_NO_NEG_LOD_BIAS(false) + DRI_CONF_FORCE_S3TC_ENABLE(false) DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER) DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC) DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF) @@ -73,7 +74,7 @@ DRI_CONF_BEGIN DRI_CONF_NO_RAST(false) DRI_CONF_SECTION_END DRI_CONF_END; -static const GLuint __driNConfigOptions = 10; +static const GLuint __driNConfigOptions = 11; #if 1 /* Including xf86PciInfo.h introduces a bunch of errors... diff --git a/src/mesa/drivers/dri/radeon/radeon_tex.c b/src/mesa/drivers/dri/radeon/radeon_tex.c index 82b5d940f8..c466af868c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tex.c +++ b/src/mesa/drivers/dri/radeon/radeon_tex.c @@ -382,6 +382,22 @@ radeonChooseTextureFormat( GLcontext *ctx, GLint internalFormat, else return &_mesa_texformat_ycbcr_rev; + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return &_mesa_texformat_rgb_dxt1; + + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return &_mesa_texformat_rgba_dxt1; + + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return &_mesa_texformat_rgba_dxt3; + + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return &_mesa_texformat_rgba_dxt5; + default: _mesa_problem(ctx, "unexpected texture format in %s", __FUNCTION__); return NULL; @@ -544,8 +560,95 @@ static void radeonTexSubImage2D( GLcontext *ctx, GLenum target, GLint level, t->dirty_images[face] |= (1 << level); } +static void radeonCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + driTextureObject * t = (driTextureObject *) texObj->DriverData; + GLuint face; + + /* which cube face or ordinary 2D image */ + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; + ASSERT(face < 6); + break; + default: + face = 0; + } + + if ( t != NULL ) { + driSwapOutTextureObject( t ); + } + else { + t = (driTextureObject *) radeonAllocTexObj( texObj ); + if (!t) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); + return; + } + } + + /* Note, this will call ChooseTextureFormat */ + _mesa_store_compressed_teximage2d(ctx, target, level, internalFormat, width, + height, border, imageSize, data, texObj, texImage); + + t->dirty_images[face] |= (1 << level); +} +static void radeonCompressedTexSubImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + driTextureObject * t = (driTextureObject *) texObj->DriverData; + GLuint face; + + + /* which cube face or ordinary 2D image */ + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; + ASSERT(face < 6); + break; + default: + face = 0; + } + + assert( t ); /* this _should_ be true */ + if ( t ) { + driSwapOutTextureObject( t ); + } + else { + t = (driTextureObject *) radeonAllocTexObj( texObj ); + if (!t) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2D"); + return; + } + } + + _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset, yoffset, width, + height, format, imageSize, data, texObj, texImage); + + t->dirty_images[face] |= (1 << level); +} + #define SCALED_FLOAT_TO_BYTE( x, scale ) \ (((GLuint)((255.0F / scale) * (x))) / 2) @@ -756,5 +859,8 @@ void radeonInitTextureFuncs( struct dd_function_table *functions ) functions->TexParameter = radeonTexParameter; functions->TexGen = radeonTexGen; + functions->CompressedTexImage2D = radeonCompressedTexImage2D; + functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D; + driInitTextureFormats(); } diff --git a/src/mesa/drivers/dri/radeon/radeon_texmem.c b/src/mesa/drivers/dri/radeon/radeon_texmem.c index c075c2c562..6ac00c27b2 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texmem.c +++ b/src/mesa/drivers/dri/radeon/radeon_texmem.c @@ -257,10 +257,21 @@ static void uploadSubImage( radeonContextPtr rmesa, radeonTexObjPtr t, tex.height = imageHeight; } else { - tex.width = imageWidth; /* compressed */ - tex.height = imageHeight; - if (tex.height < 4) - tex.height = 4; + /* In case of for instance 8x8 texture (2x2 dxt blocks), padding after the first two blocks is + needed (only with dxt1 since 2 dxt3/dxt5 blocks already use 32 Byte). */ + /* set tex.height to 1/4 since 1 "macropixel" (dxt-block) has 4 real pixels. Needed + so the kernel module reads the right amount of data. */ + tex.height = (imageHeight + 3) / 4; + tex.width = (imageWidth + 3) / 4; + switch (t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK) { + case RADEON_TXFORMAT_DXT1: + tex.width *= 8; + break; + case RADEON_TXFORMAT_DXT23: + case RADEON_TXFORMAT_DXT45: + tex.width *= 16; + break; + } } tex.image = &tmp; diff --git a/src/mesa/drivers/dri/radeon/radeon_texstate.c b/src/mesa/drivers/dri/radeon/radeon_texstate.c index 49220472df..5e818da9fd 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texstate.c +++ b/src/mesa/drivers/dri/radeon/radeon_texstate.c @@ -55,6 +55,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define RADEON_TXFORMAT_AL88 RADEON_TXFORMAT_AI88 #define RADEON_TXFORMAT_YCBCR RADEON_TXFORMAT_YVYU422 #define RADEON_TXFORMAT_YCBCR_REV RADEON_TXFORMAT_VYUY422 +#define RADEON_TXFORMAT_RGB_DXT1 RADEON_TXFORMAT_DXT1 +#define RADEON_TXFORMAT_RGBA_DXT1 RADEON_TXFORMAT_DXT1 +#define RADEON_TXFORMAT_RGBA_DXT3 RADEON_TXFORMAT_DXT23 +#define RADEON_TXFORMAT_RGBA_DXT5 RADEON_TXFORMAT_DXT45 #define _COLOR(f) \ [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, 0 } @@ -68,7 +72,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, RADEON_YUV_TO_RGB } #define _INVALID(f) \ [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 } -#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_YCBCR_REV) \ +#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \ && (tx_table[f].format != 0xffffffff) ) static const struct { @@ -95,6 +99,12 @@ tx_table[] = _INVALID(CI8), _YUV(YCBCR), _YUV(YCBCR_REV), + _INVALID(RGB_FXT1), + _INVALID(RGBA_FXT1), + _COLOR(RGB_DXT1), + _ALPHA(RGBA_DXT1), + _ALPHA(RGBA_DXT3), + _ALPHA(RGBA_DXT5), }; #undef _COLOR @@ -167,7 +177,24 @@ static void radeonSetTexImages( radeonContextPtr rmesa, /* find image size in bytes */ if (texImage->IsCompressed) { - size = texImage->CompressedSize; + /* need to calculate the size AFTER padding even though the texture is + submitted without padding. + Only handle pot textures currently - don't know if npot is even possible, + size calculation would certainly need (trivial) adjustments. + Align (and later pad) to 32byte, not sure what that 64byte blit width is + good for? */ + if ((t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK) == RADEON_TXFORMAT_DXT1) { + /* RGB_DXT1/RGBA_DXT1, 8 bytes per block */ + if ((texImage->Width + 3) < 8) /* width one block */ + size = texImage->CompressedSize * 4; + else if ((texImage->Width + 3) < 16) + size = texImage->CompressedSize * 2; + else size = texImage->CompressedSize; + } + else /* DXT3/5, 16 bytes per block */ + if ((texImage->Width + 3) < 8) + size = texImage->CompressedSize * 2; + else size = texImage->CompressedSize; } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) { size = ((texImage->Width * texImage->TexFormat->TexelBytes + 63) diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 07119a2fb6..4086ef94be 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 572cdd2561..a797c2edf9 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"); } |