i965/gen7+: Create an enum for keeping track of fast color clear state.
authorPaul Berry <stereotype441@gmail.com>
Tue, 7 May 2013 21:04:29 +0000 (14:04 -0700)
committerPaul Berry <stereotype441@gmail.com>
Wed, 12 Jun 2013 17:45:42 +0000 (10:45 -0700)
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@anholt.net>
src/mesa/drivers/dri/i965/brw_wm_surface_state.c
src/mesa/drivers/dri/i965/gen6_blorp.cpp
src/mesa/drivers/dri/i965/gen7_blorp.cpp
src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
src/mesa/drivers/dri/intel/intel_mipmap_tree.c
src/mesa/drivers/dri/intel/intel_mipmap_tree.h

index 4d4d30031ffff0b42797327998314b12b2bcc9df..ceabedbe1b8e46c20e7c054ec85c64014dca1b82 100644 (file)
@@ -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,
index bb87f6bbe679616d96e74e93179c47307171364f..3ccd90e8c88a38de4724f6606d8bc887f6588d3e 100644 (file)
@@ -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,
index aa9a3ef37593b573b779ab0134e7ad3f9162a102..68c7ca11626d61f484a2af4781cdf26a7587f9cb 100644 (file)
@@ -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,
index 22ceaa5188f41e318732efa6865c91c0939b46ec..6a7c8deff559d2c14a2ba539eb5a4943d82c7795 100644 (file)
@@ -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);
 
index ee763e520201bb488fa0cc179ec376f820e89156..601666ccec186e9c4a33b50ad04a72d575f4c809 100644 (file)
@@ -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,
index 639d4be94c26de00bf1892ea3bde84b5001ac004..d66d0b5a424c99defb30eafe8fc6be551db02f90 100644 (file)
@@ -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);