[Mesa-dev] [PATCH 1/4] ac/surface: don't set the display flag for obviously unsupported cases (v2)

Marek Olšák maraeo at gmail.com
Fri Apr 6 17:12:41 UTC 2018


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

This enables the tile swizzle for some cases of the displayable micro mode,
and it also fixes an addrlib assertion failure on Vega.
---
 src/amd/common/ac_surface.c                    | 34 +++++++++++++++++++++++---
 src/amd/common/ac_surface.h                    |  1 +
 src/amd/vulkan/radv_image.c                    |  1 +
 src/gallium/winsys/amdgpu/drm/amdgpu_surface.c |  1 +
 4 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c
index b294cd85259..1b4d72e31bd 100644
--- a/src/amd/common/ac_surface.c
+++ b/src/amd/common/ac_surface.c
@@ -408,20 +408,45 @@ static unsigned cik_get_macro_tile_index(struct radeon_surf *surf)
 	tileb = 8 * 8 * surf->bpe;
 	tileb = MIN2(surf->u.legacy.tile_split, tileb);
 
 	for (index = 0; tileb > 64; index++)
 		tileb >>= 1;
 
 	assert(index < 16);
 	return index;
 }
 
+static bool get_display_flag(const struct ac_surf_config *config,
+			     const struct radeon_surf *surf)
+{
+	unsigned num_channels = config->info.num_channels;
+	unsigned bpe = surf->bpe;
+
+	if (surf->flags & RADEON_SURF_SCANOUT &&
+	    !(surf->flags & RADEON_SURF_FMASK) &&
+	    config->info.samples <= 1 &&
+	    surf->blk_w <= 2 && surf->blk_h == 1) {
+		/* subsampled */
+		if (surf->blk_w == 2 && surf->blk_h == 1)
+			return true;
+
+		if  (/* RGBA8 or RGBA16F */
+		     (bpe >= 4 && bpe <= 8 && num_channels == 4) ||
+		     /* R5G6B5 or R5G5B5A1 */
+		     (bpe == 2 && num_channels >= 3) ||
+		     /* C8 palette */
+		     (bpe == 1 && num_channels == 1))
+			return true;
+	}
+	return false;
+}
+
 /**
  * This must be called after the first level is computed.
  *
  * Copy surface-global settings like pipe/bank config from level 0 surface
  * computation, and compute tile swizzle.
  */
 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,
@@ -442,21 +467,21 @@ static int gfx6_surface_settings(ADDR_HANDLE addrlib,
 	} else {
 		surf->u.legacy.macro_tile_index = 0;
 	}
 
 	/* Compute tile swizzle. */
 	/* TODO: fix tile swizzle with mipmapping for SI */
 	if ((info->chip_class >= CIK || config->info.levels == 1) &&
 	    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))) {
+	    !get_display_flag(config, surf)) {
 		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;
@@ -561,21 +586,21 @@ static int gfx6_compute_surface(ADDR_HANDLE addrlib,
 		AddrSurfInfoIn.tileType = ADDR_DISPLAYABLE;
 	else if (surf->flags & (RADEON_SURF_Z_OR_SBUFFER | RADEON_SURF_FMASK))
 		AddrSurfInfoIn.tileType = ADDR_DEPTH_SAMPLE_ORDER;
 	else
 		AddrSurfInfoIn.tileType = ADDR_NON_DISPLAYABLE;
 
 	AddrSurfInfoIn.flags.color = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER);
 	AddrSurfInfoIn.flags.depth = (surf->flags & RADEON_SURF_ZBUFFER) != 0;
 	AddrSurfInfoIn.flags.cube = config->is_cube;
 	AddrSurfInfoIn.flags.fmask = (surf->flags & RADEON_SURF_FMASK) != 0;
-	AddrSurfInfoIn.flags.display = (surf->flags & RADEON_SURF_SCANOUT) != 0;
+	AddrSurfInfoIn.flags.display = get_display_flag(config, surf);
 	AddrSurfInfoIn.flags.pow2Pad = config->info.levels > 1;
 	AddrSurfInfoIn.flags.tcCompatible = (surf->flags & RADEON_SURF_TC_COMPATIBLE_HTILE) != 0;
 
 	/* Only degrade the tile mode for space if TC-compatible HTILE hasn't been
 	 * requested, because TC-compatible HTILE requires 2D tiling.
 	 */
 	AddrSurfInfoIn.flags.opt4Space = !AddrSurfInfoIn.flags.tcCompatible &&
 					 !AddrSurfInfoIn.flags.fmask &&
 					 config->info.samples <= 1 &&
 					 (surf->flags & RADEON_SURF_OPTIMIZE_FOR_SPACE);
@@ -841,20 +866,21 @@ gfx9_get_preferred_swizzle_mode(ADDR_HANDLE addrlib,
 	sin.numFrags = in->numFrags;
 
 	if (flags & RADEON_SURF_SCANOUT)
 		sin.preferredSwSet.sw_D = 1;
 	else if (in->flags.depth || in->flags.stencil || is_fmask)
 		sin.preferredSwSet.sw_Z = 1;
 	else
 		sin.preferredSwSet.sw_S = 1;
 
 	if (is_fmask) {
+		sin.flags.display = 0;
 		sin.flags.color = 0;
 		sin.flags.fmask = 1;
 	}
 
 	ret = Addr2GetPreferredSurfaceSetting(addrlib, &sin, &sout);
 	if (ret != ADDR_OK)
 		return ret;
 
 	*swizzle_mode = sout.swizzleMode;
 	return 0;
@@ -936,21 +962,21 @@ static int gfx9_compute_miptree(ADDR_HANDLE addrlib,
 		surf->htile_slice_size = hout.sliceSize;
 		surf->htile_alignment = hout.baseAlign;
 	} else {
 		/* Compute tile swizzle for the color surface.
 		 * All *_X and *_T modes can use the swizzle.
 		 */
 		if (config->info.surf_index &&
 		    in->swizzleMode >= ADDR_SW_64KB_Z_T &&
 		    !out.mipChainInTail &&
 		    !(surf->flags & RADEON_SURF_SHAREABLE) &&
-		    (in->numSamples > 1 || !(surf->flags & RADEON_SURF_SCANOUT))) {
+		    !in->flags.display) {
 			ADDR2_COMPUTE_PIPEBANKXOR_INPUT xin = {0};
 			ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT xout = {0};
 
 			xin.size = sizeof(ADDR2_COMPUTE_PIPEBANKXOR_INPUT);
 			xout.size = sizeof(ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT);
 
 			xin.surfIndex = p_atomic_inc_return(config->info.surf_index) - 1;
 			xin.flags = in->flags;
 			xin.swizzleMode = in->swizzleMode;
 			xin.resourceType = in->resourceType;
@@ -1189,21 +1215,21 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
 			AddrSurfInfoIn.format = ADDR_FMT_32_32_32_32;
 			break;
 		default:
 			assert(0);
 		}
 		AddrSurfInfoIn.bpp = surf->bpe * 8;
 	}
 
 	AddrSurfInfoIn.flags.color = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER);
 	AddrSurfInfoIn.flags.depth = (surf->flags & RADEON_SURF_ZBUFFER) != 0;
-	AddrSurfInfoIn.flags.display = (surf->flags & RADEON_SURF_SCANOUT) != 0;
+	AddrSurfInfoIn.flags.display = get_display_flag(config, surf);
 	/* flags.texture currently refers to TC-compatible HTILE */
 	AddrSurfInfoIn.flags.texture = AddrSurfInfoIn.flags.color ||
 				       surf->flags & RADEON_SURF_TC_COMPATIBLE_HTILE;
 	AddrSurfInfoIn.flags.opt4space = 1;
 
 	AddrSurfInfoIn.numMipLevels = config->info.levels;
 	AddrSurfInfoIn.numSamples = config->info.samples ? config->info.samples : 1;
 	AddrSurfInfoIn.numFrags = AddrSurfInfoIn.numSamples;
 
 	/* GFX9 doesn't support 1D depth textures, so allocate all 1D textures
diff --git a/src/amd/common/ac_surface.h b/src/amd/common/ac_surface.h
index 71f320af8ee..37df859e6de 100644
--- a/src/amd/common/ac_surface.h
+++ b/src/amd/common/ac_surface.h
@@ -212,20 +212,21 @@ struct radeon_surf {
         struct gfx9_surf_layout gfx9;
     } u;
 };
 
 struct ac_surf_info {
 	uint32_t width;
 	uint32_t height;
 	uint32_t depth;
 	uint8_t samples;
 	uint8_t levels;
+	uint8_t num_channels; /* heuristic for displayability */
 	uint16_t array_size;
 	uint32_t *surf_index; /* Set a monotonic counter for tile swizzling. */
 	uint32_t *fmask_surf_index; /* GFX9+ */
 };
 
 struct ac_surf_config {
 	struct ac_surf_info info;
 	unsigned is_3d : 1;
 	unsigned is_cube : 1;
 };
diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
index dd3189c67d0..ef6f1072abd 100644
--- a/src/amd/vulkan/radv_image.c
+++ b/src/amd/vulkan/radv_image.c
@@ -919,20 +919,21 @@ radv_image_create(VkDevice _device,
 	if (!image)
 		return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
 	image->type = pCreateInfo->imageType;
 	image->info.width = pCreateInfo->extent.width;
 	image->info.height = pCreateInfo->extent.height;
 	image->info.depth = pCreateInfo->extent.depth;
 	image->info.samples = pCreateInfo->samples;
 	image->info.array_size = pCreateInfo->arrayLayers;
 	image->info.levels = pCreateInfo->mipLevels;
+	image->info.num_channels = 4; /* TODO: set this correctly */
 
 	image->vk_format = pCreateInfo->format;
 	image->tiling = pCreateInfo->tiling;
 	image->usage = pCreateInfo->usage;
 	image->flags = pCreateInfo->flags;
 
 	image->exclusive = pCreateInfo->sharingMode == VK_SHARING_MODE_EXCLUSIVE;
 	if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
 		for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; ++i)
 			if (pCreateInfo->pQueueFamilyIndices[i] == VK_QUEUE_FAMILY_EXTERNAL_KHR)
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
index fc5c9d5a127..b5a1ebb1628 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
@@ -79,20 +79,21 @@ static int amdgpu_surface_init(struct radeon_winsys *rws,
    surf->flags = flags;
 
    struct ac_surf_config config;
 
    config.info.width = tex->width0;
    config.info.height = tex->height0;
    config.info.depth = tex->depth0;
    config.info.array_size = tex->array_size;
    config.info.samples = tex->nr_samples;
    config.info.levels = tex->last_level + 1;
+   config.info.num_channels = util_format_get_nr_components(tex->format);
    config.is_3d = !!(tex->target == PIPE_TEXTURE_3D);
    config.is_cube = !!(tex->target == PIPE_TEXTURE_CUBE);
 
    /* Use different surface counters for color and FMASK, so that MSAA MRTs
     * always use consecutive surface indices when FMASK is allocated between
     * them.
     */
    if (flags & RADEON_SURF_FMASK)
       config.info.surf_index = &ws->surf_index_fmask;
    else if (!(flags & RADEON_SURF_Z_OR_SBUFFER))
-- 
2.15.1



More information about the mesa-dev mailing list