From 7e5cb4bc4c8dfc96019b815e2c9a62af12e1f958 Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Tue, 7 May 2013 14:04:29 -0700 Subject: [PATCH] i965/gen7+: Create an enum for keeping track of fast color clear state. 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 --- .../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 + .../drivers/dri/i965/gen7_wm_surface_state.c | 2 + .../drivers/dri/intel/intel_mipmap_tree.c | 4 + .../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 4d4d30031ff..ceabedbe1b8 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 bb87f6bbe67..3ccd90e8c88 100644 --- a/src/mesa/drivers/dri/i965/gen6_blorp.cpp +++ b/src/mesa/drivers/dri/i965/gen6_blorp.cpp @@ -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, ¶ms->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 aa9a3ef3759..68c7ca11626 100644 --- a/src/mesa/drivers/dri/i965/gen7_blorp.cpp +++ b/src/mesa/drivers/dri/i965/gen7_blorp.cpp @@ -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, ¶ms->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 22ceaa5188f..6a7c8deff55 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 ee763e52020..601666ccec1 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 639d4be94c2..d66d0b5a424 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); -- 2.30.2