Mesa (master): r300g: fix and re-enable 8x8 zbuffer compression mode

Marek Olšák mareko at kemper.freedesktop.org
Fri Jan 28 00:05:20 UTC 2011


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

Author: Marek Olšák <maraeo at gmail.com>
Date:   Fri Jan 28 01:01:01 2011 +0100

r300g: fix and re-enable 8x8 zbuffer compression mode

Also cleanup the whole thing.

---

 src/gallium/drivers/r300/r300_blit.c         |   11 +----
 src/gallium/drivers/r300/r300_chipset.c      |    3 +-
 src/gallium/drivers/r300/r300_context.h      |    5 ++
 src/gallium/drivers/r300/r300_emit.c         |   30 +-------------
 src/gallium/drivers/r300/r300_hyperz.c       |    6 +-
 src/gallium/drivers/r300/r300_texture_desc.c |   58 ++++++++++++++++++++++++++
 6 files changed, 69 insertions(+), 44 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index f24d558..d0eb21c 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -114,16 +114,7 @@ static boolean r300_fast_zclear_allowed(struct r300_context *r300)
     struct pipe_framebuffer_state *fb =
         (struct pipe_framebuffer_state*)r300->fb_state.state;
 
-    /* Cannot decompress zmask with a 16-bit zbuffer.
-     * Also compression causes a hung. */
-    if (util_format_get_blocksizebits(fb->zsbuf->texture->format) == 16)
-        return FALSE;
-
-    /* Cannot use compression with a linear zbuffer. */
-    if (!r300_texture(fb->zsbuf->texture)->desc.microtile)
-        return FALSE;
-
-    return TRUE;
+    return r300_texture(fb->zsbuf->texture)->desc.zmask_dwords[fb->zsbuf->u.tex.level];
 }
 
 static uint32_t r300_depth_clear_value(enum pipe_format format,
diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c
index 15dc6d0..593eadb 100644
--- a/src/gallium/drivers/r300/r300_chipset.c
+++ b/src/gallium/drivers/r300/r300_chipset.c
@@ -424,7 +424,6 @@ void r300_parse_chipset(struct r300_capabilities* caps)
     }
 
     caps->is_rv350 = caps->family >= CHIP_FAMILY_RV350;
-    /* XXX The 8x8 compression mode doesn't always work (piglit/fbo-depth fails). */
-    caps->z_compress = /*caps->is_rv350 ? R300_ZCOMP_8X8 :*/ R300_ZCOMP_4X4;
+    caps->z_compress = caps->is_rv350 ? R300_ZCOMP_8X8 : R300_ZCOMP_4X4;
     caps->dxtc_swizzle = caps->is_r400 || caps->is_r500;
 }
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 6e96ae8..57ecfb1 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -387,6 +387,11 @@ struct r300_texture_desc {
 
     /* Whether CBZB fast color clear is allowed on the miplevel. */
     boolean cbzb_allowed[R300_MAX_TEXTURE_LEVELS];
+
+    /* Zbuffer compression info for each miplevel. */
+    boolean zcomp8x8[R300_MAX_TEXTURE_LEVELS];
+    /* If zero, then disable compression. */
+    unsigned zmask_dwords[R300_MAX_TEXTURE_LEVELS];
 };
 
 struct r300_texture {
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 54e2634..2157cb3 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -1141,42 +1141,14 @@ void r300_emit_zmask_clear(struct r300_context *r300, unsigned size, void *state
     struct pipe_framebuffer_state *fb =
         (struct pipe_framebuffer_state*)r300->fb_state.state;
     struct r300_texture *tex;
-    unsigned numdw, pipes;
-    unsigned compsize = r300->screen->caps.z_compress;
-    /* The tile size of 1 DWORD is:
-     *
-     * GPU    Pipes    4x4 mode   8x8 mode
-     * ------------------------------------------
-     * R580   4P/1Z    32x32      64x64
-     * RV570  3P/1Z    48x16      96x32
-     * RV530  1P/2Z    32x16      64x32
-     */
-    static unsigned num_blocks_x_per_dw[4] = {4, 8, 12, 8};
-    static unsigned num_blocks_y_per_dw[4] = {4, 4,  4, 8};
     CS_LOCALS(r300);
 
-    if (r300->screen->caps.family == CHIP_FAMILY_RV530) {
-        pipes = r300->screen->caps.num_z_pipes;
-    } else {
-        pipes = r300->screen->caps.num_frag_pipes;
-    }
-
     tex = r300_texture(fb->zsbuf->texture);
 
-    /* Get the zbuffer size (with the aligned width and height). */
-    numdw = align(tex->desc.stride_in_pixels[fb->zsbuf->u.tex.level],
-                  num_blocks_x_per_dw[pipes-1] * compsize) *
-            align(fb->zsbuf->height,
-                  num_blocks_y_per_dw[pipes-1] * compsize);
-
-    /* Convert pixels -> dwords. */
-    numdw = ALIGN_DIVUP(numdw, num_blocks_x_per_dw[pipes-1] * compsize *
-                               num_blocks_y_per_dw[pipes-1] * compsize);
-
     BEGIN_CS(size);
     OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_ZMASK, 2);
     OUT_CS(0);
-    OUT_CS(numdw);
+    OUT_CS(tex->desc.zmask_dwords[fb->zsbuf->u.tex.level]);
     OUT_CS(0);
     END_CS;
 
diff --git a/src/gallium/drivers/r300/r300_hyperz.c b/src/gallium/drivers/r300/r300_hyperz.c
index d996d19..7767275 100644
--- a/src/gallium/drivers/r300/r300_hyperz.c
+++ b/src/gallium/drivers/r300/r300_hyperz.c
@@ -168,10 +168,10 @@ static void r300_update_hyperz(struct r300_context* r300)
         if (!r300->zmask_decompress) {
             z->zb_bw_cntl |= R300_WR_COMP_ENABLE;
         }
+    }
 
-        if (r300->screen->caps.z_compress == R300_ZCOMP_8X8) {
-            z->gb_z_peq_config |= R300_GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8;
-        }
+    if (zstex->desc.zcomp8x8[fb->zsbuf->u.tex.level]) {
+        z->gb_z_peq_config |= R300_GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8;
     }
 
     if (hiz_in_use && r300_can_hiz(r300)) {
diff --git a/src/gallium/drivers/r300/r300_texture_desc.c b/src/gallium/drivers/r300/r300_texture_desc.c
index bc33871..83469f7 100644
--- a/src/gallium/drivers/r300/r300_texture_desc.c
+++ b/src/gallium/drivers/r300/r300_texture_desc.c
@@ -334,6 +334,63 @@ static void r300_setup_cbzb_flags(struct r300_screen *rscreen,
         desc->cbzb_allowed[i] = first_level_valid && desc->macrotile[i];
 }
 
+#define ALIGN_DIVUP(x, y) (((x) + (y) - 1) / (y))
+
+static void r300_setup_zmask_flags(struct r300_screen *screen,
+                                   struct r300_texture_desc *desc)
+{
+    /* The tile size of 1 DWORD is:
+     *
+     * GPU    Pipes    4x4 mode   8x8 mode
+     * ------------------------------------------
+     * R580   4P/1Z    32x32      64x64
+     * RV570  3P/1Z    48x16      96x32
+     * RV530  1P/2Z    32x16      64x32
+     *        1P/1Z    16x16      32x32
+     */
+    static unsigned num_blocks_x_per_dw[4] = {4, 8, 12, 8};
+    static unsigned num_blocks_y_per_dw[4] = {4, 4,  4, 8};
+
+    if (util_format_is_depth_or_stencil(desc->b.b.format) &&
+        util_format_get_blocksizebits(desc->b.b.format) == 32 &&
+        desc->microtile) {
+        unsigned i, pipes;
+
+        if (screen->caps.family == CHIP_FAMILY_RV530) {
+            pipes = screen->caps.num_z_pipes;
+        } else {
+            pipes = screen->caps.num_frag_pipes;
+        }
+
+        for (i = 0; i <= desc->b.b.last_level; i++) {
+            unsigned numdw, compsize;
+
+            /* The 8x8 compression mode needs macrotiling. */
+            compsize = screen->caps.z_compress == R300_ZCOMP_8X8 &&
+                       desc->macrotile[i] ? 8 : 4;
+
+            /* Get the zbuffer size (with the aligned width and height). */
+            numdw = align(desc->stride_in_pixels[i],
+                          num_blocks_x_per_dw[pipes-1] * compsize) *
+                    align(u_minify(desc->b.b.height0, i),
+                          num_blocks_y_per_dw[pipes-1] * compsize);
+
+            /* Convert pixels -> dwords. */
+            numdw = ALIGN_DIVUP(numdw, num_blocks_x_per_dw[pipes-1] * compsize *
+                                       num_blocks_y_per_dw[pipes-1] * compsize);
+
+            /* Check that we have enough ZMASK memory. */
+            if (numdw <= screen->caps.zmask_ram * pipes) {
+                desc->zmask_dwords[i] = numdw;
+                desc->zcomp8x8[i] = compsize == 8;
+            } else {
+                desc->zmask_dwords[i] = 0;
+                desc->zcomp8x8[i] = FALSE;
+            }
+        }
+    }
+}
+
 static void r300_setup_tiling(struct r300_screen *screen,
                               struct r300_texture_desc *desc)
 {
@@ -439,6 +496,7 @@ boolean r300_texture_desc_init(struct r300_screen *rscreen,
     }
 
     r300_texture_3d_fix_mipmapping(rscreen, desc);
+    r300_setup_zmask_flags(rscreen, desc);
 
     if (max_buffer_size) {
         /* Make sure the buffer we got is large enough. */




More information about the mesa-commit mailing list