Mesa (master): i965/gen7+: Create an enum for keeping track of fast color clear state.

Paul Berry stereotype441 at kemper.freedesktop.org
Wed Jun 12 18:12:22 UTC 2013


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

Author: Paul Berry <stereotype441 at gmail.com>
Date:   Tue May  7 14:04:29 2013 -0700

i965/gen7+: Create an enum for keeping track of fast color clear state.

This patch includes code to update the fast color clear state
appropriately when rendering occurs.  The state will also need to be
updated when a fast clear or a resolve operation is performed; those
state updates will be added when the fast clear and resolve operations
are added.

v2: Create a new function, intel_miptree_used_for_rendering() to
handle updating the fast color clear state when rendering occurs.

Reviewed-by: Eric Anholt <eric at anholt.net>

---

 src/mesa/drivers/dri/i965/brw_wm_surface_state.c  |    2 +
 src/mesa/drivers/dri/i965/gen6_blorp.cpp          |    1 +
 src/mesa/drivers/dri/i965/gen7_blorp.cpp          |    1 +
 src/mesa/drivers/dri/i965/gen7_wm_surface_state.c |    2 +
 src/mesa/drivers/dri/intel/intel_mipmap_tree.c    |    4 +
 src/mesa/drivers/dri/intel/intel_mipmap_tree.h    |   94 +++++++++++++++++++++
 6 files changed, 104 insertions(+), 0 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index 4d4d300..ceabedb 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -1346,6 +1346,8 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
       }
    }
 
+   intel_miptree_used_for_rendering(irb->mt);
+
    region = irb->mt->region;
 
    surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
diff --git a/src/mesa/drivers/dri/i965/gen6_blorp.cpp b/src/mesa/drivers/dri/i965/gen6_blorp.cpp
index bb87f6b..3ccd90e 100644
--- a/src/mesa/drivers/dri/i965/gen6_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/gen6_blorp.cpp
@@ -1075,6 +1075,7 @@ gen6_blorp_exec(struct intel_context *intel,
       uint32_t wm_surf_offset_texture = 0;
       uint32_t sampler_offset;
       wm_push_const_offset = gen6_blorp_emit_wm_constants(brw, params);
+      intel_miptree_used_for_rendering(params->dst.mt);
       wm_surf_offset_renderbuffer =
          gen6_blorp_emit_surface_state(brw, params, &params->dst,
                                        I915_GEM_DOMAIN_RENDER,
diff --git a/src/mesa/drivers/dri/i965/gen7_blorp.cpp b/src/mesa/drivers/dri/i965/gen7_blorp.cpp
index aa9a3ef..68c7ca1 100644
--- a/src/mesa/drivers/dri/i965/gen7_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/gen7_blorp.cpp
@@ -862,6 +862,7 @@ gen7_blorp_exec(struct intel_context *intel,
       uint32_t wm_surf_offset_renderbuffer;
       uint32_t wm_surf_offset_texture = 0;
       wm_push_const_offset = gen6_blorp_emit_wm_constants(brw, params);
+      intel_miptree_used_for_rendering(params->dst.mt);
       wm_surf_offset_renderbuffer =
          gen7_blorp_emit_surface_state(brw, params, &params->dst,
                                        I915_GEM_DOMAIN_RENDER,
diff --git a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
index 22ceaa5..6a7c8de 100644
--- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
@@ -545,6 +545,8 @@ gen7_update_renderbuffer_surface(struct brw_context *brw,
                                     8 * 4, 32, &brw->wm.surf_offset[unit]);
    memset(surf, 0, 8 * 4);
 
+   intel_miptree_used_for_rendering(irb->mt);
+
    /* Render targets can't use IMS layout */
    assert(irb->mt->msaa_layout != INTEL_MSAA_LAYOUT_IMS);
 
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index ee763e5..601666c 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -154,6 +154,9 @@ intel_miptree_create_layout(struct intel_context *intel,
    mt->logical_width0 = width0;
    mt->logical_height0 = height0;
    mt->logical_depth0 = depth0;
+#ifndef I915
+   mt->mcs_state = INTEL_MCS_STATE_NONE;
+#endif
 
    /* The cpp is bytes per (1, blockheight)-sized block for compressed
     * textures.  This is why you'll see divides by blockheight all over
@@ -1048,6 +1051,7 @@ intel_miptree_alloc_mcs(struct intel_context *intel,
     *
     *     "The MCS surface must be stored as Tile Y."
     */
+   mt->mcs_state = INTEL_MCS_STATE_MSAA;
    mt->mcs_mt = intel_miptree_create(intel,
                                      mt->target,
                                      format,
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
index 639d4be..d66d0b5 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
@@ -200,6 +200,74 @@ enum intel_msaa_layout
    INTEL_MSAA_LAYOUT_CMS,
 };
 
+
+#ifndef I915
+/**
+ * Enum for keeping track of the state of an MCS buffer associated with a
+ * miptree.  This determines when fast clear related operations are needed.
+ *
+ * Fast clear works by deferring the memory writes that would be used to clear
+ * the buffer, so that instead of performing them at the time of the clear
+ * operation, the hardware automatically performs them at the time that the
+ * buffer is later accessed for rendering.  The MCS buffer keeps track of
+ * which regions of the buffer still have pending clear writes.
+ *
+ * This enum keeps track of the driver's knowledge of the state of the MCS
+ * buffer.
+ *
+ * MCS buffers only exist on Gen7+.
+ */
+enum intel_mcs_state
+{
+   /**
+    * There is no MCS buffer for this miptree, and one should never be
+    * allocated.
+    */
+   INTEL_MCS_STATE_NONE,
+
+   /**
+    * An MCS buffer exists for this miptree, and it is used for MSAA purposes.
+    */
+   INTEL_MCS_STATE_MSAA,
+
+   /**
+    * No deferred clears are pending for this miptree, and the contents of the
+    * color buffer are entirely correct.  An MCS buffer may or may not exist
+    * for this miptree.  If it does exist, it is entirely in the "no deferred
+    * clears pending" state.  If it does not exist, it will be created the
+    * first time a fast color clear is executed.
+    *
+    * In this state, the color buffer can be used for purposes other than
+    * rendering without needing a render target resolve.
+    */
+   INTEL_MCS_STATE_RESOLVED,
+
+   /**
+    * An MCS buffer exists for this miptree, and deferred clears are pending
+    * for some regions of the color buffer, as indicated by the MCS buffer.
+    * The contents of the color buffer are only correct for the regions where
+    * the MCS buffer doesn't indicate a deferred clear.
+    *
+    * In this state, a render target resolve must be performed before the
+    * color buffer can be used for purposes other than rendering.
+    */
+   INTEL_MCS_STATE_UNRESOLVED,
+
+   /**
+    * An MCS buffer exists for this miptree, and deferred clears are pending
+    * for the entire color buffer, and the contents of the MCS buffer reflect
+    * this.  The contents of the color buffer are undefined.
+    *
+    * In this state, a render target resolve must be performed before the
+    * color buffer can be used for purposes other than rendering.
+    *
+    * If the client attempts to clear a buffer which is already in this state,
+    * the clear can be safely skipped, since the buffer is already clear.
+    */
+   INTEL_MCS_STATE_CLEAR,
+};
+#endif
+
 struct intel_mipmap_tree
 {
    /* Effectively the key:
@@ -382,6 +450,11 @@ struct intel_mipmap_tree
     * (INTEL_MSAA_FORMAT_CMS).
     */
    struct intel_mipmap_tree *mcs_mt;
+
+   /**
+    * MCS state for this buffer.
+    */
+   enum intel_mcs_state mcs_state;
 #endif
 
    /* These are also refcounted:
@@ -600,6 +673,27 @@ intel_miptree_all_slices_resolve_depth(struct intel_context *intel,
 
 /**\}*/
 
+/**
+ * Update the fast clear state for a miptree to indicate that it has been used
+ * for rendering.
+ */
+static inline void
+intel_miptree_used_for_rendering(struct intel_mipmap_tree *mt)
+{
+#ifdef I915
+   /* Nothing needs to be done for I915, since it doesn't support fast
+    * clear.
+    */
+#else
+   /* If the buffer was previously in fast clear state, change it to
+    * unresolved state, since it won't be guaranteed to be clear after
+    * rendering occurs.
+    */
+   if (mt->mcs_state == INTEL_MCS_STATE_CLEAR)
+      mt->mcs_state = INTEL_MCS_STATE_UNRESOLVED;
+#endif
+}
+
 void
 intel_miptree_downsample(struct intel_context *intel,
                          struct intel_mipmap_tree *mt);




More information about the mesa-commit mailing list