Mesa (master): radeonsi: remove the separate DCC optimization for Stoney

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Apr 26 23:08:16 UTC 2021


Module: Mesa
Branch: master
Commit: 804e29244066f70d7111d8c07ff922a0e1362b65
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=804e29244066f70d7111d8c07ff922a0e1362b65

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Mon Apr  5 10:06:27 2021 -0400

radeonsi: remove the separate DCC optimization for Stoney

This removes some complexity from the driver.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10343>

---

 src/gallium/drivers/radeonsi/si_blit.c        |  38 +----
 src/gallium/drivers/radeonsi/si_clear.c       |  29 +---
 src/gallium/drivers/radeonsi/si_descriptors.c |  12 +-
 src/gallium/drivers/radeonsi/si_pipe.c        |  11 --
 src/gallium/drivers/radeonsi/si_pipe.h        |  48 +-----
 src/gallium/drivers/radeonsi/si_state.c       |  26 +--
 src/gallium/drivers/radeonsi/si_texture.c     | 237 --------------------------
 7 files changed, 7 insertions(+), 394 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c
index 653dfc343e7..bf95fa6c7c5 100644
--- a/src/gallium/drivers/radeonsi/si_blit.c
+++ b/src/gallium/drivers/radeonsi/si_blit.c
@@ -1276,52 +1276,16 @@ static void si_flush_resource(struct pipe_context *ctx, struct pipe_resource *re
    struct si_texture *tex = (struct si_texture *)res;
 
    assert(res->target != PIPE_BUFFER);
-   assert(!tex->dcc_separate_buffer || tex->dcc_gather_statistics);
-
-   /* st/dri calls flush twice per frame (not a bug), this prevents double
-    * decompression. */
-   if (tex->dcc_separate_buffer && !tex->separate_dcc_dirty)
-      return;
 
    if (!tex->is_depth && (tex->cmask_buffer || vi_dcc_enabled(tex, 0))) {
       si_blit_decompress_color(sctx, tex, 0, res->last_level, 0, util_max_layer(res, 0),
-                               tex->dcc_separate_buffer != NULL, false);
+                               false, false);
 
       if (tex->surface.display_dcc_offset && tex->displayable_dcc_dirty) {
          si_retile_dcc(sctx, tex);
          tex->displayable_dcc_dirty = false;
       }
    }
-
-   /* Always do the analysis even if DCC is disabled at the moment. */
-   if (tex->dcc_gather_statistics) {
-      bool separate_dcc_dirty = tex->separate_dcc_dirty;
-
-      /* If the color buffer hasn't been unbound and fast clear hasn't
-       * been used, separate_dcc_dirty is false, but there may have been
-       * new rendering. Check if the color buffer is bound and assume
-       * it's dirty.
-       *
-       * Note that DRI2 never unbinds window colorbuffers, which means
-       * the DCC pipeline statistics query would never be re-set and would
-       * keep adding new results until all free memory is exhausted if we
-       * didn't do this.
-       */
-      if (!separate_dcc_dirty) {
-         for (unsigned i = 0; i < sctx->framebuffer.state.nr_cbufs; i++) {
-            if (sctx->framebuffer.state.cbufs[i] &&
-                sctx->framebuffer.state.cbufs[i]->texture == res) {
-               separate_dcc_dirty = true;
-               break;
-            }
-         }
-      }
-
-      if (separate_dcc_dirty) {
-         tex->separate_dcc_dirty = false;
-         vi_separate_dcc_process_and_reset_stats(ctx, tex);
-      }
-   }
 }
 
 void si_flush_implicit_resources(struct si_context *sctx)
diff --git a/src/gallium/drivers/radeonsi/si_clear.c b/src/gallium/drivers/radeonsi/si_clear.c
index b6003d11921..538c4b18e92 100644
--- a/src/gallium/drivers/radeonsi/si_clear.c
+++ b/src/gallium/drivers/radeonsi/si_clear.c
@@ -293,19 +293,12 @@ static bool vi_get_fast_clear_parameters(struct si_screen *sscreen, enum pipe_fo
 bool vi_dcc_get_clear_info(struct si_context *sctx, struct si_texture *tex, unsigned level,
                            unsigned clear_value, struct si_clear_info *out)
 {
-   struct pipe_resource *dcc_buffer;
-   uint64_t dcc_offset, clear_size;
+   struct pipe_resource *dcc_buffer = &tex->buffer.b.b;
+   uint64_t dcc_offset = tex->surface.meta_offset;
+   uint32_t clear_size;
 
    assert(vi_dcc_enabled(tex, level));
 
-   if (tex->dcc_separate_buffer) {
-      dcc_buffer = &tex->dcc_separate_buffer->b.b;
-      dcc_offset = 0;
-   } else {
-      dcc_buffer = &tex->buffer.b.b;
-      dcc_offset = tex->surface.meta_offset;
-   }
-
    if (sctx->chip_class >= GFX10) {
       /* 4x and 8x MSAA needs a sophisticated compute shader for
        * the clear. */
@@ -606,21 +599,6 @@ static void si_fast_clear(struct si_context *sctx, unsigned *buffers,
       bool eliminate_needed = false;
       bool fmask_decompress_needed = false;
 
-      /* Fast clear is the most appropriate place to enable DCC for
-       * displayable surfaces.
-       */
-      if (sctx->family == CHIP_STONEY && !too_small) {
-         vi_separate_dcc_try_enable(sctx, tex);
-
-         /* RB+ isn't supported with a CMASK clear only on Stoney,
-          * so all clears are considered to be hypothetically slow
-          * clears, which is weighed when determining whether to
-          * enable separate DCC.
-          */
-         if (tex->dcc_gather_statistics) /* only for Stoney */
-            tex->num_slow_clears++;
-      }
-
       /* Try to clear DCC first, otherwise try CMASK. */
       if (vi_dcc_enabled(tex, level)) {
          uint32_t reset_value;
@@ -666,7 +644,6 @@ static void si_fast_clear(struct si_context *sctx, unsigned *buffers,
          num_clears++;
          clear_types |= SI_CLEAR_TYPE_DCC;
 
-         tex->separate_dcc_dirty = true;
          si_mark_display_dcc_dirty(sctx, tex);
 
          /* DCC fast clear with MSAA should clear CMASK to 0xC. */
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index 6946f3419e5..78fb5d79b13 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -231,15 +231,6 @@ static void si_sampler_view_add_buffer(struct si_context *sctx, struct pipe_reso
 
    priority = si_get_sampler_view_priority(&tex->buffer);
    radeon_add_to_gfx_buffer_list_check_mem(sctx, &tex->buffer, usage, priority, check_mem);
-
-   if (resource->target == PIPE_BUFFER)
-      return;
-
-   /* Add separate DCC. */
-   if (tex->dcc_separate_buffer) {
-      radeon_add_to_gfx_buffer_list_check_mem(sctx, tex->dcc_separate_buffer, usage,
-                                              RADEON_PRIO_SEPARATE_META, check_mem);
-   }
 }
 
 static void si_sampler_views_begin_new_cs(struct si_context *sctx, struct si_samplers *samplers)
@@ -331,8 +322,7 @@ void si_set_mutable_tex_desc_fields(struct si_screen *sscreen, struct si_texture
       state[6] &= C_008F28_COMPRESSION_EN;
 
       if (!(access & SI_IMAGE_ACCESS_DCC_OFF) && vi_dcc_enabled(tex, first_level)) {
-         meta_va =
-            (!tex->dcc_separate_buffer ? tex->buffer.gpu_address : 0) + tex->surface.meta_offset;
+         meta_va = tex->buffer.gpu_address + tex->surface.meta_offset;
 
          if (sscreen->info.chip_class == GFX8) {
             meta_va += tex->surface.u.legacy.color.dcc_level[base_level].dcc_offset;
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index 3556c8a074d..ac57c8d13d1 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -284,17 +284,6 @@ static void si_destroy_context(struct pipe_context *context)
    if (sctx->blitter)
       util_blitter_destroy(sctx->blitter);
 
-   /* Release DCC stats. */
-   for (int i = 0; i < ARRAY_SIZE(sctx->dcc_stats); i++) {
-      assert(!sctx->dcc_stats[i].query_active);
-
-      for (int j = 0; j < ARRAY_SIZE(sctx->dcc_stats[i].ps_stats); j++)
-         if (sctx->dcc_stats[i].ps_stats[j])
-            sctx->b.destroy_query(&sctx->b, sctx->dcc_stats[i].ps_stats[j]);
-
-      si_texture_reference(&sctx->dcc_stats[i].tex, NULL);
-   }
-
    if (sctx->query_result_shader)
       sctx->b.delete_compute_state(&sctx->b, sctx->query_result_shader);
    if (sctx->sh_query_result_shader)
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 60a26230986..da316134201 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -385,37 +385,14 @@ struct si_texture {
 
    /* We need to track DCC dirtiness, because st/dri usually calls
     * flush_resource twice per frame (not a bug) and we don't wanna
-    * decompress DCC twice. Also, the dirty tracking must be done even
-    * if DCC isn't used, because it's required by the DCC usage analysis
-    * for a possible future enablement.
+    * decompress DCC twice.
     */
-   bool separate_dcc_dirty : 1;
    bool displayable_dcc_dirty : 1;
 
-   /* Statistics gathering for the DCC enablement heuristic. */
-   bool dcc_gather_statistics : 1;
    /* Counter that should be non-zero if the texture is bound to a
     * framebuffer.
     */
    unsigned framebuffers_bound;
-   /* Whether the texture is a displayable back buffer and needs DCC
-    * decompression, which is expensive. Therefore, it's enabled only
-    * if statistics suggest that it will pay off and it's allocated
-    * separately. It can't be bound as a sampler by apps. Limited to
-    * target == 2D and last_level == 0. If enabled, dcc_offset contains
-    * the absolute GPUVM address, not the relative one.
-    */
-   struct si_resource *dcc_separate_buffer;
-   /* When DCC is temporarily disabled, the separate buffer is here. */
-   struct si_resource *last_dcc_separate_buffer;
-   /* Estimate of how much this color buffer is written to in units of
-    * full-screen draws: ps_invocations / (width * height)
-    * Shader kills, late Z, and blending with trivial discards make it
-    * inaccurate (we need to count CB updates, not PS invocations).
-    */
-   unsigned ps_draw_ratio;
-   /* The number of clears since the last DCC usage analysis. */
-   unsigned num_slow_clears;
 };
 
 struct si_surface {
@@ -1281,25 +1258,6 @@ struct si_context {
 
    bool force_cb_shader_coherent;
 
-   /* Statistics gathering for the DCC enablement heuristic. It can't be
-    * in si_texture because si_texture can be shared by multiple
-    * contexts. This is for back buffers only. We shouldn't get too many
-    * of those.
-    *
-    * X11 DRI3 rotates among a finite set of back buffers. They should
-    * all fit in this array. If they don't, separate DCC might never be
-    * enabled by DCC stat gathering.
-    */
-   struct {
-      struct si_texture *tex;
-      /* Query queue: 0 = usually active, 1 = waiting, 2 = readback. */
-      struct pipe_query *ps_stats[3];
-      /* If all slots are used and another slot is needed,
-       * the least recently used slot is evicted based on this. */
-      int64_t last_use_timestamp;
-      bool query_active;
-   } dcc_stats[5];
-
    struct si_tracked_regs tracked_regs;
 
    /* Resources that need to be flushed, but will not get an explicit
@@ -1617,10 +1575,6 @@ struct pipe_surface *si_create_surface_custom(struct pipe_context *pipe,
                                               const struct pipe_surface *templ, unsigned width0,
                                               unsigned height0, unsigned width, unsigned height);
 unsigned si_translate_colorswap(enum pipe_format format, bool do_endian_swap);
-void vi_separate_dcc_try_enable(struct si_context *sctx, struct si_texture *tex);
-void vi_separate_dcc_start_query(struct si_context *sctx, struct si_texture *tex);
-void vi_separate_dcc_stop_query(struct si_context *sctx, struct si_texture *tex);
-void vi_separate_dcc_process_and_reset_stats(struct pipe_context *ctx, struct si_texture *tex);
 bool si_texture_disable_dcc(struct si_context *sctx, struct si_texture *tex);
 void si_init_screen_texture_functions(struct si_screen *sscreen);
 void si_init_context_texture_functions(struct si_context *sctx);
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index c6ded8ea179..923ed3a25a3 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -2583,8 +2583,6 @@ void si_update_fb_dirtiness_after_rendering(struct si_context *sctx)
          tex->dirty_level_mask |= 1 << surf->u.tex.level;
          tex->fmask_is_identity = false;
       }
-      if (tex->dcc_gather_statistics)
-         tex->separate_dcc_dirty = true;
    }
 }
 
@@ -2656,15 +2654,6 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
 
    si_update_fb_dirtiness_after_rendering(sctx);
 
-   for (i = 0; i < sctx->framebuffer.state.nr_cbufs; i++) {
-      if (!sctx->framebuffer.state.cbufs[i])
-         continue;
-
-      tex = (struct si_texture *)sctx->framebuffer.state.cbufs[i]->texture;
-      if (tex->dcc_gather_statistics)
-         vi_separate_dcc_stop_query(sctx, tex);
-   }
-
    /* Disable DCC if the formats are incompatible. */
    for (i = 0; i < state->nr_cbufs; i++) {
       if (!state->cbufs[i])
@@ -2821,12 +2810,6 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
 
       p_atomic_inc(&tex->framebuffers_bound);
 
-      if (tex->dcc_gather_statistics) {
-         /* Dirty tracking must be enabled for DCC usage analysis. */
-         sctx->framebuffer.compressed_cb_mask |= 1 << i;
-         vi_separate_dcc_start_query(sctx, tex);
-      }
-
       /* Update the minimum but don't keep 0. */
       if (!sctx->framebuffer.min_bytes_per_pixel ||
           tex->surface.bpe < sctx->framebuffer.min_bytes_per_pixel)
@@ -2967,11 +2950,6 @@ static void si_emit_framebuffer_state(struct si_context *sctx)
                                    RADEON_PRIO_SEPARATE_META);
       }
 
-      if (tex->dcc_separate_buffer)
-         radeon_add_to_buffer_list(sctx, &sctx->gfx_cs, tex->dcc_separate_buffer,
-                                   RADEON_USAGE_READWRITE | RADEON_USAGE_NEEDS_IMPLICIT_SYNC,
-                                   RADEON_PRIO_SEPARATE_META);
-
       /* Compute mutable surface parameters. */
       cb_color_base = tex->buffer.gpu_address >> 8;
       cb_color_fmask = 0;
@@ -3011,9 +2989,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx)
          if (!is_msaa_resolve_dst)
             cb_color_info |= S_028C70_DCC_ENABLE(1);
 
-         cb_dcc_base =
-            ((!tex->dcc_separate_buffer ? tex->buffer.gpu_address : 0) + tex->surface.meta_offset) >>
-            8;
+         cb_dcc_base = (tex->buffer.gpu_address + tex->surface.meta_offset) >> 8;
 
          unsigned dcc_tile_swizzle = tex->surface.tile_swizzle;
          dcc_tile_swizzle &= ((1 << tex->surface.meta_alignment_log2) - 1) >> 8;
diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c
index 50621e0ed8c..5ec7ed81ed3 100644
--- a/src/gallium/drivers/radeonsi/si_texture.c
+++ b/src/gallium/drivers/radeonsi/si_texture.c
@@ -347,8 +347,6 @@ static bool si_texture_discard_dcc(struct si_screen *sscreen, struct si_texture
    if (!si_can_disable_dcc(tex))
       return false;
 
-   assert(tex->dcc_separate_buffer == NULL);
-
    /* Disable DCC. */
    ac_surface_zero_dcc_fields(&tex->surface);
 
@@ -491,11 +489,7 @@ static void si_reallocate_texture_inplace(struct si_context *sctx, struct si_tex
    tex->can_sample_z = new_tex->can_sample_z;
    tex->can_sample_s = new_tex->can_sample_s;
 
-   tex->separate_dcc_dirty = new_tex->separate_dcc_dirty;
    tex->displayable_dcc_dirty = new_tex->displayable_dcc_dirty;
-   tex->dcc_gather_statistics = new_tex->dcc_gather_statistics;
-   si_resource_reference(&tex->dcc_separate_buffer, new_tex->dcc_separate_buffer);
-   si_resource_reference(&tex->last_dcc_separate_buffer, new_tex->last_dcc_separate_buffer);
 
    if (new_bind_flag == PIPE_BIND_LINEAR) {
       assert(!tex->surface.meta_offset);
@@ -516,7 +510,6 @@ static void si_set_tex_bo_metadata(struct si_screen *sscreen, struct si_texture
 
    memset(&md, 0, sizeof(md));
 
-   assert(tex->dcc_separate_buffer == NULL);
    assert(tex->surface.fmask_size == 0);
 
    static const unsigned char swizzle[] = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z,
@@ -802,8 +795,6 @@ static void si_texture_destroy(struct pipe_screen *screen, struct pipe_resource
       si_resource_reference(&tex->cmask_buffer, NULL);
    }
    radeon_bo_reference(((struct si_screen*)screen)->ws, &resource->buf, NULL);
-   si_resource_reference(&tex->dcc_separate_buffer, NULL);
-   si_resource_reference(&tex->last_dcc_separate_buffer, NULL);
    FREE(tex);
 }
 
@@ -966,12 +957,6 @@ static struct si_texture *si_texture_create_object(struct pipe_screen *screen,
    /* Applies to GCN. */
    tex->last_msaa_resolve_target_micro_mode = tex->surface.micro_tile_mode;
 
-   /* Disable separate DCC at the beginning. DRI2 doesn't reuse buffers
-    * between frames, so the only thing that can enable separate DCC
-    * with DRI2 is multiple slow clears within a frame.
-    */
-   tex->ps_draw_ratio = 0;
-
    if (!ac_surface_override_offset_stride(&sscreen->info, &tex->surface,
                                      tex->buffer.b.b.last_level + 1,
                                           offset, pitch_in_bytes / tex->surface.bpe))
@@ -2189,228 +2174,6 @@ unsigned si_translate_colorswap(enum pipe_format format, bool do_endian_swap)
    return ~0U;
 }
 
-/* PIPELINE_STAT-BASED DCC ENABLEMENT FOR DISPLAYABLE SURFACES */
-
-static void vi_dcc_clean_up_context_slot(struct si_context *sctx, int slot)
-{
-   int i;
-
-   if (sctx->dcc_stats[slot].query_active)
-      vi_separate_dcc_stop_query(sctx, sctx->dcc_stats[slot].tex);
-
-   for (i = 0; i < ARRAY_SIZE(sctx->dcc_stats[slot].ps_stats); i++)
-      if (sctx->dcc_stats[slot].ps_stats[i]) {
-         sctx->b.destroy_query(&sctx->b, sctx->dcc_stats[slot].ps_stats[i]);
-         sctx->dcc_stats[slot].ps_stats[i] = NULL;
-      }
-
-   si_texture_reference(&sctx->dcc_stats[slot].tex, NULL);
-}
-
-/**
- * Return the per-context slot where DCC statistics queries for the texture live.
- */
-static unsigned vi_get_context_dcc_stats_index(struct si_context *sctx, struct si_texture *tex)
-{
-   int i, empty_slot = -1;
-
-   /* Remove zombie textures (textures kept alive by this array only). */
-   for (i = 0; i < ARRAY_SIZE(sctx->dcc_stats); i++)
-      if (sctx->dcc_stats[i].tex && sctx->dcc_stats[i].tex->buffer.b.b.reference.count == 1)
-         vi_dcc_clean_up_context_slot(sctx, i);
-
-   /* Find the texture. */
-   for (i = 0; i < ARRAY_SIZE(sctx->dcc_stats); i++) {
-      /* Return if found. */
-      if (sctx->dcc_stats[i].tex == tex) {
-         sctx->dcc_stats[i].last_use_timestamp = os_time_get();
-         return i;
-      }
-
-      /* Record the first seen empty slot. */
-      if (empty_slot == -1 && !sctx->dcc_stats[i].tex)
-         empty_slot = i;
-   }
-
-   /* Not found. Remove the oldest member to make space in the array. */
-   if (empty_slot == -1) {
-      int oldest_slot = 0;
-
-      /* Find the oldest slot. */
-      for (i = 1; i < ARRAY_SIZE(sctx->dcc_stats); i++)
-         if (sctx->dcc_stats[oldest_slot].last_use_timestamp >
-             sctx->dcc_stats[i].last_use_timestamp)
-            oldest_slot = i;
-
-      /* Clean up the oldest slot. */
-      vi_dcc_clean_up_context_slot(sctx, oldest_slot);
-      empty_slot = oldest_slot;
-   }
-
-   /* Add the texture to the new slot. */
-   si_texture_reference(&sctx->dcc_stats[empty_slot].tex, tex);
-   sctx->dcc_stats[empty_slot].last_use_timestamp = os_time_get();
-   return empty_slot;
-}
-
-static struct pipe_query *vi_create_resuming_pipestats_query(struct si_context *sctx)
-{
-   struct si_query_hw *query =
-      (struct si_query_hw *)sctx->b.create_query(&sctx->b, PIPE_QUERY_PIPELINE_STATISTICS, 0);
-
-   query->flags |= SI_QUERY_HW_FLAG_BEGIN_RESUMES;
-   return (struct pipe_query *)query;
-}
-
-/**
- * Called when binding a color buffer.
- */
-void vi_separate_dcc_start_query(struct si_context *sctx, struct si_texture *tex)
-{
-   unsigned i = vi_get_context_dcc_stats_index(sctx, tex);
-
-   assert(!sctx->dcc_stats[i].query_active);
-
-   if (!sctx->dcc_stats[i].ps_stats[0])
-      sctx->dcc_stats[i].ps_stats[0] = vi_create_resuming_pipestats_query(sctx);
-
-   /* begin or resume the query */
-   sctx->b.begin_query(&sctx->b, sctx->dcc_stats[i].ps_stats[0]);
-   sctx->dcc_stats[i].query_active = true;
-}
-
-/**
- * Called when unbinding a color buffer.
- */
-void vi_separate_dcc_stop_query(struct si_context *sctx, struct si_texture *tex)
-{
-   unsigned i = vi_get_context_dcc_stats_index(sctx, tex);
-
-   assert(sctx->dcc_stats[i].query_active);
-   assert(sctx->dcc_stats[i].ps_stats[0]);
-
-   /* pause or end the query */
-   sctx->b.end_query(&sctx->b, sctx->dcc_stats[i].ps_stats[0]);
-   sctx->dcc_stats[i].query_active = false;
-}
-
-static bool vi_should_enable_separate_dcc(struct si_texture *tex)
-{
-   /* The minimum number of fullscreen draws per frame that is required
-    * to enable DCC. */
-   return tex->ps_draw_ratio + tex->num_slow_clears >= 5;
-}
-
-/* Called by fast clear. */
-void vi_separate_dcc_try_enable(struct si_context *sctx, struct si_texture *tex)
-{
-   /* The intent is to use this with shared displayable back buffers,
-    * but it's not strictly limited only to them.
-    */
-   if (!tex->buffer.b.is_shared ||
-       !(tex->buffer.external_usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH) ||
-       tex->buffer.b.b.target != PIPE_TEXTURE_2D || tex->buffer.b.b.last_level > 0 ||
-       !tex->surface.meta_size || sctx->screen->debug_flags & DBG(NO_DCC) ||
-       sctx->screen->debug_flags & DBG(NO_DCC_FB))
-      return;
-
-   assert(sctx->chip_class >= GFX8);
-   assert(!tex->is_depth);
-
-   if (tex->surface.meta_offset)
-      return; /* already enabled */
-
-   /* Enable the DCC stat gathering. */
-   if (!tex->dcc_gather_statistics) {
-      tex->dcc_gather_statistics = true;
-      vi_separate_dcc_start_query(sctx, tex);
-   }
-
-   if (!vi_should_enable_separate_dcc(tex))
-      return; /* stats show that DCC decompression is too expensive */
-
-   assert(tex->surface.num_meta_levels);
-   assert(!tex->dcc_separate_buffer);
-
-   si_texture_discard_cmask(sctx->screen, tex);
-
-   /* Get a DCC buffer. */
-   if (tex->last_dcc_separate_buffer) {
-      assert(tex->dcc_gather_statistics);
-      assert(!tex->dcc_separate_buffer);
-      tex->dcc_separate_buffer = tex->last_dcc_separate_buffer;
-      tex->last_dcc_separate_buffer = NULL;
-   } else {
-      tex->dcc_separate_buffer =
-         si_aligned_buffer_create(sctx->b.screen, SI_RESOURCE_FLAG_UNMAPPABLE, PIPE_USAGE_DEFAULT,
-                                  tex->surface.meta_size, 1 << tex->surface.meta_alignment_log2);
-      if (!tex->dcc_separate_buffer)
-         return;
-   }
-
-   /* dcc_offset is the absolute GPUVM address. */
-   tex->surface.meta_offset = tex->dcc_separate_buffer->gpu_address;
-
-   /* no need to flag anything since this is called by fast clear that
-    * flags framebuffer state
-    */
-}
-
-/**
- * Called by pipe_context::flush_resource, the place where DCC decompression
- * takes place.
- */
-void vi_separate_dcc_process_and_reset_stats(struct pipe_context *ctx, struct si_texture *tex)
-{
-   struct si_context *sctx = (struct si_context *)ctx;
-   struct pipe_query *tmp;
-   unsigned i = vi_get_context_dcc_stats_index(sctx, tex);
-   bool query_active = sctx->dcc_stats[i].query_active;
-   bool disable = false;
-
-   if (sctx->dcc_stats[i].ps_stats[2]) {
-      union pipe_query_result result;
-
-      /* Read the results. */
-      struct pipe_query *query = sctx->dcc_stats[i].ps_stats[2];
-      ctx->get_query_result(ctx, query, true, &result);
-      si_query_buffer_reset(sctx, &((struct si_query_hw *)query)->buffer);
-
-      /* Compute the approximate number of fullscreen draws. */
-      tex->ps_draw_ratio = result.pipeline_statistics.ps_invocations /
-                           (tex->buffer.b.b.width0 * tex->buffer.b.b.height0);
-      sctx->last_tex_ps_draw_ratio = tex->ps_draw_ratio;
-
-      disable = tex->dcc_separate_buffer && !vi_should_enable_separate_dcc(tex);
-   }
-
-   tex->num_slow_clears = 0;
-
-   /* stop the statistics query for ps_stats[0] */
-   if (query_active)
-      vi_separate_dcc_stop_query(sctx, tex);
-
-   /* Move the queries in the queue by one. */
-   tmp = sctx->dcc_stats[i].ps_stats[2];
-   sctx->dcc_stats[i].ps_stats[2] = sctx->dcc_stats[i].ps_stats[1];
-   sctx->dcc_stats[i].ps_stats[1] = sctx->dcc_stats[i].ps_stats[0];
-   sctx->dcc_stats[i].ps_stats[0] = tmp;
-
-   /* create and start a new query as ps_stats[0] */
-   if (query_active)
-      vi_separate_dcc_start_query(sctx, tex);
-
-   if (disable) {
-      assert(!tex->last_dcc_separate_buffer);
-      tex->last_dcc_separate_buffer = tex->dcc_separate_buffer;
-      tex->dcc_separate_buffer = NULL;
-      tex->surface.meta_offset = 0;
-      /* no need to flag anything since this is called after
-       * decompression that re-sets framebuffer state
-       */
-   }
-}
-
 static struct pipe_memory_object *
 si_memobj_from_handle(struct pipe_screen *screen, struct winsys_handle *whandle, bool dedicated)
 {



More information about the mesa-commit mailing list