Mesa (master): r300g: fix texturing with sizes > 2048 on r500

Marek Olšák mareko at kemper.freedesktop.org
Thu Apr 7 19:39:41 PDT 2011


Module: Mesa
Branch: master
Commit: 10ea8567f49f4daaa654b6e4c365a816f855073b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=10ea8567f49f4daaa654b6e4c365a816f855073b

Author: Marek Olšák <maraeo at gmail.com>
Date:   Fri Apr  8 03:11:22 2011 +0200

r300g: fix texturing with sizes > 2048 on r500

---

 src/gallium/drivers/r300/r300_chipset.c       |    1 +
 src/gallium/drivers/r300/r300_chipset.h       |    2 +
 src/gallium/drivers/r300/r300_context.h       |    3 +-
 src/gallium/drivers/r300/r300_emit.c          |    6 ++++
 src/gallium/drivers/r300/r300_screen.c        |    3 ++
 src/gallium/drivers/r300/r300_state_derived.c |    5 ++-
 src/gallium/drivers/r300/r300_texture.c       |   40 +++++++++++++++++++++---
 7 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c
index 990acea..1068d35 100644
--- a/src/gallium/drivers/r300/r300_chipset.c
+++ b/src/gallium/drivers/r300/r300_chipset.c
@@ -419,4 +419,5 @@ void r300_parse_chipset(struct r300_capabilities* caps)
     caps->is_rv350 = caps->family >= CHIP_FAMILY_RV350;
     caps->z_compress = caps->is_rv350 ? R300_ZCOMP_8X8 : R300_ZCOMP_4X4;
     caps->dxtc_swizzle = caps->is_r400 || caps->is_r500;
+    caps->has_us_format = caps->is_r500;
 }
diff --git a/src/gallium/drivers/r300/r300_chipset.h b/src/gallium/drivers/r300/r300_chipset.h
index 68943d5..3777f0c 100644
--- a/src/gallium/drivers/r300/r300_chipset.h
+++ b/src/gallium/drivers/r300/r300_chipset.h
@@ -90,6 +90,8 @@ struct r300_capabilities {
     boolean high_second_pipe;
     /* DXTC texture swizzling. */
     boolean dxtc_swizzle;
+    /* Whether R500_US_FORMAT0_0 is supported (depends on DRM). */
+    boolean has_us_format;
 };
 
 /* Enumerations for legibility and telling which card we're running on. */
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 550d3a7..c1f766f 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -190,6 +190,7 @@ struct r300_texture_format_state {
     uint32_t format1; /* R300_TX_FORMAT1: 0x44c0 */
     uint32_t format2; /* R300_TX_FORMAT2: 0x4500 */
     uint32_t tile_config; /* R300_TX_OFFSET (subset thereof) */
+    uint32_t us_format0;   /* R500_US_FORMAT0_0: 0x4640 (through 15) */
 };
 
 struct r300_sampler_view {
@@ -211,7 +212,7 @@ struct r300_texture_sampler_state {
     struct r300_texture_format_state format;
     uint32_t filter0;      /* R300_TX_FILTER0: 0x4400 */
     uint32_t filter1;      /* R300_TX_FILTER1: 0x4440 */
-    uint32_t border_color;  /* R300_TX_BORDER_COLOR: 0x45c0 */
+    uint32_t border_color; /* R300_TX_BORDER_COLOR: 0x45c0 */
 };
 
 struct r300_textures_state {
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 6b91f93..a21668a 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -775,6 +775,7 @@ void r300_emit_textures_state(struct r300_context *r300,
     struct r300_texture_sampler_state *texstate;
     struct r300_resource *tex;
     unsigned i;
+    boolean has_us_format = r300->screen->caps.has_us_format;
     CS_LOCALS(r300);
 
     BEGIN_CS(size);
@@ -796,6 +797,11 @@ void r300_emit_textures_state(struct r300_context *r300,
 
             OUT_CS_REG(R300_TX_OFFSET_0 + (i * 4), texstate->format.tile_config);
             OUT_CS_RELOC(tex);
+
+            if (has_us_format) {
+                OUT_CS_REG(R500_US_FORMAT0_0 + (i * 4),
+                           texstate->format.us_format0);
+            }
         }
     }
     END_CS;
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 07d854d..eb1b452 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -482,6 +482,9 @@ struct pipe_screen* r300_screen_create(struct r300_winsys_screen *rws)
     if (SCREEN_DBG_ON(r300screen, DBG_NO_HIZ))
         r300screen->caps.hiz_ram = 0;
 
+    if (!rws->get_value(rws, R300_VID_DRM_2_8_0))
+        r300screen->caps.has_us_format = FALSE;
+
     pipe_mutex_init(r300screen->num_contexts_mutex);
 
     util_slab_create(&r300screen->pool_buffers,
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index e943f1a..c80cf78 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -771,6 +771,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
     unsigned min_level, max_level, i, j, size;
     unsigned count = MIN2(state->sampler_view_count,
                           state->sampler_state_count);
+    boolean has_us_format = r300->screen->caps.has_us_format;
 
     /* The KIL opcode fix, see below. */
     if (!count && !r300->screen->caps.is_r500)
@@ -923,7 +924,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
 
             texstate->filter0 |= i << 28;
 
-            size += 16;
+            size += 16 + (has_us_format ? 2 : 0);
             state->count = i+1;
         } else {
             /* For the KIL opcode to work on r3xx-r4xx, the texture unit
@@ -952,7 +953,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
                 texstate->border_color = 0;
 
                 texstate->filter0 |= i << 28;
-                size += 16;
+                size += 16 + (has_us_format ? 2 : 0);
                 state->count = i+1;
             }
         }
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index ea6d982..47d1c3e 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -751,6 +751,16 @@ void r300_texture_setup_format_state(struct r300_screen *screen,
     struct pipe_resource *pt = &tex->b.b.b;
     struct r300_texture_desc *desc = &tex->tex;
     boolean is_r500 = screen->caps.is_r500;
+    unsigned width, height, depth;
+    unsigned txwidth, txheight, txdepth;
+
+    width = u_minify(desc->width0, level);
+    height = u_minify(desc->height0, level);
+    depth = u_minify(desc->depth0, level);
+
+    txwidth = (width - 1) & 0x7ff;
+    txheight = (height - 1) & 0x7ff;
+    txdepth = util_logbase2(depth) & 0xf;
 
     /* Mask out all the fields we change. */
     out->format0 = 0;
@@ -760,9 +770,9 @@ void r300_texture_setup_format_state(struct r300_screen *screen,
 
     /* Set sampler state. */
     out->format0 =
-        R300_TX_WIDTH((u_minify(desc->width0, level) - 1) & 0x7ff) |
-        R300_TX_HEIGHT((u_minify(desc->height0, level) - 1) & 0x7ff) |
-        R300_TX_DEPTH(util_logbase2(u_minify(desc->depth0, level)) & 0xf);
+        R300_TX_WIDTH(txwidth) |
+        R300_TX_HEIGHT(txheight) |
+        R300_TX_DEPTH(txdepth);
 
     if (desc->uses_stride_addressing) {
         /* rectangles love this */
@@ -780,12 +790,32 @@ void r300_texture_setup_format_state(struct r300_screen *screen,
     /* large textures on r500 */
     if (is_r500)
     {
-        if (desc->width0 > 2048) {
+        unsigned us_width = txwidth;
+        unsigned us_height = txheight;
+        unsigned us_depth = txdepth;
+
+        if (width > 2048) {
             out->format2 |= R500_TXWIDTH_BIT11;
         }
-        if (desc->height0 > 2048) {
+        if (height > 2048) {
             out->format2 |= R500_TXHEIGHT_BIT11;
         }
+
+        /* The US_FORMAT register fixes an R500 TX addressing bug.
+         * Don't ask why it must be set like this. I don't know it either. */
+        if (width > 2048) {
+            us_width = (0x000007FF + us_width) >> 1;
+            us_depth |= 0x0000000D;
+        }
+        if (height > 2048) {
+            us_height = (0x000007FF + us_height) >> 1;
+            us_depth |= 0x0000000E;
+        }
+
+        out->us_format0 =
+            R300_TX_WIDTH(us_width) |
+            R300_TX_HEIGHT(us_height) |
+            R300_TX_DEPTH(us_depth);
     }
 
     out->tile_config = R300_TXO_MACRO_TILE(desc->macrotile[level]) |



More information about the mesa-commit mailing list