radeonsi: enable fast color clear for level 0 of mipmapped textures on <= VI
authorMarek Olšák <marek.olsak@amd.com>
Sun, 8 Apr 2018 04:19:50 +0000 (00:19 -0400)
committerMarek Olšák <marek.olsak@amd.com>
Fri, 27 Apr 2018 21:56:04 +0000 (17:56 -0400)
GFX9 is more complicated and needs a compute shader that we should just
copy from amdvlk.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeonsi/si_clear.c
src/gallium/drivers/radeonsi/si_state.c

index 4e05d9bf5b27b231d30104fd297b12eded98dc0c..b08a9558b4d3e10a922a9bff6795b4ea0683ed3c 100644 (file)
@@ -369,19 +369,26 @@ static void si_do_fast_color_clear(struct si_context *sctx,
                        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;
index a7c99427e172ffc5545c908bdc018ee1e0bdc62a..fee4f06dbee4b6e83b781973a79b8d2445f6ed78 100644 (file)
@@ -2963,7 +2963,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
 
        /* 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)))
@@ -2998,10 +2998,14 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
                /* 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;
@@ -3035,6 +3039,8 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
                        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) |
@@ -3048,8 +3054,8 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
                        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 */
@@ -3073,6 +3079,8 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
 
                        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;
 
@@ -3107,7 +3115,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
                        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 */