[Mesa-dev] [PATCH 28/30] i965: Use the new tracking mechanism for HiZ

Jason Ekstrand jason at jlekstrand.net
Fri May 26 23:30:32 UTC 2017


This is similar to the previous commit only for HiZ.  For HiZ, apart
from everything looking different, there is really only one functional
change:  We now track the ISL_AUX_STATE_COMPRESSED_NO_CLEAR state.
Previously, if you rendered to a resolved slice of the miptree and then
did a fast-clear with a different clear color, that slice would get
resolved even though it hadn't been fast-cleared.  Now that we can track
COMPRESSED_NO_CLEAR, we know that it doesn't have any blocks in the
"clear" state so we can skip the resolve.
---
 src/mesa/drivers/dri/i965/brw_clear.c         |   3 +-
 src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 222 ++++++++++++++------------
 src/mesa/drivers/dri/i965/intel_mipmap_tree.h |  24 ---
 3 files changed, 124 insertions(+), 125 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_clear.c b/src/mesa/drivers/dri/i965/brw_clear.c
index aa2e994..be72d67 100644
--- a/src/mesa/drivers/dri/i965/brw_clear.c
+++ b/src/mesa/drivers/dri/i965/brw_clear.c
@@ -162,7 +162,8 @@ brw_fast_clear_depth(struct gl_context *ctx)
     * flags out of the HiZ buffer into the real depth buffer.
     */
    if (mt->fast_clear_color.f32[0] != ctx->Depth.Clear) {
-      intel_miptree_all_slices_resolve_depth(brw, mt);
+      intel_miptree_prepare_access(brw, mt, 0, INTEL_REMAINING_LEVELS,
+                                   0, INTEL_REMAINING_LAYERS, true, false);
       mt->fast_clear_color.f32[0] = ctx->Depth.Clear;
    }
 
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
index 3e30b2a..a1a8177 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -325,7 +325,6 @@ intel_miptree_create_layout(struct brw_context *brw,
       INTEL_AUX_DISABLE_ALL : INTEL_AUX_DISABLE_NONE;
    mt->aux_disable |= INTEL_AUX_DISABLE_CCS;
    mt->is_scanout = (layout_flags & MIPTREE_LAYOUT_FOR_SCANOUT) != 0;
-   exec_list_make_empty(&mt->hiz_map);
    mt->aux_state = NULL;
    mt->cpp = _mesa_get_format_bytes(format);
    mt->num_samples = num_samples;
@@ -974,7 +973,6 @@ intel_miptree_release(struct intel_mipmap_tree **mt)
          brw_bo_unreference((*mt)->mcs_buf->bo);
          free((*mt)->mcs_buf);
       }
-      intel_resolve_map_clear(&(*mt)->hiz_map);
       free_aux_state_map((*mt)->aux_state);
 
       intel_miptree_release(&(*mt)->plane[0]);
@@ -1909,6 +1907,11 @@ intel_miptree_alloc_hiz(struct brw_context *brw,
    assert(mt->hiz_buf == NULL);
    assert((mt->aux_disable & INTEL_AUX_DISABLE_HIZ) == 0);
 
+   enum isl_aux_state **aux_state =
+      create_aux_state_map(mt, ISL_AUX_STATE_AUX_INVALID);
+   if (!aux_state)
+      return false;
+
    if (brw->gen == 7) {
       mt->hiz_buf = intel_gen7_hiz_buf_create(brw, mt);
    } else if (brw->gen >= 8) {
@@ -1917,24 +1920,15 @@ intel_miptree_alloc_hiz(struct brw_context *brw,
       mt->hiz_buf = intel_hiz_miptree_buf_create(brw, mt);
    }
 
-   if (!mt->hiz_buf)
+   if (!mt->hiz_buf) {
+      free(aux_state);
       return false;
+   }
 
-   /* Mark that all slices need a HiZ resolve. */
-   for (unsigned level = mt->first_level; level <= mt->last_level; ++level) {
-      if (!intel_miptree_level_enable_hiz(brw, mt, level))
-         continue;
-
-      for (unsigned layer = 0; layer < mt->level[level].depth; ++layer) {
-         struct intel_resolve_map *m = malloc(sizeof(struct intel_resolve_map));
-         exec_node_init(&m->link);
-         m->level = level;
-         m->layer = layer;
-         m->need = BLORP_HIZ_OP_HIZ_RESOLVE;
+   for (unsigned level = mt->first_level; level <= mt->last_level; ++level)
+      intel_miptree_level_enable_hiz(brw, mt, level);
 
-         exec_list_push_tail(&mt->hiz_map, &m->link);
-      }
-   }
+   mt->aux_state = aux_state;
 
    return true;
 }
@@ -1993,41 +1987,6 @@ intel_miptree_level_has_hiz(struct intel_mipmap_tree *mt, uint32_t level)
    return mt->level[level].has_hiz;
 }
 
-static bool
-intel_miptree_depth_hiz_resolve(struct brw_context *brw,
-                                struct intel_mipmap_tree *mt,
-                                uint32_t start_level, uint32_t num_levels,
-                                uint32_t start_layer, uint32_t num_layers,
-                                enum blorp_hiz_op need)
-{
-   bool did_resolve = false;
-
-   foreach_list_typed_safe(struct intel_resolve_map, map, link, &mt->hiz_map) {
-      if (map->level < start_level ||
-          map->level >= (start_level + num_levels) ||
-          map->layer < start_layer ||
-          map->layer >= (start_layer + num_layers))
-         continue;
-
-      if (map->need != need)
-	 continue;
-
-      intel_hiz_exec(brw, mt, map->level, map->layer, need);
-      intel_resolve_map_remove(map);
-      did_resolve = true;
-   }
-
-   return did_resolve;
-}
-
-bool
-intel_miptree_all_slices_resolve_depth(struct brw_context *brw,
-				       struct intel_mipmap_tree *mt)
-{
-   return intel_miptree_depth_hiz_resolve(brw, mt, 0, UINT32_MAX, 0, UINT32_MAX,
-                                          BLORP_HIZ_OP_DEPTH_RESOLVE);
-}
-
 bool
 intel_miptree_has_color_unresolved(const struct intel_mipmap_tree *mt,
                                    unsigned start_level, unsigned num_levels,
@@ -2267,6 +2226,96 @@ intel_miptree_finish_mcs_write(struct brw_context *brw,
    }
 }
 
+static void
+intel_miptree_prepare_hiz_access(struct brw_context *brw,
+                                 struct intel_mipmap_tree *mt,
+                                 uint32_t level, uint32_t layer,
+                                 bool hiz_supported, bool fast_clear_supported)
+{
+   enum blorp_hiz_op hiz_op = BLORP_HIZ_OP_NONE;
+   switch (intel_miptree_get_aux_state(mt, level, layer)) {
+   case ISL_AUX_STATE_CLEAR:
+   case ISL_AUX_STATE_COMPRESSED_CLEAR:
+      if (!hiz_supported || !fast_clear_supported)
+         hiz_op = BLORP_HIZ_OP_DEPTH_RESOLVE;
+      break;
+
+   case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:
+      if (!hiz_supported)
+         hiz_op = BLORP_HIZ_OP_DEPTH_RESOLVE;
+      break;
+
+   case ISL_AUX_STATE_PASS_THROUGH:
+   case ISL_AUX_STATE_RESOLVED:
+      break;
+
+   case ISL_AUX_STATE_AUX_INVALID:
+      if (hiz_supported)
+         hiz_op = BLORP_HIZ_OP_HIZ_RESOLVE;
+      break;
+   }
+
+   if (hiz_op != BLORP_HIZ_OP_NONE) {
+      intel_hiz_exec(brw, mt, level, layer, hiz_op);
+
+      switch (hiz_op) {
+      case BLORP_HIZ_OP_DEPTH_RESOLVE:
+         intel_miptree_set_aux_state(brw, mt, level, layer, 1,
+                                     ISL_AUX_STATE_RESOLVED);
+         break;
+
+      case BLORP_HIZ_OP_HIZ_RESOLVE:
+         /* The HiZ resolve operation is actually an ambiguate */
+         intel_miptree_set_aux_state(brw, mt, level, layer, 1,
+                                     ISL_AUX_STATE_RESOLVED);
+         break;
+
+      default:
+         unreachable("Invalid HiZ op");
+      }
+   }
+}
+
+static void
+intel_miptree_finish_hiz_write(struct brw_context *brw,
+                               struct intel_mipmap_tree *mt,
+                               uint32_t level, uint32_t layer,
+                               bool written_with_hiz)
+{
+   switch (intel_miptree_get_aux_state(mt, level, layer)) {
+   case ISL_AUX_STATE_CLEAR:
+      assert(written_with_hiz);
+      intel_miptree_set_aux_state(brw, mt, level, layer, 1,
+                                  ISL_AUX_STATE_COMPRESSED_CLEAR);
+      break;
+
+   case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:
+   case ISL_AUX_STATE_COMPRESSED_CLEAR:
+      assert(written_with_hiz);
+      break; /* Nothing to do */
+
+   case ISL_AUX_STATE_RESOLVED:
+      if (written_with_hiz) {
+         intel_miptree_set_aux_state(brw, mt, level, layer, 1,
+                                     ISL_AUX_STATE_COMPRESSED_NO_CLEAR);
+      } else {
+         intel_miptree_set_aux_state(brw, mt, level, layer, 1,
+                                     ISL_AUX_STATE_AUX_INVALID);
+      }
+
+   case ISL_AUX_STATE_PASS_THROUGH:
+      if (written_with_hiz) {
+         intel_miptree_set_aux_state(brw, mt, level, layer, 1,
+                                     ISL_AUX_STATE_COMPRESSED_NO_CLEAR);
+      }
+      break;
+
+   case ISL_AUX_STATE_AUX_INVALID:
+      assert(!written_with_hiz);
+      break;
+   }
+}
+
 void
 intel_miptree_prepare_access(struct brw_context *brw,
                              struct intel_mipmap_tree *mt,
@@ -2305,16 +2354,17 @@ intel_miptree_prepare_access(struct brw_context *brw,
       if (!mt->hiz_buf)
          return;
 
-      if (aux_supported) {
-         assert(fast_clear_supported);
-         intel_miptree_depth_hiz_resolve(brw, mt, start_level, num_levels,
-                                         start_layer, num_layers,
-                                         BLORP_HIZ_OP_HIZ_RESOLVE);
-      } else {
-         assert(!fast_clear_supported);
-         intel_miptree_depth_hiz_resolve(brw, mt, start_level, num_levels,
-                                         start_layer, num_layers,
-                                         BLORP_HIZ_OP_DEPTH_RESOLVE);
+      for (uint32_t level = start_level; level <= last_level; level++) {
+         if (!intel_miptree_level_has_hiz(mt, level))
+            continue;
+
+         const uint32_t level_layers =
+            MIN2(num_layers, mt->level[level].depth);
+         for (uint32_t a = 0; a < level_layers; a++) {
+            intel_miptree_prepare_hiz_access(brw, mt, level, start_layer + a,
+                                             aux_supported,
+                                             fast_clear_supported);
+         }
       }
    }
 }
@@ -2351,18 +2401,9 @@ intel_miptree_finish_write(struct brw_context *brw,
       if (!intel_miptree_level_has_hiz(mt, level))
          return;
 
-      if (written_with_aux) {
-         for (unsigned a = 0; a < num_layers; a++) {
-            intel_miptree_check_level_layer(mt, level, start_layer);
-            intel_resolve_map_set(&mt->hiz_map, level, start_layer + a,
-                                  BLORP_HIZ_OP_DEPTH_RESOLVE);
-         }
-      } else {
-         for (unsigned a = 0; a < num_layers; a++) {
-            intel_miptree_check_level_layer(mt, level, start_layer);
-            intel_resolve_map_set(&mt->hiz_map, level, start_layer + a,
-                                  BLORP_HIZ_OP_HIZ_RESOLVE);
-         }
+      for (uint32_t a = 0; a < num_layers; a++) {
+         intel_miptree_finish_hiz_write(brw, mt, level, start_layer + a,
+                                        written_with_aux);
       }
    }
 }
@@ -2376,24 +2417,13 @@ intel_miptree_get_aux_state(const struct intel_mipmap_tree *mt,
    if (_mesa_is_format_color_format(mt->format)) {
       assert(mt->mcs_buf != NULL);
       assert(mt->num_samples <= 1 || mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS);
-      return mt->aux_state[level][layer];
    } else if (mt->format == MESA_FORMAT_S_UINT8) {
       unreachable("Cannot get aux state for stencil");
    } else {
       assert(mt->hiz_buf != NULL);
-      const struct intel_resolve_map *map =
-         intel_resolve_map_const_get(&mt->hiz_map, level, layer);
-      if (!map)
-         return ISL_AUX_STATE_RESOLVED;
-      switch (map->need) {
-      case BLORP_HIZ_OP_DEPTH_RESOLVE:
-         return ISL_AUX_STATE_COMPRESSED_CLEAR;
-      case BLORP_HIZ_OP_HIZ_RESOLVE:
-         return ISL_AUX_STATE_AUX_INVALID;
-      default:
-         unreachable("Invalid hiz op");
-      }
    }
+
+   return mt->aux_state[level][layer];
 }
 
 void
@@ -2410,23 +2440,14 @@ intel_miptree_set_aux_state(struct brw_context *brw,
    if (_mesa_is_format_color_format(mt->format)) {
       assert(mt->mcs_buf != NULL);
       assert(mt->num_samples <= 1 || mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS);
-
-      for (unsigned a = 0; a < num_layers; a++)
-         mt->aux_state[level][start_layer + a] = aux_state;
    } else if (mt->format == MESA_FORMAT_S_UINT8) {
       unreachable("Cannot get aux state for stencil");
    } else {
       assert(mt->hiz_buf != NULL);
-
-      /* Right now, this only applies to clears. */
-      assert(aux_state == ISL_AUX_STATE_CLEAR);
-
-      for (unsigned a = 0; a < num_layers; a++) {
-         intel_miptree_check_level_layer(mt, level, start_layer);
-         intel_resolve_map_set(&mt->hiz_map, level, start_layer + a,
-                               BLORP_HIZ_OP_DEPTH_RESOLVE);
-      }
    }
+
+   for (unsigned a = 0; a < num_layers; a++)
+      mt->aux_state[level][start_layer + a] = aux_state;
 }
 
 /* On Gen9 color buffers may be compressed by the hardware (lossless
@@ -2647,7 +2668,8 @@ intel_miptree_make_shareable(struct brw_context *brw,
        * any will likely crash due to the missing aux buffer. So let's delete
        * all pending ops.
        */
-      exec_list_make_empty(&mt->hiz_map);
+      free(mt->aux_state);
+      mt->aux_state = NULL;
    }
 }
 
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
index 528c32c..428c097 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
@@ -542,23 +542,6 @@ struct intel_mipmap_tree
    struct intel_miptree_hiz_buffer *hiz_buf;
 
    /**
-    * \brief Maps of miptree slices to needed resolves.
-    *
-    * hiz_map is used only when the miptree has a child HiZ miptree.
-    *
-    * Let \c mt be a depth miptree with HiZ enabled. Then the resolve map is
-    * \c mt->hiz_map. The resolve map of the child HiZ miptree, \c
-    * mt->hiz_mt->hiz_map, is unused.
-    *
-    *
-    * color_resolve_map is used only when the miptree uses fast clear (Gen7+)
-    * lossless compression (Gen9+). It should be noted that absence in the
-    * map means implicitly RESOLVED state. If item is found it always
-    * indicates state other than RESOLVED.
-    */
-   struct exec_list hiz_map; /* List of intel_resolve_map. */
-
-   /**
     * \brief Maps miptree slices to their current aux state
     *
     * This two-dimensional array is indexed as [level][layer] and stores an
@@ -825,13 +808,6 @@ intel_miptree_alloc_hiz(struct brw_context *brw,
 bool
 intel_miptree_level_has_hiz(struct intel_mipmap_tree *mt, uint32_t level);
 
-/**
- * \return false if no resolve was needed
- */
-bool
-intel_miptree_all_slices_resolve_depth(struct brw_context *brw,
-				       struct intel_mipmap_tree *mt);
-
 /**\}*/
 
 bool
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list