From 418aecea7d626d57da8987c062aeb3d046c6dd9a Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Mon, 6 May 2013 10:37:04 -0700 Subject: [PATCH] i965/blorp: Write blorp code to do render target resolves. 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 --- 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 + .../drivers/dri/intel/intel_mipmap_tree.c | 23 +++++++ .../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 08082060b7d..ffc27ccd7b4 100644 --- a/src/mesa/drivers/dri/i965/brw_blorp.h +++ b/src/mesa/drivers/dri/i965/brw_blorp.h @@ -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, }; diff --git a/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp b/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp index 8df493e0d18..1e2205ea15c 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: @@ -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, ¶ms); + 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 ce1f71db9e7..04422fe6df5 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -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) diff --git a/src/mesa/drivers/dri/i965/gen7_blorp.cpp b/src/mesa/drivers/dri/i965/gen7_blorp.cpp index 1b2d3099491..822f954804e 100644 --- a/src/mesa/drivers/dri/i965/gen7_blorp.cpp +++ b/src/mesa/drivers/dri/i965/gen7_blorp.cpp @@ -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; } diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index ba941c099f2..bf2c417c4e7 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -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. * diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h index c44c8eaf4a9..8ea1befdd1c 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h @@ -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); -- 2.30.2