diff options
Diffstat (limited to 'src/amd/common')
-rw-r--r-- | src/amd/common/ac_surface.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c index f956c14a106..ec37d376981 100644 --- a/src/amd/common/ac_surface.c +++ b/src/amd/common/ac_surface.c @@ -927,9 +927,11 @@ static int gfx9_compute_miptree(ADDR_HANDLE addrlib, in->numSamples == 1) { ADDR2_COMPUTE_DCCINFO_INPUT din = {0}; ADDR2_COMPUTE_DCCINFO_OUTPUT dout = {0}; + ADDR2_META_MIP_INFO meta_mip_info[RADEON_SURF_MAX_LEVELS] = {}; din.size = sizeof(ADDR2_COMPUTE_DCCINFO_INPUT); dout.size = sizeof(ADDR2_COMPUTE_DCCINFO_OUTPUT); + dout.pMipInfo = meta_mip_info; din.dccKeyFlags.pipeAligned = 1; din.dccKeyFlags.rbAligned = 1; @@ -955,21 +957,37 @@ static int gfx9_compute_miptree(ADDR_HANDLE addrlib, surf->dcc_alignment = dout.dccRamBaseAlign; surf->num_dcc_levels = in->numMipLevels; - /* Disable DCC for the smallest levels. It seems to be - * required for DCC readability between CB and shaders - * when TC L2 isn't flushed. This was guessed. + /* Disable DCC for levels that are in the mip tail. + * + * There are two issues that this is intended to + * address: + * + * 1. Multiple mip levels may share a cache line. This + * can lead to corruption when switching between + * rendering to different mip levels because the + * RBs don't maintain coherency. + * + * 2. Texturing with metadata after rendering sometimes + * fails with corruption, probably for a similar + * reason. + * + * Working around these issues for all levels in the + * mip tail may be overly conservative, but it's what + * Vulkan does. * * Alternative solutions that also work but are worse: - * - Disable DCC. + * - Disable DCC entirely. * - Flush TC L2 after rendering. */ - for (unsigned i = 1; i < in->numMipLevels; i++) { - if (mip_info[i].pitch * - mip_info[i].height * surf->bpe < 1024) { + for (unsigned i = 0; i < in->numMipLevels; i++) { + if (meta_mip_info[i].inMiptail) { surf->num_dcc_levels = i; break; } } + + if (!surf->num_dcc_levels) + surf->dcc_size = 0; } /* FMASK */ |