<div dir="ltr">Ping. Thanks.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Apr 24, 2018 at 3:56 PM, Marek Olšák <span dir="ltr"><<a href="mailto:maraeo@gmail.com" target="_blank">maraeo@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Marek Olšák <<a href="mailto:marek.olsak@amd.com">marek.olsak@amd.com</a>><br>
<br>
v2: require the previous level to be clearable for determining whether<br>
    the last unaligned level is clearable<br>
---<br>
 src/amd/common/ac_surface.c | 18 +++++++++++++++++-<br>
 1 file changed, 17 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c<br>
index a23952717e3..487f6c6431b 100644<br>
--- a/src/amd/common/ac_surface.c<br>
+++ b/src/amd/common/ac_surface.c<br>
@@ -336,36 +336,52 @@ static int gfx6_compute_level(ADDR_HANDLE addrlib,<br>
                surf->u.legacy.tiling_index[<wbr>level] = AddrSurfInfoOut->tileIndex;<br>
<br>
        surf->surf_size = surf_level->offset + AddrSurfInfoOut->surfSize;<br>
<br>
        /* Clear DCC fields at the beginning. */<br>
        surf_level->dcc_offset = 0;<br>
<br>
        /* The previous level's flag tells us if we can use DCC for this level. */<br>
        if (AddrSurfInfoIn->flags.<wbr>dccCompatible &&<br>
            (level == 0 || AddrDccOut-><wbr>subLvlCompressible)) {<br>
+               bool prev_level_clearable = level == 0 ||<br>
+                                           AddrDccOut->dccRamSizeAligned;<br>
+<br>
                AddrDccIn->colorSurfSize = AddrSurfInfoOut->surfSize;<br>
                AddrDccIn->tileMode = AddrSurfInfoOut->tileMode;<br>
<span class="">                AddrDccIn->tileInfo = *AddrSurfInfoOut->pTileInfo;<br>
                AddrDccIn->tileIndex = AddrSurfInfoOut->tileIndex;<br>
                AddrDccIn->macroModeIndex = AddrSurfInfoOut-><wbr>macroModeIndex;<br>
<br>
                ret = AddrComputeDccInfo(addrlib,<br>
                                         AddrDccIn,<br>
                                         AddrDccOut);<br>
<br>
                if (ret == ADDR_OK) {<br>
                        surf_level->dcc_offset = surf->dcc_size;<br>
-                       surf_level->dcc_fast_clear_<wbr>size = AddrDccOut->dccFastClearSize;<br>
                        surf->num_dcc_levels = level + 1;<br>
                        surf->dcc_size = surf_level->dcc_offset + AddrDccOut->dccRamSize;<br>
                        surf->dcc_alignment = MAX2(surf->dcc_alignment, AddrDccOut->dccRamBaseAlign);<br>
+<br>
+                       /* If the DCC size of a subresource (1 mip level or 1 slice)<br>
+                        * is not aligned, the DCC memory layout is not contiguous for<br>
+                        * that subresource, which means we can't use fast clear.<br>
+                        *<br>
+                        * We only do fast clears for whole mipmap levels. If we did<br>
+                        * per-slice fast clears, the same restriction would apply.<br>
+                        * (i.e. only compute the slice size and see if it's aligned)<br>
+                        */<br>
</span>+                       if (AddrDccOut->dccRamSizeAligned ||<br>
+                           (prev_level_clearable && level == config->info.levels - 1))<br>
+                               surf_level->dcc_fast_clear_<wbr>size = AddrDccOut->dccFastClearSize;<br>
<span class="">+                       else<br>
+                               surf_level->dcc_fast_clear_<wbr>size = 0;<br>
                }<br>
        }<br>
<br>
        /* TC-compatible HTILE. */<br>
        if (!is_stencil &&<br>
            AddrSurfInfoIn->flags.depth &&<br>
            surf_level->mode == RADEON_SURF_MODE_2D &&<br>
            level == 0) {<br>
                AddrHtileIn->flags.<wbr>tcCompatible = AddrSurfInfoIn->flags.<wbr>tcCompatible;<br>
                AddrHtileIn->pitch = AddrSurfInfoOut->pitch;<br>
-- <br>
</span>2.17.0<br>
<br>
</blockquote></div><br></div>