Add a mask to track if a texture level is still in its decompressed
state or that we would need to decompress again.

Signed-off-by: Bas Nieuwenhuizen <b...@basnieuwenhuizen.nl>
---
 src/gallium/drivers/radeon/r600_pipe_common.h |  1 +
 src/gallium/drivers/radeon/r600_texture.c     |  1 +
 src/gallium/drivers/radeonsi/si_blit.c        |  9 ++++++---
 src/gallium/drivers/radeonsi/si_pipe.h        |  1 +
 src/gallium/drivers/radeonsi/si_state.c       |  6 ++++++
 src/gallium/drivers/radeonsi/si_state_draw.c  | 14 ++++++++++++++
 6 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h 
b/src/gallium/drivers/radeon/r600_pipe_common.h
index f21a0b3..6e82ba6 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -206,6 +206,7 @@ struct r600_texture {
        bool                            is_depth;
        unsigned                        dirty_level_mask; /* each bit says if 
that mipmap is compressed */
        unsigned                        stencil_dirty_level_mask; /* each bit 
says if that mipmap is compressed */
+       unsigned                        dcc_compressed_level_mask;
        struct r600_texture             *flushed_depth_texture;
        boolean                         is_flushing_texture;
        struct radeon_surf              surface;
diff --git a/src/gallium/drivers/radeon/r600_texture.c 
b/src/gallium/drivers/radeon/r600_texture.c
index 90e47ba..1d3bf32 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -1347,6 +1347,7 @@ void evergreen_do_fast_color_clear(struct 
r600_common_context *rctx,
                        rctx->clear_buffer(&rctx->b, &tex->dcc_buffer->b.b,
                                        0, tex->surface.dcc_size, reset_value, 
true);
 
+                       tex->dcc_compressed_level_mask |= 1 << 
fb->cbufs[i]->u.tex.level;
                        if (clear_words_needed)
                                tex->dirty_level_mask |= 1 << 
fb->cbufs[i]->u.tex.level;
                } else {
diff --git a/src/gallium/drivers/radeonsi/si_blit.c 
b/src/gallium/drivers/radeonsi/si_blit.c
index 82d323e..73adf43 100644
--- a/src/gallium/drivers/radeonsi/si_blit.c
+++ b/src/gallium/drivers/radeonsi/si_blit.c
@@ -273,16 +273,17 @@ static void si_blit_decompress_color(struct pipe_context 
*ctx,
        struct si_context *sctx = (struct si_context *)ctx;
        unsigned layer, level, checked_last_layer, max_layer;
 
-       if (!rtex->dirty_level_mask && !need_dcc_decompress)
+       if (!rtex->dirty_level_mask && (!need_dcc_decompress || 
!rtex->dcc_compressed_level_mask))
                return;
 
        for (level = first_level; level <= last_level; level++) {
                void* custom_blend;
 
-               if (!(rtex->dirty_level_mask & (1 << level)) && 
!need_dcc_decompress)
+               if (!(rtex->dirty_level_mask & (1 << level)) &&
+                   (!need_dcc_decompress || !(rtex->dcc_compressed_level_mask 
& (1 << level))))
                        continue;
 
-               if(need_dcc_decompress) {
+               if(need_dcc_decompress && (rtex->dcc_compressed_level_mask & (1 
<< level))) {
                        custom_blend = sctx->custom_blend_dcc_decompress;
                } else if(rtex->fmask.size) {
                        custom_blend = sctx->custom_blend_decompress;
@@ -315,6 +316,8 @@ static void si_blit_decompress_color(struct pipe_context 
*ctx,
                 * I don't think this case occurs often though. */
                if (first_layer == 0 && last_layer == max_layer) {
                        rtex->dirty_level_mask &= ~(1 << level);
+                       if(custom_blend == sctx->custom_blend_dcc_decompress)
+                               rtex->dcc_compressed_level_mask &= ~(1 << 
level);
                }
        }
 }
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h 
b/src/gallium/drivers/radeonsi/si_pipe.h
index 8c751c6..45f9475 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -127,6 +127,7 @@ struct si_framebuffer {
        unsigned                        log_samples;
        unsigned                        cb0_is_integer;
        unsigned                        compressed_cb_mask;
+       unsigned                        dcc_compressed_cb_mask;
        unsigned                        export_16bpc;
        unsigned                        dirty_cbufs;
        bool                            dirty_zsbuf;
diff --git a/src/gallium/drivers/radeonsi/si_state.c 
b/src/gallium/drivers/radeonsi/si_state.c
index 46f7341..f8218ac 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -2132,6 +2132,7 @@ static void si_set_framebuffer_state(struct pipe_context 
*ctx,
 
        sctx->framebuffer.export_16bpc = 0;
        sctx->framebuffer.compressed_cb_mask = 0;
+       sctx->framebuffer.dcc_compressed_cb_mask = 0;
        sctx->framebuffer.nr_samples = util_framebuffer_get_num_samples(state);
        sctx->framebuffer.log_samples = 
util_logbase2(sctx->framebuffer.nr_samples);
        sctx->framebuffer.cb0_is_integer = state->nr_cbufs && state->cbufs[0] &&
@@ -2158,6 +2159,11 @@ static void si_set_framebuffer_state(struct pipe_context 
*ctx,
                if (rtex->fmask.size && rtex->cmask.size) {
                        sctx->framebuffer.compressed_cb_mask |= 1 << i;
                }
+
+               if (rtex->surface.dcc_enabled) {
+                       sctx->framebuffer.dcc_compressed_cb_mask |= 1 << i;
+               }
+
                r600_context_add_resource_size(ctx, surf->base.texture);
        }
        /* Set the 16BPC export for possible dual-src blending. */
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c 
b/src/gallium/drivers/radeonsi/si_state_draw.c
index c42d7cd..4616962 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -879,6 +879,20 @@ void si_draw_vbo(struct pipe_context *ctx, const struct 
pipe_draw_info *info)
                } while (mask);
        }
 
+       if (sctx->framebuffer.dcc_compressed_cb_mask) {
+               struct pipe_surface *surf;
+               struct r600_texture *rtex;
+               unsigned mask = sctx->framebuffer.dcc_compressed_cb_mask;
+
+               do {
+                       unsigned i = u_bit_scan(&mask);
+                       surf = sctx->framebuffer.state.cbufs[i];
+                       rtex = (struct r600_texture*)surf->texture;
+
+                       rtex->dcc_compressed_level_mask |= 1 << 
surf->u.tex.level;
+               } while (mask);
+       }
+
        pipe_resource_reference(&ib.buffer, NULL);
        sctx->b.num_draw_calls++;
 }
-- 
2.5.3

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to