summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2017-10-03 16:06:59 -0400
committerAdam Jackson <ajax@redhat.com>2017-10-03 16:06:59 -0400
commit7e3da0f877a4094aaaa0abe6e04a8a077858ef9a (patch)
tree016837b33ab169f0128835d1b7663c6f36832bb5
parent2b4a64fcd2ac3a226d518fe5d17fda5fac77a0b6 (diff)
downloadmesa-7e3da0f.zip
mesa-7e3da0f.tar.gz
mesa-7e3da0f.tar.xz
Backport S3TC support from master
-rw-r--r--0001-mesa-Squash-merge-of-S3TC-support.patch2492
-rw-r--r--mesa.spec10
2 files changed, 2502 insertions, 0 deletions
diff --git a/0001-mesa-Squash-merge-of-S3TC-support.patch b/0001-mesa-Squash-merge-of-S3TC-support.patch
new file mode 100644
index 0000000..1b4433b
--- /dev/null
+++ b/0001-mesa-Squash-merge-of-S3TC-support.patch
@@ -0,0 +1,2492 @@
+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
+
diff --git a/mesa.spec b/mesa.spec
index da0be8b..8c6b13c 100644
--- a/mesa.spec
+++ b/mesa.spec
@@ -71,6 +71,9 @@ Source2: vl_mpeg12_decoder.c
# Fedora opts to ignore the optional part of clause 2 and treat that code as 2 clause BSD.
Source3: Mesa-MLAA-License-Clarification-Email.txt
+# https://cgit.freedesktop.org/~ajax/mesa/log/?h=mesa-17.2-s3tc
+Patch0: 0001-mesa-Squash-merge-of-S3TC-support.patch
+
Patch1: 0001-llvm-SONAME-without-version.patch
Patch2: 0002-hardware-gloat.patch
Patch3: 0003-evergreen-big-endian.patch
@@ -373,6 +376,10 @@ Headers for development with the Vulkan API.
cp %{SOURCE3} docs/
+# this is a hack for S3TC support. r200_screen.c is symlinked to
+# radeon_screen.c in git, but is its own file in the tarball.
+cp -f src/mesa/drivers/dri/{radeon,r200}/radeon_screen.c
+
%build
autoreconf -vfi
@@ -681,6 +688,9 @@ popd
%endif
%changelog
+* Tue Oct 03 2017 Adam Jackson <ajax@redhat.com> - 17.2.2-2
+- Backport S3TC support from master
+
* Tue Oct 3 2017 Peter Robinson <pbrobinson@fedoraproject.org> 17.2.2-1
- Update to 17.2.2 GA