From 269953e7798fa3c3d4edd3363d7d6a560a50e9f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 7 Jan 2020 23:53:26 -0500 Subject: [PATCH] radeonsi/gfx9: force the micro tile mode for MSAA resolve correctly on gfx9 Fixes: 69ea473 "amd/addrlib: update to the latest version" Closes: #2325 Reviewed-by: Pierre-Eric Pelloux-Prayer --- src/amd/common/ac_surface.c | 20 +++++++++++++++++--- src/amd/common/ac_surface.h | 1 + src/gallium/drivers/radeonsi/si_blit.c | 5 ++++- src/gallium/drivers/radeonsi/si_pipe.h | 5 +++++ src/gallium/drivers/radeonsi/si_texture.c | 6 ++++++ 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c index 92aab57920a..8a39f8b02d0 100644 --- a/src/amd/common/ac_surface.c +++ b/src/amd/common/ac_surface.c @@ -971,6 +971,7 @@ static int gfx6_compute_surface(ADDR_HANDLE addrlib, /* This is only called when expecting a tiled layout. */ static int gfx9_get_preferred_swizzle_mode(ADDR_HANDLE addrlib, + struct radeon_surf *surf, ADDR2_COMPUTE_SURFACE_INFO_INPUT *in, bool is_fmask, AddrSwizzleMode *swizzle_mode) { @@ -1002,6 +1003,19 @@ gfx9_get_preferred_swizzle_mode(ADDR_HANDLE addrlib, sin.flags.fmask = 1; } + if (surf->flags & RADEON_SURF_FORCE_MICRO_TILE_MODE) { + sin.forbiddenBlock.linear = 1; + + if (surf->micro_tile_mode == RADEON_MICRO_MODE_DISPLAY) + sin.preferredSwSet.sw_D = 1; + else if (surf->micro_tile_mode == RADEON_MICRO_MODE_THIN) + sin.preferredSwSet.sw_S = 1; + else if (surf->micro_tile_mode == RADEON_MICRO_MODE_DEPTH) + sin.preferredSwSet.sw_Z = 1; + else if (surf->micro_tile_mode == RADEON_MICRO_MODE_ROTATED) + sin.preferredSwSet.sw_R = 1; + } + ret = Addr2GetPreferredSurfaceSetting(addrlib, &sin, &sout); if (ret != ADDR_OK) return ret; @@ -1314,7 +1328,7 @@ static int gfx9_compute_miptree(ADDR_HANDLE addrlib, fin.size = sizeof(ADDR2_COMPUTE_FMASK_INFO_INPUT); fout.size = sizeof(ADDR2_COMPUTE_FMASK_INFO_OUTPUT); - ret = gfx9_get_preferred_swizzle_mode(addrlib, in, + ret = gfx9_get_preferred_swizzle_mode(addrlib, surf, in, true, &fin.swizzleMode); if (ret != ADDR_OK) return ret; @@ -1536,7 +1550,7 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib, break; } - r = gfx9_get_preferred_swizzle_mode(addrlib, &AddrSurfInfoIn, + r = gfx9_get_preferred_swizzle_mode(addrlib, surf, &AddrSurfInfoIn, false, &AddrSurfInfoIn.swizzleMode); if (r) return r; @@ -1575,7 +1589,7 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib, AddrSurfInfoIn.format = ADDR_FMT_8; if (!AddrSurfInfoIn.flags.depth) { - r = gfx9_get_preferred_swizzle_mode(addrlib, &AddrSurfInfoIn, + r = gfx9_get_preferred_swizzle_mode(addrlib, surf, &AddrSurfInfoIn, false, &AddrSurfInfoIn.swizzleMode); if (r) goto error; diff --git a/src/amd/common/ac_surface.h b/src/amd/common/ac_surface.h index 5de487baee4..a552383caf0 100644 --- a/src/amd/common/ac_surface.h +++ b/src/amd/common/ac_surface.h @@ -73,6 +73,7 @@ enum radeon_micro_mode { #define RADEON_SURF_FORCE_SWIZZLE_MODE (1 << 28) #define RADEON_SURF_NO_FMASK (1 << 29) #define RADEON_SURF_NO_HTILE (1 << 30) +#define RADEON_SURF_FORCE_MICRO_TILE_MODE (1u << 31) struct legacy_surf_level { uint64_t offset; diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c index 643b15a09b4..80dedf61e0a 100644 --- a/src/gallium/drivers/radeonsi/si_blit.c +++ b/src/gallium/drivers/radeonsi/si_blit.c @@ -1162,10 +1162,13 @@ resolve_to_temp: templ.array_size = 1; templ.usage = PIPE_USAGE_DEFAULT; templ.flags = SI_RESOURCE_FLAG_FORCE_MSAA_TILING | + SI_RESOURCE_FLAG_FORCE_MICRO_TILE_MODE | + SI_RESOURCE_FLAG_MICRO_TILE_MODE_SET(src->surface.micro_tile_mode) | SI_RESOURCE_FLAG_DISABLE_DCC; /* The src and dst microtile modes must be the same. */ - if (src->surface.micro_tile_mode == RADEON_MICRO_MODE_DISPLAY) + if (sctx->chip_class <= GFX8 && + src->surface.micro_tile_mode == RADEON_MICRO_MODE_DISPLAY) templ.bind = PIPE_BIND_SCANOUT; else templ.bind = 0; diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 06d233e1043..f78ab7aa2ba 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -116,6 +116,11 @@ #define SI_RESOURCE_FLAG_CLEAR (PIPE_RESOURCE_FLAG_DRV_PRIV << 7) /* For const_uploader, upload data via GTT and copy to VRAM on context flush via SDMA. */ #define SI_RESOURCE_FLAG_UPLOAD_FLUSH_EXPLICIT_VIA_SDMA (PIPE_RESOURCE_FLAG_DRV_PRIV << 8) +/* Set a micro tile mode: */ +#define SI_RESOURCE_FLAG_FORCE_MICRO_TILE_MODE (PIPE_RESOURCE_FLAG_DRV_PRIV << 9) +#define SI_RESOURCE_FLAG_MICRO_TILE_MODE_SHIFT (util_logbase2(PIPE_RESOURCE_FLAG_DRV_PRIV) + 10) +#define SI_RESOURCE_FLAG_MICRO_TILE_MODE_SET(x) (((x) & 0x3) << SI_RESOURCE_FLAG_MICRO_TILE_MODE_SHIFT) +#define SI_RESOURCE_FLAG_MICRO_TILE_MODE_GET(x) (((x) >> SI_RESOURCE_FLAG_MICRO_TILE_MODE_SHIFT) & 0x3) enum si_clear_code { diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c index 183d5bd5294..bcf9187082b 100644 --- a/src/gallium/drivers/radeonsi/si_texture.c +++ b/src/gallium/drivers/radeonsi/si_texture.c @@ -330,6 +330,12 @@ static int si_init_surface(struct si_screen *sscreen, if (sscreen->debug_flags & DBG(NO_FMASK)) flags |= RADEON_SURF_NO_FMASK; + if (sscreen->info.chip_class == GFX9 && + (ptex->flags & SI_RESOURCE_FLAG_FORCE_MICRO_TILE_MODE)) { + flags |= RADEON_SURF_FORCE_MICRO_TILE_MODE; + surface->micro_tile_mode = SI_RESOURCE_FLAG_MICRO_TILE_MODE_GET(ptex->flags); + } + if (sscreen->info.chip_class >= GFX10 && (ptex->flags & SI_RESOURCE_FLAG_FORCE_MSAA_TILING)) { flags |= RADEON_SURF_FORCE_SWIZZLE_MODE;