ac/surface/gfx9: don't allow DCC for the smallest mipmap levels
authorMarek Olšák <marek.olsak@amd.com>
Thu, 17 Aug 2017 21:35:36 +0000 (23:35 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Tue, 22 Aug 2017 11:29:47 +0000 (13:29 +0200)
This fixes garbage there if we don't flush TC L2 after rendering.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/amd/common/ac_surface.c

index 610071a956ff741dc313b268943244bfb301f8f5..4edefc7c40a6b9209847d1b583cc639470ca9986 100644 (file)
@@ -908,6 +908,23 @@ static int gfx9_compute_miptree(ADDR_HANDLE addrlib,
                        surf->u.gfx9.dcc_pitch_max = dout.pitch - 1;
                        surf->dcc_size = dout.dccRamSize;
                        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.
+                        *
+                        * Alternative solutions that also work but are worse:
+                        * - Disable DCC.
+                        * - 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) {
+                                       surf->num_dcc_levels = i;
+                                       break;
+                               }
+                       }
                }
 
                /* FMASK */
@@ -1061,6 +1078,7 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
 
        surf->u.gfx9.resource_type = AddrSurfInfoIn.resourceType;
 
+       surf->num_dcc_levels = 0;
        surf->surf_size = 0;
        surf->dcc_size = 0;
        surf->htile_size = 0;
@@ -1087,7 +1105,6 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
        }
 
        surf->is_linear = surf->u.gfx9.surf.swizzle_mode == ADDR_SW_LINEAR;
-       surf->num_dcc_levels = surf->dcc_size ? config->info.levels : 0;
 
        switch (surf->u.gfx9.surf.swizzle_mode) {
                /* S = standard. */