pingou / rpms / mesa

Forked from rpms/mesa 6 years ago
Clone
Blob Blame History Raw
From aff9c0e3d29983f90438dd4006e6f2654c878fd4 Mon Sep 17 00:00:00 2001
From: Matt Turner <mattst88@gmail.com>
Date: Wed, 27 Sep 2017 19:58:28 -0700
Subject: [PATCH] mesa: Squash merge of S3TC support

(cherry picked from commit 04396a134f003aece573df593acfa1ab4418ffe8)
(cherry picked from commit f7daa737d17df6d0a847e5c61e48d25e598671f4)
(cherry picked from commit 7ce9999166f24996d24d56d3effcae181d401111)
(cherry picked from commit 82c54c4fdc8495d7522c782141c080314459690a)
(cherry picked from commit fb5338c4b77db70ea26b0745cff1cb3e330a5139)
(cherry picked from commit 34cf3c43beed2fafb4512e921f39c818478f86d7)
(cherry picked from commit 78c6221f18ab451f2e57bc61852595a60f82e3cb)
(cherry picked from commit c5d508028454f42923aee1ea1ab876f01f680ae7)
(cherry picked from commit f6c56e07fc5a8e81fd90688c9fee239f18c3480e)
(cherry picked from commit 3a8a5e77e8f992aaa3539e060885138c2fcddad1)
(cherry picked from commit dc546a7bb3fae1d597e5a22d9527540ec4f072c8)
(cherry picked from commit c17c47207b96172ca9c85a16f7fb7f1d3ea959d8)
(cherry picked from commit 8d02abd0feaaef28a35d89903bd534a7f27c38d7)
(cherry picked from commit 74b5568978968f580b9809135198db1015bc55b7)
---
 configure.ac                                     |   4 +-
 src/gallium/auxiliary/util/u_format.c            |   2 +-
 src/gallium/auxiliary/util/u_format_s3tc.c       | 133 +--
 src/gallium/auxiliary/util/u_format_s3tc.h       |   6 -
 src/gallium/drivers/freedreno/freedreno_screen.c |   2 -
 src/gallium/drivers/i915/i915_screen.c           |   2 -
 src/gallium/drivers/llvmpipe/lp_screen.c         |   6 -
 src/gallium/drivers/llvmpipe/lp_test_format.c    |   7 -
 src/gallium/drivers/nouveau/nouveau_screen.c     |   2 -
 src/gallium/drivers/r300/r300_screen.c           |   3 +-
 src/gallium/drivers/r300/r300_texture.c          |   4 -
 src/gallium/drivers/r600/r600_state_common.c     |   4 -
 src/gallium/drivers/radeon/r600_pipe_common.c    |   1 -
 src/gallium/drivers/radeonsi/si_state.c          |   4 -
 src/gallium/drivers/softpipe/sp_screen.c         |   6 -
 src/gallium/drivers/swr/swr_screen.cpp           |   6 -
 src/gallium/drivers/virgl/virgl_screen.c         |   5 +-
 src/gallium/include/state_tracker/st_api.h       |   1 -
 src/gallium/state_trackers/dri/dri_screen.c      |  16 -
 src/gallium/state_trackers/osmesa/osmesa.c       |   1 -
 src/gallium/tests/unit/u_format_test.c           |   7 -
 src/mesa/Makefile.sources                        |   1 -
 src/mesa/SConscript                              |   4 -
 src/mesa/drivers/dri/common/xmlpool/t_options.h  |   5 -
 src/mesa/drivers/dri/i915/intel_extensions.c     |   5 +-
 src/mesa/drivers/dri/i915/intel_screen.c         |   1 -
 src/mesa/drivers/dri/i965/intel_extensions.c     |   4 +-
 src/mesa/drivers/dri/i965/intel_screen.c         |   2 -
 src/mesa/drivers/dri/nouveau/nv10_context.c      |   6 +-
 src/mesa/drivers/dri/nouveau/nv20_context.c      |   6 +-
 src/mesa/drivers/dri/r200/r200_context.c         |  10 +-
 src/mesa/drivers/dri/radeon/radeon_context.c     |  10 +-
 src/mesa/drivers/dri/radeon/radeon_screen.c      |   2 -
 src/mesa/main/context.c                          |   2 -
 src/mesa/main/dlopen.h                           |  97 ---
 src/mesa/main/extensions.c                       |   6 +-
 src/mesa/main/mtypes.h                           |   3 -
 src/mesa/main/texcompress_s3tc.c                 | 269 ++----
 src/mesa/main/texcompress_s3tc.h                 |   3 -
 src/mesa/main/texcompress_s3tc_tmp.h             | 989 +++++++++++++++++++++++
 src/mesa/main/texformat.c                        |  14 +-
 src/mesa/main/teximage.c                         |  32 -
 src/mesa/state_tracker/st_context.c              |   2 +-
 src/mesa/state_tracker/st_extensions.c           |   8 +-
 src/mesa/state_tracker/st_extensions.h           |   3 +-
 src/mesa/state_tracker/st_format.c               |   4 +-
 src/mesa/state_tracker/st_manager.c              |   2 +-
 47 files changed, 1083 insertions(+), 629 deletions(-)
 delete mode 100644 src/mesa/main/dlopen.h
 create mode 100644 src/mesa/main/texcompress_s3tc_tmp.h

diff --git a/configure.ac b/configure.ac
index 49dd002502..cdce1ea8b1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -862,9 +862,9 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([[
 
 dnl Check to see if dlopen is in default libraries (like Solaris, which
 dnl has it in libc), or if libdl is needed to get it.
-AC_CHECK_FUNC([dlopen], [DEFINES="$DEFINES -DHAVE_DLOPEN"],
+AC_CHECK_FUNC([dlopen], [],
     [AC_CHECK_LIB([dl], [dlopen],
-       [DEFINES="$DEFINES -DHAVE_DLOPEN"; DLOPEN_LIBS="-ldl"])])
+       [DLOPEN_LIBS="-ldl"])])
 AC_SUBST([DLOPEN_LIBS])
 
 dnl Check if that library also has dladdr
diff --git a/src/gallium/auxiliary/util/u_format.c b/src/gallium/auxiliary/util/u_format.c
index 3d281905ce..0fc3231654 100644
--- a/src/gallium/auxiliary/util/u_format.c
+++ b/src/gallium/auxiliary/util/u_format.c
@@ -238,7 +238,7 @@ util_format_is_subsampled_422(enum pipe_format format)
 boolean
 util_format_is_supported(enum pipe_format format, unsigned bind)
 {
-   if (util_format_is_s3tc(format) && !util_format_s3tc_enabled) {
+   if (format >= PIPE_FORMAT_COUNT) {
       return FALSE;
    }
 
diff --git a/src/gallium/auxiliary/util/u_format_s3tc.c b/src/gallium/auxiliary/util/u_format_s3tc.c
index 8c4f2150be..3f755e5363 100644
--- a/src/gallium/auxiliary/util/u_format_s3tc.c
+++ b/src/gallium/auxiliary/util/u_format_s3tc.c
@@ -28,136 +28,15 @@
 #include "u_format.h"
 #include "u_format_s3tc.h"
 #include "util/format_srgb.h"
+#include "../../../mesa/main/texcompress_s3tc_tmp.h"
 
 
-#if defined(_WIN32) || defined(WIN32)
-#define DXTN_LIBNAME "dxtn.dll"
-#elif defined(__CYGWIN__)
-#define DXTN_LIBNAME "cygtxc_dxtn.dll"
-#elif defined(__APPLE__)
-#define DXTN_LIBNAME "libtxc_dxtn.dylib"
-#else
-#define DXTN_LIBNAME "libtxc_dxtn.so"
-#endif
+util_format_dxtn_fetch_t util_format_dxt1_rgb_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgb_dxt1;
+util_format_dxtn_fetch_t util_format_dxt1_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt1;
+util_format_dxtn_fetch_t util_format_dxt3_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt3;
+util_format_dxtn_fetch_t util_format_dxt5_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt5;
 
-
-static void
-util_format_dxt1_rgb_fetch_stub(int src_stride,
-                                const uint8_t *src,
-                                int col, int row,
-                                uint8_t *dst)
-{
-   assert(0);
-}
-
-
-static void
-util_format_dxt1_rgba_fetch_stub(int src_stride,
-                                 const uint8_t *src,
-                                 int col, int row,
-                                 uint8_t *dst )
-{
-   assert(0);
-}
-
-
-static void
-util_format_dxt3_rgba_fetch_stub(int src_stride,
-                                 const uint8_t *src,
-                                 int col, int row,
-                                 uint8_t *dst )
-{
-   assert(0);
-}
-
-
-static void
-util_format_dxt5_rgba_fetch_stub(int src_stride,
-                                 const uint8_t *src,
-                                 int col, int row,
-                                 uint8_t *dst )
-{
-   assert(0);
-}
-
-
-static void
-util_format_dxtn_pack_stub(int src_comps,
-                           int width, int height,
-                           const uint8_t *src,
-                           enum util_format_dxtn dst_format,
-                           uint8_t *dst,
-                           int dst_stride)
-{
-   assert(0);
-}
-
-
-boolean util_format_s3tc_enabled = FALSE;
-
-util_format_dxtn_fetch_t util_format_dxt1_rgb_fetch = util_format_dxt1_rgb_fetch_stub;
-util_format_dxtn_fetch_t util_format_dxt1_rgba_fetch = util_format_dxt1_rgba_fetch_stub;
-util_format_dxtn_fetch_t util_format_dxt3_rgba_fetch = util_format_dxt3_rgba_fetch_stub;
-util_format_dxtn_fetch_t util_format_dxt5_rgba_fetch = util_format_dxt5_rgba_fetch_stub;
-
-util_format_dxtn_pack_t util_format_dxtn_pack = util_format_dxtn_pack_stub;
-
-
-void
-util_format_s3tc_init(void)
-{
-   static boolean first_time = TRUE;
-   struct util_dl_library *library = NULL;
-   util_dl_proc fetch_2d_texel_rgb_dxt1;
-   util_dl_proc fetch_2d_texel_rgba_dxt1;
-   util_dl_proc fetch_2d_texel_rgba_dxt3;
-   util_dl_proc fetch_2d_texel_rgba_dxt5;
-   util_dl_proc tx_compress_dxtn;
-
-   if (!first_time)
-      return;
-   first_time = FALSE;
-
-   if (util_format_s3tc_enabled)
-      return;
-
-   library = util_dl_open(DXTN_LIBNAME);
-   if (!library) {
-      debug_printf("couldn't open " DXTN_LIBNAME ", software DXTn "
-                   "compression/decompression unavailable\n");
-      return;
-   }
-
-   fetch_2d_texel_rgb_dxt1 =
-         util_dl_get_proc_address(library, "fetch_2d_texel_rgb_dxt1");
-   fetch_2d_texel_rgba_dxt1 =
-         util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt1");
-   fetch_2d_texel_rgba_dxt3 =
-         util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt3");
-   fetch_2d_texel_rgba_dxt5 =
-         util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt5");
-   tx_compress_dxtn =
-         util_dl_get_proc_address(library, "tx_compress_dxtn");
-
-   if (!util_format_dxt1_rgb_fetch ||
-       !util_format_dxt1_rgba_fetch ||
-       !util_format_dxt3_rgba_fetch ||
-       !util_format_dxt5_rgba_fetch ||
-       !util_format_dxtn_pack) {
-      debug_printf("couldn't reference all symbols in " DXTN_LIBNAME
-                   ", software DXTn compression/decompression "
-                   "unavailable\n");
-      util_dl_close(library);
-      return;
-   }
-
-   util_format_dxt1_rgb_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgb_dxt1;
-   util_format_dxt1_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt1;
-   util_format_dxt3_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt3;
-   util_format_dxt5_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt5;
-   util_format_dxtn_pack = (util_format_dxtn_pack_t)tx_compress_dxtn;
-   util_format_s3tc_enabled = TRUE;
-}
+util_format_dxtn_pack_t util_format_dxtn_pack = (util_format_dxtn_pack_t)tx_compress_dxtn;
 
 
 /*
diff --git a/src/gallium/auxiliary/util/u_format_s3tc.h b/src/gallium/auxiliary/util/u_format_s3tc.h
index ae20010cdf..6f188c67f9 100644
--- a/src/gallium/auxiliary/util/u_format_s3tc.h
+++ b/src/gallium/auxiliary/util/u_format_s3tc.h
@@ -58,8 +58,6 @@ typedef void
                             uint8_t *dst,
                             int dst_stride);
 
-extern boolean util_format_s3tc_enabled;
-
 extern util_format_dxtn_fetch_t util_format_dxt1_rgb_fetch;
 extern util_format_dxtn_fetch_t util_format_dxt1_rgba_fetch;
 extern util_format_dxtn_fetch_t util_format_dxt3_rgba_fetch;
@@ -69,10 +67,6 @@ extern util_format_dxtn_pack_t util_format_dxtn_pack;
 
 
 void
-util_format_s3tc_init(void);
-
-
-void
 util_format_dxt1_rgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
 
 void
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
index a915d65ee0..59402ef3f6 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -875,8 +875,6 @@ fd_screen_create(struct fd_device *dev)
 
 	slab_create_parent(&screen->transfer_pool, sizeof(struct fd_transfer), 16);
 
-	util_format_s3tc_init();
-
 	return pscreen;
 
 fail:
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index 4ad98e2a08..b5675e417c 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -621,7 +621,5 @@ i915_screen_create(struct i915_winsys *iws)
 
    i915_debug_init(is);
 
-   util_format_s3tc_init();
-
    return &is->base;
 }
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index e98e30d50a..3ec68a5771 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -528,10 +528,6 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
        format != PIPE_FORMAT_ETC1_RGB8)
       return FALSE;
 
-   if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
-      return util_format_s3tc_enabled;
-   }
-
    /*
     * Everything can be supported by u_format
     * (those without fetch_rgba_float might be not but shouldn't hit that)
@@ -682,7 +678,5 @@ llvmpipe_create_screen(struct sw_winsys *winsys)
    }
    (void) mtx_init(&screen->rast_mutex, mtx_plain);
 
-   util_format_s3tc_init();
-
    return &screen->base;
 }
diff --git a/src/gallium/drivers/llvmpipe/lp_test_format.c b/src/gallium/drivers/llvmpipe/lp_test_format.c
index 9b16162131..e9a6e01fdc 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_format.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_format.c
@@ -357,8 +357,6 @@ test_all(unsigned verbose, FILE *fp)
    enum pipe_format format;
    boolean success = TRUE;
 
-   util_format_s3tc_init();
-
 #if USE_TEXTURE_CACHE
    cache_ptr = align_malloc(sizeof(struct lp_build_format_cache), 16);
 #endif
@@ -383,11 +381,6 @@ test_all(unsigned verbose, FILE *fp)
       if (util_format_is_pure_integer(format))
 	 continue;
 
-      if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC &&
-          !util_format_s3tc_enabled) {
-         continue;
-      }
-
       /* only have util fetch func for etc1 */
       if (format_desc->layout == UTIL_FORMAT_LAYOUT_ETC &&
           format != PIPE_FORMAT_ETC1_RGB8) {
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index 13b76d7681..ea68809c6e 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -242,8 +242,6 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
 
    nouveau_disk_cache_create(screen);
 
-   util_format_s3tc_init();
-
    screen->lowmem_bindings = PIPE_BIND_GLOBAL; /* gallium limit */
    screen->vidmem_bindings =
       PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL |
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 5cdb24871c..82d7183b9e 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -127,7 +127,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 
         /* r300 cannot do swizzling of compressed textures. Supported otherwise. */
         case PIPE_CAP_TEXTURE_SWIZZLE:
-            return util_format_s3tc_enabled ? r300screen->caps.dxtc_swizzle : 1;
+            return r300screen->caps.dxtc_swizzle;
 
         /* We don't support color clamping on r500, so that we can use color
          * intepolators for generic varyings. */
@@ -762,7 +762,6 @@ struct pipe_screen* r300_screen_create(struct radeon_winsys *rws, unsigned flags
 
     slab_create_parent(&r300screen->pool_transfers, sizeof(struct pipe_transfer), 64);
 
-    util_format_s3tc_init();
     (void) mtx_init(&r300screen->cmask_mutex, mtx_plain);
 
     return &r300screen->screen;
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index cdf9ccb973..87632fcbb4 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -251,10 +251,6 @@ uint32_t r300_translate_texformat(enum pipe_format format,
 
     /* S3TC formats. */
     if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
-        if (!util_format_s3tc_enabled) {
-            return ~0; /* Unsupported. */
-        }
-
         switch (format) {
             case PIPE_FORMAT_DXT1_RGB:
             case PIPE_FORMAT_DXT1_RGBA:
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index 4c97efa73b..306b3c0abb 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -2403,10 +2403,6 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen,
 	}
 
 	if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
-		if (!util_format_s3tc_enabled) {
-			goto out_unknown;
-		}
-
 		switch (format) {
 		case PIPE_FORMAT_DXT1_RGB:
 		case PIPE_FORMAT_DXT1_RGBA:
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c
index b02203c3c1..a3c6ed0a22 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.c
+++ b/src/gallium/drivers/radeon/r600_pipe_common.c
@@ -1408,7 +1408,6 @@ bool r600_common_screen_init(struct r600_common_screen *rscreen,
 		       1 << util_logbase2(rscreen->force_aniso));
 	}
 
-	util_format_s3tc_init();
 	(void) mtx_init(&rscreen->aux_context_lock, mtx_plain);
 	(void) mtx_init(&rscreen->gpu_load_mutex, mtx_plain);
 
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index c610103032..931c326b49 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -1525,10 +1525,6 @@ static uint32_t si_translate_texformat(struct pipe_screen *screen,
 		if (!enable_compressed_formats)
 			goto out_unknown;
 
-		if (!util_format_s3tc_enabled) {
-			goto out_unknown;
-		}
-
 		switch (format) {
 		case PIPE_FORMAT_DXT1_RGB:
 		case PIPE_FORMAT_DXT1_RGBA:
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 5c96a14c80..6aa6beb1ad 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -455,10 +455,6 @@ softpipe_is_format_supported( struct pipe_screen *screen,
     * All other operations (sampling, transfer, etc).
     */
 
-   if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
-      return util_format_s3tc_enabled;
-   }
-
    /*
     * Everything else should be supported by u_format.
     */
@@ -585,8 +581,6 @@ softpipe_create_screen(struct sw_winsys *winsys)
    screen->base.get_compute_param = softpipe_get_compute_param;
    screen->use_llvm = debug_get_option_use_llvm();
 
-   util_format_s3tc_init();
-
    softpipe_init_screen_texture_funcs(&screen->base);
    softpipe_init_screen_fence_funcs(&screen->base);
 
diff --git a/src/gallium/drivers/swr/swr_screen.cpp b/src/gallium/drivers/swr/swr_screen.cpp
index 952ae0c77a..d4f4ee8da1 100644
--- a/src/gallium/drivers/swr/swr_screen.cpp
+++ b/src/gallium/drivers/swr/swr_screen.cpp
@@ -147,10 +147,6 @@ swr_is_format_supported(struct pipe_screen *_screen,
       return FALSE;
    }
 
-   if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
-      return util_format_s3tc_enabled;
-   }
-
    return TRUE;
 }
 
@@ -1140,8 +1136,6 @@ swr_create_screen_internal(struct sw_winsys *winsys)
 
    swr_fence_init(&screen->base);
 
-   util_format_s3tc_init();
-
    swr_validate_env_options(screen);
 
    return &screen->base;
diff --git a/src/gallium/drivers/virgl/virgl_screen.c b/src/gallium/drivers/virgl/virgl_screen.c
index 5df08407d7..c8c29d0812 100644
--- a/src/gallium/drivers/virgl/virgl_screen.c
+++ b/src/gallium/drivers/virgl/virgl_screen.c
@@ -480,9 +480,7 @@ virgl_is_format_supported( struct pipe_screen *screen,
     */
 
    if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
-      if (util_format_s3tc_enabled)
-         goto out_lookup;
-      return FALSE;
+      goto out_lookup;
    }
    if (format_desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
       goto out_lookup;
@@ -606,6 +604,5 @@ virgl_create_screen(struct virgl_winsys *vws)
 
    slab_create_parent(&screen->texture_transfer_pool, sizeof(struct virgl_transfer), 16);
 
-   util_format_s3tc_init();
    return &screen->base;
 }
diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h
index bc62a69da3..fe9fb1816a 100644
--- a/src/gallium/include/state_tracker/st_api.h
+++ b/src/gallium/include/state_tracker/st_api.h
@@ -246,7 +246,6 @@ struct st_config_options
    boolean disable_shader_bit_encoding;
    boolean force_glsl_extensions_warn;
    unsigned force_glsl_version;
-   boolean force_s3tc_enable;
    boolean allow_glsl_extension_directive_midshader;
    boolean allow_glsl_builtin_variable_redeclaration;
    boolean allow_higher_compat_version;
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index 6bd479074f..09af6a6234 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -62,7 +62,6 @@ const __DRIconfigOptionsExtension gallium_config_options = {
       DRI_CONF_SECTION_END
 
       DRI_CONF_SECTION_QUALITY
-         DRI_CONF_FORCE_S3TC_ENABLE("false")
          DRI_CONF_PP_CELSHADE(0)
          DRI_CONF_PP_NORED(0)
          DRI_CONF_PP_NOGREEN(0)
@@ -109,8 +108,6 @@ dri_fill_st_options(struct dri_screen *screen)
       driQueryOptionb(optionCache, "force_glsl_extensions_warn");
    options->force_glsl_version =
       driQueryOptioni(optionCache, "force_glsl_version");
-   options->force_s3tc_enable =
-      driQueryOptionb(optionCache, "force_s3tc_enable");
    options->allow_glsl_extension_directive_midshader =
       driQueryOptionb(optionCache, "allow_glsl_extension_directive_midshader");
    options->allow_glsl_builtin_variable_redeclaration =
@@ -564,19 +561,6 @@ dri_init_screen_helper(struct dri_screen *screen,
    else
       screen->target = PIPE_TEXTURE_RECT;
 
-   /* Handle force_s3tc_enable. */
-   if (!util_format_s3tc_enabled && screen->options.force_s3tc_enable) {
-      /* Ensure libtxc_dxtn has been loaded if available.
-       * Forcing S3TC on before calling this would prevent loading
-       * the library.
-       * This is just a precaution, the driver should have called it
-       * already.
-       */
-      util_format_s3tc_init();
-
-      util_format_s3tc_enabled = TRUE;
-   }
-
    dri_postprocessing_init(screen);
 
    screen->st_api->query_versions(screen->st_api, &screen->base,
diff --git a/src/gallium/state_trackers/osmesa/osmesa.c b/src/gallium/state_trackers/osmesa/osmesa.c
index 751d255c54..2f9558db31 100644
--- a/src/gallium/state_trackers/osmesa/osmesa.c
+++ b/src/gallium/state_trackers/osmesa/osmesa.c
@@ -688,7 +688,6 @@ OSMesaCreateContextAttribs(const int *attribList, OSMesaContext sharelist)
    attribs.options.disable_blend_func_extended = FALSE;
    attribs.options.disable_glsl_line_continuations = FALSE;
    attribs.options.disable_shader_bit_encoding = FALSE;
-   attribs.options.force_s3tc_enable = FALSE;
    attribs.options.force_glsl_version = 0;
 
    osmesa_init_st_visual(&attribs.visual,
diff --git a/src/gallium/tests/unit/u_format_test.c b/src/gallium/tests/unit/u_format_test.c
index 69d6c7dd3a..6de581fd04 100644
--- a/src/gallium/tests/unit/u_format_test.c
+++ b/src/gallium/tests/unit/u_format_test.c
@@ -722,11 +722,6 @@ test_all(void)
       assert(format_desc->block.height <= UTIL_FORMAT_MAX_UNPACKED_HEIGHT);
       assert(format_desc->block.width  <= UTIL_FORMAT_MAX_UNPACKED_WIDTH);
 
-      if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC &&
-          !util_format_s3tc_enabled) {
-         continue;
-      }
-
 #     define TEST_ONE_FUNC(name) \
       if (format_desc->name) { \
          if (!test_one_func(format_desc, &test_format_##name, #name)) { \
@@ -758,8 +753,6 @@ int main(int argc, char **argv)
 {
    boolean success;
 
-   util_format_s3tc_init();
-
    success = test_all();
 
    return success ? 0 : 1;
diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources
index 86fbf3974e..bc93ded3db 100644
--- a/src/mesa/Makefile.sources
+++ b/src/mesa/Makefile.sources
@@ -67,7 +67,6 @@ MAIN_FILES = \
 	main/depth.h \
 	main/dlist.c \
 	main/dlist.h \
-	main/dlopen.h \
 	main/drawpix.c \
 	main/drawpix.h \
 	main/drawtex.c \
diff --git a/src/mesa/SConscript b/src/mesa/SConscript
index b63e15a3f0..ba98ad4323 100644
--- a/src/mesa/SConscript
+++ b/src/mesa/SConscript
@@ -31,10 +31,6 @@ if env['platform'] == 'windows':
     if not env['gles']:
         # prevent _glapi_* from being declared __declspec(dllimport)
         env.Append(CPPDEFINES = ['_GLAPI_NO_EXPORTS'])
-else:
-    env.Append(CPPDEFINES = [
-        ('HAVE_DLOPEN', '1'),
-    ])
 
 # parse Makefile.sources
 source_lists = env.ParseSourceList('Makefile.sources')
diff --git a/src/mesa/drivers/dri/common/xmlpool/t_options.h b/src/mesa/drivers/dri/common/xmlpool/t_options.h
index e308839aa7..afe342df07 100644
--- a/src/mesa/drivers/dri/common/xmlpool/t_options.h
+++ b/src/mesa/drivers/dri/common/xmlpool/t_options.h
@@ -172,11 +172,6 @@ DRI_CONF_OPT_BEGIN_B(no_neg_lod_bias, def) \
         DRI_CONF_DESC(en,gettext("Forbid negative texture LOD bias")) \
 DRI_CONF_OPT_END
 
-#define DRI_CONF_FORCE_S3TC_ENABLE(def) \
-DRI_CONF_OPT_BEGIN_B(force_s3tc_enable, def) \
-        DRI_CONF_DESC(en,gettext("Enable S3TC texture compression even if software support is not available")) \
-DRI_CONF_OPT_END
-
 #define DRI_CONF_PRECISE_TRIG(def) \
 DRI_CONF_OPT_BEGIN_B(precise_trig, def) \
         DRI_CONF_DESC(en,gettext("Prefer accuracy over performance in trig functions")) \
diff --git a/src/mesa/drivers/dri/i915/intel_extensions.c b/src/mesa/drivers/dri/i915/intel_extensions.c
index 4f2c6fa34e..c85bd787fe 100644
--- a/src/mesa/drivers/dri/i915/intel_extensions.c
+++ b/src/mesa/drivers/dri/i915/intel_extensions.c
@@ -100,9 +100,6 @@ intelInitExtensions(struct gl_context *ctx)
          ctx->Extensions.ARB_occlusion_query = true;
    }
 
-   if (intel->ctx.Mesa_DXTn
-       || driQueryOptionb(&intel->optionCache, "force_s3tc_enable"))
-      ctx->Extensions.EXT_texture_compression_s3tc = true;
-
+   ctx->Extensions.EXT_texture_compression_s3tc = true;
    ctx->Extensions.ANGLE_texture_compression_dxt = true;
 }
diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c
index 863f6ef7ec..c223133363 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -67,7 +67,6 @@ DRI_CONF_BEGIN
 
    DRI_CONF_SECTION_END
    DRI_CONF_SECTION_QUALITY
-      DRI_CONF_FORCE_S3TC_ENABLE("false")
    DRI_CONF_SECTION_END
    DRI_CONF_SECTION_DEBUG
       DRI_CONF_NO_RAST("false")
diff --git a/src/mesa/drivers/dri/i965/intel_extensions.c b/src/mesa/drivers/dri/i965/intel_extensions.c
index b91bbdc8d9..4fe97a0ce7 100644
--- a/src/mesa/drivers/dri/i965/intel_extensions.c
+++ b/src/mesa/drivers/dri/i965/intel_extensions.c
@@ -297,8 +297,6 @@ intelInitExtensions(struct gl_context *ctx)
    if (ctx->API != API_OPENGL_CORE)
       ctx->Extensions.ARB_color_buffer_float = true;
 
-   if (ctx->Mesa_DXTn || driQueryOptionb(&brw->optionCache, "force_s3tc_enable"))
-      ctx->Extensions.EXT_texture_compression_s3tc = true;
-
+   ctx->Extensions.EXT_texture_compression_s3tc = true;
    ctx->Extensions.ANGLE_texture_compression_dxt = true;
 }
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index 5adb8ef1f6..e60f9fb10a 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -69,8 +69,6 @@ DRI_CONF_BEGIN
    DRI_CONF_SECTION_END
 
    DRI_CONF_SECTION_QUALITY
-      DRI_CONF_FORCE_S3TC_ENABLE("false")
-
       DRI_CONF_PRECISE_TRIG("false")
 
       DRI_CONF_OPT_BEGIN(clamp_max_samples, int, -1)
diff --git a/src/mesa/drivers/dri/nouveau/nv10_context.c b/src/mesa/drivers/dri/nouveau/nv10_context.c
index 7a86ba2358..be2178fb79 100644
--- a/src/mesa/drivers/dri/nouveau/nv10_context.c
+++ b/src/mesa/drivers/dri/nouveau/nv10_context.c
@@ -451,10 +451,8 @@ nv10_context_create(struct nouveau_screen *screen, gl_api api,
 	ctx->Extensions.EXT_texture_env_dot3 = true;
 	ctx->Extensions.NV_fog_distance = true;
 	ctx->Extensions.NV_texture_rectangle = true;
-	if (ctx->Mesa_DXTn) {
-		ctx->Extensions.EXT_texture_compression_s3tc = true;
-		ctx->Extensions.ANGLE_texture_compression_dxt = true;
-	}
+	ctx->Extensions.EXT_texture_compression_s3tc = true;
+	ctx->Extensions.ANGLE_texture_compression_dxt = true;
 
 	/* GL constants. */
 	ctx->Const.MaxTextureLevels = 12;
diff --git a/src/mesa/drivers/dri/nouveau/nv20_context.c b/src/mesa/drivers/dri/nouveau/nv20_context.c
index ec638c036b..0ab2db0b08 100644
--- a/src/mesa/drivers/dri/nouveau/nv20_context.c
+++ b/src/mesa/drivers/dri/nouveau/nv20_context.c
@@ -462,10 +462,8 @@ nv20_context_create(struct nouveau_screen *screen, gl_api api,
 	ctx->Extensions.EXT_texture_env_dot3 = true;
 	ctx->Extensions.NV_fog_distance = true;
 	ctx->Extensions.NV_texture_rectangle = true;
-	if (ctx->Mesa_DXTn) {
-		ctx->Extensions.EXT_texture_compression_s3tc = true;
-		ctx->Extensions.ANGLE_texture_compression_dxt = true;
-	}
+	ctx->Extensions.EXT_texture_compression_s3tc = true;
+	ctx->Extensions.ANGLE_texture_compression_dxt = true;
 
 	/* GL constants. */
 	ctx->Const.MaxTextureCoordUnits = NV20_TEXTURE_UNITS;
diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
index 5a7f33499b..de15d520fe 100644
--- a/src/mesa/drivers/dri/r200/r200_context.c
+++ b/src/mesa/drivers/dri/r200/r200_context.c
@@ -362,14 +362,8 @@ GLboolean r200CreateContext( gl_api api,
 	others get the bit ordering right but don't actually do YUV-RGB conversion */
       ctx->Extensions.MESA_ycbcr_texture = true;
    }
-   if (rmesa->radeon.glCtx.Mesa_DXTn) {
-      ctx->Extensions.EXT_texture_compression_s3tc = true;
-      ctx->Extensions.ANGLE_texture_compression_dxt = true;
-   }
-   else if (driQueryOptionb (&rmesa->radeon.optionCache, "force_s3tc_enable")) {
-      ctx->Extensions.EXT_texture_compression_s3tc = true;
-      ctx->Extensions.ANGLE_texture_compression_dxt = true;
-   }
+   ctx->Extensions.EXT_texture_compression_s3tc = true;
+   ctx->Extensions.ANGLE_texture_compression_dxt = true;
 
 #if 0
    r200InitDriverFuncs( ctx );
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c
index 5ef3467ac1..e84b544c19 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_context.c
@@ -310,14 +310,8 @@ r100CreateContext( gl_api api,
    ctx->Extensions.NV_texture_rectangle = true;
    ctx->Extensions.OES_EGL_image = true;
 
-   if (rmesa->radeon.glCtx.Mesa_DXTn) {
-      ctx->Extensions.EXT_texture_compression_s3tc = true;
-      ctx->Extensions.ANGLE_texture_compression_dxt = true;
-   }
-   else if (driQueryOptionb (&rmesa->radeon.optionCache, "force_s3tc_enable")) {
-      ctx->Extensions.EXT_texture_compression_s3tc = true;
-      ctx->Extensions.ANGLE_texture_compression_dxt = true;
-   }
+   ctx->Extensions.EXT_texture_compression_s3tc = true;
+   ctx->Extensions.ANGLE_texture_compression_dxt = true;
 
    /* XXX these should really go right after _mesa_init_driver_functions() */
    radeon_fbo_init(&rmesa->radeon);
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index 0f072aff20..4192283fee 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -86,7 +86,6 @@ 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)
@@ -113,7 +112,6 @@ 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)
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 3aabdc92bb..1a15016e7a 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -861,8 +861,6 @@ init_attrib_groups(struct gl_context *ctx)
    if (!_mesa_init_texture( ctx ))
       return GL_FALSE;
 
-   _mesa_init_texture_s3tc( ctx );
-
    /* Miscellaneous */
    ctx->NewState = _NEW_ALL;
    ctx->NewDriverState = ~0;
diff --git a/src/mesa/main/dlopen.h b/src/mesa/main/dlopen.h
deleted file mode 100644
index 4d20ff2c7c..0000000000
--- a/src/mesa/main/dlopen.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#ifndef DLOPEN_H
-#define DLOPEN_H
-
-/**
- * Wrapper functions for dlopen(), dlsym(), dlclose().
- * Note that the #ifdef tests for various environments should be expanded.
- */
-
-#if defined(HAVE_DLOPEN)
-#include <dlfcn.h>
-#endif
-#if defined(_WIN32)
-#include <windows.h>
-#endif
-
-typedef void (*GenericFunc)(void);
-
-/**
- * Wrapper for dlopen().
- * Note that 'flags' isn't used at this time.
- */
-static inline void *
-_mesa_dlopen(const char *libname, int flags)
-{
-#if defined(HAVE_DLOPEN)
-   flags = RTLD_LAZY | RTLD_GLOBAL; /* Overriding flags at this time */
-   return dlopen(libname, flags);
-#elif defined(_WIN32)
-   return LoadLibraryA(libname);
-#else
-   return NULL;
-#endif
-}
-
-/**
- * Wrapper for dlsym() that does a cast to a generic function type,
- * rather than a void *.  This reduces the number of warnings that are
- * generated.
- */
-static inline GenericFunc
-_mesa_dlsym(void *handle, const char *fname)
-{
-   union {
-      void *v;
-      GenericFunc f;
-   } u;
-#if defined(HAVE_DLOPEN)
-   u.v = dlsym(handle, fname);
-#elif defined(_WIN32)
-   u.v = (void *) GetProcAddress(handle, fname);
-#else
-   u.v = NULL;
-#endif
-   return u.f;
-}
-
-/**
- * Wrapper for dlclose().
- */
-static inline void
-_mesa_dlclose(void *handle)
-{
-#if defined(HAVE_DLOPEN)
-   dlclose(handle);
-#elif defined(_WIN32)
-   FreeLibrary(handle);
-#else
-   (void) handle;
-#endif
-}
-
-#endif
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 62a731675d..46083001d2 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -176,10 +176,8 @@ _mesa_enable_sw_extensions(struct gl_context *ctx)
    ctx->Extensions.EXT_gpu_program_parameters = GL_TRUE;
    ctx->Extensions.OES_standard_derivatives = GL_TRUE;
    ctx->Extensions.TDFX_texture_compression_FXT1 = GL_TRUE;
-   if (ctx->Mesa_DXTn) {
-      ctx->Extensions.ANGLE_texture_compression_dxt = GL_TRUE;
-      ctx->Extensions.EXT_texture_compression_s3tc = GL_TRUE;
-   }
+   ctx->Extensions.ANGLE_texture_compression_dxt = GL_TRUE;
+   ctx->Extensions.EXT_texture_compression_s3tc = GL_TRUE;
 }
 
 /**
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 0cb002469b..f4641b9c68 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -4958,9 +4958,6 @@ struct gl_context
     */
    GLboolean HasConfig;
 
-   /** software compression/decompression supported or not */
-   GLboolean Mesa_DXTn;
-
    GLboolean TextureFormatSupported[MESA_FORMAT_COUNT];
 
    GLboolean RasterDiscard;  /**< GL_RASTERIZER_DISCARD */
diff --git a/src/mesa/main/texcompress_s3tc.c b/src/mesa/main/texcompress_s3tc.c
index 992ad058bf..1c6cbba892 100644
--- a/src/mesa/main/texcompress_s3tc.c
+++ b/src/mesa/main/texcompress_s3tc.c
@@ -31,91 +31,17 @@
 
 #include "glheader.h"
 #include "imports.h"
-#include "dlopen.h"
 #include "image.h"
 #include "macros.h"
 #include "mtypes.h"
 #include "texcompress.h"
 #include "texcompress_s3tc.h"
+#include "texcompress_s3tc_tmp.h"
 #include "texstore.h"
 #include "format_unpack.h"
 #include "util/format_srgb.h"
 
 
-#if defined(_WIN32) || defined(WIN32)
-#define DXTN_LIBNAME "dxtn.dll"
-#define RTLD_LAZY 0
-#define RTLD_GLOBAL 0
-#elif defined(__CYGWIN__)
-#define DXTN_LIBNAME "cygtxc_dxtn.dll"
-#else
-#define DXTN_LIBNAME "libtxc_dxtn.so"
-#endif
-
-typedef void (*dxtFetchTexelFuncExt)( GLint srcRowstride, const GLubyte *pixdata, GLint col, GLint row, GLvoid *texelOut );
-
-static dxtFetchTexelFuncExt fetch_ext_rgb_dxt1 = NULL;
-static dxtFetchTexelFuncExt fetch_ext_rgba_dxt1 = NULL;
-static dxtFetchTexelFuncExt fetch_ext_rgba_dxt3 = NULL;
-static dxtFetchTexelFuncExt fetch_ext_rgba_dxt5 = NULL;
-
-typedef void (*dxtCompressTexFuncExt)(GLint srccomps, GLint width,
-                                      GLint height, const GLubyte *srcPixData,
-                                      GLenum destformat, GLubyte *dest,
-                                      GLint dstRowStride);
-
-static dxtCompressTexFuncExt ext_tx_compress_dxtn = NULL;
-
-static void *dxtlibhandle = NULL;
-
-
-void
-_mesa_init_texture_s3tc( struct gl_context *ctx )
-{
-   /* called during context initialization */
-   ctx->Mesa_DXTn = GL_FALSE;
-   if (!dxtlibhandle) {
-      dxtlibhandle = _mesa_dlopen(DXTN_LIBNAME, 0);
-      if (!dxtlibhandle) {
-	 _mesa_warning(ctx, "couldn't open " DXTN_LIBNAME ", software DXTn "
-	    "compression/decompression unavailable");
-      }
-      else {
-         /* the fetch functions are not per context! Might be problematic... */
-         fetch_ext_rgb_dxt1 = (dxtFetchTexelFuncExt)
-            _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgb_dxt1");
-         fetch_ext_rgba_dxt1 = (dxtFetchTexelFuncExt)
-            _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt1");
-         fetch_ext_rgba_dxt3 = (dxtFetchTexelFuncExt)
-            _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt3");
-         fetch_ext_rgba_dxt5 = (dxtFetchTexelFuncExt)
-            _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt5");
-         ext_tx_compress_dxtn = (dxtCompressTexFuncExt)
-            _mesa_dlsym(dxtlibhandle, "tx_compress_dxtn");
-
-         if (!fetch_ext_rgb_dxt1 ||
-             !fetch_ext_rgba_dxt1 ||
-             !fetch_ext_rgba_dxt3 ||
-             !fetch_ext_rgba_dxt5 ||
-             !ext_tx_compress_dxtn) {
-	    _mesa_warning(ctx, "couldn't reference all symbols in "
-	       DXTN_LIBNAME ", software DXTn compression/decompression "
-	       "unavailable");
-            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;
-            _mesa_dlclose(dxtlibhandle);
-            dxtlibhandle = NULL;
-         }
-      }
-   }
-   if (dxtlibhandle) {
-      ctx->Mesa_DXTn = GL_TRUE;
-   }
-}
-
 /**
  * Store user's image in rgb_dxt1 format.
  */
@@ -158,14 +84,9 @@ _mesa_texstore_rgb_dxt1(TEXSTORE_PARAMS)
 
    dst = dstSlices[0];
 
-   if (ext_tx_compress_dxtn) {
-      (*ext_tx_compress_dxtn)(3, srcWidth, srcHeight, pixels,
-                              GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
-                              dst, dstRowStride);
-   }
-   else {
-      _mesa_warning(ctx, "external dxt library not available: texstore_rgb_dxt1");
-   }
+   tx_compress_dxtn(3, srcWidth, srcHeight, pixels,
+                    GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+                    dst, dstRowStride);
 
    free((void *) tempImage);
 
@@ -216,14 +137,9 @@ _mesa_texstore_rgba_dxt1(TEXSTORE_PARAMS)
 
    dst = dstSlices[0];
 
-   if (ext_tx_compress_dxtn) {
-      (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels,
-                              GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
-                              dst, dstRowStride);
-   }
-   else {
-      _mesa_warning(ctx, "external dxt library not available: texstore_rgba_dxt1");
-   }
+   tx_compress_dxtn(4, srcWidth, srcHeight, pixels,
+                    GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
+                    dst, dstRowStride);
 
    free((void*) tempImage);
 
@@ -273,14 +189,9 @@ _mesa_texstore_rgba_dxt3(TEXSTORE_PARAMS)
 
    dst = dstSlices[0];
 
-   if (ext_tx_compress_dxtn) {
-      (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels,
-                              GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
-                              dst, dstRowStride);
-   }
-   else {
-      _mesa_warning(ctx, "external dxt library not available: texstore_rgba_dxt3");
-   }
+   tx_compress_dxtn(4, srcWidth, srcHeight, pixels,
+                    GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
+                    dst, dstRowStride);
 
    free((void *) tempImage);
 
@@ -330,14 +241,9 @@ _mesa_texstore_rgba_dxt5(TEXSTORE_PARAMS)
 
    dst = dstSlices[0];
 
-   if (ext_tx_compress_dxtn) {
-      (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels,
-                              GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
-                              dst, dstRowStride);
-   }
-   else {
-      _mesa_warning(ctx, "external dxt library not available: texstore_rgba_dxt5");
-   }
+   tx_compress_dxtn(4, srcWidth, srcHeight, pixels,
+                    GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
+                    dst, dstRowStride);
 
    free((void *) tempImage);
 
@@ -345,85 +251,52 @@ _mesa_texstore_rgba_dxt5(TEXSTORE_PARAMS)
 }
 
 
-/** Report problem with dxt texture decompression, once */
-static void
-problem(const char *func)
-{
-   static GLboolean warned = GL_FALSE;
-   if (!warned) {
-      _mesa_debug(NULL, "attempted to decode DXT texture without "
-                  "library available: %s\n", func);
-      warned = GL_TRUE;
-   }
-}
-
-
 static void
 fetch_rgb_dxt1(const GLubyte *map,
                GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
-   if (fetch_ext_rgb_dxt1) {
-      GLubyte tex[4];
-      fetch_ext_rgb_dxt1(rowStride, map, i, j, tex);
-      texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
-      texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
-      texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
-      texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
-   }
-   else {
-      problem("rgb_dxt1");
-   }
+   GLubyte tex[4];
+   fetch_2d_texel_rgb_dxt1(rowStride, map, i, j, tex);
+   texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
+   texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
+   texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
+   texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
 }
 
 static void
 fetch_rgba_dxt1(const GLubyte *map,
                 GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
-   if (fetch_ext_rgba_dxt1) {
-      GLubyte tex[4];
-      fetch_ext_rgba_dxt1(rowStride, map, i, j, tex);
-      texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
-      texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
-      texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
-      texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
-   }
-   else {
-      problem("rgba_dxt1");
-   }
+   GLubyte tex[4];
+   fetch_2d_texel_rgba_dxt1(rowStride, map, i, j, tex);
+   texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
+   texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
+   texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
+   texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
 }
 
 static void
 fetch_rgba_dxt3(const GLubyte *map,
                 GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
-   if (fetch_ext_rgba_dxt3) {
-      GLubyte tex[4];
-      fetch_ext_rgba_dxt3(rowStride, map, i, j, tex);
-      texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
-      texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
-      texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
-      texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
-   }
-   else {
-      problem("rgba_dxt3");
-   }
+   GLubyte tex[4];
+   fetch_2d_texel_rgba_dxt3(rowStride, map, i, j, tex);
+   texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
+   texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
+   texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
+   texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
 }
 
 static void
 fetch_rgba_dxt5(const GLubyte *map,
                 GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
-   if (fetch_ext_rgba_dxt5) {
-      GLubyte tex[4];
-      fetch_ext_rgba_dxt5(rowStride, map, i, j, tex);
-      texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
-      texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
-      texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
-      texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
-   }
-   else {
-      problem("rgba_dxt5");
-   }
+   GLubyte tex[4];
+   fetch_2d_texel_rgba_dxt5(rowStride, map, i, j, tex);
+   texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
+   texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
+   texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
+   texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
 }
 
 
@@ -431,68 +304,48 @@ static void
 fetch_srgb_dxt1(const GLubyte *map,
                 GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
-   if (fetch_ext_rgb_dxt1) {
-      GLubyte tex[4];
-      fetch_ext_rgb_dxt1(rowStride, map, i, j, tex);
-      texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
-      texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
-      texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
-      texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
-   }
-   else {
-      problem("srgb_dxt1");
-   }
+   GLubyte tex[4];
+   fetch_2d_texel_rgb_dxt1(rowStride, map, i, j, tex);
+   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
+   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
+   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
+   texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
 }
 
 static void
 fetch_srgba_dxt1(const GLubyte *map,
                  GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
-   if (fetch_ext_rgba_dxt1) {
-      GLubyte tex[4];
-      fetch_ext_rgba_dxt1(rowStride, map, i, j, tex);
-      texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
-      texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
-      texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
-      texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
-   }
-   else {
-      problem("srgba_dxt1");
-   }
+   GLubyte tex[4];
+   fetch_2d_texel_rgba_dxt1(rowStride, map, i, j, tex);
+   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
+   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
+   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
+   texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
 }
 
 static void
 fetch_srgba_dxt3(const GLubyte *map,
                  GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
-   if (fetch_ext_rgba_dxt3) {
-      GLubyte tex[4];
-      fetch_ext_rgba_dxt3(rowStride, map, i, j, tex);
-      texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
-      texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
-      texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
-      texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
-   }
-   else {
-      problem("srgba_dxt3");
-   }
+   GLubyte tex[4];
+   fetch_2d_texel_rgba_dxt3(rowStride, map, i, j, tex);
+   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
+   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
+   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
+   texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
 }
 
 static void
 fetch_srgba_dxt5(const GLubyte *map,
                  GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
-   if (fetch_ext_rgba_dxt5) {
-      GLubyte tex[4];
-      fetch_ext_rgba_dxt5(rowStride, map, i, j, tex);
-      texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
-      texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
-      texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
-      texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
-   }
-   else {
-      problem("srgba_dxt5");
-   }
+   GLubyte tex[4];
+   fetch_2d_texel_rgba_dxt5(rowStride, map, i, j, tex);
+   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
+   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
+   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
+   texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
 }
 
 
diff --git a/src/mesa/main/texcompress_s3tc.h b/src/mesa/main/texcompress_s3tc.h
index 438b71fe33..0dbb5fc537 100644
--- a/src/mesa/main/texcompress_s3tc.h
+++ b/src/mesa/main/texcompress_s3tc.h
@@ -44,9 +44,6 @@ extern GLboolean
 _mesa_texstore_rgba_dxt5(TEXSTORE_PARAMS);
 
 
-extern void
-_mesa_init_texture_s3tc(struct gl_context *ctx);
-
 extern compressed_fetch_func
 _mesa_get_dxt_fetch_func(mesa_format format);
 
diff --git a/src/mesa/main/texcompress_s3tc_tmp.h b/src/mesa/main/texcompress_s3tc_tmp.h
new file mode 100644
index 0000000000..61630f2475
--- /dev/null
+++ b/src/mesa/main/texcompress_s3tc_tmp.h
@@ -0,0 +1,989 @@
+/*
+ * libtxc_dxtn
+ * Version:  1.0
+ *
+ * Copyright (C) 2004  Roland Scheidegger   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#else
+#include <GL/gl.h>
+#endif
+
+typedef GLubyte GLchan;
+#define UBYTE_TO_CHAN(b)  (b)
+#define CHAN_MAX 255
+#define RCOMP 0
+#define GCOMP 1
+#define BCOMP 2
+#define ACOMP 3
+
+#define EXP5TO8R(packedcol)					\
+   ((((packedcol) >> 8) & 0xf8) | (((packedcol) >> 13) & 0x7))
+
+#define EXP6TO8G(packedcol)					\
+   ((((packedcol) >> 3) & 0xfc) | (((packedcol) >>  9) & 0x3))
+
+#define EXP5TO8B(packedcol)					\
+   ((((packedcol) << 3) & 0xf8) | (((packedcol) >>  2) & 0x7))
+
+#define EXP4TO8(col)						\
+   ((col) | ((col) << 4))
+
+/* inefficient. To be efficient, it would be necessary to decode 16 pixels at once */
+
+static void dxt135_decode_imageblock ( const GLubyte *img_block_src,
+                         GLint i, GLint j, GLuint dxt_type, GLvoid *texel ) {
+   GLchan *rgba = (GLchan *) texel;
+   const GLushort color0 = img_block_src[0] | (img_block_src[1] << 8);
+   const GLushort color1 = img_block_src[2] | (img_block_src[3] << 8);
+   const GLuint bits = img_block_src[4] | (img_block_src[5] << 8) |
+      (img_block_src[6] << 16) | (img_block_src[7] << 24);
+   /* What about big/little endian? */
+   GLubyte bit_pos = 2 * (j * 4 + i) ;
+   GLubyte code = (GLubyte) ((bits >> bit_pos) & 3);
+
+   rgba[ACOMP] = CHAN_MAX;
+   switch (code) {
+   case 0:
+      rgba[RCOMP] = UBYTE_TO_CHAN( EXP5TO8R(color0) );
+      rgba[GCOMP] = UBYTE_TO_CHAN( EXP6TO8G(color0) );
+      rgba[BCOMP] = UBYTE_TO_CHAN( EXP5TO8B(color0) );
+      break;
+   case 1:
+      rgba[RCOMP] = UBYTE_TO_CHAN( EXP5TO8R(color1) );
+      rgba[GCOMP] = UBYTE_TO_CHAN( EXP6TO8G(color1) );
+      rgba[BCOMP] = UBYTE_TO_CHAN( EXP5TO8B(color1) );
+      break;
+   case 2:
+      if ((dxt_type > 1) || (color0 > color1)) {
+         rgba[RCOMP] = UBYTE_TO_CHAN( ((EXP5TO8R(color0) * 2 + EXP5TO8R(color1)) / 3) );
+         rgba[GCOMP] = UBYTE_TO_CHAN( ((EXP6TO8G(color0) * 2 + EXP6TO8G(color1)) / 3) );
+         rgba[BCOMP] = UBYTE_TO_CHAN( ((EXP5TO8B(color0) * 2 + EXP5TO8B(color1)) / 3) );
+      }
+      else {
+         rgba[RCOMP] = UBYTE_TO_CHAN( ((EXP5TO8R(color0) + EXP5TO8R(color1)) / 2) );
+         rgba[GCOMP] = UBYTE_TO_CHAN( ((EXP6TO8G(color0) + EXP6TO8G(color1)) / 2) );
+         rgba[BCOMP] = UBYTE_TO_CHAN( ((EXP5TO8B(color0) + EXP5TO8B(color1)) / 2) );
+      }
+      break;
+   case 3:
+      if ((dxt_type > 1) || (color0 > color1)) {
+         rgba[RCOMP] = UBYTE_TO_CHAN( ((EXP5TO8R(color0) + EXP5TO8R(color1) * 2) / 3) );
+         rgba[GCOMP] = UBYTE_TO_CHAN( ((EXP6TO8G(color0) + EXP6TO8G(color1) * 2) / 3) );
+         rgba[BCOMP] = UBYTE_TO_CHAN( ((EXP5TO8B(color0) + EXP5TO8B(color1) * 2) / 3) );
+      }
+      else {
+         rgba[RCOMP] = 0;
+         rgba[GCOMP] = 0;
+         rgba[BCOMP] = 0;
+         if (dxt_type == 1) rgba[ACOMP] = UBYTE_TO_CHAN(0);
+      }
+      break;
+   default:
+   /* CANNOT happen (I hope) */
+      break;
+   }
+}
+
+
+static void fetch_2d_texel_rgb_dxt1(GLint srcRowStride, const GLubyte *pixdata,
+                         GLint i, GLint j, GLvoid *texel)
+{
+   /* Extract the (i,j) pixel from pixdata and return it
+    * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
+    */
+
+   const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8);
+   dxt135_decode_imageblock(blksrc, (i&3), (j&3), 0, texel);
+}
+
+
+static void fetch_2d_texel_rgba_dxt1(GLint srcRowStride, const GLubyte *pixdata,
+                         GLint i, GLint j, GLvoid *texel)
+{
+   /* Extract the (i,j) pixel from pixdata and return it
+    * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
+    */
+
+   const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8);
+   dxt135_decode_imageblock(blksrc, (i&3), (j&3), 1, texel);
+}
+
+static void fetch_2d_texel_rgba_dxt3(GLint srcRowStride, const GLubyte *pixdata,
+                         GLint i, GLint j, GLvoid *texel) {
+
+   /* Extract the (i,j) pixel from pixdata and return it
+    * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
+    */
+
+   GLchan *rgba = (GLchan *) texel;
+   const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 16);
+   const GLubyte anibble = (blksrc[((j&3) * 4 + (i&3)) / 2] >> (4 * (i&1))) & 0xf;
+   dxt135_decode_imageblock(blksrc + 8, (i&3), (j&3), 2, texel);
+   rgba[ACOMP] = UBYTE_TO_CHAN( (GLubyte)(EXP4TO8(anibble)) );
+}
+
+static void fetch_2d_texel_rgba_dxt5(GLint srcRowStride, const GLubyte *pixdata,
+                         GLint i, GLint j, GLvoid *texel) {
+
+   /* Extract the (i,j) pixel from pixdata and return it
+    * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
+    */
+
+   GLchan *rgba = (GLchan *) texel;
+   const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 16);
+   const GLubyte alpha0 = blksrc[0];
+   const GLubyte alpha1 = blksrc[1];
+   const GLubyte bit_pos = ((j&3) * 4 + (i&3)) * 3;
+   const GLubyte acodelow = blksrc[2 + bit_pos / 8];
+   const GLubyte acodehigh = blksrc[3 + bit_pos / 8];
+   const GLubyte code = (acodelow >> (bit_pos & 0x7) |
+      (acodehigh  << (8 - (bit_pos & 0x7)))) & 0x7;
+   dxt135_decode_imageblock(blksrc + 8, (i&3), (j&3), 2, texel);
+   if (code == 0)
+      rgba[ACOMP] = UBYTE_TO_CHAN( alpha0 );
+   else if (code == 1)
+      rgba[ACOMP] = UBYTE_TO_CHAN( alpha1 );
+   else if (alpha0 > alpha1)
+      rgba[ACOMP] = UBYTE_TO_CHAN( ((alpha0 * (8 - code) + (alpha1 * (code - 1))) / 7) );
+   else if (code < 6)
+      rgba[ACOMP] = UBYTE_TO_CHAN( ((alpha0 * (6 - code) + (alpha1 * (code - 1))) / 5) );
+   else if (code == 6)
+      rgba[ACOMP] = 0;
+   else
+      rgba[ACOMP] = CHAN_MAX;
+}
+
+
+/* weights used for error function, basically weights (unsquared 2/4/1) according to rgb->luminance conversion
+   not sure if this really reflects visual perception */
+#define REDWEIGHT 4
+#define GREENWEIGHT 16
+#define BLUEWEIGHT 1
+
+#define ALPHACUT 127
+
+static void fancybasecolorsearch( GLubyte *blkaddr, GLubyte srccolors[4][4][4], GLubyte *bestcolor[2],
+                           GLint numxpixels, GLint numypixels, GLint type, GLboolean haveAlpha)
+{
+   /* use same luminance-weighted distance metric to determine encoding as for finding the base colors */
+
+   /* TODO could also try to find a better encoding for the 3-color-encoding type, this really should be done
+      if it's rgba_dxt1 and we have alpha in the block, currently even values which will be mapped to black
+      due to their alpha value will influence the result */
+   GLint i, j, colors, z;
+   GLuint pixerror, pixerrorred, pixerrorgreen, pixerrorblue, pixerrorbest;
+   GLint colordist, blockerrlin[2][3];
+   GLubyte nrcolor[2];
+   GLint pixerrorcolorbest[3];
+   GLubyte enc = 0;
+   GLubyte cv[4][4];
+   GLubyte testcolor[2][3];
+
+/*   fprintf(stderr, "color begin 0 r/g/b %d/%d/%d, 1 r/g/b %d/%d/%d\n",
+      bestcolor[0][0], bestcolor[0][1], bestcolor[0][2], bestcolor[1][0], bestcolor[1][1], bestcolor[1][2]);*/
+   if (((bestcolor[0][0] & 0xf8) << 8 | (bestcolor[0][1] & 0xfc) << 3 | bestcolor[0][2] >> 3) <
+      ((bestcolor[1][0] & 0xf8) << 8 | (bestcolor[1][1] & 0xfc) << 3 | bestcolor[1][2] >> 3)) {
+      testcolor[0][0] = bestcolor[0][0];
+      testcolor[0][1] = bestcolor[0][1];
+      testcolor[0][2] = bestcolor[0][2];
+      testcolor[1][0] = bestcolor[1][0];
+      testcolor[1][1] = bestcolor[1][1];
+      testcolor[1][2] = bestcolor[1][2];
+   }
+   else {
+      testcolor[1][0] = bestcolor[0][0];
+      testcolor[1][1] = bestcolor[0][1];
+      testcolor[1][2] = bestcolor[0][2];
+      testcolor[0][0] = bestcolor[1][0];
+      testcolor[0][1] = bestcolor[1][1];
+      testcolor[0][2] = bestcolor[1][2];
+   }
+
+   for (i = 0; i < 3; i ++) {
+      cv[0][i] = testcolor[0][i];
+      cv[1][i] = testcolor[1][i];
+      cv[2][i] = (testcolor[0][i] * 2 + testcolor[1][i]) / 3;
+      cv[3][i] = (testcolor[0][i] + testcolor[1][i] * 2) / 3;
+   }
+
+   blockerrlin[0][0] = 0;
+   blockerrlin[0][1] = 0;
+   blockerrlin[0][2] = 0;
+   blockerrlin[1][0] = 0;
+   blockerrlin[1][1] = 0;
+   blockerrlin[1][2] = 0;
+
+   nrcolor[0] = 0;
+   nrcolor[1] = 0;
+
+   for (j = 0; j < numypixels; j++) {
+      for (i = 0; i < numxpixels; i++) {
+         pixerrorbest = 0xffffffff;
+         for (colors = 0; colors < 4; colors++) {
+            colordist = srccolors[j][i][0] - (cv[colors][0]);
+            pixerror = colordist * colordist * REDWEIGHT;
+            pixerrorred = colordist;
+            colordist = srccolors[j][i][1] - (cv[colors][1]);
+            pixerror += colordist * colordist * GREENWEIGHT;
+            pixerrorgreen = colordist;
+            colordist = srccolors[j][i][2] - (cv[colors][2]);
+            pixerror += colordist * colordist * BLUEWEIGHT;
+            pixerrorblue = colordist;
+            if (pixerror < pixerrorbest) {
+               enc = colors;
+               pixerrorbest = pixerror;
+               pixerrorcolorbest[0] = pixerrorred;
+               pixerrorcolorbest[1] = pixerrorgreen;
+               pixerrorcolorbest[2] = pixerrorblue;
+            }
+         }
+         if (enc == 0) {
+            for (z = 0; z < 3; z++) {
+               blockerrlin[0][z] += 3 * pixerrorcolorbest[z];
+            }
+            nrcolor[0] += 3;
+         }
+         else if (enc == 2) {
+            for (z = 0; z < 3; z++) {
+               blockerrlin[0][z] += 2 * pixerrorcolorbest[z];
+            }
+            nrcolor[0] += 2;
+            for (z = 0; z < 3; z++) {
+               blockerrlin[1][z] += 1 * pixerrorcolorbest[z];
+            }
+            nrcolor[1] += 1;
+         }
+         else if (enc == 3) {
+            for (z = 0; z < 3; z++) {
+               blockerrlin[0][z] += 1 * pixerrorcolorbest[z];
+            }
+            nrcolor[0] += 1;
+            for (z = 0; z < 3; z++) {
+               blockerrlin[1][z] += 2 * pixerrorcolorbest[z];
+            }
+            nrcolor[1] += 2;
+         }
+         else if (enc == 1) {
+            for (z = 0; z < 3; z++) {
+               blockerrlin[1][z] += 3 * pixerrorcolorbest[z];
+            }
+            nrcolor[1] += 3;
+         }
+      }
+   }
+   if (nrcolor[0] == 0) nrcolor[0] = 1;
+   if (nrcolor[1] == 0) nrcolor[1] = 1;
+   for (j = 0; j < 2; j++) {
+      for (i = 0; i < 3; i++) {
+	 GLint newvalue = testcolor[j][i] + blockerrlin[j][i] / nrcolor[j];
+	 if (newvalue <= 0)
+	    testcolor[j][i] = 0;
+	 else if (newvalue >= 255)
+	    testcolor[j][i] = 255;
+	 else testcolor[j][i] = newvalue;
+      }
+   }
+
+   if ((abs(testcolor[0][0] - testcolor[1][0]) < 8) &&
+       (abs(testcolor[0][1] - testcolor[1][1]) < 4) &&
+       (abs(testcolor[0][2] - testcolor[1][2]) < 8)) {
+       /* both colors are so close they might get encoded as the same 16bit values */
+      GLubyte coldiffred, coldiffgreen, coldiffblue, coldiffmax, factor, ind0, ind1;
+
+      coldiffred = abs(testcolor[0][0] - testcolor[1][0]);
+      coldiffgreen = 2 * abs(testcolor[0][1] - testcolor[1][1]);
+      coldiffblue = abs(testcolor[0][2] - testcolor[1][2]);
+      coldiffmax = coldiffred;
+      if (coldiffmax < coldiffgreen) coldiffmax = coldiffgreen;
+      if (coldiffmax < coldiffblue) coldiffmax = coldiffblue;
+      if (coldiffmax > 0) {
+         if (coldiffmax > 4) factor = 2;
+         else if (coldiffmax > 2) factor = 3;
+         else factor = 4;
+         /* Won't do much if the color value is near 255... */
+         /* argh so many ifs */
+         if (testcolor[1][1] >= testcolor[0][1]) {
+            ind1 = 1; ind0 = 0;
+         }
+         else {
+            ind1 = 0; ind0 = 1;
+         }
+         if ((testcolor[ind1][1] + factor * coldiffgreen) <= 255)
+            testcolor[ind1][1] += factor * coldiffgreen;
+         else testcolor[ind1][1] = 255;
+         if ((testcolor[ind1][0] - testcolor[ind0][1]) > 0) {
+            if ((testcolor[ind1][0] + factor * coldiffred) <= 255)
+               testcolor[ind1][0] += factor * coldiffred;
+            else testcolor[ind1][0] = 255;
+         }
+         else {
+            if ((testcolor[ind0][0] + factor * coldiffred) <= 255)
+               testcolor[ind0][0] += factor * coldiffred;
+            else testcolor[ind0][0] = 255;
+         }
+         if ((testcolor[ind1][2] - testcolor[ind0][2]) > 0) {
+            if ((testcolor[ind1][2] + factor * coldiffblue) <= 255)
+               testcolor[ind1][2] += factor * coldiffblue;
+            else testcolor[ind1][2] = 255;
+         }
+         else {
+            if ((testcolor[ind0][2] + factor * coldiffblue) <= 255)
+               testcolor[ind0][2] += factor * coldiffblue;
+            else testcolor[ind0][2] = 255;
+         }
+      }
+   }
+
+   if (((testcolor[0][0] & 0xf8) << 8 | (testcolor[0][1] & 0xfc) << 3 | testcolor[0][2] >> 3) <
+      ((testcolor[1][0] & 0xf8) << 8 | (testcolor[1][1] & 0xfc) << 3 | testcolor[1][2]) >> 3) {
+      for (i = 0; i < 3; i++) {
+         bestcolor[0][i] = testcolor[0][i];
+         bestcolor[1][i] = testcolor[1][i];
+      }
+   }
+   else {
+      for (i = 0; i < 3; i++) {
+         bestcolor[0][i] = testcolor[1][i];
+         bestcolor[1][i] = testcolor[0][i];
+      }
+   }
+
+/*     fprintf(stderr, "color end 0 r/g/b %d/%d/%d, 1 r/g/b %d/%d/%d\n",
+     bestcolor[0][0], bestcolor[0][1], bestcolor[0][2], bestcolor[1][0], bestcolor[1][1], bestcolor[1][2]);*/
+}
+
+
+
+static void storedxtencodedblock( GLubyte *blkaddr, GLubyte srccolors[4][4][4], GLubyte *bestcolor[2],
+                           GLint numxpixels, GLint numypixels, GLuint type, GLboolean haveAlpha)
+{
+   /* use same luminance-weighted distance metric to determine encoding as for finding the base colors */
+
+   GLint i, j, colors;
+   GLuint testerror, testerror2, pixerror, pixerrorbest;
+   GLint colordist;
+   GLushort color0, color1, tempcolor;
+   GLuint bits = 0, bits2 = 0;
+   GLubyte *colorptr;
+   GLubyte enc = 0;
+   GLubyte cv[4][4];
+
+   bestcolor[0][0] = bestcolor[0][0] & 0xf8;
+   bestcolor[0][1] = bestcolor[0][1] & 0xfc;
+   bestcolor[0][2] = bestcolor[0][2] & 0xf8;
+   bestcolor[1][0] = bestcolor[1][0] & 0xf8;
+   bestcolor[1][1] = bestcolor[1][1] & 0xfc;
+   bestcolor[1][2] = bestcolor[1][2] & 0xf8;
+
+   color0 = bestcolor[0][0] << 8 | bestcolor[0][1] << 3 | bestcolor[0][2] >> 3;
+   color1 = bestcolor[1][0] << 8 | bestcolor[1][1] << 3 | bestcolor[1][2] >> 3;
+   if (color0 < color1) {
+      tempcolor = color0; color0 = color1; color1 = tempcolor;
+      colorptr = bestcolor[0]; bestcolor[0] = bestcolor[1]; bestcolor[1] = colorptr;
+   }
+
+
+   for (i = 0; i < 3; i++) {
+      cv[0][i] = bestcolor[0][i];
+      cv[1][i] = bestcolor[1][i];
+      cv[2][i] = (bestcolor[0][i] * 2 + bestcolor[1][i]) / 3;
+      cv[3][i] = (bestcolor[0][i] + bestcolor[1][i] * 2) / 3;
+   }
+
+   testerror = 0;
+   for (j = 0; j < numypixels; j++) {
+      for (i = 0; i < numxpixels; i++) {
+         pixerrorbest = 0xffffffff;
+         for (colors = 0; colors < 4; colors++) {
+            colordist = srccolors[j][i][0] - cv[colors][0];
+            pixerror = colordist * colordist * REDWEIGHT;
+            colordist = srccolors[j][i][1] - cv[colors][1];
+            pixerror += colordist * colordist * GREENWEIGHT;
+            colordist = srccolors[j][i][2] - cv[colors][2];
+            pixerror += colordist * colordist * BLUEWEIGHT;
+            if (pixerror < pixerrorbest) {
+               pixerrorbest = pixerror;
+               enc = colors;
+            }
+         }
+         testerror += pixerrorbest;
+         bits |= enc << (2 * (j * 4 + i));
+      }
+   }
+   /* some hw might disagree but actually decoding should always use 4-color encoding
+      for non-dxt1 formats */
+   if (type == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || type == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) {
+      for (i = 0; i < 3; i++) {
+         cv[2][i] = (bestcolor[0][i] + bestcolor[1][i]) / 2;
+         /* this isn't used. Looks like the black color constant can only be used
+            with RGB_DXT1 if I read the spec correctly (note though that the radeon gpu disagrees,
+            it will decode 3 to black even with DXT3/5), and due to how the color searching works
+            it won't get used even then */
+         cv[3][i] = 0;
+      }
+      testerror2 = 0;
+      for (j = 0; j < numypixels; j++) {
+         for (i = 0; i < numxpixels; i++) {
+            pixerrorbest = 0xffffffff;
+            if ((type == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) && (srccolors[j][i][3] <= ALPHACUT)) {
+               enc = 3;
+               pixerrorbest = 0; /* don't calculate error */
+            }
+            else {
+               /* we're calculating the same what we have done already for colors 0-1 above... */
+               for (colors = 0; colors < 3; colors++) {
+                  colordist = srccolors[j][i][0] - cv[colors][0];
+                  pixerror = colordist * colordist * REDWEIGHT;
+                  colordist = srccolors[j][i][1] - cv[colors][1];
+                  pixerror += colordist * colordist * GREENWEIGHT;
+                  colordist = srccolors[j][i][2] - cv[colors][2];
+                  pixerror += colordist * colordist * BLUEWEIGHT;
+                  if (pixerror < pixerrorbest) {
+                     pixerrorbest = pixerror;
+                     /* need to exchange colors later */
+                     if (colors > 1) enc = colors;
+                     else enc = colors ^ 1;
+                  }
+               }
+            }
+            testerror2 += pixerrorbest;
+            bits2 |= enc << (2 * (j * 4 + i));
+         }
+      }
+   } else {
+      testerror2 = 0xffffffff;
+   }
+
+   /* finally we're finished, write back colors and bits */
+   if ((testerror > testerror2) || (haveAlpha)) {
+      *blkaddr++ = color1 & 0xff;
+      *blkaddr++ = color1 >> 8;
+      *blkaddr++ = color0 & 0xff;
+      *blkaddr++ = color0 >> 8;
+      *blkaddr++ = bits2 & 0xff;
+      *blkaddr++ = ( bits2 >> 8) & 0xff;
+      *blkaddr++ = ( bits2 >> 16) & 0xff;
+      *blkaddr = bits2 >> 24;
+   }
+   else {
+      *blkaddr++ = color0 & 0xff;
+      *blkaddr++ = color0 >> 8;
+      *blkaddr++ = color1 & 0xff;
+      *blkaddr++ = color1 >> 8;
+      *blkaddr++ = bits & 0xff;
+      *blkaddr++ = ( bits >> 8) & 0xff;
+      *blkaddr++ = ( bits >> 16) & 0xff;
+      *blkaddr = bits >> 24;
+   }
+}
+
+static void encodedxtcolorblockfaster( GLubyte *blkaddr, GLubyte srccolors[4][4][4],
+                         GLint numxpixels, GLint numypixels, GLuint type )
+{
+/* simplistic approach. We need two base colors, simply use the "highest" and the "lowest" color
+   present in the picture as base colors */
+
+   /* define lowest and highest color as shortest and longest vector to 0/0/0, though the
+      vectors are weighted similar to their importance in rgb-luminance conversion
+      doesn't work too well though...
+      This seems to be a rather difficult problem */
+
+   GLubyte *bestcolor[2];
+   GLubyte basecolors[2][3];
+   GLubyte i, j;
+   GLuint lowcv, highcv, testcv;
+   GLboolean haveAlpha = GL_FALSE;
+
+   lowcv = highcv = srccolors[0][0][0] * srccolors[0][0][0] * REDWEIGHT +
+                          srccolors[0][0][1] * srccolors[0][0][1] * GREENWEIGHT +
+                          srccolors[0][0][2] * srccolors[0][0][2] * BLUEWEIGHT;
+   bestcolor[0] = bestcolor[1] = srccolors[0][0];
+   for (j = 0; j < numypixels; j++) {
+      for (i = 0; i < numxpixels; i++) {
+         /* don't use this as a base color if the pixel will get black/transparent anyway */
+         if ((type != GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) || (srccolors[j][i][3] > ALPHACUT)) {
+            testcv = srccolors[j][i][0] * srccolors[j][i][0] * REDWEIGHT +
+                     srccolors[j][i][1] * srccolors[j][i][1] * GREENWEIGHT +
+                     srccolors[j][i][2] * srccolors[j][i][2] * BLUEWEIGHT;
+            if (testcv > highcv) {
+               highcv = testcv;
+               bestcolor[1] = srccolors[j][i];
+            }
+            else if (testcv < lowcv) {
+               lowcv = testcv;
+               bestcolor[0] = srccolors[j][i];
+            }
+         }
+         else haveAlpha = GL_TRUE;
+      }
+   }
+   /* make sure the original color values won't get touched... */
+   for (j = 0; j < 2; j++) {
+      for (i = 0; i < 3; i++) {
+         basecolors[j][i] = bestcolor[j][i];
+      }
+   }
+   bestcolor[0] = basecolors[0];
+   bestcolor[1] = basecolors[1];
+
+   /* try to find better base colors */
+   fancybasecolorsearch(blkaddr, srccolors, bestcolor, numxpixels, numypixels, type, haveAlpha);
+   /* find the best encoding for these colors, and store the result */
+   storedxtencodedblock(blkaddr, srccolors, bestcolor, numxpixels, numypixels, type, haveAlpha);
+}
+
+static void writedxt5encodedalphablock( GLubyte *blkaddr, GLubyte alphabase1, GLubyte alphabase2,
+                         GLubyte alphaenc[16])
+{
+   *blkaddr++ = alphabase1;
+   *blkaddr++ = alphabase2;
+   *blkaddr++ = alphaenc[0] | (alphaenc[1] << 3) | ((alphaenc[2] & 3) << 6);
+   *blkaddr++ = (alphaenc[2] >> 2) | (alphaenc[3] << 1) | (alphaenc[4] << 4) | ((alphaenc[5] & 1) << 7);
+   *blkaddr++ = (alphaenc[5] >> 1) | (alphaenc[6] << 2) | (alphaenc[7] << 5);
+   *blkaddr++ = alphaenc[8] | (alphaenc[9] << 3) | ((alphaenc[10] & 3) << 6);
+   *blkaddr++ = (alphaenc[10] >> 2) | (alphaenc[11] << 1) | (alphaenc[12] << 4) | ((alphaenc[13] & 1) << 7);
+   *blkaddr++ = (alphaenc[13] >> 1) | (alphaenc[14] << 2) | (alphaenc[15] << 5);
+}
+
+static void encodedxt5alpha(GLubyte *blkaddr, GLubyte srccolors[4][4][4],
+                            GLint numxpixels, GLint numypixels)
+{
+   GLubyte alphabase[2], alphause[2];
+   GLshort alphatest[2];
+   GLuint alphablockerror1, alphablockerror2, alphablockerror3;
+   GLubyte i, j, aindex, acutValues[7];
+   GLubyte alphaenc1[16], alphaenc2[16], alphaenc3[16];
+   GLboolean alphaabsmin = GL_FALSE;
+   GLboolean alphaabsmax = GL_FALSE;
+   GLshort alphadist;
+
+   /* find lowest and highest alpha value in block, alphabase[0] lowest, alphabase[1] highest */
+   alphabase[0] = 0xff; alphabase[1] = 0x0;
+   for (j = 0; j < numypixels; j++) {
+      for (i = 0; i < numxpixels; i++) {
+         if (srccolors[j][i][3] == 0)
+            alphaabsmin = GL_TRUE;
+         else if (srccolors[j][i][3] == 255)
+            alphaabsmax = GL_TRUE;
+         else {
+            if (srccolors[j][i][3] > alphabase[1])
+               alphabase[1] = srccolors[j][i][3];
+            if (srccolors[j][i][3] < alphabase[0])
+               alphabase[0] = srccolors[j][i][3];
+         }
+      }
+   }
+
+
+   if ((alphabase[0] > alphabase[1]) && !(alphaabsmin && alphaabsmax)) { /* one color, either max or min */
+      /* shortcut here since it is a very common case (and also avoids later problems) */
+      /* || (alphabase[0] == alphabase[1] && !alphaabsmin && !alphaabsmax) */
+      /* could also thest for alpha0 == alpha1 (and not min/max), but probably not common, so don't bother */
+
+      *blkaddr++ = srccolors[0][0][3];
+      blkaddr++;
+      *blkaddr++ = 0;
+      *blkaddr++ = 0;
+      *blkaddr++ = 0;
+      *blkaddr++ = 0;
+      *blkaddr++ = 0;
+      *blkaddr++ = 0;
+/*      fprintf(stderr, "enc0 used\n");*/
+      return;
+   }
+
+   /* find best encoding for alpha0 > alpha1 */
+   /* it's possible this encoding is better even if both alphaabsmin and alphaabsmax are true */
+   alphablockerror1 = 0x0;
+   alphablockerror2 = 0xffffffff;
+   alphablockerror3 = 0xffffffff;
+   if (alphaabsmin) alphause[0] = 0;
+   else alphause[0] = alphabase[0];
+   if (alphaabsmax) alphause[1] = 255;
+   else alphause[1] = alphabase[1];
+   /* calculate the 7 cut values, just the middle between 2 of the computed alpha values */
+   for (aindex = 0; aindex < 7; aindex++) {
+      /* don't forget here is always rounded down */
+      acutValues[aindex] = (alphause[0] * (2*aindex + 1) + alphause[1] * (14 - (2*aindex + 1))) / 14;
+   }
+
+   for (j = 0; j < numypixels; j++) {
+      for (i = 0; i < numxpixels; i++) {
+         /* maybe it's overkill to have the most complicated calculation just for the error
+            calculation which we only need to figure out if encoding1 or encoding2 is better... */
+         if (srccolors[j][i][3] > acutValues[0]) {
+            alphaenc1[4*j + i] = 0;
+            alphadist = srccolors[j][i][3] - alphause[1];
+         }
+         else if (srccolors[j][i][3] > acutValues[1]) {
+            alphaenc1[4*j + i] = 2;
+            alphadist = srccolors[j][i][3] - (alphause[1] * 6 + alphause[0] * 1) / 7;
+         }
+         else if (srccolors[j][i][3] > acutValues[2]) {
+            alphaenc1[4*j + i] = 3;
+            alphadist = srccolors[j][i][3] - (alphause[1] * 5 + alphause[0] * 2) / 7;
+         }
+         else if (srccolors[j][i][3] > acutValues[3]) {
+            alphaenc1[4*j + i] = 4;
+            alphadist = srccolors[j][i][3] - (alphause[1] * 4 + alphause[0] * 3) / 7;
+         }
+         else if (srccolors[j][i][3] > acutValues[4]) {
+            alphaenc1[4*j + i] = 5;
+            alphadist = srccolors[j][i][3] - (alphause[1] * 3 + alphause[0] * 4) / 7;
+         }
+         else if (srccolors[j][i][3] > acutValues[5]) {
+            alphaenc1[4*j + i] = 6;
+            alphadist = srccolors[j][i][3] - (alphause[1] * 2 + alphause[0] * 5) / 7;
+         }
+         else if (srccolors[j][i][3] > acutValues[6]) {
+            alphaenc1[4*j + i] = 7;
+            alphadist = srccolors[j][i][3] - (alphause[1] * 1 + alphause[0] * 6) / 7;
+         }
+         else {
+            alphaenc1[4*j + i] = 1;
+            alphadist = srccolors[j][i][3] - alphause[0];
+         }
+         alphablockerror1 += alphadist * alphadist;
+      }
+   }
+/*      for (i = 0; i < 16; i++) {
+         fprintf(stderr, "%d ", alphaenc1[i]);
+      }
+      fprintf(stderr, "cutVals ");
+      for (i = 0; i < 8; i++) {
+         fprintf(stderr, "%d ", acutValues[i]);
+      }
+      fprintf(stderr, "srcVals ");
+      for (j = 0; j < numypixels; j++)
+         for (i = 0; i < numxpixels; i++) {
+            fprintf(stderr, "%d ", srccolors[j][i][3]);
+         }
+
+      fprintf(stderr, "\n");
+   }*/
+   /* it's not very likely this encoding is better if both alphaabsmin and alphaabsmax
+      are false but try it anyway */
+   if (alphablockerror1 >= 32) {
+
+      /* don't bother if encoding is already very good, this condition should also imply
+      we have valid alphabase colors which we absolutely need (alphabase[0] <= alphabase[1]) */
+      alphablockerror2 = 0;
+      for (aindex = 0; aindex < 5; aindex++) {
+         /* don't forget here is always rounded down */
+         acutValues[aindex] = (alphabase[0] * (10 - (2*aindex + 1)) + alphabase[1] * (2*aindex + 1)) / 10;
+      }
+      for (j = 0; j < numypixels; j++) {
+         for (i = 0; i < numxpixels; i++) {
+             /* maybe it's overkill to have the most complicated calculation just for the error
+               calculation which we only need to figure out if encoding1 or encoding2 is better... */
+            if (srccolors[j][i][3] == 0) {
+               alphaenc2[4*j + i] = 6;
+               alphadist = 0;
+            }
+            else if (srccolors[j][i][3] == 255) {
+               alphaenc2[4*j + i] = 7;
+               alphadist = 0;
+            }
+            else if (srccolors[j][i][3] <= acutValues[0]) {
+               alphaenc2[4*j + i] = 0;
+               alphadist = srccolors[j][i][3] - alphabase[0];
+            }
+            else if (srccolors[j][i][3] <= acutValues[1]) {
+               alphaenc2[4*j + i] = 2;
+               alphadist = srccolors[j][i][3] - (alphabase[0] * 4 + alphabase[1] * 1) / 5;
+            }
+            else if (srccolors[j][i][3] <= acutValues[2]) {
+               alphaenc2[4*j + i] = 3;
+               alphadist = srccolors[j][i][3] - (alphabase[0] * 3 + alphabase[1] * 2) / 5;
+            }
+            else if (srccolors[j][i][3] <= acutValues[3]) {
+               alphaenc2[4*j + i] = 4;
+               alphadist = srccolors[j][i][3] - (alphabase[0] * 2 + alphabase[1] * 3) / 5;
+            }
+            else if (srccolors[j][i][3] <= acutValues[4]) {
+               alphaenc2[4*j + i] = 5;
+               alphadist = srccolors[j][i][3] - (alphabase[0] * 1 + alphabase[1] * 4) / 5;
+            }
+            else {
+               alphaenc2[4*j + i] = 1;
+               alphadist = srccolors[j][i][3] - alphabase[1];
+            }
+            alphablockerror2 += alphadist * alphadist;
+         }
+      }
+
+
+      /* skip this if the error is already very small
+         this encoding is MUCH better on average than #2 though, but expensive! */
+      if ((alphablockerror2 > 96) && (alphablockerror1 > 96)) {
+         GLshort blockerrlin1 = 0;
+         GLshort blockerrlin2 = 0;
+         GLubyte nralphainrangelow = 0;
+         GLubyte nralphainrangehigh = 0;
+         alphatest[0] = 0xff;
+         alphatest[1] = 0x0;
+         /* if we have large range it's likely there are values close to 0/255, try to map them to 0/255 */
+         for (j = 0; j < numypixels; j++) {
+            for (i = 0; i < numxpixels; i++) {
+               if ((srccolors[j][i][3] > alphatest[1]) && (srccolors[j][i][3] < (255 -(alphabase[1] - alphabase[0]) / 28)))
+                  alphatest[1] = srccolors[j][i][3];
+               if ((srccolors[j][i][3] < alphatest[0]) && (srccolors[j][i][3] > (alphabase[1] - alphabase[0]) / 28))
+                  alphatest[0] = srccolors[j][i][3];
+            }
+         }
+          /* shouldn't happen too often, don't really care about those degenerated cases */
+          if (alphatest[1] <= alphatest[0]) {
+             alphatest[0] = 1;
+             alphatest[1] = 254;
+/*             fprintf(stderr, "only 1 or 0 colors for encoding!\n");*/
+         }
+         for (aindex = 0; aindex < 5; aindex++) {
+         /* don't forget here is always rounded down */
+            acutValues[aindex] = (alphatest[0] * (10 - (2*aindex + 1)) + alphatest[1] * (2*aindex + 1)) / 10;
+         }
+
+         /* find the "average" difference between the alpha values and the next encoded value.
+            This is then used to calculate new base values.
+            Should there be some weighting, i.e. those values closer to alphatest[x] have more weight,
+            since they will see more improvement, and also because the values in the middle are somewhat
+            likely to get no improvement at all (because the base values might move in different directions)?
+            OTOH it would mean the values in the middle are even less likely to get an improvement
+         */
+         for (j = 0; j < numypixels; j++) {
+            for (i = 0; i < numxpixels; i++) {
+               if (srccolors[j][i][3] <= alphatest[0] / 2) {
+               }
+               else if (srccolors[j][i][3] > ((255 + alphatest[1]) / 2)) {
+               }
+               else if (srccolors[j][i][3] <= acutValues[0]) {
+                  blockerrlin1 += (srccolors[j][i][3] - alphatest[0]);
+                  nralphainrangelow += 1;
+               }
+               else if (srccolors[j][i][3] <= acutValues[1]) {
+                  blockerrlin1 += (srccolors[j][i][3] - (alphatest[0] * 4 + alphatest[1] * 1) / 5);
+                  blockerrlin2 += (srccolors[j][i][3] - (alphatest[0] * 4 + alphatest[1] * 1) / 5);
+                  nralphainrangelow += 1;
+                  nralphainrangehigh += 1;
+               }
+               else if (srccolors[j][i][3] <= acutValues[2]) {
+                  blockerrlin1 += (srccolors[j][i][3] - (alphatest[0] * 3 + alphatest[1] * 2) / 5);
+                  blockerrlin2 += (srccolors[j][i][3] - (alphatest[0] * 3 + alphatest[1] * 2) / 5);
+                  nralphainrangelow += 1;
+                  nralphainrangehigh += 1;
+               }
+               else if (srccolors[j][i][3] <= acutValues[3]) {
+                  blockerrlin1 += (srccolors[j][i][3] - (alphatest[0] * 2 + alphatest[1] * 3) / 5);
+                  blockerrlin2 += (srccolors[j][i][3] - (alphatest[0] * 2 + alphatest[1] * 3) / 5);
+                  nralphainrangelow += 1;
+                  nralphainrangehigh += 1;
+               }
+               else if (srccolors[j][i][3] <= acutValues[4]) {
+                  blockerrlin1 += (srccolors[j][i][3] - (alphatest[0] * 1 + alphatest[1] * 4) / 5);
+                  blockerrlin2 += (srccolors[j][i][3] - (alphatest[0] * 1 + alphatest[1] * 4) / 5);
+                  nralphainrangelow += 1;
+                  nralphainrangehigh += 1;
+                  }
+               else {
+                  blockerrlin2 += (srccolors[j][i][3] - alphatest[1]);
+                  nralphainrangehigh += 1;
+               }
+            }
+         }
+         /* shouldn't happen often, needed to avoid div by zero */
+         if (nralphainrangelow == 0) nralphainrangelow = 1;
+         if (nralphainrangehigh == 0) nralphainrangehigh = 1;
+         alphatest[0] = alphatest[0] + (blockerrlin1 / nralphainrangelow);
+/*         fprintf(stderr, "block err lin low %d, nr %d\n", blockerrlin1, nralphainrangelow);
+         fprintf(stderr, "block err lin high %d, nr %d\n", blockerrlin2, nralphainrangehigh);*/
+         /* again shouldn't really happen often... */
+         if (alphatest[0] < 0) {
+            alphatest[0] = 0;
+/*            fprintf(stderr, "adj alpha base val to 0\n");*/
+         }
+         alphatest[1] = alphatest[1] + (blockerrlin2 / nralphainrangehigh);
+         if (alphatest[1] > 255) {
+            alphatest[1] = 255;
+/*            fprintf(stderr, "adj alpha base val to 255\n");*/
+         }
+
+         alphablockerror3 = 0;
+         for (aindex = 0; aindex < 5; aindex++) {
+         /* don't forget here is always rounded down */
+            acutValues[aindex] = (alphatest[0] * (10 - (2*aindex + 1)) + alphatest[1] * (2*aindex + 1)) / 10;
+         }
+         for (j = 0; j < numypixels; j++) {
+            for (i = 0; i < numxpixels; i++) {
+                /* maybe it's overkill to have the most complicated calculation just for the error
+                  calculation which we only need to figure out if encoding1 or encoding2 is better... */
+               if (srccolors[j][i][3] <= alphatest[0] / 2) {
+                  alphaenc3[4*j + i] = 6;
+                  alphadist = srccolors[j][i][3];
+               }
+               else if (srccolors[j][i][3] > ((255 + alphatest[1]) / 2)) {
+                  alphaenc3[4*j + i] = 7;
+                  alphadist = 255 - srccolors[j][i][3];
+               }
+               else if (srccolors[j][i][3] <= acutValues[0]) {
+                  alphaenc3[4*j + i] = 0;
+                  alphadist = srccolors[j][i][3] - alphatest[0];
+               }
+               else if (srccolors[j][i][3] <= acutValues[1]) {
+                 alphaenc3[4*j + i] = 2;
+                 alphadist = srccolors[j][i][3] - (alphatest[0] * 4 + alphatest[1] * 1) / 5;
+               }
+               else if (srccolors[j][i][3] <= acutValues[2]) {
+                  alphaenc3[4*j + i] = 3;
+                  alphadist = srccolors[j][i][3] - (alphatest[0] * 3 + alphatest[1] * 2) / 5;
+               }
+               else if (srccolors[j][i][3] <= acutValues[3]) {
+                  alphaenc3[4*j + i] = 4;
+                  alphadist = srccolors[j][i][3] - (alphatest[0] * 2 + alphatest[1] * 3) / 5;
+               }
+               else if (srccolors[j][i][3] <= acutValues[4]) {
+                  alphaenc3[4*j + i] = 5;
+                  alphadist = srccolors[j][i][3] - (alphatest[0] * 1 + alphatest[1] * 4) / 5;
+               }
+               else {
+                  alphaenc3[4*j + i] = 1;
+                  alphadist = srccolors[j][i][3] - alphatest[1];
+               }
+               alphablockerror3 += alphadist * alphadist;
+            }
+         }
+      }
+   }
+  /* write the alpha values and encoding back. */
+   if ((alphablockerror1 <= alphablockerror2) && (alphablockerror1 <= alphablockerror3)) {
+/*      if (alphablockerror1 > 96) fprintf(stderr, "enc1 used, error %d\n", alphablockerror1);*/
+      writedxt5encodedalphablock( blkaddr, alphause[1], alphause[0], alphaenc1 );
+   }
+   else if (alphablockerror2 <= alphablockerror3) {
+/*      if (alphablockerror2 > 96) fprintf(stderr, "enc2 used, error %d\n", alphablockerror2);*/
+      writedxt5encodedalphablock( blkaddr, alphabase[0], alphabase[1], alphaenc2 );
+   }
+   else {
+/*      fprintf(stderr, "enc3 used, error %d\n", alphablockerror3);*/
+      writedxt5encodedalphablock( blkaddr, (GLubyte)alphatest[0], (GLubyte)alphatest[1], alphaenc3 );
+   }
+}
+
+static void extractsrccolors( GLubyte srcpixels[4][4][4], const GLchan *srcaddr,
+                         GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
+{
+   GLubyte i, j, c;
+   const GLchan *curaddr;
+   for (j = 0; j < numypixels; j++) {
+      curaddr = srcaddr + j * srcRowStride * comps;
+      for (i = 0; i < numxpixels; i++) {
+         for (c = 0; c < comps; c++) {
+            srcpixels[j][i][c] = *curaddr++ / (CHAN_MAX / 255);
+         }
+      }
+   }
+}
+
+
+static void tx_compress_dxtn(GLint srccomps, GLint width, GLint height, const GLubyte *srcPixData,
+                     GLenum destFormat, GLubyte *dest, GLint dstRowStride)
+{
+      GLubyte *blkaddr = dest;
+      GLubyte srcpixels[4][4][4];
+      const GLchan *srcaddr = srcPixData;
+      GLint numxpixels, numypixels;
+      GLint i, j;
+      GLint dstRowDiff;
+
+   switch (destFormat) {
+   case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+   case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+      /* hmm we used to get called without dstRowStride... */
+      dstRowDiff = dstRowStride >= (width * 2) ? dstRowStride - (((width + 3) & ~3) * 2) : 0;
+/*      fprintf(stderr, "dxt1 tex width %d tex height %d dstRowStride %d\n",
+              width, height, dstRowStride); */
+      for (j = 0; j < height; j += 4) {
+         if (height > j + 3) numypixels = 4;
+         else numypixels = height - j;
+         srcaddr = srcPixData + j * width * srccomps;
+         for (i = 0; i < width; i += 4) {
+            if (width > i + 3) numxpixels = 4;
+            else numxpixels = width - i;
+            extractsrccolors(srcpixels, srcaddr, width, numxpixels, numypixels, srccomps);
+            encodedxtcolorblockfaster(blkaddr, srcpixels, numxpixels, numypixels, destFormat);
+            srcaddr += srccomps * numxpixels;
+            blkaddr += 8;
+         }
+         blkaddr += dstRowDiff;
+      }
+      break;
+   case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+      dstRowDiff = dstRowStride >= (width * 4) ? dstRowStride - (((width + 3) & ~3) * 4) : 0;
+/*      fprintf(stderr, "dxt3 tex width %d tex height %d dstRowStride %d\n",
+              width, height, dstRowStride); */
+      for (j = 0; j < height; j += 4) {
+         if (height > j + 3) numypixels = 4;
+         else numypixels = height - j;
+         srcaddr = srcPixData + j * width * srccomps;
+         for (i = 0; i < width; i += 4) {
+            if (width > i + 3) numxpixels = 4;
+            else numxpixels = width - i;
+            extractsrccolors(srcpixels, srcaddr, width, numxpixels, numypixels, srccomps);
+            *blkaddr++ = (srcpixels[0][0][3] >> 4) | (srcpixels[0][1][3] & 0xf0);
+            *blkaddr++ = (srcpixels[0][2][3] >> 4) | (srcpixels[0][3][3] & 0xf0);
+            *blkaddr++ = (srcpixels[1][0][3] >> 4) | (srcpixels[1][1][3] & 0xf0);
+            *blkaddr++ = (srcpixels[1][2][3] >> 4) | (srcpixels[1][3][3] & 0xf0);
+            *blkaddr++ = (srcpixels[2][0][3] >> 4) | (srcpixels[2][1][3] & 0xf0);
+            *blkaddr++ = (srcpixels[2][2][3] >> 4) | (srcpixels[2][3][3] & 0xf0);
+            *blkaddr++ = (srcpixels[3][0][3] >> 4) | (srcpixels[3][1][3] & 0xf0);
+            *blkaddr++ = (srcpixels[3][2][3] >> 4) | (srcpixels[3][3][3] & 0xf0);
+            encodedxtcolorblockfaster(blkaddr, srcpixels, numxpixels, numypixels, destFormat);
+            srcaddr += srccomps * numxpixels;
+            blkaddr += 8;
+         }
+         blkaddr += dstRowDiff;
+      }
+      break;
+   case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+      dstRowDiff = dstRowStride >= (width * 4) ? dstRowStride - (((width + 3) & ~3) * 4) : 0;
+/*      fprintf(stderr, "dxt5 tex width %d tex height %d dstRowStride %d\n",
+              width, height, dstRowStride); */
+      for (j = 0; j < height; j += 4) {
+         if (height > j + 3) numypixels = 4;
+         else numypixels = height - j;
+         srcaddr = srcPixData + j * width * srccomps;
+         for (i = 0; i < width; i += 4) {
+            if (width > i + 3) numxpixels = 4;
+            else numxpixels = width - i;
+            extractsrccolors(srcpixels, srcaddr, width, numxpixels, numypixels, srccomps);
+            encodedxt5alpha(blkaddr, srcpixels, numxpixels, numypixels);
+            encodedxtcolorblockfaster(blkaddr + 8, srcpixels, numxpixels, numypixels, destFormat);
+            srcaddr += srccomps * numxpixels;
+            blkaddr += 16;
+         }
+         blkaddr += dstRowDiff;
+      }
+      break;
+   default:
+      assert(false);
+      return;
+   }
+}
diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c
index baa3988f0a..3f8e7a49a2 100644
--- a/src/mesa/main/texformat.c
+++ b/src/mesa/main/texformat.c
@@ -249,9 +249,7 @@ _mesa_choose_tex_format(struct gl_context *ctx, GLenum target,
        * 1D ARRAY textures in S3TC format.
        */
       if (target != GL_TEXTURE_1D && target != GL_TEXTURE_1D_ARRAY) {
-         if (ctx->Mesa_DXTn)
-            RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_DXT1);
-         RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FXT1);
+         RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_DXT1);
       }
       RETURN_IF_SUPPORTED(MESA_FORMAT_BGR_UNORM8);
       RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8X8_UNORM);
@@ -260,9 +258,7 @@ _mesa_choose_tex_format(struct gl_context *ctx, GLenum target,
    case GL_COMPRESSED_RGBA_ARB:
       /* We don't use texture compression for 1D and 1D array textures. */
       if (target != GL_TEXTURE_1D && target != GL_TEXTURE_1D_ARRAY) {
-         if (ctx->Mesa_DXTn)
-            RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_DXT3); /* Not rgba_dxt1, see spec */
-         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FXT1);
+         RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_DXT3); /* Not rgba_dxt1, see spec */
       }
       RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_UNORM);
       RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM);
@@ -502,15 +498,13 @@ _mesa_choose_tex_format(struct gl_context *ctx, GLenum target,
       RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB);
       break;
    case GL_COMPRESSED_SRGB_EXT:
-      if (ctx->Mesa_DXTn)
-         RETURN_IF_SUPPORTED(MESA_FORMAT_SRGB_DXT1);
+      RETURN_IF_SUPPORTED(MESA_FORMAT_SRGB_DXT1);
       RETURN_IF_SUPPORTED(MESA_FORMAT_BGR_SRGB8);
       RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB);
       RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB);
       break;
    case GL_COMPRESSED_SRGB_ALPHA_EXT:
-      if (ctx->Mesa_DXTn)
-         RETURN_IF_SUPPORTED(MESA_FORMAT_SRGBA_DXT3); /* Not srgba_dxt1, see spec */
+      RETURN_IF_SUPPORTED(MESA_FORMAT_SRGBA_DXT3); /* Not srgba_dxt1, see spec */
       RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SRGB);
       RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB);
       RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB);
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 5509d808cd..1d6da393c2 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -2765,38 +2765,6 @@ _mesa_choose_texture_format(struct gl_context *ctx,
       }
    }
 
-   /* If the application requested compression to an S3TC format but we don't
-    * have the DXTn library, force a generic compressed format instead.
-    */
-   if (internalFormat != format && format != GL_NONE) {
-      const GLenum before = internalFormat;
-
-      switch (internalFormat) {
-      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-         if (!ctx->Mesa_DXTn)
-            internalFormat = GL_COMPRESSED_RGB;
-         break;
-      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-         if (!ctx->Mesa_DXTn)
-            internalFormat = GL_COMPRESSED_RGBA;
-         break;
-      default:
-         break;
-      }
-
-      if (before != internalFormat) {
-         _mesa_warning(ctx,
-                       "DXT compression requested (%s), "
-                       "but libtxc_dxtn library not installed.  Using %s "
-                       "instead.",
-                       _mesa_enum_to_string(before),
-                       _mesa_enum_to_string(internalFormat));
-      }
-   }
-
-   /* choose format from scratch */
    f = ctx->Driver.ChooseTextureFormat(ctx, target, internalFormat,
                                        format, type);
    assert(f != MESA_FORMAT_NONE);
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 381ff9dae0..b96313e2aa 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -405,7 +405,7 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
    /* GL limits and extensions */
    st_init_limits(pipe->screen, &ctx->Const, &ctx->Extensions);
    st_init_extensions(pipe->screen, &ctx->Const,
-                      &ctx->Extensions, &st->options, ctx->Mesa_DXTn);
+                      &ctx->Extensions, &st->options);
 
    if (st_have_perfmon(st)) {
       ctx->Extensions.AMD_performance_monitor = GL_TRUE;
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 74193cc492..65b6bd34aa 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -569,8 +569,7 @@ get_max_samples_for_formats(struct pipe_screen *screen,
 void st_init_extensions(struct pipe_screen *screen,
                         struct gl_constants *consts,
                         struct gl_extensions *extensions,
-                        struct st_config_options *options,
-                        boolean has_lib_dxtc)
+                        struct st_config_options *options)
 {
    unsigned i;
    GLboolean *extension_table = (GLboolean *) extensions;
@@ -960,11 +959,6 @@ void st_init_extensions(struct pipe_screen *screen,
 
    /* Below are the cases which cannot be moved into tables easily. */
 
-   if (!has_lib_dxtc && !options->force_s3tc_enable) {
-      extensions->EXT_texture_compression_s3tc = GL_FALSE;
-      extensions->ANGLE_texture_compression_dxt = GL_FALSE;
-   }
-
    if (screen->get_shader_param(screen, PIPE_SHADER_TESS_CTRL,
                                 PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) {
       extensions->ARB_tessellation_shader = GL_TRUE;
diff --git a/src/mesa/state_tracker/st_extensions.h b/src/mesa/state_tracker/st_extensions.h
index faff11fd5d..951185caa3 100644
--- a/src/mesa/state_tracker/st_extensions.h
+++ b/src/mesa/state_tracker/st_extensions.h
@@ -40,8 +40,7 @@ extern void st_init_limits(struct pipe_screen *screen,
 extern void st_init_extensions(struct pipe_screen *screen,
                                struct gl_constants *consts,
                                struct gl_extensions *extensions,
-                               struct st_config_options *options,
-                               boolean has_lib_dxtc);
+                               struct st_config_options *options);
 
 
 #endif /* ST_EXTENSIONS_H */
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index 012f1a4015..4d0b4265b7 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -2275,13 +2275,13 @@ st_ChooseTextureFormat(struct gl_context *ctx, GLenum target,
    }
 
    pFormat = st_choose_format(st, internalFormat, format, type,
-                              pTarget, 0, bindings, ctx->Mesa_DXTn);
+                              pTarget, 0, bindings, GL_TRUE);
 
    if (pFormat == PIPE_FORMAT_NONE && !is_renderbuffer) {
       /* try choosing format again, this time without render target bindings */
       pFormat = st_choose_format(st, internalFormat, format, type,
                                  pTarget, 0, PIPE_BIND_SAMPLER_VIEW,
-                                 ctx->Mesa_DXTn);
+                                 GL_TRUE);
    }
 
    if (pFormat == PIPE_FORMAT_NONE) {
diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
index 5ad0816184..999e1230cb 100644
--- a/src/mesa/state_tracker/st_manager.c
+++ b/src/mesa/state_tracker/st_manager.c
@@ -1137,7 +1137,7 @@ get_version(struct pipe_screen *screen,
    _mesa_init_extensions(&extensions);
 
    st_init_limits(screen, &consts, &extensions);
-   st_init_extensions(screen, &consts, &extensions, options, GL_TRUE);
+   st_init_extensions(screen, &consts, &extensions, options);
 
    return _mesa_get_version(&extensions, &consts, api);
 }
-- 
2.13.5