ac/surface: don't compute DCC if it's unsupported by DCN on gfx9+
authorMarek Olšák <marek.olsak@amd.com>
Sat, 18 Apr 2020 00:27:32 +0000 (20:27 -0400)
committerMarge Bot <eric+marge@anholt.net>
Wed, 29 Apr 2020 14:53:25 +0000 (14:53 +0000)
Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4697>

src/amd/common/ac_surface.c
src/gallium/drivers/radeonsi/si_texture.c

index d455a0f..3b0955d 100644 (file)
@@ -1029,7 +1029,7 @@ gfx9_get_preferred_swizzle_mode(ADDR_HANDLE addrlib,
        return 0;
 }
 
-static bool gfx9_is_dcc_capable(const struct radeon_info *info, unsigned sw_mode)
+static bool is_dcc_supported_by_CB(const struct radeon_info *info, unsigned sw_mode)
 {
        if (info->chip_class >= GFX10)
                return sw_mode == ADDR_SW_64KB_Z_X || sw_mode == ADDR_SW_64KB_R_X;
@@ -1037,6 +1037,23 @@ static bool gfx9_is_dcc_capable(const struct radeon_info *info, unsigned sw_mode
        return sw_mode != ADDR_SW_LINEAR;
 }
 
+static bool is_dcc_supported_by_DCN(const struct radeon_info *info,
+                                   const struct ac_surf_config *config,
+                                   const struct radeon_surf *surf,
+                                   bool rb_aligned, bool pipe_aligned)
+{
+       if (!info->use_display_dcc_unaligned &&
+           !info->use_display_dcc_with_retile_blit)
+               return false;
+
+       /* Handle unaligned DCC. */
+       if (info->use_display_dcc_unaligned &&
+           (rb_aligned || pipe_aligned))
+               return false;
+
+       return true;
+}
+
 static int gfx9_compute_miptree(ADDR_HANDLE addrlib,
                                const struct radeon_info *info,
                                const struct ac_surf_config *config,
@@ -1163,7 +1180,11 @@ static int gfx9_compute_miptree(ADDR_HANDLE addrlib,
                if (info->has_graphics &&
                    !(surf->flags & RADEON_SURF_DISABLE_DCC) &&
                    !compressed &&
-                   gfx9_is_dcc_capable(info, in->swizzleMode)) {
+                   is_dcc_supported_by_CB(info, in->swizzleMode) &&
+                   (!in->flags.display ||
+                    is_dcc_supported_by_DCN(info, config, surf,
+                                            !in->flags.metaRbUnaligned,
+                                            !in->flags.metaPipeUnaligned))) {
                        ADDR2_COMPUTE_DCCINFO_INPUT din = {0};
                        ADDR2_COMPUTE_DCCINFO_OUTPUT dout = {0};
                        ADDR2_META_MIP_INFO meta_mip_info[RADEON_SURF_MAX_LEVELS] = {};
@@ -1623,10 +1644,10 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
                        goto error;
 
                /* Display needs unaligned DCC. */
-               if (info->use_display_dcc_unaligned &&
-                   surf->num_dcc_levels &&
-                   (surf->u.gfx9.dcc.pipe_aligned ||
-                    surf->u.gfx9.dcc.rb_aligned))
+               if (surf->num_dcc_levels &&
+                   !is_dcc_supported_by_DCN(info, config, surf,
+                                            surf->u.gfx9.dcc.rb_aligned,
+                                            surf->u.gfx9.dcc.pipe_aligned))
                        displayable = false;
        }
        surf->is_displayable = displayable;
@@ -1735,9 +1756,8 @@ int ac_compute_surface(ADDR_HANDLE addrlib, const struct radeon_info *info,
        }
 
        if (surf->dcc_size &&
-           (info->use_display_dcc_unaligned ||
-            info->use_display_dcc_with_retile_blit ||
-            !(surf->flags & RADEON_SURF_SCANOUT))) {
+           /* dcc_size is computed on GFX9+ only if it's displayable. */
+           (info->chip_class >= GFX9 || !get_display_flag(config, surf))) {
                surf->dcc_offset = align64(surf->total_size, surf->dcc_alignment);
                surf->total_size = surf->dcc_offset + surf->dcc_size;
 
index 1ee4547..43fc648 100644 (file)
@@ -789,18 +789,7 @@ static bool si_has_displayable_dcc(struct si_texture *tex)
    if (sscreen->info.chip_class <= GFX8)
       return false;
 
-   /* This needs a cache flush before scanout.
-    * (it can't be scanned out and rendered to simultaneously)
-    */
-   if (sscreen->info.use_display_dcc_unaligned && tex->surface.dcc_offset &&
-       !tex->surface.u.gfx9.dcc.pipe_aligned && !tex->surface.u.gfx9.dcc.rb_aligned)
-      return true;
-
-   /* This needs an explicit flush (flush_resource). */
-   if (sscreen->info.use_display_dcc_with_retile_blit && tex->surface.display_dcc_offset)
-      return true;
-
-   return false;
+   return tex->surface.is_displayable && tex->surface.dcc_offset;
 }
 
 static bool si_resource_get_param(struct pipe_screen *screen, struct pipe_context *context,