amd/common/gfx9: workaround DCC corruption more conservatively
authorNicolai Hähnle <nicolai.haehnle@amd.com>
Thu, 12 Oct 2017 09:21:26 +0000 (11:21 +0200)
committerNicolai Hähnle <nicolai.haehnle@amd.com>
Mon, 23 Oct 2017 16:10:20 +0000 (18:10 +0200)
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 <marek.olsak@amd.com>
src/amd/common/ac_surface.c

index f956c14a106fd11a5e392f535786b484e1fa696e..ec37d376981dde0956cbabd246edc1e2bdaf0d79 100644 (file)
@@ -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 */