From: Marek Olšák <marek.ol...@amd.com>

This works for both multi-sample and single-sample color buffers.
---
 src/gallium/drivers/radeon/r600_texture.c |  6 ++++-
 src/gallium/drivers/radeonsi/si_blit.c    | 38 +++++++++++++++++++++++++++++--
 src/gallium/drivers/radeonsi/si_pipe.c    |  1 +
 src/gallium/drivers/radeonsi/si_pipe.h    |  1 +
 src/gallium/drivers/radeonsi/si_state.c   | 17 +++++++++++++-
 5 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_texture.c 
b/src/gallium/drivers/radeon/r600_texture.c
index 837e97e..e3b918e 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -458,7 +458,11 @@ static void r600_texture_alloc_cmask_separate(struct 
r600_common_screen *rscreen
 
        assert(rtex->cmask.size == 0);
 
-       r600_texture_get_cmask_info(rscreen, rtex, &rtex->cmask);
+       if (rscreen->chip_class >= SI) {
+               si_texture_get_cmask_info(rscreen, rtex, &rtex->cmask);
+       } else {
+               r600_texture_get_cmask_info(rscreen, rtex, &rtex->cmask);
+       }
 
        rtex->cmask_buffer = (struct r600_resource *)
                pipe_buffer_create(&rscreen->b, PIPE_BIND_CUSTOM,
diff --git a/src/gallium/drivers/radeonsi/si_blit.c 
b/src/gallium/drivers/radeonsi/si_blit.c
index dd303c8..6bc89ab 100644
--- a/src/gallium/drivers/radeonsi/si_blit.c
+++ b/src/gallium/drivers/radeonsi/si_blit.c
@@ -277,7 +277,8 @@ static void si_blit_decompress_color(struct pipe_context 
*ctx,
 
                        si_blitter_begin(ctx, SI_DECOMPRESS);
                        util_blitter_custom_color(sctx->blitter, cbsurf,
-                                                 
sctx->custom_blend_decompress);
+                               rtex->fmask.size ? 
sctx->custom_blend_decompress :
+                                                  
sctx->custom_blend_fastclear);
                        si_blitter_end(ctx);
 
                        pipe_surface_reference(&cbsurf, NULL);
@@ -322,6 +323,31 @@ static void si_clear(struct pipe_context *ctx, unsigned 
buffers,
        struct si_context *sctx = (struct si_context *)ctx;
        struct pipe_framebuffer_state *fb = &sctx->framebuffer.state;
 
+       if (buffers & PIPE_CLEAR_COLOR) {
+               evergreen_do_fast_color_clear(&sctx->b, fb, 
&sctx->framebuffer.atom,
+                                             &buffers, color);
+       }
+
+       if (buffers & PIPE_CLEAR_COLOR) {
+               int i;
+
+               /* These buffers cannot use fast clear, make sure to disable 
expansion. */
+               for (i = 0; i < fb->nr_cbufs; i++) {
+                       struct r600_texture *tex;
+
+                       /* If not clearing this buffer, skip. */
+                       if (!(buffers & (PIPE_CLEAR_COLOR0 << i)))
+                               continue;
+
+                       if (!fb->cbufs[i])
+                               continue;
+
+                       tex = (struct r600_texture *)fb->cbufs[i]->texture;
+                       if (tex->fmask.size == 0)
+                               tex->dirty_level_mask &= ~(1 << 
fb->cbufs[i]->u.tex.level);
+               }
+       }
+
        si_blitter_begin(ctx, SI_CLEAR);
        util_blitter_clear(sctx->blitter, fb->width, fb->height,
                           util_framebuffer_get_num_layers(fb),
@@ -700,8 +726,16 @@ static void si_blit(struct pipe_context *ctx,
 }
 
 static void si_flush_resource(struct pipe_context *ctx,
-                             struct pipe_resource *resource)
+                             struct pipe_resource *res)
 {
+       struct r600_texture *rtex = (struct r600_texture*)res;
+
+       assert(res->target != PIPE_BUFFER);
+
+       if (!rtex->is_depth && rtex->cmask.size) {
+               si_blit_decompress_color(ctx, rtex, 0, res->last_level,
+                                        0, res->array_size - 1);
+       }
 }
 
 void si_init_blit_functions(struct si_context *sctx)
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c 
b/src/gallium/drivers/radeonsi/si_pipe.c
index 2a256d3..cab6584 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -104,6 +104,7 @@ static void si_destroy_context(struct pipe_context *context)
        sctx->b.b.delete_depth_stencil_alpha_state(&sctx->b.b, 
sctx->custom_dsa_flush_inplace);
        sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_resolve);
        sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_decompress);
+       sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_fastclear);
        util_unreference_framebuffer_state(&sctx->framebuffer.state);
 
        util_blitter_destroy(sctx->blitter);
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h 
b/src/gallium/drivers/radeonsi/si_pipe.h
index c66c88e..e8aa13e 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -95,6 +95,7 @@ struct si_context {
        void                            *custom_dsa_flush_inplace;
        void                            *custom_blend_resolve;
        void                            *custom_blend_decompress;
+       void                            *custom_blend_fastclear;
        struct si_screen                *screen;
 
        union {
diff --git a/src/gallium/drivers/radeonsi/si_state.c 
b/src/gallium/drivers/radeonsi/si_state.c
index 597fee6..4094421 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -1667,6 +1667,20 @@ static void si_initialize_color_surface(struct 
si_context *sctx,
        if (rtex->fmask.size) {
                surf->cb_color_fmask = (offset + rtex->fmask.offset) >> 8;
                surf->cb_color_fmask_slice = 
S_028C88_TILE_MAX(rtex->fmask.slice_tile_max);
+       } else {
+               /* This must be set for fast clear to work without FMASK. */
+               surf->cb_color_fmask = surf->cb_color_base;
+               surf->cb_color_fmask_slice = surf->cb_color_slice;
+               surf->cb_color_attrib |= 
S_028C74_FMASK_TILE_MODE_INDEX(tile_mode_index);
+
+               if (sctx->b.chip_class == SI) {
+                       unsigned bankh = util_logbase2(rtex->surface.bankh);
+                       surf->cb_color_attrib |= 
S_028C74_FMASK_BANK_HEIGHT(bankh);
+               }
+
+               if (sctx->b.chip_class >= CIK) {
+                       surf->cb_color_pitch |= S_028C64_FMASK_TILE_MAX(pitch);
+               }
        }
 
        /* Determine pixel shader export format */
@@ -1866,7 +1880,7 @@ static void si_set_framebuffer_state(struct pipe_context 
*ctx,
                        sctx->framebuffer.export_16bpc |= 1 << i;
                }
 
-               if (rtex->fmask.size || rtex->cmask.size) {
+               if (rtex->fmask.size && rtex->cmask.size) {
                        sctx->framebuffer.compressed_cb_mask |= 1 << i;
                }
        }
@@ -2957,6 +2971,7 @@ void si_init_state_functions(struct si_context *sctx)
        sctx->custom_dsa_flush_inplace = si_create_db_flush_dsa(sctx, false, 
false, 0);
        sctx->custom_blend_resolve = si_create_blend_custom(sctx, 
V_028808_CB_RESOLVE);
        sctx->custom_blend_decompress = si_create_blend_custom(sctx, 
V_028808_CB_FMASK_DECOMPRESS);
+       sctx->custom_blend_fastclear = si_create_blend_custom(sctx, 
V_028808_CB_ELIMINATE_FAST_CLEAR);
 
        sctx->b.b.set_clip_state = si_set_clip_state;
        sctx->b.b.set_scissor_states = si_set_scissor_states;
-- 
1.8.3.2

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

Reply via email to