[Mesa-dev] [PATCH v2 03/12] i965/gen7+: Create an enum for keeping track of fast color clear state.

Paul Berry stereotype441 at gmail.com
Tue Jun 4 17:01:06 PDT 2013


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.
---
 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(+)

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 c7bb815..2f6cb5a 100644
--- a/src/mesa/drivers/dri/i965/gen6_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/gen6_blorp.cpp
@@ -1094,6 +1094,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 f83c7f2..7bbfb5d 100644
--- a/src/mesa/drivers/dri/i965/gen7_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/gen7_blorp.cpp
@@ -863,6 +863,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);
-- 
1.8.3



More information about the mesa-dev mailing list