[Mesa-dev] [PATCH 07/14] ac/surface: enable tile swizzle for mipmapped textures

Marek Olšák maraeo at gmail.com
Mon Jul 31 23:40:30 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

The tile swizzle computation was done after the whole miptree was computed,
but that was too late, because at that point AddrSurfInfoOut contained
information about the smallest miplevel, which is never 2D-tiled.

The correct way is to do the computation before the second level is computed.
---
 src/amd/common/ac_surface.c | 80 ++++++++++++++++++++++++++-------------------
 1 file changed, 46 insertions(+), 34 deletions(-)

diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c
index 1eff4e5..87a8993 100644
--- a/src/amd/common/ac_surface.c
+++ b/src/amd/common/ac_surface.c
@@ -400,42 +400,74 @@ static unsigned cik_get_macro_tile_index(struct radeon_surf *surf)
 	tileb = MIN2(surf->u.legacy.tile_split, tileb);
 
 	for (index = 0; tileb > 64; index++)
 		tileb >>= 1;
 
 	assert(index < 16);
 	return index;
 }
 
 /**
+ * This must be called after the first level is computed.
+ *
  * Copy surface-global settings like pipe/bank config from level 0 surface
- * computation.
+ * computation, and compute tile swizzle.
  */
-static void gfx6_surface_settings(const struct radeon_info* info,
-				  ADDR_COMPUTE_SURFACE_INFO_OUTPUT* csio,
-				  struct radeon_surf *surf)
+static int gfx6_surface_settings(ADDR_HANDLE addrlib,
+				 const struct radeon_info *info,
+				 const struct ac_surf_config *config,
+				 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* csio,
+				 struct radeon_surf *surf)
 {
 	surf->surf_alignment = csio->baseAlign;
 	surf->u.legacy.pipe_config = csio->pTileInfo->pipeConfig - 1;
 	gfx6_set_micro_tile_mode(surf, info);
 
 	/* For 2D modes only. */
 	if (csio->tileMode >= ADDR_TM_2D_TILED_THIN1) {
 		surf->u.legacy.bankw = csio->pTileInfo->bankWidth;
 		surf->u.legacy.bankh = csio->pTileInfo->bankHeight;
 		surf->u.legacy.mtilea = csio->pTileInfo->macroAspectRatio;
 		surf->u.legacy.tile_split = csio->pTileInfo->tileSplitBytes;
 		surf->u.legacy.num_banks = csio->pTileInfo->banks;
 		surf->u.legacy.macro_tile_index = csio->macroModeIndex;
 	} else {
 		surf->u.legacy.macro_tile_index = 0;
 	}
+
+	/* Compute tile swizzle. */
+	if (config->info.surf_index &&
+	    surf->u.legacy.level[0].mode == RADEON_SURF_MODE_2D &&
+	    !(surf->flags & (RADEON_SURF_Z_OR_SBUFFER | RADEON_SURF_SHAREABLE)) &&
+	    (config->info.samples > 1 || !(surf->flags & RADEON_SURF_SCANOUT))) {
+		ADDR_COMPUTE_BASE_SWIZZLE_INPUT AddrBaseSwizzleIn = {0};
+		ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT AddrBaseSwizzleOut = {0};
+
+		AddrBaseSwizzleIn.size = sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT);
+		AddrBaseSwizzleOut.size = sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT);
+
+		AddrBaseSwizzleIn.surfIndex = p_atomic_inc_return(config->info.surf_index) - 1;
+		AddrBaseSwizzleIn.tileIndex = csio->tileIndex;
+		AddrBaseSwizzleIn.macroModeIndex = csio->macroModeIndex;
+		AddrBaseSwizzleIn.pTileInfo = csio->pTileInfo;
+		AddrBaseSwizzleIn.tileMode = csio->tileMode;
+
+		int r = AddrComputeBaseSwizzle(addrlib, &AddrBaseSwizzleIn,
+					       &AddrBaseSwizzleOut);
+		if (r != ADDR_OK)
+			return r;
+
+		assert(AddrBaseSwizzleOut.tileSwizzle <=
+		       u_bit_consecutive(0, sizeof(surf->tile_swizzle) * 8));
+		surf->tile_swizzle = AddrBaseSwizzleOut.tileSwizzle;
+	}
+	return 0;
 }
 
 /**
  * Fill in the tiling information in \p surf based on the given surface config.
  *
  * The following fields of \p surf must be initialized by the caller:
  * blk_w, blk_h, bpe, flags.
  */
 static int gfx6_compute_surface(ADDR_HANDLE addrlib,
 				const struct radeon_info *info,
@@ -637,21 +669,24 @@ static int gfx6_compute_surface(ADDR_HANDLE addrlib,
 		for (level = 0; level < config->info.levels; level++) {
 			r = gfx6_compute_level(addrlib, config, surf, false, level, compressed,
 					       &AddrSurfInfoIn, &AddrSurfInfoOut,
 					       &AddrDccIn, &AddrDccOut, &AddrHtileIn, &AddrHtileOut);
 			if (r)
 				return r;
 
 			if (level > 0)
 				continue;
 
-			gfx6_surface_settings(info, &AddrSurfInfoOut, surf);
+			r = gfx6_surface_settings(addrlib, info, config,
+						  &AddrSurfInfoOut, surf);
+			if (r)
+				return r;
 		}
 	}
 
 	/* Calculate texture layout information for stencil. */
 	if (surf->flags & RADEON_SURF_SBUFFER) {
 		AddrSurfInfoIn.bpp = 8;
 		AddrSurfInfoIn.flags.depth = 0;
 		AddrSurfInfoIn.flags.stencil = 1;
 		AddrSurfInfoIn.flags.tcCompatible = 0;
 		/* This will be ignored if AddrSurfInfoIn.pTileInfo is NULL. */
@@ -669,22 +704,26 @@ static int gfx6_compute_surface(ADDR_HANDLE addrlib,
 			if (!only_stencil) {
 				if (surf->u.legacy.stencil_level[level].nblk_x !=
 				    surf->u.legacy.level[level].nblk_x)
 					surf->u.legacy.stencil_adjusted = true;
 			} else {
 				surf->u.legacy.level[level].nblk_x =
 					surf->u.legacy.stencil_level[level].nblk_x;
 			}
 
 			if (level == 0) {
-				if (only_stencil)
-					gfx6_surface_settings(info, &AddrSurfInfoOut, surf);
+				if (only_stencil) {
+					r = gfx6_surface_settings(addrlib, info, config,
+								  &AddrSurfInfoOut, surf);
+					if (r)
+						return r;
+				}
 
 				/* For 2D modes only. */
 				if (AddrSurfInfoOut.tileMode >= ADDR_TM_2D_TILED_THIN1) {
 					surf->u.legacy.stencil_tile_split =
 						AddrSurfInfoOut.pTileInfo->tileSplitBytes;
 				}
 			}
 		}
 	}
 
@@ -698,47 +737,20 @@ static int gfx6_compute_surface(ADDR_HANDLE addrlib,
 					 info->num_tile_pipes);
 	}
 
 	/* Make sure HTILE covers the whole miptree, because the shader reads
 	 * TC-compatible HTILE even for levels where it's disabled by DB.
 	 */
 	if (surf->htile_size && config->info.levels > 1)
 		surf->htile_size *= 2;
 
 	surf->is_linear = surf->u.legacy.level[0].mode == RADEON_SURF_MODE_LINEAR_ALIGNED;
-
-	/* Work out tile swizzle. */
-	if (config->info.surf_index &&
-	    surf->u.legacy.level[0].mode == RADEON_SURF_MODE_2D &&
-	    !(surf->flags & (RADEON_SURF_Z_OR_SBUFFER | RADEON_SURF_SHAREABLE)) &&
-	    (config->info.samples > 1 || !(surf->flags & RADEON_SURF_SCANOUT))) {
-		ADDR_COMPUTE_BASE_SWIZZLE_INPUT AddrBaseSwizzleIn = {0};
-		ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT AddrBaseSwizzleOut = {0};
-
-		AddrBaseSwizzleIn.size = sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT);
-		AddrBaseSwizzleOut.size = sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT);
-
-		AddrBaseSwizzleIn.surfIndex = p_atomic_inc_return(config->info.surf_index) - 1;
-		AddrBaseSwizzleIn.tileIndex = AddrSurfInfoIn.tileIndex;
-		AddrBaseSwizzleIn.macroModeIndex = AddrSurfInfoOut.macroModeIndex;
-		AddrBaseSwizzleIn.pTileInfo = AddrSurfInfoOut.pTileInfo;
-		AddrBaseSwizzleIn.tileMode = AddrSurfInfoOut.tileMode;
-
-		r = AddrComputeBaseSwizzle(addrlib, &AddrBaseSwizzleIn,
-					   &AddrBaseSwizzleOut);
-		if (r != ADDR_OK)
-			return r;
-
-		assert(AddrBaseSwizzleOut.tileSwizzle <=
-		       u_bit_consecutive(0, sizeof(surf->tile_swizzle) * 8));
-		surf->tile_swizzle = AddrBaseSwizzleOut.tileSwizzle;
-	}
 	return 0;
 }
 
 /* This is only called when expecting a tiled layout. */
 static int
 gfx9_get_preferred_swizzle_mode(ADDR_HANDLE addrlib,
 				ADDR2_COMPUTE_SURFACE_INFO_INPUT *in,
 				bool is_fmask, AddrSwizzleMode *swizzle_mode)
 {
 	ADDR_E_RETURNCODE ret;
-- 
2.7.4



More information about the mesa-dev mailing list