ac/surface: add radeon_surf::has_stencil for convenience
[mesa.git] / src / amd / common / ac_surface.c
index 87a89936e1c01fe26b2befafdfd64501cc7ba4c5..c6ff57362f79455eae6b98cb20c4fdf111afb498 100644 (file)
@@ -435,7 +435,9 @@ static int gfx6_surface_settings(ADDR_HANDLE addrlib,
        }
 
        /* Compute tile swizzle. */
-       if (config->info.surf_index &&
+       /* TODO: fix tile swizzle with mipmapping for SI */
+       if ((info->chip_class >= CIK || config->info.levels == 1) &&
+           config->info.surf_index &&
            surf->u.legacy.level[0].mode == RADEON_SURF_MODE_2D &&
            !(surf->flags & (RADEON_SURF_Z_OR_SBUFFER | RADEON_SURF_SHAREABLE)) &&
            (config->info.samples > 1 || !(surf->flags & RADEON_SURF_SCANOUT))) {
@@ -653,6 +655,7 @@ static int gfx6_compute_surface(ADDR_HANDLE addrlib,
                }
        }
 
+       surf->has_stencil = !!(surf->flags & RADEON_SURF_SBUFFER);
        surf->num_dcc_levels = 0;
        surf->surf_size = 0;
        surf->dcc_size = 0;
@@ -732,9 +735,16 @@ static int gfx6_compute_surface(ADDR_HANDLE addrlib,
         * complicated.
         */
        if (surf->dcc_size && config->info.levels > 1) {
+               /* The smallest miplevels that are never compressed by DCC
+                * still read the DCC buffer via TC if the base level uses DCC,
+                * and for some reason the DCC buffer needs to be larger if
+                * the miptree uses non-zero tile_swizzle. Otherwise there are
+                * VM faults.
+                *
+                * "dcc_alignment * 4" was determined by trial and error.
+                */
                surf->dcc_size = align64(surf->surf_size >> 8,
-                                        info->pipe_interleave_bytes *
-                                        info->num_tile_pipes);
+                                        surf->dcc_alignment * 4);
        }
 
        /* Make sure HTILE covers the whole miptree, because the shader reads
@@ -899,6 +909,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 */
@@ -1035,6 +1062,11 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
 
        case RADEON_SURF_MODE_1D:
        case RADEON_SURF_MODE_2D:
+               if (surf->flags & RADEON_SURF_IMPORTED) {
+                       AddrSurfInfoIn.swizzleMode = surf->u.gfx9.surf.swizzle_mode;
+                       break;
+               }
+
                r = gfx9_get_preferred_swizzle_mode(addrlib, &AddrSurfInfoIn, false,
                                                    &AddrSurfInfoIn.swizzleMode);
                if (r)
@@ -1046,7 +1078,9 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
        }
 
        surf->u.gfx9.resource_type = AddrSurfInfoIn.resourceType;
+       surf->has_stencil = !!(surf->flags & RADEON_SURF_SBUFFER);
 
+       surf->num_dcc_levels = 0;
        surf->surf_size = 0;
        surf->dcc_size = 0;
        surf->htile_size = 0;
@@ -1073,7 +1107,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. */