Mesa (7.9): r300g: fix the border color for every format other than PIPE_FORMAT_B8G8R8A8

Marek Olšák mareko at kemper.freedesktop.org
Sat Sep 25 00:14:15 UTC 2010


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

Author: Marek Olšák <maraeo at gmail.com>
Date:   Thu Sep 23 22:56:50 2010 +0200

r300g: fix the border color for every format other than PIPE_FORMAT_B8G8R8A8

TX_BORDER_COLOR should be formatted according to the texture format.
Also the interaction with ARB_texture_swizzle should be fixed too.

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

---

 src/gallium/drivers/r300/r300_context.h       |    1 -
 src/gallium/drivers/r300/r300_state.c         |    4 -
 src/gallium/drivers/r300/r300_state_derived.c |   85 ++++++++++++++++++++++++-
 3 files changed, 84 insertions(+), 6 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 7f655db..8f4e2de 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -162,7 +162,6 @@ struct r300_sampler_state {
 
     uint32_t filter0;      /* R300_TX_FILTER0: 0x4400 */
     uint32_t filter1;      /* R300_TX_FILTER1: 0x4440 */
-    uint32_t border_color; /* R300_TX_BORDER_COLOR: 0x45c0 */
 
     /* Min/max LOD must be clamped to [0, last_level], thus
      * it's dependent on a currently bound texture */
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 8ccb639..53c1657 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -1171,7 +1171,6 @@ static void*
     struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state);
     boolean is_r500 = r300->screen->caps.is_r500;
     int lod_bias;
-    union util_color uc;
 
     sampler->state = *state;
 
@@ -1228,9 +1227,6 @@ static void*
         sampler->filter1 |= r500_anisotropy(state->max_anisotropy);
     }
 
-    util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
-    sampler->border_color = uc.ui;
-
     /* R500-specific fixups and optimizations */
     if (r300->screen->caps.is_r500) {
         sampler->filter1 |= R500_BORDER_FIX;
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index f9a5168..566a828 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -567,6 +567,85 @@ static void r300_update_rs_block(struct r300_context *r300)
     }
 }
 
+static uint32_t r300_get_border_color(enum pipe_format format,
+                                      const unsigned char swizzle_view[4],
+                                      const float border[4])
+{
+    const struct util_format_description *desc;
+    unsigned char swizzle[4];
+    unsigned i;
+    float border_swizzled[4];
+    uint32_t r;
+
+    desc = util_format_description(format);
+
+    /* Combine the swizzles. */
+    for (i = 0; i < 4; i++) {
+        swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ?
+                     desc->swizzle[swizzle_view[i]] : swizzle_view[i];
+    }
+
+    /* Apply swizzling. */
+    for (i = 0; i < 4; i++) {
+        switch (swizzle[i]) {
+            case UTIL_FORMAT_SWIZZLE_X:
+                border_swizzled[i] = border[0];
+                break;
+            case UTIL_FORMAT_SWIZZLE_Y:
+                border_swizzled[i] = border[1];
+                break;
+            case UTIL_FORMAT_SWIZZLE_Z:
+                border_swizzled[i] = border[2];
+                break;
+            case UTIL_FORMAT_SWIZZLE_W:
+                border_swizzled[i] = border[3];
+                break;
+            case UTIL_FORMAT_SWIZZLE_0:
+                border_swizzled[i] = 0;
+                break;
+            default: /* 1, NONE */
+                border_swizzled[i] = 1;
+        }
+    }
+
+    /* We don't use util_pack_format because it does not handle the formats
+     * we want, e.g. R4G4B4A4 is non-existent in Gallium. */
+    switch (desc->channel[0].size) {
+        case 4:
+            r = ((float_to_ubyte(border_swizzled[0]) & 0xf0) >> 4) |
+                ((float_to_ubyte(border_swizzled[1]) & 0xf0) << 0) |
+                ((float_to_ubyte(border_swizzled[2]) & 0xf0) << 4) |
+                ((float_to_ubyte(border_swizzled[3]) & 0xf0) << 8);
+            break;
+
+        case 5:
+            if (desc->channel[1].size == 5) {
+                r = ((float_to_ubyte(border_swizzled[0]) & 0xf8) >> 3) |
+                    ((float_to_ubyte(border_swizzled[1]) & 0xf8) << 2) |
+                    ((float_to_ubyte(border_swizzled[2]) & 0xf8) << 7) |
+                    ((float_to_ubyte(border_swizzled[3]) & 0x80) << 8);
+            } else if (desc->channel[1].size == 6) {
+                r = ((float_to_ubyte(border_swizzled[0]) & 0xf8) >> 3) |
+                    ((float_to_ubyte(border_swizzled[1]) & 0xfc) << 3) |
+                    ((float_to_ubyte(border_swizzled[2]) & 0xf8) << 8);
+            } else {
+                assert(0);
+            }
+            break;
+
+        default:
+            /* I think the fat formats (16, 32) are specified
+             * as the 8-bit ones. I am not sure how compressed formats
+             * work here. */
+            r = ((float_to_ubyte(border_swizzled[0]) & 0xff) << 0) |
+                ((float_to_ubyte(border_swizzled[1]) & 0xff) << 8) |
+                ((float_to_ubyte(border_swizzled[2]) & 0xff) << 16) |
+                ((float_to_ubyte(border_swizzled[3]) & 0xff) << 24);
+    }
+
+    return r;
+}
+
 static void r300_merge_textures_and_samplers(struct r300_context* r300)
 {
     struct r300_textures_state *state =
@@ -599,7 +678,11 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
             texstate->format = view->format;
             texstate->filter0 = sampler->filter0;
             texstate->filter1 = sampler->filter1;
-            texstate->border_color = sampler->border_color;
+
+            /* Set the border color. */
+            texstate->border_color =
+                r300_get_border_color(view->base.format, view->swizzle,
+                                      sampler->state.border_color);
 
             /* determine min/max levels */
             max_level = MIN3(sampler->max_lod + view->base.first_level,




More information about the mesa-commit mailing list