summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/common/xmlpool.h6
-rw-r--r--src/mesa/drivers/dri/i830/i830_context.c10
-rw-r--r--src/mesa/drivers/dri/i830/i830_screen.c3
-rw-r--r--src/mesa/drivers/dri/i830/i830_tex.c16
-rw-r--r--src/mesa/drivers/dri/i830/i830_texmem.c14
-rw-r--r--src/mesa/drivers/dri/i830/i830_texstate.c19
-rw-r--r--src/mesa/drivers/dri/i915/i830_texstate.c19
-rw-r--r--src/mesa/drivers/dri/i915/i915_texstate.c18
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.c10
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.h5
-rw-r--r--src/mesa/drivers/dri/i915/intel_screen.c13
-rw-r--r--src/mesa/drivers/dri/i915/intel_screen.h7
-rw-r--r--src/mesa/drivers/dri/i915/intel_tex.c29
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.c10
-rw-r--r--src/mesa/drivers/dri/r200/r200_screen.c3
-rw-r--r--src/mesa/drivers/dri/r200/r200_tex.c129
-rw-r--r--src/mesa/drivers/dri/r200/r200_texmem.c21
-rw-r--r--src/mesa/drivers/dri/r200/r200_texstate.c31
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.c9
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.c3
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_tex.c106
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texmem.c19
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texstate.c31
-rw-r--r--src/mesa/main/mtypes.h3
-rw-r--r--src/mesa/main/texcompress_s3tc.c137
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 7b8222e0a20..efd13a136ab 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 b69f11a0c0d..3e6f8a9a1fb 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 52aa22d9d16..f323baccbfa 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 2fb4cc93249..41b5d929330 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 6a30b496555..7faf90874ce 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 d5440141bfe..358c554f3b3 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 a393fd1d52e..ba452279baf 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 60ba0629528..2f94e6743ac 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 c1559e9567e..302ddfa840e 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 839062921ba..625e96f580f 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 e7e9b129154..8007ff48c2e 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 ffe5e8e50d2..f2fb1c6bc95 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 4e22d7e3f77..b6b8188275a 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 d5ca2f9b3a6..0868febc346 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 e338e5b353c..1411394ab50 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 346c27cee0a..3d259c2ca66 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 bc937ce6cb2..3f8e5d6e7f8 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 003c1e3e473..f6df2c4f822 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 5f419347b45..fc69ec1b5bc 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 a3b2047bc8e..d725d312f4f 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 82b5d940f88..c466af868c4 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 c075c2c5625..6ac00c27b2c 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 49220472dfc..5e818da9fd1 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 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");
}