[Mesa-dev] [PATCH 15/30] i965/miptree: Add new entrypoints for resolve management

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


This commit adds a new unified interface for doing resolves.  The basic
format is that, prior to any surface access such as texturing or
rendering, you call intel_miptree_prepare_access.  If the surface was
written, you call intel_miptree_finish_write.  These two functions take
parameters which tell them whether or not auxiliary compression and fast
clears are supported on the surface.  Later commits will add wrappers
around these two functions for texturing, rendering, etc.
---
 src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 156 +++++++++++++++++++++++++-
 src/mesa/drivers/dri/i965/intel_mipmap_tree.h |  80 +++++++++++++
 2 files changed, 232 insertions(+), 4 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
index 6cd32ce..0659e75 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -2028,8 +2028,7 @@ bool
 intel_miptree_all_slices_resolve_hiz(struct brw_context *brw,
 				     struct intel_mipmap_tree *mt)
 {
-   return intel_miptree_depth_hiz_resolve(brw, mt,
-                                          0, UINT32_MAX, 0, UINT32_MAX,
+   return intel_miptree_depth_hiz_resolve(brw, mt, 0, UINT32_MAX, 0, UINT32_MAX,
                                           BLORP_HIZ_OP_HIZ_RESOLVE);
 }
 
@@ -2037,8 +2036,7 @@ 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,
+   return intel_miptree_depth_hiz_resolve(brw, mt, 0, UINT32_MAX, 0, UINT32_MAX,
                                           BLORP_HIZ_OP_DEPTH_RESOLVE);
 }
 
@@ -2221,6 +2219,156 @@ intel_miptree_all_slices_resolve_color(struct brw_context *brw,
    intel_miptree_resolve_color(brw, mt, 0, UINT32_MAX, 0, UINT32_MAX, flags);
 }
 
+void
+intel_miptree_prepare_access(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,
+                             bool aux_supported, bool fast_clear_supported)
+{
+   if (_mesa_is_format_color_format(mt->format)) {
+      if (!mt->mcs_buf)
+         return;
+
+      if (mt->num_samples > 1) {
+         /* Nothing to do for MSAA */
+      } else {
+         /* TODO: This is fairly terrible.  We can do better. */
+         if (!aux_supported || !fast_clear_supported) {
+            intel_miptree_resolve_color(brw, mt, start_level, num_levels,
+                                        start_layer, num_layers, 0);
+         }
+      }
+   } else if (mt->format == MESA_FORMAT_S_UINT8) {
+      /* Nothing to do for stencil */
+   } else {
+      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);
+      }
+   }
+}
+
+void
+intel_miptree_finish_write(struct brw_context *brw,
+                           struct intel_mipmap_tree *mt, uint32_t level,
+                           uint32_t start_layer, uint32_t num_layers,
+                           bool written_with_aux)
+{
+   assert(start_layer < mt->level[level].depth);
+   if (num_layers == INTEL_REMAINING_LAYERS)
+      num_layers = mt->level[level].depth - start_layer;
+   assert(num_layers <= mt->level[level].depth - start_layer);
+
+   if (_mesa_is_format_color_format(mt->format)) {
+      if (mt->num_samples > 1) {
+         /* Nothing to do for MSAA */
+      } else {
+         if (written_with_aux) {
+            intel_miptree_used_for_rendering(brw, mt, level,
+                                             start_layer, num_layers);
+         }
+      }
+   } else if (mt->format == MESA_FORMAT_S_UINT8) {
+      /* Nothing to do for stencil */
+   } else {
+      if (written_with_aux) {
+         for (unsigned a = 0; a < num_layers; a++) {
+            intel_miptree_check_level_layer(mt, level, start_layer);
+            intel_miptree_slice_set_needs_depth_resolve(mt, level,
+                                                        start_layer + a);
+         }
+      } else {
+         for (unsigned a = 0; a < num_layers; a++) {
+            intel_miptree_check_level_layer(mt, level, start_layer);
+            intel_miptree_slice_set_needs_hiz_resolve(mt, level,
+                                                      start_layer + a);
+         }
+      }
+   }
+}
+
+enum isl_aux_state
+intel_miptree_get_aux_state(const struct intel_mipmap_tree *mt,
+                            uint32_t level, uint32_t layer)
+{
+   if (_mesa_is_format_color_format(mt->format)) {
+      assert(mt->mcs_buf != NULL);
+      if (mt->num_samples > 1) {
+         return ISL_AUX_STATE_COMPRESSED_CLEAR;
+      } else {
+         switch (intel_miptree_get_fast_clear_state(mt, level, layer)) {
+         case INTEL_FAST_CLEAR_STATE_RESOLVED:
+            return ISL_AUX_STATE_RESOLVED;
+         case INTEL_FAST_CLEAR_STATE_UNRESOLVED:
+            return ISL_AUX_STATE_COMPRESSED_CLEAR;
+         case INTEL_FAST_CLEAR_STATE_CLEAR:
+            return ISL_AUX_STATE_CLEAR;
+         default:
+            unreachable("Invalid fast clear state");
+         }
+      }
+   } 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");
+      }
+   }
+}
+
+void
+intel_miptree_set_aux_state(struct brw_context *brw,
+                            struct intel_mipmap_tree *mt, uint32_t level,
+                            uint32_t start_layer, uint32_t num_layers,
+                            enum isl_aux_state aux_state)
+{
+   assert(start_layer < mt->level[level].depth);
+   if (num_layers == INTEL_REMAINING_LAYERS)
+      num_layers = mt->level[level].depth - start_layer;
+   assert(num_layers <= mt->level[level].depth - start_layer);
+
+   /* Right now, this only applies to clears. */
+   assert(aux_state == ISL_AUX_STATE_CLEAR);
+
+   if (_mesa_is_format_color_format(mt->format)) {
+      if (mt->num_samples > 1)
+         assert(mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS);
+
+      assert(level == 0 && start_layer == 0 && num_layers == 1);
+      intel_miptree_set_fast_clear_state(brw, mt, 0, 0, 1,
+                                         INTEL_FAST_CLEAR_STATE_CLEAR);
+   } else if (mt->format == MESA_FORMAT_S_UINT8) {
+      assert(!"Cannot set aux state for stencil");
+   } else {
+      for (unsigned a = 0; a < num_layers; a++) {
+         intel_miptree_check_level_layer(mt, level, start_layer);
+         intel_miptree_slice_set_needs_depth_resolve(mt, level,
+                                                     start_layer + a);
+      }
+   }
+}
+
 /**
  * Make it possible to share the BO backing the given miptree with another
  * process or another miptree.
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
index ffcedef..e74fca6 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
@@ -912,6 +912,86 @@ intel_miptree_all_slices_resolve_color(struct brw_context *brw,
                                        struct intel_mipmap_tree *mt,
                                        int flags);
 
+#define INTEL_REMAINING_LAYERS UINT32_MAX
+#define INTEL_REMAINING_LEVELS UINT32_MAX
+
+/** Prepare a miptree for access
+ *
+ * This function should be called prior to any access to miptree in order to
+ * perform any needed resolves.
+ *
+ * \param[in]  start_level    The first mip level to be accessed
+ *
+ * \param[in]  num_levels     The number of miplevels to be accessed or
+ *                            INTEL_REMAINING_LEVELS to indicate every level
+ *                            above start_level will be accessed
+ *
+ * \param[in]  start_layer    The first array slice or 3D layer to be accessed
+ *
+ * \param[in]  num_layers     The number of array slices or 3D layers be
+ *                            accessed or INTEL_REMAINING_LAYERS to indicate
+ *                            every layer above start_layer will be accessed
+ *
+ * \param[in]  aux_supported  Whether or not the access will support the
+ *                            miptree's auxiliary compression format;  this
+ *                            must be false for uncompressed miptrees
+ *
+ * \param[in]  fast_clear_supported Whether or not the access will support
+ *                                  fast clears in the miptree's auxiliary
+ *                                  compression format
+ */
+void
+intel_miptree_prepare_access(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,
+                             bool aux_supported, bool fast_clear_supported);
+
+/** Complete a write operation
+ *
+ * This function should be called after any operation writes to a miptree.
+ * This will update the miptree's compression state so that future resolves
+ * happen correctly.  Technically, this function can be called before the
+ * write occurs but the caller must ensure that they don't interlace
+ * intel_miptree_prepare_access and intel_miptree_finish_write calls to
+ * overlapping layer/level ranges.
+ *
+ * \param[in]  level             The mip level that was written
+ *
+ * \param[in]  start_layer       The first array slice or 3D layer written
+ *
+ * \param[in]  num_layers        The number of array slices or 3D layers
+ *                               written or INTEL_REMAINING_LAYERS to indicate
+ *                               every layer above start_layer was written
+ *
+ * \param[in]  written_with_aux  Whether or not the write was done with
+ *                               auxiliary compression enabled
+ */
+void
+intel_miptree_finish_write(struct brw_context *brw,
+                           struct intel_mipmap_tree *mt, uint32_t level,
+                           uint32_t start_layer, uint32_t num_layers,
+                           bool written_with_aux);
+
+/** Get the auxiliary compression state of a miptree slice */
+enum isl_aux_state
+intel_miptree_get_aux_state(const struct intel_mipmap_tree *mt,
+                            uint32_t level, uint32_t layer);
+
+/** Set the auxiliary compression state of a miptree slice range
+ *
+ * This function directly sets the auxiliary compression state of a slice
+ * range of a miptree.  It only modifies data structures and does not do any
+ * resolves.  This should only be called by code which directly performs
+ * compression operations such as fast clears and resolves.  Most code should
+ * use intel_miptree_prepare_access or intel_miptree_finish_write.
+ */
+void
+intel_miptree_set_aux_state(struct brw_context *brw,
+                            struct intel_mipmap_tree *mt, uint32_t level,
+                            uint32_t start_layer, uint32_t num_layers,
+                            enum isl_aux_state aux_state);
+
 void
 intel_miptree_make_shareable(struct brw_context *brw,
                              struct intel_mipmap_tree *mt);
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list