From f9ccfda9bc8166f833fdb64adf1eca5b8ee69251 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Nicolai=20H=C3=A4hnle?= Date: Thu, 12 Oct 2017 11:21:26 +0200 Subject: [PATCH] amd/common/gfx9: workaround DCC corruption more conservatively MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Fixes KHR-GL45.texture_swizzle.smoke and others on Vega. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102809 Cc: mesa-stable@lists.freedesktop.org Reviewed-by: Marek Olšák --- src/amd/common/ac_surface.c | 32 +++++++++++++++++++++++++------- 1 file 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 */ -- 2.30.2