Merge branch 'radv_better_tiling_3d' into 'main'

ac/surface,radv: select better swizzle mode for 2D compatibles images or 3D CB render targets

See merge request mesa/mesa!38084
This commit is contained in:
Samuel Pitoiset 2025-12-20 01:47:46 +01:00
commit 5f0dcba520
3 changed files with 56 additions and 6 deletions

View file

@ -1533,6 +1533,13 @@ static int gfx6_compute_surface(struct ac_addrlib *addrlib, const struct radeon_
if (!modes[i].supported)
continue;
/* 2D swizzle modes are optimal for 2D compatible images or 3D
* CB render targets.
*/
if (modes[i].align_depth > 1 &&
surf->flags & (RADEON_SURF_VIEW_3D_AS_2D_ARRAY | RADEON_SURF_CB_RENDER_TARGET))
continue;
uint64_t size = ac_estimate_size(config, surf->blk_w, surf->blk_h, surf->bpe * 8,
config->info.width, config->info.height,
modes[i].align_width, modes[i].align_height,
@ -2676,6 +2683,13 @@ static int gfx9_compute_surface(struct ac_addrlib *addrlib, const struct radeon_
const struct ac_surf_config *config, enum radeon_surf_mode mode,
struct radeon_surf *surf)
{
bool is_color_surface = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER);
bool is_cb_render_target = !!(surf->flags & RADEON_SURF_CB_RENDER_TARGET);
/* For GFX10+ MSAA PRT surface won't use the prt flag because it's not supported. */
bool is_prt_surface = (surf->flags & RADEON_SURF_PRT) != 0 &&
(config->info.samples <= 1 || info->gfx_level < GFX10) &&
is_color_surface;
bool view3dAs2dArray = false;
bool compressed;
ADDR2_COMPUTE_SURFACE_INFO_INPUT AddrSurfInfoIn = {0};
int r;
@ -2688,7 +2702,19 @@ static int gfx9_compute_surface(struct ac_addrlib *addrlib, const struct radeon_
if (!compressed)
AddrSurfInfoIn.bpp = surf->bpe * 8;
bool is_color_surface = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER);
/* Only compatible with non-sparse because 3D sparse requires 3D tiling. */
if (!is_prt_surface) {
/* Try to select a better swizzle for 2D compatible images. */
if (surf->flags & RADEON_SURF_VIEW_3D_AS_2D_ARRAY)
view3dAs2dArray = true;
/* 2D swizzle modes for 3D CB render targets are optimal regardless of
* the access pattern because CB prefers thin tiling.
*/
if (config->is_3d && is_cb_render_target)
view3dAs2dArray = true;
}
AddrSurfInfoIn.flags.color = is_color_surface && !(surf->flags & RADEON_SURF_NO_RENDER_TARGET);
AddrSurfInfoIn.flags.depth = (surf->flags & RADEON_SURF_ZBUFFER) != 0;
AddrSurfInfoIn.flags.display = get_display_flag(config, surf);
@ -2696,10 +2722,8 @@ static int gfx9_compute_surface(struct ac_addrlib *addrlib, const struct radeon_
AddrSurfInfoIn.flags.texture = (is_color_surface && !(surf->flags & RADEON_SURF_NO_TEXTURE)) ||
(surf->flags & RADEON_SURF_TC_COMPATIBLE_HTILE);
AddrSurfInfoIn.flags.opt4space = 1;
/* For GFX10+ MSAA PRT surface won't use the prt flag because it's not supported. */
AddrSurfInfoIn.flags.prt = (surf->flags & RADEON_SURF_PRT) != 0 &&
(config->info.samples <= 1 || info->gfx_level < GFX10) &&
is_color_surface;
AddrSurfInfoIn.flags.prt = is_prt_surface;
AddrSurfInfoIn.flags.view3dAs2dArray = view3dAs2dArray;
AddrSurfInfoIn.numMipLevels = config->info.levels;
AddrSurfInfoIn.numSamples = MAX2(1, config->info.samples);
@ -3473,6 +3497,10 @@ static bool gfx12_compute_surface(struct ac_addrlib *addrlib, const struct radeo
{
bool compressed = surf->blk_w == 4 && surf->blk_h == 4;
bool stencil_only = (surf->flags & RADEON_SURF_SBUFFER) && !(surf->flags & RADEON_SURF_ZBUFFER);
bool is_cb_render_target = !!(surf->flags & RADEON_SURF_CB_RENDER_TARGET);
bool is_prt_surface = !!(surf->flags & RADEON_SURF_PRT);
bool view3dAs2dArray = false;
ADDR3_COMPUTE_SURFACE_INFO_INPUT AddrSurfInfoIn = {0};
AddrSurfInfoIn.size = sizeof(ADDR3_COMPUTE_SURFACE_INFO_INPUT);
@ -3486,11 +3514,25 @@ static bool gfx12_compute_surface(struct ac_addrlib *addrlib, const struct radeo
AddrSurfInfoIn.bpp = surf->bpe * 8;
}
/* Only compatible with non-sparse because 3D sparse requires 3D tiling. */
if (!is_prt_surface) {
/* Try to select a better swizzle for 2D compatible images. */
if (surf->flags & RADEON_SURF_VIEW_3D_AS_2D_ARRAY)
view3dAs2dArray = true;
/* 2D swizzle modes for 3D CB render targets are optimal regardless of
* the access pattern because CB prefers thin tiling.
*/
if (config->is_3d && is_cb_render_target)
view3dAs2dArray = true;
}
AddrSurfInfoIn.flags.depth = !!(surf->flags & RADEON_SURF_ZBUFFER);
AddrSurfInfoIn.flags.stencil = stencil_only;
AddrSurfInfoIn.flags.blockCompressed = compressed;
AddrSurfInfoIn.flags.isVrsImage = !!(surf->flags & RADEON_SURF_VRS_RATE);
AddrSurfInfoIn.flags.standardPrt = !!(surf->flags & RADEON_SURF_PRT);
AddrSurfInfoIn.flags.standardPrt = is_prt_surface;
AddrSurfInfoIn.flags.view3dAs2dArray = view3dAs2dArray;
if (config->is_3d)
AddrSurfInfoIn.resourceType = ADDR_RSRC_TEX_3D;

View file

@ -79,6 +79,8 @@ enum radeon_micro_mode
#define RADEON_SURF_ENCODE_SRC (1ull << 41)
#define RADEON_SURF_ALIASED (1ull << 42)
#define RADEON_SURF_REPLAYABLE (1ull << 43)
#define RADEON_SURF_VIEW_3D_AS_2D_ARRAY (1ull << 44)
#define RADEON_SURF_CB_RENDER_TARGET (1ull << 45)
struct legacy_surf_level {
uint32_t offset_256B; /* divided by 256, the hw can only do 40-bit addresses */

View file

@ -657,6 +657,12 @@ radv_get_surface_flags(struct radv_device *device, struct radv_image *image, uns
UNREACHABLE("unhandled image type");
}
if (image->vk.create_flags & (VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT | VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT))
flags |= RADEON_SURF_VIEW_3D_AS_2D_ARRAY;
if (image->vk.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
flags |= RADEON_SURF_CB_RENDER_TARGET;
/* Required for clearing/initializing a specific layer on GFX8. */
flags |= RADEON_SURF_CONTIGUOUS_DCC_LAYERS;