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

v2: require the previous level to be clearable for determining whether
    the last unaligned level is clearable
---
 src/amd/common/ac_surface.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c
index a23952717e3..487f6c6431b 100644
--- a/src/amd/common/ac_surface.c
+++ b/src/amd/common/ac_surface.c
@@ -336,36 +336,52 @@ static int gfx6_compute_level(ADDR_HANDLE addrlib,
                surf->u.legacy.tiling_index[level] = AddrSurfInfoOut->tileIndex;
 
        surf->surf_size = surf_level->offset + AddrSurfInfoOut->surfSize;
 
        /* Clear DCC fields at the beginning. */
        surf_level->dcc_offset = 0;
 
        /* The previous level's flag tells us if we can use DCC for this level. 
*/
        if (AddrSurfInfoIn->flags.dccCompatible &&
            (level == 0 || AddrDccOut->subLvlCompressible)) {
+               bool prev_level_clearable = level == 0 ||
+                                           AddrDccOut->dccRamSizeAligned;
+
                AddrDccIn->colorSurfSize = AddrSurfInfoOut->surfSize;
                AddrDccIn->tileMode = AddrSurfInfoOut->tileMode;
                AddrDccIn->tileInfo = *AddrSurfInfoOut->pTileInfo;
                AddrDccIn->tileIndex = AddrSurfInfoOut->tileIndex;
                AddrDccIn->macroModeIndex = AddrSurfInfoOut->macroModeIndex;
 
                ret = AddrComputeDccInfo(addrlib,
                                         AddrDccIn,
                                         AddrDccOut);
 
                if (ret == ADDR_OK) {
                        surf_level->dcc_offset = surf->dcc_size;
-                       surf_level->dcc_fast_clear_size = 
AddrDccOut->dccFastClearSize;
                        surf->num_dcc_levels = level + 1;
                        surf->dcc_size = surf_level->dcc_offset + 
AddrDccOut->dccRamSize;
                        surf->dcc_alignment = MAX2(surf->dcc_alignment, 
AddrDccOut->dccRamBaseAlign);
+
+                       /* If the DCC size of a subresource (1 mip level or 1 
slice)
+                        * is not aligned, the DCC memory layout is not 
contiguous for
+                        * that subresource, which means we can't use fast 
clear.
+                        *
+                        * We only do fast clears for whole mipmap levels. If 
we did
+                        * per-slice fast clears, the same restriction would 
apply.
+                        * (i.e. only compute the slice size and see if it's 
aligned)
+                        */
+                       if (AddrDccOut->dccRamSizeAligned ||
+                           (prev_level_clearable && level == 
config->info.levels - 1))
+                               surf_level->dcc_fast_clear_size = 
AddrDccOut->dccFastClearSize;
+                       else
+                               surf_level->dcc_fast_clear_size = 0;
                }
        }
 
        /* TC-compatible HTILE. */
        if (!is_stencil &&
            AddrSurfInfoIn->flags.depth &&
            surf_level->mode == RADEON_SURF_MODE_2D &&
            level == 0) {
                AddrHtileIn->flags.tcCompatible = 
AddrSurfInfoIn->flags.tcCompatible;
                AddrHtileIn->pitch = AddrSurfInfoOut->pitch;
-- 
2.17.0

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

Reply via email to