i965/blorp: Write blorp code to do render target resolves.
authorPaul Berry <stereotype441@gmail.com>
Mon, 6 May 2013 17:37:04 +0000 (10:37 -0700)
committerPaul Berry <stereotype441@gmail.com>
Wed, 12 Jun 2013 18:10:07 +0000 (11:10 -0700)
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.

Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_blorp.h
src/mesa/drivers/dri/i965/brw_blorp_clear.cpp
src/mesa/drivers/dri/i965/brw_defines.h
src/mesa/drivers/dri/i965/gen7_blorp.cpp
src/mesa/drivers/dri/intel/intel_mipmap_tree.c
src/mesa/drivers/dri/intel/intel_mipmap_tree.h

index 08082060b7d41ab7b36e1658fd960f87aab2951e..ffc27ccd7b4a28806744368f43b3f53a3cf52626 100644 (file)
@@ -50,6 +50,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" */
 
@@ -197,6 +201,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,
 };
 
 
index 8df493e0d18ec0bc018ae8431e092fccad26be06..1e2205ea15c9a8bf38def35bd65b6af6798b46da 100644 (file)
@@ -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:
@@ -266,6 +280,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)
@@ -452,4 +503,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" */
index ce1f71db9e76c873c8472dbb00fbb6d763420cca..04422fe6df5d8e050e7436de026535e97e629c49 100644 (file)
@@ -1618,6 +1618,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)
index 1b2d3099491600ca6c96ab9d296c7e3e21cdb1e2..822f954804eb5ad76726763be4be22483bc60e43 100644 (file)
@@ -590,6 +590,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;
    }
index ba941c099f281366f7d0aff0b46bda07e44ddad8..bf2c417c4e7e789d09a0f804122a8ce1fa789066 100644 (file)
@@ -1451,6 +1451,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.
  *
index c44c8eaf4a9ace16bba7f0f23b4b4a8a1a40105a..8ea1befdd1c075d86d0139557a9ffa871e742709 100644 (file)
@@ -718,6 +718,10 @@ intel_miptree_used_for_rendering(struct intel_mipmap_tree *mt)
 #endif
 }
 
+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);