[Mesa-dev] [PATCH 28/30] i965: Use the new tracking mechanism for HiZ
Jason Ekstrand
jason at jlekstrand.net
Wed May 31 01:00:45 UTC 2017
On Fri, May 26, 2017 at 4:30 PM, Jason Ekstrand <jason at jlekstrand.net>
wrote:
> This is similar to the previous commit only for HiZ. For HiZ, apart
> from everything looking different, there is really only one functional
> change: We now track the ISL_AUX_STATE_COMPRESSED_NO_CLEAR state.
> Previously, if you rendered to a resolved slice of the miptree and then
> did a fast-clear with a different clear color, that slice would get
> resolved even though it hadn't been fast-cleared. Now that we can track
> COMPRESSED_NO_CLEAR, we know that it doesn't have any blocks in the
> "clear" state so we can skip the resolve.
> ---
> src/mesa/drivers/dri/i965/brw_clear.c | 3 +-
> src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 222
> ++++++++++++++------------
> src/mesa/drivers/dri/i965/intel_mipmap_tree.h | 24 ---
> 3 files changed, 124 insertions(+), 125 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_clear.c
> b/src/mesa/drivers/dri/i965/brw_clear.c
> index aa2e994..be72d67 100644
> --- a/src/mesa/drivers/dri/i965/brw_clear.c
> +++ b/src/mesa/drivers/dri/i965/brw_clear.c
> @@ -162,7 +162,8 @@ brw_fast_clear_depth(struct gl_context *ctx)
> * flags out of the HiZ buffer into the real depth buffer.
> */
> if (mt->fast_clear_color.f32[0] != ctx->Depth.Clear) {
> - intel_miptree_all_slices_resolve_depth(brw, mt);
> + intel_miptree_prepare_access(brw, mt, 0, INTEL_REMAINING_LEVELS,
> + 0, INTEL_REMAINING_LAYERS, true,
> false);
> mt->fast_clear_color.f32[0] = ctx->Depth.Clear;
> }
>
> diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
> b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
> index 3e30b2a..a1a8177 100644
> --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
> +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
> @@ -325,7 +325,6 @@ intel_miptree_create_layout(struct brw_context *brw,
> INTEL_AUX_DISABLE_ALL : INTEL_AUX_DISABLE_NONE;
> mt->aux_disable |= INTEL_AUX_DISABLE_CCS;
> mt->is_scanout = (layout_flags & MIPTREE_LAYOUT_FOR_SCANOUT) != 0;
> - exec_list_make_empty(&mt->hiz_map);
> mt->aux_state = NULL;
> mt->cpp = _mesa_get_format_bytes(format);
> mt->num_samples = num_samples;
> @@ -974,7 +973,6 @@ intel_miptree_release(struct intel_mipmap_tree **mt)
> brw_bo_unreference((*mt)->mcs_buf->bo);
> free((*mt)->mcs_buf);
> }
> - intel_resolve_map_clear(&(*mt)->hiz_map);
> free_aux_state_map((*mt)->aux_state);
>
> intel_miptree_release(&(*mt)->plane[0]);
> @@ -1909,6 +1907,11 @@ intel_miptree_alloc_hiz(struct brw_context *brw,
> assert(mt->hiz_buf == NULL);
> assert((mt->aux_disable & INTEL_AUX_DISABLE_HIZ) == 0);
>
> + enum isl_aux_state **aux_state =
> + create_aux_state_map(mt, ISL_AUX_STATE_AUX_INVALID);
> + if (!aux_state)
> + return false;
> +
> if (brw->gen == 7) {
> mt->hiz_buf = intel_gen7_hiz_buf_create(brw, mt);
> } else if (brw->gen >= 8) {
> @@ -1917,24 +1920,15 @@ intel_miptree_alloc_hiz(struct brw_context *brw,
> mt->hiz_buf = intel_hiz_miptree_buf_create(brw, mt);
> }
>
> - if (!mt->hiz_buf)
> + if (!mt->hiz_buf) {
> + free(aux_state);
> return false;
> + }
>
> - /* Mark that all slices need a HiZ resolve. */
> - for (unsigned level = mt->first_level; level <= mt->last_level;
> ++level) {
> - if (!intel_miptree_level_enable_hiz(brw, mt, level))
> - continue;
> -
> - for (unsigned layer = 0; layer < mt->level[level].depth; ++layer) {
> - struct intel_resolve_map *m = malloc(sizeof(struct
> intel_resolve_map));
> - exec_node_init(&m->link);
> - m->level = level;
> - m->layer = layer;
> - m->need = BLORP_HIZ_OP_HIZ_RESOLVE;
> + for (unsigned level = mt->first_level; level <= mt->last_level;
> ++level)
> + intel_miptree_level_enable_hiz(brw, mt, level);
>
> - exec_list_push_tail(&mt->hiz_map, &m->link);
> - }
> - }
> + mt->aux_state = aux_state;
>
> return true;
> }
> @@ -1993,41 +1987,6 @@ intel_miptree_level_has_hiz(struct
> intel_mipmap_tree *mt, uint32_t level)
> return mt->level[level].has_hiz;
> }
>
> -static bool
> -intel_miptree_depth_hiz_resolve(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,
> - enum blorp_hiz_op need)
> -{
> - bool did_resolve = false;
> -
> - foreach_list_typed_safe(struct intel_resolve_map, map, link,
> &mt->hiz_map) {
> - if (map->level < start_level ||
> - map->level >= (start_level + num_levels) ||
> - map->layer < start_layer ||
> - map->layer >= (start_layer + num_layers))
> - continue;
> -
> - if (map->need != need)
> - continue;
> -
> - intel_hiz_exec(brw, mt, map->level, map->layer, need);
> - intel_resolve_map_remove(map);
> - did_resolve = true;
> - }
> -
> - return did_resolve;
> -}
> -
> -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,
> - BLORP_HIZ_OP_DEPTH_RESOLVE);
> -}
> -
> bool
> intel_miptree_has_color_unresolved(const struct intel_mipmap_tree *mt,
> unsigned start_level, unsigned
> num_levels,
> @@ -2267,6 +2226,96 @@ intel_miptree_finish_mcs_write(struct brw_context
> *brw,
> }
> }
>
> +static void
> +intel_miptree_prepare_hiz_access(struct brw_context *brw,
> + struct intel_mipmap_tree *mt,
> + uint32_t level, uint32_t layer,
> + bool hiz_supported, bool
> fast_clear_supported)
> +{
> + enum blorp_hiz_op hiz_op = BLORP_HIZ_OP_NONE;
> + switch (intel_miptree_get_aux_state(mt, level, layer)) {
> + case ISL_AUX_STATE_CLEAR:
> + case ISL_AUX_STATE_COMPRESSED_CLEAR:
> + if (!hiz_supported || !fast_clear_supported)
> + hiz_op = BLORP_HIZ_OP_DEPTH_RESOLVE;
> + break;
> +
> + case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:
> + if (!hiz_supported)
> + hiz_op = BLORP_HIZ_OP_DEPTH_RESOLVE;
> + break;
> +
> + case ISL_AUX_STATE_PASS_THROUGH:
> + case ISL_AUX_STATE_RESOLVED:
> + break;
> +
> + case ISL_AUX_STATE_AUX_INVALID:
> + if (hiz_supported)
> + hiz_op = BLORP_HIZ_OP_HIZ_RESOLVE;
> + break;
> + }
> +
> + if (hiz_op != BLORP_HIZ_OP_NONE) {
> + intel_hiz_exec(brw, mt, level, layer, hiz_op);
> +
> + switch (hiz_op) {
> + case BLORP_HIZ_OP_DEPTH_RESOLVE:
> + intel_miptree_set_aux_state(brw, mt, level, layer, 1,
> + ISL_AUX_STATE_RESOLVED);
> + break;
> +
> + case BLORP_HIZ_OP_HIZ_RESOLVE:
> + /* The HiZ resolve operation is actually an ambiguate */
> + intel_miptree_set_aux_state(brw, mt, level, layer, 1,
> + ISL_AUX_STATE_RESOLVED);
>
This should be ISL_AUX_STATE_PASS_THROUGH. I've fixed it locally.
> + break;
> +
> + default:
> + unreachable("Invalid HiZ op");
> + }
> + }
> +}
> +
> +static void
> +intel_miptree_finish_hiz_write(struct brw_context *brw,
> + struct intel_mipmap_tree *mt,
> + uint32_t level, uint32_t layer,
> + bool written_with_hiz)
> +{
> + switch (intel_miptree_get_aux_state(mt, level, layer)) {
> + case ISL_AUX_STATE_CLEAR:
> + assert(written_with_hiz);
> + intel_miptree_set_aux_state(brw, mt, level, layer, 1,
> + ISL_AUX_STATE_COMPRESSED_CLEAR);
> + break;
> +
> + case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:
> + case ISL_AUX_STATE_COMPRESSED_CLEAR:
> + assert(written_with_hiz);
> + break; /* Nothing to do */
> +
> + case ISL_AUX_STATE_RESOLVED:
> + if (written_with_hiz) {
> + intel_miptree_set_aux_state(brw, mt, level, layer, 1,
> + ISL_AUX_STATE_COMPRESSED_NO_CLEAR);
> + } else {
> + intel_miptree_set_aux_state(brw, mt, level, layer, 1,
> + ISL_AUX_STATE_AUX_INVALID);
> + }
> +
> + case ISL_AUX_STATE_PASS_THROUGH:
> + if (written_with_hiz) {
> + intel_miptree_set_aux_state(brw, mt, level, layer, 1,
> + ISL_AUX_STATE_COMPRESSED_NO_CLEAR);
> + }
> + break;
> +
> + case ISL_AUX_STATE_AUX_INVALID:
> + assert(!written_with_hiz);
> + break;
> + }
> +}
> +
> void
> intel_miptree_prepare_access(struct brw_context *brw,
> struct intel_mipmap_tree *mt,
> @@ -2305,16 +2354,17 @@ intel_miptree_prepare_access(struct brw_context
> *brw,
> 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);
> + for (uint32_t level = start_level; level <= last_level; level++) {
> + if (!intel_miptree_level_has_hiz(mt, level))
> + continue;
> +
> + const uint32_t level_layers =
> + MIN2(num_layers, mt->level[level].depth);
> + for (uint32_t a = 0; a < level_layers; a++) {
> + intel_miptree_prepare_hiz_access(brw, mt, level, start_layer
> + a,
> + aux_supported,
> + fast_clear_supported);
> + }
> }
> }
> }
> @@ -2351,18 +2401,9 @@ intel_miptree_finish_write(struct brw_context *brw,
> if (!intel_miptree_level_has_hiz(mt, level))
> return;
>
> - if (written_with_aux) {
> - for (unsigned a = 0; a < num_layers; a++) {
> - intel_miptree_check_level_layer(mt, level, start_layer);
> - intel_resolve_map_set(&mt->hiz_map, level, start_layer + a,
> - BLORP_HIZ_OP_DEPTH_RESOLVE);
> - }
> - } else {
> - for (unsigned a = 0; a < num_layers; a++) {
> - intel_miptree_check_level_layer(mt, level, start_layer);
> - intel_resolve_map_set(&mt->hiz_map, level, start_layer + a,
> - BLORP_HIZ_OP_HIZ_RESOLVE);
> - }
> + for (uint32_t a = 0; a < num_layers; a++) {
> + intel_miptree_finish_hiz_write(brw, mt, level, start_layer + a,
> + written_with_aux);
> }
> }
> }
> @@ -2376,24 +2417,13 @@ intel_miptree_get_aux_state(const struct
> intel_mipmap_tree *mt,
> if (_mesa_is_format_color_format(mt->format)) {
> assert(mt->mcs_buf != NULL);
> assert(mt->num_samples <= 1 || mt->msaa_layout ==
> INTEL_MSAA_LAYOUT_CMS);
> - return mt->aux_state[level][layer];
> } 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");
> - }
> }
> +
> + return mt->aux_state[level][layer];
> }
>
> void
> @@ -2410,23 +2440,14 @@ intel_miptree_set_aux_state(struct brw_context
> *brw,
> if (_mesa_is_format_color_format(mt->format)) {
> assert(mt->mcs_buf != NULL);
> assert(mt->num_samples <= 1 || mt->msaa_layout ==
> INTEL_MSAA_LAYOUT_CMS);
> -
> - for (unsigned a = 0; a < num_layers; a++)
> - mt->aux_state[level][start_layer + a] = aux_state;
> } else if (mt->format == MESA_FORMAT_S_UINT8) {
> unreachable("Cannot get aux state for stencil");
> } else {
> assert(mt->hiz_buf != NULL);
> -
> - /* Right now, this only applies to clears. */
> - assert(aux_state == ISL_AUX_STATE_CLEAR);
> -
> - for (unsigned a = 0; a < num_layers; a++) {
> - intel_miptree_check_level_layer(mt, level, start_layer);
> - intel_resolve_map_set(&mt->hiz_map, level, start_layer + a,
> - BLORP_HIZ_OP_DEPTH_RESOLVE);
> - }
> }
> +
> + for (unsigned a = 0; a < num_layers; a++)
> + mt->aux_state[level][start_layer + a] = aux_state;
> }
>
> /* On Gen9 color buffers may be compressed by the hardware (lossless
> @@ -2647,7 +2668,8 @@ intel_miptree_make_shareable(struct brw_context
> *brw,
> * any will likely crash due to the missing aux buffer. So let's
> delete
> * all pending ops.
> */
> - exec_list_make_empty(&mt->hiz_map);
> + free(mt->aux_state);
> + mt->aux_state = NULL;
> }
> }
>
> diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
> b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
> index 528c32c..428c097 100644
> --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
> +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
> @@ -542,23 +542,6 @@ struct intel_mipmap_tree
> struct intel_miptree_hiz_buffer *hiz_buf;
>
> /**
> - * \brief Maps of miptree slices to needed resolves.
> - *
> - * hiz_map is used only when the miptree has a child HiZ miptree.
> - *
> - * Let \c mt be a depth miptree with HiZ enabled. Then the resolve map
> is
> - * \c mt->hiz_map. The resolve map of the child HiZ miptree, \c
> - * mt->hiz_mt->hiz_map, is unused.
> - *
> - *
> - * color_resolve_map is used only when the miptree uses fast clear
> (Gen7+)
> - * lossless compression (Gen9+). It should be noted that absence in the
> - * map means implicitly RESOLVED state. If item is found it always
> - * indicates state other than RESOLVED.
> - */
> - struct exec_list hiz_map; /* List of intel_resolve_map. */
> -
> - /**
> * \brief Maps miptree slices to their current aux state
> *
> * This two-dimensional array is indexed as [level][layer] and stores
> an
> @@ -825,13 +808,6 @@ intel_miptree_alloc_hiz(struct brw_context *brw,
> bool
> intel_miptree_level_has_hiz(struct intel_mipmap_tree *mt, uint32_t
> level);
>
> -/**
> - * \return false if no resolve was needed
> - */
> -bool
> -intel_miptree_all_slices_resolve_depth(struct brw_context *brw,
> - struct intel_mipmap_tree *mt);
> -
> /**\}*/
>
> bool
> --
> 2.5.0.400.gff86faf
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20170530/75c6d6d9/attachment-0001.html>
More information about the mesa-dev
mailing list