[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