[Mesa-dev] [PATCH 08/12] i965/blorp: Write blorp code to do render target resolves.

Paul Berry stereotype441 at gmail.com
Tue May 21 16:52:12 PDT 2013


This patch implements the "render target resolve" blorp operation.
This will be needed when a buffer that has experienced a fast color
clear is later used for a purpose other than as a render target
(texturing, glReadPixels, or swapped to the screen).  It resolves any
remaining deferred clear operation that was not taken care of during
normal rendering.

Fortunately not much work is necessary; all we need to do is scale
down the size of the rectangle primitive being emitted, run the
fragment shader with the "Render Target Resolve Enable" bit set, and
ensure that the fragment shader writes to the render target using the
"replicated color" message.  We already have a fragment shader that
does that (the shader that we use for fast color clears), so for
simplicity we re-use it.
---
 src/mesa/drivers/dri/i965/brw_blorp.h          |  5 +++
 src/mesa/drivers/dri/i965/brw_blorp_clear.cpp  | 60 ++++++++++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_defines.h        |  1 +
 src/mesa/drivers/dri/i965/gen7_blorp.cpp       |  3 ++
 src/mesa/drivers/dri/intel/intel_mipmap_tree.c | 23 ++++++++++
 src/mesa/drivers/dri/intel/intel_mipmap_tree.h |  4 ++
 6 files changed, 96 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_blorp.h b/src/mesa/drivers/dri/i965/brw_blorp.h
index 687d7eb..2750aba 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.h
+++ b/src/mesa/drivers/dri/i965/brw_blorp.h
@@ -49,6 +49,10 @@ bool
 brw_blorp_clear_color(struct intel_context *intel, struct gl_framebuffer *fb,
                       bool partial_clear);
 
+void
+brw_blorp_resolve_color(struct intel_context *intel,
+                        struct intel_mipmap_tree *mt);
+
 #ifdef __cplusplus
 } /* end extern "C" */
 
@@ -200,6 +204,7 @@ struct brw_blorp_prog_data
 enum gen7_fast_clear_op {
    GEN7_FAST_CLEAR_OP_NONE,
    GEN7_FAST_CLEAR_OP_FAST_CLEAR,
+   GEN7_FAST_CLEAR_OP_RESOLVE,
 };
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp b/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp
index 4ced318..a598dff 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp
+++ b/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp
@@ -68,6 +68,20 @@ public:
                           bool partial_clear);
 };
 
+
+/**
+ * Parameters for a blorp operation that performs a "render target resolve".
+ * This is used to resolve pending fast clear pixels before a color buffer is
+ * used for texturing, ReadPixels, or scanout.
+ */
+class brw_blorp_rt_resolve_params : public brw_blorp_const_color_params
+{
+public:
+   brw_blorp_rt_resolve_params(struct brw_context *brw,
+                               struct intel_mipmap_tree *mt);
+};
+
+
 class brw_blorp_const_color_program
 {
 public:
@@ -264,6 +278,43 @@ brw_blorp_clear_params::brw_blorp_clear_params(struct brw_context *brw,
    }
 }
 
+
+brw_blorp_rt_resolve_params::brw_blorp_rt_resolve_params(
+      struct brw_context *brw,
+      struct intel_mipmap_tree *mt)
+{
+   dst.set(brw, mt, 0 /* level */, 0 /* layer */);
+
+   /* From the Ivy Bridge PRM, Vol2 Part1 11.9 "Render Target Resolve":
+    *
+    *     A rectangle primitive must be scaled down by the following factors
+    *     with respect to render target being resolved.
+    *
+    * The scaledown factors in the table that follows are related to the
+    * alignment size returned by intel_get_non_msrt_mcs_alignment(), but with
+    * X and Y alignment each divided by 2.
+    */
+   unsigned x_align, y_align;
+   intel_get_non_msrt_mcs_alignment(&brw->intel, mt, &x_align, &y_align);
+   unsigned x_scaledown = x_align / 2;
+   unsigned y_scaledown = y_align / 2;
+   x0 = y0 = 0;
+   x1 = ALIGN(mt->logical_width0, x_scaledown) / x_scaledown;
+   y1 = ALIGN(mt->logical_height0, y_scaledown) / y_scaledown;
+
+   fast_clear_op = GEN7_FAST_CLEAR_OP_RESOLVE;
+
+   /* Note: there is no need to initialize push constants because it doesn't
+    * matter what data gets dispatched to the render target.  However, we must
+    * ensure that the fragment shader delivers the data using the "replicated
+    * color" message.
+    */
+   use_wm_prog = true;
+   memset(&wm_prog_key, 0, sizeof(wm_prog_key));
+   wm_prog_key.use_simd16_replicated_data = true;
+}
+
+
 uint32_t
 brw_blorp_const_color_params::get_wm_prog(struct brw_context *brw,
                                           brw_blorp_prog_data **prog_data)
@@ -448,4 +499,13 @@ brw_blorp_clear_color(struct intel_context *intel, struct gl_framebuffer *fb,
    return true;
 }
 
+void
+brw_blorp_resolve_color(struct intel_context *intel, struct intel_mipmap_tree *mt)
+{
+   struct brw_context *brw = brw_context(&intel->ctx);
+   brw_blorp_rt_resolve_params params(brw, mt);
+   brw_blorp_exec(intel, &params);
+   mt->mcs_state = INTEL_MCS_STATE_RESOLVED;
+}
+
 } /* extern "C" */
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index 90b16ab..b81517d 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -1616,6 +1616,7 @@ enum brw_wm_barycentric_interp_mode {
 # define GEN7_PS_OMASK_TO_RENDER_TARGET			(1 << 9)
 # define GEN7_PS_RENDER_TARGET_FAST_CLEAR_ENABLE	(1 << 8)
 # define GEN7_PS_DUAL_SOURCE_BLEND_ENABLE		(1 << 7)
+# define GEN7_PS_RENDER_TARGET_RESOLVE_ENABLE		(1 << 6)
 # define GEN7_PS_POSOFFSET_NONE				(0 << 3)
 # define GEN7_PS_POSOFFSET_CENTROID			(2 << 3)
 # define GEN7_PS_POSOFFSET_SAMPLE			(3 << 3)
diff --git a/src/mesa/drivers/dri/i965/gen7_blorp.cpp b/src/mesa/drivers/dri/i965/gen7_blorp.cpp
index 5f7e10f..fdd3dd3 100644
--- a/src/mesa/drivers/dri/i965/gen7_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/gen7_blorp.cpp
@@ -593,6 +593,9 @@ gen7_blorp_emit_ps_config(struct brw_context *brw,
    case GEN7_FAST_CLEAR_OP_FAST_CLEAR:
       dw4 |= GEN7_PS_RENDER_TARGET_FAST_CLEAR_ENABLE;
       break;
+   case GEN7_FAST_CLEAR_OP_RESOLVE:
+      dw4 |= GEN7_PS_RENDER_TARGET_RESOLVE_ENABLE;
+      break;
    default:
       break;
    }
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index 657532f..7a3c135 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -1412,6 +1412,29 @@ intel_miptree_all_slices_resolve_depth(struct intel_context *intel,
 					   GEN6_HIZ_OP_DEPTH_RESOLVE);
 }
 
+
+void
+intel_miptree_resolve_color(struct intel_context *intel,
+                            struct intel_mipmap_tree *mt)
+{
+#ifdef I915
+   /* Fast color clear is not supported on the i915 (pre-Gen4) driver */
+#else
+   switch (mt->mcs_state) {
+   case INTEL_MCS_STATE_NONE:
+   case INTEL_MCS_STATE_MSAA:
+   case INTEL_MCS_STATE_RESOLVED:
+      /* No resolve needed */
+      break;
+   case INTEL_MCS_STATE_UNRESOLVED:
+   case INTEL_MCS_STATE_CLEAR:
+      brw_blorp_resolve_color(intel, mt);
+      break;
+   }
+#endif
+}
+
+
 /**
  * \brief Get pointer offset into stencil buffer.
  *
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
index 4c9ff94..f4ef4e6 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
@@ -692,6 +692,10 @@ intel_miptree_all_slices_resolve_depth(struct intel_context *intel,
 /**\}*/
 
 void
+intel_miptree_resolve_color(struct intel_context *intel,
+                            struct intel_mipmap_tree *mt);
+
+void
 intel_miptree_downsample(struct intel_context *intel,
                          struct intel_mipmap_tree *mt);
 
-- 
1.8.2.3



More information about the mesa-dev mailing list