[Mesa-dev] [PATCH 15/30] i965/miptree: Add new entrypoints for resolve management
Nanley Chery
nanleychery at gmail.com
Fri Jun 2 23:30:23 UTC 2017
On Fri, May 26, 2017 at 04:30:19PM -0700, Jason Ekstrand wrote:
> This commit adds a new unified interface for doing resolves. The basic
> format is that, prior to any surface access such as texturing or
> rendering, you call intel_miptree_prepare_access. If the surface was
> written, you call intel_miptree_finish_write. These two functions take
> parameters which tell them whether or not auxiliary compression and fast
> clears are supported on the surface. Later commits will add wrappers
> around these two functions for texturing, rendering, etc.
> ---
> src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 156 +++++++++++++++++++++++++-
> src/mesa/drivers/dri/i965/intel_mipmap_tree.h | 80 +++++++++++++
> 2 files changed, 232 insertions(+), 4 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
> index 6cd32ce..0659e75 100644
> --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
> +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
> @@ -2028,8 +2028,7 @@ bool
> intel_miptree_all_slices_resolve_hiz(struct brw_context *brw,
> struct intel_mipmap_tree *mt)
> {
> - return intel_miptree_depth_hiz_resolve(brw, mt,
> - 0, UINT32_MAX, 0, UINT32_MAX,
> + return intel_miptree_depth_hiz_resolve(brw, mt, 0, UINT32_MAX, 0, UINT32_MAX,
> BLORP_HIZ_OP_HIZ_RESOLVE);
> }
>
> @@ -2037,8 +2036,7 @@ bool
> intel_miptree_all_slices_resolve_depth(struct brw_context *brw,
> struct intel_mipmap_tree *mt)
> {
> - return intel_miptree_depth_hiz_resolve(brw, mt,
> - 0, UINT32_MAX, 0, UINT32_MAX,
> + return intel_miptree_depth_hiz_resolve(brw, mt, 0, UINT32_MAX, 0, UINT32_MAX,
> BLORP_HIZ_OP_DEPTH_RESOLVE);
> }
>
> @@ -2221,6 +2219,156 @@ intel_miptree_all_slices_resolve_color(struct brw_context *brw,
> intel_miptree_resolve_color(brw, mt, 0, UINT32_MAX, 0, UINT32_MAX, flags);
> }
>
> +void
> +intel_miptree_prepare_access(struct brw_context *brw,
> + struct intel_mipmap_tree *mt,
> + uint32_t start_level, uint32_t num_levels,
> + uint32_t start_layer, uint32_t num_layers,
> + bool aux_supported, bool fast_clear_supported)
> +{
> + if (_mesa_is_format_color_format(mt->format)) {
> + if (!mt->mcs_buf)
> + return;
> +
> + if (mt->num_samples > 1) {
> + /* Nothing to do for MSAA */
> + } else {
> + /* TODO: This is fairly terrible. We can do better. */
> + if (!aux_supported || !fast_clear_supported) {
> + intel_miptree_resolve_color(brw, mt, start_level, num_levels,
> + start_layer, num_layers, 0);
> + }
> + }
> + } else if (mt->format == MESA_FORMAT_S_UINT8) {
> + /* Nothing to do for stencil */
> + } else {
> + if (!mt->hiz_buf)
> + return;
> +
> + if (aux_supported) {
> + assert(fast_clear_supported);
> + intel_miptree_depth_hiz_resolve(brw, mt, start_level, num_levels,
> + start_layer, num_layers,
> + BLORP_HIZ_OP_HIZ_RESOLVE);
> + } else {
> + assert(!fast_clear_supported);
> + intel_miptree_depth_hiz_resolve(brw, mt, start_level, num_levels,
> + start_layer, num_layers,
> + BLORP_HIZ_OP_DEPTH_RESOLVE);
> + }
> + }
> +}
> +
> +void
> +intel_miptree_finish_write(struct brw_context *brw,
> + struct intel_mipmap_tree *mt, uint32_t level,
> + uint32_t start_layer, uint32_t num_layers,
> + bool written_with_aux)
> +{
> + assert(start_layer < mt->level[level].depth);
> + if (num_layers == INTEL_REMAINING_LAYERS)
> + num_layers = mt->level[level].depth - start_layer;
> + assert(num_layers <= mt->level[level].depth - start_layer);
> +
> + if (_mesa_is_format_color_format(mt->format)) {
> + if (mt->num_samples > 1) {
> + /* Nothing to do for MSAA */
> + } else {
> + if (written_with_aux) {
> + intel_miptree_used_for_rendering(brw, mt, level,
> + start_layer, num_layers);
> + }
> + }
> + } else if (mt->format == MESA_FORMAT_S_UINT8) {
> + /* Nothing to do for stencil */
> + } else {
> + if (written_with_aux) {
> + for (unsigned a = 0; a < num_layers; a++) {
> + intel_miptree_check_level_layer(mt, level, start_layer);
> + intel_miptree_slice_set_needs_depth_resolve(mt, level,
> + start_layer + a);
> + }
> + } else {
> + for (unsigned a = 0; a < num_layers; a++) {
> + intel_miptree_check_level_layer(mt, level, start_layer);
> + intel_miptree_slice_set_needs_hiz_resolve(mt, level,
> + start_layer + a);
> + }
> + }
> + }
> +}
> +
> +enum isl_aux_state
> +intel_miptree_get_aux_state(const struct intel_mipmap_tree *mt,
> + uint32_t level, uint32_t layer)
> +{
> + if (_mesa_is_format_color_format(mt->format)) {
> + assert(mt->mcs_buf != NULL);
> + if (mt->num_samples > 1) {
> + return ISL_AUX_STATE_COMPRESSED_CLEAR;
> + } else {
> + switch (intel_miptree_get_fast_clear_state(mt, level, layer)) {
> + case INTEL_FAST_CLEAR_STATE_RESOLVED:
> + return ISL_AUX_STATE_RESOLVED;
> + case INTEL_FAST_CLEAR_STATE_UNRESOLVED:
> + return ISL_AUX_STATE_COMPRESSED_CLEAR;
> + case INTEL_FAST_CLEAR_STATE_CLEAR:
> + return ISL_AUX_STATE_CLEAR;
> + default:
> + unreachable("Invalid fast clear state");
> + }
> + }
> + } else if (mt->format == MESA_FORMAT_S_UINT8) {
> + unreachable("Cannot get aux state for stencil");
> + } else {
> + assert(mt->hiz_buf != NULL);
> + const struct intel_resolve_map *map =
> + intel_resolve_map_const_get(&mt->hiz_map, level, layer);
> + if (!map)
> + return ISL_AUX_STATE_RESOLVED;
> + switch (map->need) {
> + case BLORP_HIZ_OP_DEPTH_RESOLVE:
> + return ISL_AUX_STATE_COMPRESSED_CLEAR;
> + case BLORP_HIZ_OP_HIZ_RESOLVE:
> + return ISL_AUX_STATE_AUX_INVALID;
> + default:
> + unreachable("Invalid hiz op");
> + }
> + }
> +}
> +
> +void
> +intel_miptree_set_aux_state(struct brw_context *brw,
> + struct intel_mipmap_tree *mt, uint32_t level,
> + uint32_t start_layer, uint32_t num_layers,
> + enum isl_aux_state aux_state)
> +{
> + assert(start_layer < mt->level[level].depth);
> + if (num_layers == INTEL_REMAINING_LAYERS)
> + num_layers = mt->level[level].depth - start_layer;
> + assert(num_layers <= mt->level[level].depth - start_layer);
> +
> + /* Right now, this only applies to clears. */
> + assert(aux_state == ISL_AUX_STATE_CLEAR);
> +
> + if (_mesa_is_format_color_format(mt->format)) {
> + if (mt->num_samples > 1)
> + assert(mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS);
> +
> + assert(level == 0 && start_layer == 0 && num_layers == 1);
> + intel_miptree_set_fast_clear_state(brw, mt, 0, 0, 1,
> + INTEL_FAST_CLEAR_STATE_CLEAR);
> + } else if (mt->format == MESA_FORMAT_S_UINT8) {
> + assert(!"Cannot set aux state for stencil");
> + } else {
> + for (unsigned a = 0; a < num_layers; a++) {
> + intel_miptree_check_level_layer(mt, level, start_layer);
> + intel_miptree_slice_set_needs_depth_resolve(mt, level,
> + start_layer + a);
> + }
> + }
> +}
> +
> /**
> * Make it possible to share the BO backing the given miptree with another
> * process or another miptree.
> diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
> index ffcedef..e74fca6 100644
> --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
> +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
> @@ -912,6 +912,86 @@ intel_miptree_all_slices_resolve_color(struct brw_context *brw,
> struct intel_mipmap_tree *mt,
> int flags);
>
> +#define INTEL_REMAINING_LAYERS UINT32_MAX
> +#define INTEL_REMAINING_LEVELS UINT32_MAX
> +
> +/** Prepare a miptree for access
> + *
> + * This function should be called prior to any access to miptree in order to
> + * perform any needed resolves.
> + *
> + * \param[in] start_level The first mip level to be accessed
> + *
> + * \param[in] num_levels The number of miplevels to be accessed or
> + * INTEL_REMAINING_LEVELS to indicate every level
> + * above start_level will be accessed
> + *
> + * \param[in] start_layer The first array slice or 3D layer to be accessed
> + *
> + * \param[in] num_layers The number of array slices or 3D layers be
> + * accessed or INTEL_REMAINING_LAYERS to indicate
> + * every layer above start_layer will be accessed
> + *
> + * \param[in] aux_supported Whether or not the access will support the
> + * miptree's auxiliary compression format; this
> + * must be false for uncompressed miptrees
> + *
> + * \param[in] fast_clear_supported Whether or not the access will support
> + * fast clears in the miptree's auxiliary
> + * compression format
> + */
> +void
> +intel_miptree_prepare_access(struct brw_context *brw,
> + struct intel_mipmap_tree *mt,
> + uint32_t start_level, uint32_t num_levels,
> + uint32_t start_layer, uint32_t num_layers,
> + bool aux_supported, bool fast_clear_supported);
> +
> +/** Complete a write operation
> + *
> + * This function should be called after any operation writes to a miptree.
> + * This will update the miptree's compression state so that future resolves
> + * happen correctly. Technically, this function can be called before the
> + * write occurs but the caller must ensure that they don't interlace
> + * intel_miptree_prepare_access and intel_miptree_finish_write calls to
> + * overlapping layer/level ranges.
> + *
> + * \param[in] level The mip level that was written
> + *
> + * \param[in] start_layer The first array slice or 3D layer written
> + *
> + * \param[in] num_layers The number of array slices or 3D layers
> + * written or INTEL_REMAINING_LAYERS to indicate
> + * every layer above start_layer was written
> + *
> + * \param[in] written_with_aux Whether or not the write was done with
> + * auxiliary compression enabled
> + */
> +void
> +intel_miptree_finish_write(struct brw_context *brw,
> + struct intel_mipmap_tree *mt, uint32_t level,
> + uint32_t start_layer, uint32_t num_layers,
> + bool written_with_aux);
I think we discussed this before and I forgot the answer. How does this
finish_write function enable future resolves to happen correctly? I'm
trying to understand why prepare_access doesn't do this.
More information about the mesa-dev
mailing list