texture compression
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index a4aa534..9942227 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -480,6 +480,17 @@
                                    GLsizei imageSize, const GLvoid *data,
                                    struct gl_texture_object *texObj,
                                    struct gl_texture_image *texImage);
+   /**
+    * Called to validate a certain compressed format.
+    */
+   GLboolean (*IsCompressedFormat)( GLcontext *ctx, GLenum internalFormat );
+   /**
+    * Called to get bytes of storage needed for the given texture size and
+    * compressed format.
+    */
+   GLuint (*CompressedTextureSize)( GLcontext *ctx,
+                                    GLsizei width, GLsizei height, GLsizei depth,
+                                    GLenum format );
    /*@}*/
 
    /**
diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c
index e6a9695..1b9daac 100644
--- a/src/mesa/main/texcompress.c
+++ b/src/mesa/main/texcompress.c
@@ -96,11 +96,20 @@
 {
    GLuint size;
 
+   if (ctx->Driver.CompressedTextureSize) {
+      return ctx->Driver.CompressedTextureSize(ctx, width, height, depth, format);
+   }
+
    switch (format) {
    case GL_COMPRESSED_RGB_FXT1_3DFX:
    case GL_COMPRESSED_RGBA_FXT1_3DFX:
       /* round up to multiple of 4 */
       size = ((width + 7) / 8) * ((height + 3) / 4) * 16;
+      /* Textures smaller than 4x4 will effectively be made into 4x4 and
+       * take 8 bytes.
+       */
+      if (size < 16)
+         size = 16;
       return size;
    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
@@ -150,6 +159,10 @@
    GLint bytesPerTile, stride;
 
    switch (format) {
+   case GL_COMPRESSED_RGB_FXT1_3DFX:
+   case GL_COMPRESSED_RGBA_FXT1_3DFX:
+      bytesPerTile = 8;
+      break;
    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
       bytesPerTile = 8;
@@ -193,6 +206,10 @@
    (void) img;
 
    switch (format) {
+   case GL_COMPRESSED_RGB_FXT1_3DFX:
+   case GL_COMPRESSED_RGBA_FXT1_3DFX:
+      bytesPerTile = 8;
+      break;
    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
       bytesPerTile = 8;
diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c
index b5c721f..0000767f 100644
--- a/src/mesa/main/texformat.c
+++ b/src/mesa/main/texformat.c
@@ -453,6 +453,40 @@
    fetch_3d_texel_ycbcr_rev,		/* FetchTexel3D */
 };
 
+const struct gl_texture_format _mesa_texformat_rgb_fxt1 = {
+   MESA_FORMAT_RGB_FXT1,		/* MesaFormat */
+   GL_RGB,				/* BaseFormat */
+   4, /*approx*/			/* RedBits */
+   4, /*approx*/			/* GreenBits */
+   4, /*approx*/			/* BlueBits */
+   0,					/* AlphaBits */
+   0,					/* LuminanceBits */
+   0,					/* IntensityBits */
+   0,					/* IndexBits */
+   0,					/* DepthBits */
+   0,					/* TexelBytes */
+   NULL, /*impossible*/ 		/* FetchTexel1D */
+   fetch_2d_texel_rgb_fxt1, 		/* FetchTexel2D */
+   NULL, /*impossible*/ 		/* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_rgba_fxt1 = {
+   MESA_FORMAT_RGBA_FXT1,		/* MesaFormat */
+   GL_RGBA,				/* BaseFormat */
+   4, /*approx*/			/* RedBits */
+   4, /*approx*/			/* GreenBits */
+   4, /*approx*/			/* BlueBits */
+   1, /*approx*/			/* AlphaBits */
+   0,					/* LuminanceBits */
+   0,					/* IntensityBits */
+   0,					/* IndexBits */
+   0,					/* DepthBits */
+   0,					/* TexelBytes */
+   NULL, /*impossible*/ 		/* FetchTexel1D */
+   fetch_2d_texel_rgba_fxt1, 		/* FetchTexel2D */
+   NULL, /*impossible*/ 		/* FetchTexel3D */
+};
+
 const struct gl_texture_format _mesa_texformat_rgb_dxt1 = {
    MESA_FORMAT_RGB_DXT1,		/* MesaFormat */
    GL_RGB,				/* BaseFormat */
@@ -838,13 +872,17 @@
    case GL_COMPRESSED_RGB_ARB:
       if (!ctx->Extensions.ARB_texture_compression)
 	 _mesa_problem(ctx, "texture compression extension not enabled");
-      if (ctx->Extensions.EXT_texture_compression_s3tc)
+      if (ctx->Extensions.TDFX_texture_compression_FXT1)
+         return &_mesa_texformat_rgb_fxt1;
+      else if (ctx->Extensions.EXT_texture_compression_s3tc)
          return &_mesa_texformat_rgb_dxt1;
       return &_mesa_texformat_rgb;
    case GL_COMPRESSED_RGBA_ARB:
       if (!ctx->Extensions.ARB_texture_compression)
 	 _mesa_problem(ctx, "texture compression extension not enabled");
-      if (ctx->Extensions.EXT_texture_compression_s3tc)
+      if (ctx->Extensions.TDFX_texture_compression_FXT1)
+         return &_mesa_texformat_rgba_fxt1;
+      else if (ctx->Extensions.EXT_texture_compression_s3tc)
          return &_mesa_texformat_rgba_dxt3;  /* Not rgba_dxt1!  See the spec */
       return &_mesa_texformat_rgba;
 
@@ -855,6 +893,18 @@
       else
          return &_mesa_texformat_ycbcr_rev;
 
+   /* GL_3DFX_texture_compression_FXT1 */
+   case GL_COMPRESSED_RGB_FXT1_3DFX:
+      if (ctx->Extensions.TDFX_texture_compression_FXT1)
+         return &_mesa_texformat_rgb_fxt1;
+      else
+         return NULL;
+   case GL_COMPRESSED_RGBA_FXT1_3DFX:
+      if (ctx->Extensions.TDFX_texture_compression_FXT1)
+         return &_mesa_texformat_rgba_fxt1;
+      else
+         return NULL;
+
    /* GL_EXT_texture_compression_s3tc */
    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
       if (ctx->Extensions.EXT_texture_compression_s3tc)
diff --git a/src/mesa/main/texformat.h b/src/mesa/main/texformat.h
index 07fa2ad..c43da46 100644
--- a/src/mesa/main/texformat.h
+++ b/src/mesa/main/texformat.h
@@ -75,6 +75,8 @@
    MESA_FORMAT_YCBCR_REV,	/*                     UorV UorV YYYY YYYY */
    /*@}*/
 
+   MESA_FORMAT_RGB_FXT1,
+   MESA_FORMAT_RGBA_FXT1,
    MESA_FORMAT_RGB_DXT1,
    MESA_FORMAT_RGBA_DXT1,
    MESA_FORMAT_RGBA_DXT3,
@@ -162,6 +164,8 @@
 extern const struct gl_texture_format _mesa_texformat_ci8;
 extern const struct gl_texture_format _mesa_texformat_ycbcr;
 extern const struct gl_texture_format _mesa_texformat_ycbcr_rev;
+extern const struct gl_texture_format _mesa_texformat_rgb_fxt1;
+extern const struct gl_texture_format _mesa_texformat_rgba_fxt1;
 extern const struct gl_texture_format _mesa_texformat_rgb_dxt1;
 extern const struct gl_texture_format _mesa_texformat_rgba_dxt1;
 extern const struct gl_texture_format _mesa_texformat_rgba_dxt3;
diff --git a/src/mesa/main/texformat_tmp.h b/src/mesa/main/texformat_tmp.h
index 840fcd2..b0af8b8 100644
--- a/src/mesa/main/texformat_tmp.h
+++ b/src/mesa/main/texformat_tmp.h
@@ -362,6 +362,27 @@
 
 
 #if DIM == 2
+static void FETCH(rgb_fxt1)( const struct gl_texture_image *texImage,
+                             GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   /* Extract the (i,j) pixel from texImage->Data and return it
+    * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
+    */
+}
+#endif
+
+#if DIM == 2
+static void FETCH(rgba_fxt1)( const struct gl_texture_image *texImage,
+                              GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   /* Extract the (i,j) pixel from texImage->Data and return it
+    * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
+    */
+}
+#endif
+
+
+#if DIM == 2
 static void FETCH(rgb_dxt1)( const struct gl_texture_image *texImage,
                              GLint i, GLint j, GLint k, GLvoid *texel )
 {
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index cf199dd..efe197e 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -262,6 +262,18 @@
             return GL_RGBA;
          else
             return -1;
+      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+         if (ctx->Extensions.EXT_texture_compression_s3tc)
+            return GL_RGB;
+         else
+            return -1;
+      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+         if (ctx->Extensions.EXT_texture_compression_s3tc)
+            return GL_RGBA;
+         else
+            return -1;
 
       case GL_YCBCR_MESA:
          if (ctx->Extensions.MESA_ycbcr_texture)
@@ -366,13 +378,20 @@
  * are supported.
  */
 static GLboolean
-is_compressed_format(GLenum internalFormat)
+is_compressed_format(GLcontext *ctx, GLenum internalFormat)
 {
    switch (internalFormat) {
       case GL_COMPRESSED_RGB_FXT1_3DFX:
       case GL_COMPRESSED_RGBA_FXT1_3DFX:
+      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
          return GL_TRUE;
       default:
+         if (ctx->Driver.IsCompressedFormat) {
+            return ctx->Driver.IsCompressedFormat(ctx, internalFormat);
+         }
          return GL_FALSE;
    }
 }
@@ -916,7 +935,7 @@
    img->Height2 = height - 2 * border; /*1 << img->HeightLog2;*/
    img->Depth2 = depth - 2 * border; /*1 << img->DepthLog2;*/
    img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
-   img->IsCompressed = is_compressed_format(internalFormat);
+   img->IsCompressed = is_compressed_format(ctx, internalFormat);
    if (img->IsCompressed)
       img->CompressedSize = _mesa_compressed_texture_size(ctx, width, height,
                                                        depth, internalFormat);
@@ -1236,7 +1255,7 @@
       }
    }
 
-   if (is_compressed_format(internalFormat)) {
+   if (is_compressed_format(ctx, internalFormat)) {
       if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
          /* OK */
       }
@@ -1569,7 +1588,7 @@
       return GL_TRUE;
    }
 
-   if (is_compressed_format(internalFormat)) {
+   if (is_compressed_format(ctx, internalFormat)) {
       if (target != GL_TEXTURE_2D) {
          _mesa_error(ctx, GL_INVALID_ENUM,
                      "glCopyTexImage%d(target)", dimensions);
@@ -2612,7 +2631,7 @@
 
    maxTextureSize = 1 << (maxLevels - 1);
 
-   if (!is_compressed_format(internalFormat))
+   if (!is_compressed_format(ctx, internalFormat))
       return GL_INVALID_ENUM;
 
    if (border != 0)
@@ -2701,7 +2720,7 @@
 
    maxTextureSize = 1 << (maxLevels - 1);
 
-   if (!is_compressed_format(format))
+   if (!is_compressed_format(ctx, format))
       return GL_INVALID_ENUM;
 
    if (width < 1 || width > maxTextureSize)