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

GFX9 is more complicated and needs a compute shader that we should just
copy from amdvlk.
---
 src/gallium/drivers/radeonsi/si_clear.c | 17 ++++++++++++-----
 src/gallium/drivers/radeonsi/si_state.c | 16 ++++++++++++----
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_clear.c 
b/src/gallium/drivers/radeonsi/si_clear.c
index 4e05d9bf5b2..b08a9558b4d 100644
--- a/src/gallium/drivers/radeonsi/si_clear.c
+++ b/src/gallium/drivers/radeonsi/si_clear.c
@@ -362,33 +362,40 @@ static void si_do_fast_color_clear(struct si_context 
*sctx,
                unsigned clear_bit = PIPE_CLEAR_COLOR0 << i;
 
                if (!fb->cbufs[i])
                        continue;
 
                /* if this colorbuffer is not being cleared */
                if (!(*buffers & clear_bit))
                        continue;
 
                unsigned level = fb->cbufs[i]->u.tex.level;
+               if (level > 0)
+                       continue;
+
                tex = (struct r600_texture *)fb->cbufs[i]->texture;
 
+               /* TODO: GFX9: Implement DCC fast clear for level 0 of
+                * mipmapped textures. Mipmapped DCC has to clear a rectangular
+                * area of DCC for level 0 (because the whole miptree is
+                * organized in a 2D plane).
+                */
+               if (sctx->chip_class >= GFX9 &&
+                   tex->resource.b.b.last_level > 0)
+                       continue;
+
                /* the clear is allowed if all layers are bound */
                if (fb->cbufs[i]->u.tex.first_layer != 0 ||
                    fb->cbufs[i]->u.tex.last_layer != 
util_max_layer(&tex->resource.b.b, 0)) {
                        continue;
                }
 
-               /* cannot clear mipmapped textures */
-               if (fb->cbufs[i]->texture->last_level != 0) {
-                       continue;
-               }
-
                /* only supported on tiled surfaces */
                if (tex->surface.is_linear) {
                        continue;
                }
 
                /* shared textures can't use fast clear without an explicit 
flush,
                 * because there is no way to communicate the clear color among
                 * all clients
                 */
                if (tex->resource.b.is_shared &&
diff --git a/src/gallium/drivers/radeonsi/si_state.c 
b/src/gallium/drivers/radeonsi/si_state.c
index 3faf36f2470..26f61afcab0 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -2956,21 +2956,21 @@ static void si_emit_framebuffer_state(struct si_context 
*sctx, struct r600_atom
 {
        struct radeon_winsys_cs *cs = sctx->gfx_cs;
        struct pipe_framebuffer_state *state = &sctx->framebuffer.state;
        unsigned i, nr_cbufs = state->nr_cbufs;
        struct r600_texture *tex = NULL;
        struct r600_surface *cb = NULL;
        unsigned cb_color_info = 0;
 
        /* Colorbuffers. */
        for (i = 0; i < nr_cbufs; i++) {
-               uint64_t cb_color_base, cb_color_fmask, cb_dcc_base;
+               uint64_t cb_color_base, cb_color_fmask, cb_color_cmask, 
cb_dcc_base;
                unsigned cb_color_attrib;
 
                if (!(sctx->framebuffer.dirty_cbufs & (1 << i)))
                        continue;
 
                cb = (struct r600_surface*)state->cbufs[i];
                if (!cb) {
                        radeon_set_context_reg(cs, R_028C70_CB_COLOR0_INFO + i 
* 0x3C,
                                               
S_028C70_FORMAT(V_028C70_COLOR_INVALID));
                        continue;
@@ -2991,24 +2991,28 @@ static void si_emit_framebuffer_state(struct si_context 
*sctx, struct r600_atom
 
                if (tex->dcc_separate_buffer)
                        radeon_add_to_buffer_list(sctx, sctx->gfx_cs,
                                                  tex->dcc_separate_buffer,
                                                  RADEON_USAGE_READWRITE,
                                                  RADEON_PRIO_DCC);
 
                /* Compute mutable surface parameters. */
                cb_color_base = tex->resource.gpu_address >> 8;
                cb_color_fmask = 0;
+               cb_color_cmask = tex->cmask.base_address_reg;
                cb_dcc_base = 0;
                cb_color_info = cb->cb_color_info | tex->cb_color_info;
                cb_color_attrib = cb->cb_color_attrib;
 
+               if (cb->base.u.tex.level > 0)
+                       cb_color_info &= C_028C70_FAST_CLEAR;
+
                if (tex->fmask.size) {
                        cb_color_fmask = (tex->resource.gpu_address + 
tex->fmask.offset) >> 8;
                        cb_color_fmask |= tex->fmask.tile_swizzle;
                }
 
                /* Set up DCC. */
                if (vi_dcc_enabled(tex, cb->base.u.tex.level)) {
                        bool is_msaa_resolve_dst = state->cbufs[0] &&
                                                   
state->cbufs[0]->texture->nr_samples > 1 &&
                                                   state->cbufs[1] == &cb->base 
&&
@@ -3028,35 +3032,37 @@ static void si_emit_framebuffer_state(struct si_context 
*sctx, struct r600_atom
                        if (tex->dcc_offset)
                                meta = tex->surface.u.gfx9.dcc;
                        else
                                meta = tex->surface.u.gfx9.cmask;
 
                        /* Set mutable surface parameters. */
                        cb_color_base += tex->surface.u.gfx9.surf_offset >> 8;
                        cb_color_base |= tex->surface.tile_swizzle;
                        if (!tex->fmask.size)
                                cb_color_fmask = cb_color_base;
+                       if (cb->base.u.tex.level > 0)
+                               cb_color_cmask = cb_color_base;
                        cb_color_attrib |= 
S_028C74_COLOR_SW_MODE(tex->surface.u.gfx9.surf.swizzle_mode) |
                                           
S_028C74_FMASK_SW_MODE(tex->surface.u.gfx9.fmask.swizzle_mode) |
                                           S_028C74_RB_ALIGNED(meta.rb_aligned) 
|
                                           
S_028C74_PIPE_ALIGNED(meta.pipe_aligned);
 
                        radeon_set_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE 
+ i * 0x3C, 15);
                        radeon_emit(cs, cb_color_base);         /* 
CB_COLOR0_BASE */
                        radeon_emit(cs, S_028C64_BASE_256B(cb_color_base >> 
32)); /* CB_COLOR0_BASE_EXT */
                        radeon_emit(cs, cb->cb_color_attrib2);  /* 
CB_COLOR0_ATTRIB2 */
                        radeon_emit(cs, cb->cb_color_view);     /* 
CB_COLOR0_VIEW */
                        radeon_emit(cs, cb_color_info);         /* 
CB_COLOR0_INFO */
                        radeon_emit(cs, cb_color_attrib);       /* 
CB_COLOR0_ATTRIB */
                        radeon_emit(cs, cb->cb_dcc_control);    /* 
CB_COLOR0_DCC_CONTROL */
-                       radeon_emit(cs, tex->cmask.base_address_reg); /* 
CB_COLOR0_CMASK */
-                       radeon_emit(cs, 
S_028C80_BASE_256B(tex->cmask.base_address_reg >> 32)); /* 
CB_COLOR0_CMASK_BASE_EXT */
+                       radeon_emit(cs, cb_color_cmask);        /* 
CB_COLOR0_CMASK */
+                       radeon_emit(cs, S_028C80_BASE_256B(cb_color_cmask >> 
32)); /* CB_COLOR0_CMASK_BASE_EXT */
                        radeon_emit(cs, cb_color_fmask);        /* 
CB_COLOR0_FMASK */
                        radeon_emit(cs, S_028C88_BASE_256B(cb_color_fmask >> 
32)); /* CB_COLOR0_FMASK_BASE_EXT */
                        radeon_emit(cs, tex->color_clear_value[0]); /* 
CB_COLOR0_CLEAR_WORD0 */
                        radeon_emit(cs, tex->color_clear_value[1]); /* 
CB_COLOR0_CLEAR_WORD1 */
                        radeon_emit(cs, cb_dcc_base);           /* 
CB_COLOR0_DCC_BASE */
                        radeon_emit(cs, S_028C98_BASE_256B(cb_dcc_base >> 32)); 
/* CB_COLOR0_DCC_BASE_EXT */
 
                        radeon_set_context_reg(cs, R_0287A0_CB_MRT0_EPITCH + i 
* 4,
                                               
S_0287A0_EPITCH(tex->surface.u.gfx9.surf.epitch));
                } else {
@@ -3066,20 +3072,22 @@ static void si_emit_framebuffer_state(struct si_context 
*sctx, struct r600_atom
                        unsigned pitch_tile_max, slice_tile_max, 
tile_mode_index;
                        unsigned cb_color_pitch, cb_color_slice, 
cb_color_fmask_slice;
 
                        cb_color_base += level_info->offset >> 8;
                        /* Only macrotiled modes can set tile swizzle. */
                        if (level_info->mode == RADEON_SURF_MODE_2D)
                                cb_color_base |= tex->surface.tile_swizzle;
 
                        if (!tex->fmask.size)
                                cb_color_fmask = cb_color_base;
+                       if (cb->base.u.tex.level > 0)
+                               cb_color_cmask = cb_color_base;
                        if (cb_dcc_base)
                                cb_dcc_base += level_info->dcc_offset >> 8;
 
                        pitch_tile_max = level_info->nblk_x / 8 - 1;
                        slice_tile_max = level_info->nblk_x *
                                         level_info->nblk_y / 64 - 1;
                        tile_mode_index = si_tile_mode_index(tex, 
cb->base.u.tex.level, false);
 
                        cb_color_attrib |= 
S_028C74_TILE_MODE_INDEX(tile_mode_index);
                        cb_color_pitch = S_028C64_TILE_MAX(pitch_tile_max);
@@ -3100,21 +3108,21 @@ static void si_emit_framebuffer_state(struct si_context 
*sctx, struct r600_atom
 
                        radeon_set_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE 
+ i * 0x3C,
                                                   sctx->chip_class >= VI ? 14 
: 13);
                        radeon_emit(cs, cb_color_base);         /* 
CB_COLOR0_BASE */
                        radeon_emit(cs, cb_color_pitch);        /* 
CB_COLOR0_PITCH */
                        radeon_emit(cs, cb_color_slice);        /* 
CB_COLOR0_SLICE */
                        radeon_emit(cs, cb->cb_color_view);     /* 
CB_COLOR0_VIEW */
                        radeon_emit(cs, cb_color_info);         /* 
CB_COLOR0_INFO */
                        radeon_emit(cs, cb_color_attrib);       /* 
CB_COLOR0_ATTRIB */
                        radeon_emit(cs, cb->cb_dcc_control);    /* 
CB_COLOR0_DCC_CONTROL */
-                       radeon_emit(cs, tex->cmask.base_address_reg);   /* 
CB_COLOR0_CMASK */
+                       radeon_emit(cs, cb_color_cmask);        /* 
CB_COLOR0_CMASK */
                        radeon_emit(cs, tex->cmask.slice_tile_max);     /* 
CB_COLOR0_CMASK_SLICE */
                        radeon_emit(cs, cb_color_fmask);                /* 
CB_COLOR0_FMASK */
                        radeon_emit(cs, cb_color_fmask_slice);          /* 
CB_COLOR0_FMASK_SLICE */
                        radeon_emit(cs, tex->color_clear_value[0]);     /* 
CB_COLOR0_CLEAR_WORD0 */
                        radeon_emit(cs, tex->color_clear_value[1]);     /* 
CB_COLOR0_CLEAR_WORD1 */
 
                        if (sctx->chip_class >= VI) /* 
R_028C94_CB_COLOR0_DCC_BASE */
                                radeon_emit(cs, cb_dcc_base);
                }
        }
-- 
2.17.0

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

Reply via email to