[Mesa-dev] [PATCH 1/7] ac/surface: handle DCC subresource fast clear restriction on VI

Marek Olšák maraeo at gmail.com
Tue Apr 24 19:56:47 UTC 2018


From: Marek Olšák <marek.olsak at 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



More information about the mesa-dev mailing list