Mesa (7.9): r300g: fix texture swizzling with compressed textures on r400-r500

Marek Olšák mareko at kemper.freedesktop.org
Wed Dec 1 16:58:20 PST 2010


Module: Mesa
Branch: 7.9
Commit: 988a35c7f71933998054d0b4ee3b0bc81673f28e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=988a35c7f71933998054d0b4ee3b0bc81673f28e

Author: Marek Olšák <maraeo at gmail.com>
Date:   Tue Nov 30 23:28:43 2010 +0100

r300g: fix texture swizzling with compressed textures on r400-r500

This fixes all S3TC piglit/texwrap tests.

NOTE: This is a candidate for the 7.9 branch.
(cherry picked from commit 6478a4de14d368bf85ba3477d73fd1bd91067e86)

---

 src/gallium/drivers/r300/r300_chipset.c       |    1 +
 src/gallium/drivers/r300/r300_chipset.h       |    2 ++
 src/gallium/drivers/r300/r300_reg.h           |    2 +-
 src/gallium/drivers/r300/r300_state.c         |    4 +++-
 src/gallium/drivers/r300/r300_state_derived.c |    9 +++++++--
 src/gallium/drivers/r300/r300_texture.c       |   17 ++++++++++-------
 src/gallium/drivers/r300/r300_texture.h       |    6 ++++--
 7 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c
index 48c2409..583e981 100644
--- a/src/gallium/drivers/r300/r300_chipset.c
+++ b/src/gallium/drivers/r300/r300_chipset.c
@@ -424,4 +424,5 @@ void r300_parse_chipset(struct r300_capabilities* caps)
     }
 
     caps->is_rv350 = caps->family >= CHIP_FAMILY_RV350;
+    caps->dxtc_swizzle = caps->is_r400 || caps->is_r500;
 }
diff --git a/src/gallium/drivers/r300/r300_chipset.h b/src/gallium/drivers/r300/r300_chipset.h
index e7ca642..7ea4175 100644
--- a/src/gallium/drivers/r300/r300_chipset.h
+++ b/src/gallium/drivers/r300/r300_chipset.h
@@ -79,6 +79,8 @@ struct r300_capabilities {
     boolean is_r500;
     /* Whether or not the second pixel pipe is accessed with the high bit */
     boolean high_second_pipe;
+    /* DXTC texture swizzling. */
+    boolean dxtc_swizzle;
 };
 
 /* Enumerations for legibility and telling which card we're running on. */
diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
index 6bea783..788c513 100644
--- a/src/gallium/drivers/r300/r300_reg.h
+++ b/src/gallium/drivers/r300/r300_reg.h
@@ -1520,11 +1520,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #	define R300_TX_TRI_PERF_3_8            (3<<15)
 #	define R300_ANISO_THRESHOLD_MASK       (7<<17)
 
+#       define R400_DXTC_SWIZZLE_ENABLE        (1<<21)
 #	define R500_MACRO_SWITCH               (1<<22)
 #       define R500_TX_MAX_ANISO(x)            ((x) << 23)
 #       define R500_TX_MAX_ANISO_MASK          (63 << 23)
 #       define R500_TX_ANISO_HIGH_QUALITY      (1 << 30)
-
 #	define R500_BORDER_FIX                 (1<<31)
 
 #define R300_TX_FORMAT0_0                   0x4480
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 105b3e5..7779766 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -1363,6 +1363,7 @@ r300_create_sampler_view(struct pipe_context *pipe,
     struct r300_sampler_view *view = CALLOC_STRUCT(r300_sampler_view);
     struct r300_texture *tex = r300_texture(texture);
     boolean is_r500 = r300_screen(pipe->screen)->caps.is_r500;
+    boolean dxtc_swizzle = r300_screen(pipe->screen)->caps.dxtc_swizzle;
 
     if (view) {
         view->base = *templ;
@@ -1379,7 +1380,8 @@ r300_create_sampler_view(struct pipe_context *pipe,
         view->format = tex->tx_format;
         view->format.format1 |= r300_translate_texformat(templ->format,
                                                          view->swizzle,
-                                                         is_r500);
+                                                         is_r500,
+                                                         dxtc_swizzle);
         if (is_r500) {
             view->format.format2 |= r500_tx_format_msb_bit(templ->format);
         }
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index f9b3a59..9d8b6da 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -741,13 +741,18 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
                 if (sampler->state.compare_mode == PIPE_TEX_COMPARE_NONE) {
                     texstate->format.format1 |=
                         r300_get_swizzle_combined(depth_swizzle,
-                                                  view->swizzle);
+                                                  view->swizzle, FALSE);
                 } else {
                     texstate->format.format1 |=
-                        r300_get_swizzle_combined(depth_swizzle, 0);
+                        r300_get_swizzle_combined(depth_swizzle, 0, FALSE);
                 }
             }
 
+            if (r300->screen->caps.dxtc_swizzle &&
+                util_format_is_compressed(tex->desc.b.b.format)) {
+                texstate->filter1 |= R400_DXTC_SWIZZLE_ENABLE;
+            }
+
             /* to emulate 1D textures through 2D ones correctly */
             if (tex->desc.b.b.target == PIPE_TEXTURE_1D) {
                 texstate->filter0 &= ~R300_TX_WRAP_T_MASK;
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 34105aa..7e2f69a 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -40,7 +40,8 @@
 #include "pipe/p_screen.h"
 
 unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
-                                   const unsigned char *swizzle_view)
+                                   const unsigned char *swizzle_view,
+                                   boolean dxtc_swizzle)
 {
     unsigned i;
     unsigned char swizzle[4];
@@ -51,10 +52,10 @@ unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
         R300_TX_FORMAT_B_SHIFT,
         R300_TX_FORMAT_A_SHIFT
     };
-    const uint32_t swizzle_bit[4] = {
-        R300_TX_FORMAT_X,
+    uint32_t swizzle_bit[4] = {
+        dxtc_swizzle ? R300_TX_FORMAT_Z : R300_TX_FORMAT_X,
         R300_TX_FORMAT_Y,
-        R300_TX_FORMAT_Z,
+        dxtc_swizzle ? R300_TX_FORMAT_X : R300_TX_FORMAT_Z,
         R300_TX_FORMAT_W
     };
 
@@ -107,7 +108,8 @@ unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
  * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */
 uint32_t r300_translate_texformat(enum pipe_format format,
                                   const unsigned char *swizzle_view,
-                                  boolean is_r500)
+                                  boolean is_r500,
+                                  boolean dxtc_swizzle)
 {
     uint32_t result = 0;
     const struct util_format_description *desc;
@@ -169,7 +171,8 @@ uint32_t r300_translate_texformat(enum pipe_format format,
             }
     }
 
-    result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view);
+    result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view,
+                    util_format_is_compressed(format) && dxtc_swizzle);
 
     /* S3TC formats. */
     if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
@@ -538,7 +541,7 @@ boolean r300_is_zs_format_supported(enum pipe_format format)
 
 boolean r300_is_sampler_format_supported(enum pipe_format format)
 {
-    return r300_translate_texformat(format, 0, TRUE) != ~0;
+    return r300_translate_texformat(format, 0, TRUE, FALSE) != ~0;
 }
 
 void r300_texture_setup_format_state(struct r300_screen *screen,
diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h
index c4588a0..fe9d351 100644
--- a/src/gallium/drivers/r300/r300_texture.h
+++ b/src/gallium/drivers/r300/r300_texture.h
@@ -35,11 +35,13 @@ struct r300_texture;
 struct r300_screen;
 
 unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
-                                   const unsigned char *swizzle_view);
+                                   const unsigned char *swizzle_view,
+                                   boolean dxtc_swizzle);
 
 uint32_t r300_translate_texformat(enum pipe_format format,
                                   const unsigned char *swizzle_view,
-                                  boolean is_r500);
+                                  boolean is_r500,
+                                  boolean dxtc_swizzle);
 
 uint32_t r500_tx_format_msb_bit(enum pipe_format format);
 



More information about the mesa-commit mailing list