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 <eric@anholt.net>
This commit is contained in:
Paul Berry 2013-05-07 14:04:29 -07:00
parent 8f5147c199
commit 7e5cb4bc4c
6 changed files with 104 additions and 0 deletions

View 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,

View 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,

View 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,

View 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);

View 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,

View 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);