[Mesa-dev] [v2 11/17] i965: Track fast color clear state in level/layer granularity

Jason Ekstrand jason at jlekstrand.net
Wed Nov 23 21:05:31 UTC 2016


On Wed, Nov 23, 2016 at 1:16 AM, Topi Pohjolainen <
topi.pohjolainen at gmail.com> wrote:

> v2: Added intel_resolve_map_clear() into intel_miptree_release()
>
> Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
> Reviewed-by: Jason Ekstrand <jason at jlekstrand.net> (v1)
> ---
>  src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 64
> +++++++++++++++++++--------
>  src/mesa/drivers/dri/i965/intel_mipmap_tree.h | 14 +++---
>  2 files changed, 53 insertions(+), 25 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
> b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
> index 3895b2e..a4a7ee0 100644
> --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
> +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
> @@ -397,11 +397,11 @@ intel_miptree_create_layout(struct brw_context *brw,
>     mt->logical_width0 = width0;
>     mt->logical_height0 = height0;
>     mt->logical_depth0 = depth0;
> -   mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_RESOLVED;
>     mt->disable_aux_buffers = (layout_flags & MIPTREE_LAYOUT_DISABLE_AUX)
> != 0;
>     mt->no_ccs = true;
>     mt->is_scanout = (layout_flags & MIPTREE_LAYOUT_FOR_SCANOUT) != 0;
>     exec_list_make_empty(&mt->hiz_map);
> +   exec_list_make_empty(&mt->color_resolve_map);
>     mt->cpp = _mesa_get_format_bytes(format);
>     mt->num_samples = num_samples;
>     mt->compressed = _mesa_is_format_compressed(format);
> @@ -933,7 +933,7 @@ intel_update_winsys_renderbuffer_miptree(struct
> brw_context *intel,
>      */
>     if (intel_tiling_supports_non_msrt_mcs(intel,
> singlesample_mt->tiling) &&
>         intel_miptree_supports_non_msrt_fast_clear(intel,
> singlesample_mt)) {
> -      singlesample_mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_
> RESOLVED;
> +      singlesample_mt->no_ccs = false;
>     }
>
>     if (num_samples == 0) {
> @@ -1048,6 +1048,7 @@ intel_miptree_release(struct intel_mipmap_tree **mt)
>           free((*mt)->mcs_buf);
>        }
>        intel_resolve_map_clear(&(*mt)->hiz_map);
> +      intel_resolve_map_clear(&(*mt)->color_resolve_map);
>
>        intel_miptree_release(&(*mt)->plane[0]);
>        intel_miptree_release(&(*mt)->plane[1]);
> @@ -1633,7 +1634,12 @@ intel_miptree_alloc_mcs(struct brw_context *brw,
>        return false;
>
>     intel_miptree_init_mcs(brw, mt, 0xFF);
> -   mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_CLEAR;
> +
> +   /* Multisampled miptrees are only supported for single level. */
> +   assert(mt->first_level == 0);
> +   intel_miptree_set_fast_clear_state(mt, mt->first_level, 0,
> +                                      mt->logical_depth0,
> +                                      INTEL_FAST_CLEAR_STATE_CLEAR);
>
>     return true;
>  }
> @@ -1713,7 +1719,6 @@ intel_miptree_alloc_non_msrt_mcs(struct brw_context
> *brw,
>         *    Software needs to initialize MCS with zeros."
>         */
>        intel_miptree_init_mcs(brw, mt, 0);
> -      mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_RESOLVED;
>        mt->msaa_layout = INTEL_MSAA_LAYOUT_CMS;
>     }
>
> @@ -2209,7 +2214,15 @@ enum intel_fast_clear_state
>  intel_miptree_get_fast_clear_state(const struct intel_mipmap_tree *mt,
>                                     unsigned level, unsigned layer)
>  {
> -   return mt->fast_clear_state;
> +   intel_miptree_check_level_layer(mt, level, layer);
> +
> +   const struct intel_resolve_map *item =
> +      intel_resolve_map_const_get(&mt->color_resolve_map, level, layer);
> +
> +   if (!item)
> +      return INTEL_FAST_CLEAR_STATE_RESOLVED;
> +
> +   return item->fast_clear_state;
>  }
>
>  static void
> @@ -2244,7 +2257,9 @@ intel_miptree_set_fast_clear_state(struct
> intel_mipmap_tree *mt,
>
>     assert(first_layer + num_layers <= mt->physical_depth0);
>
> -   mt->fast_clear_state = new_state;
> +   while (num_layers--)
>

nitpick:  I think I'd rather a simple "for (unsigned i = 0; i < num_layers;
i++)"  It's a bit more obvious


> +      intel_resolve_map_set(&mt->color_resolve_map, level,
> +                            first_layer++, new_state);
>

We probably want to assert here that state != RESOLVED (see below).  If
that's not valid, we would have to switch on whether or not it's RESOLVED
and if it is RESOLVED, walk the list and delete things.


>  }
>
>  bool
> @@ -2252,7 +2267,9 @@ intel_miptree_has_color_unresolved(const struct
> intel_mipmap_tree *mt,
>                                     unsigned start_level, unsigned
> num_levels,
>                                     unsigned start_layer, unsigned
> num_layers)
>  {
> -   return mt->fast_clear_state != INTEL_FAST_CLEAR_STATE_RESOLVED;
> +   return intel_resolve_map_find_any(&mt->color_resolve_map,
> +                                     start_level, num_levels,
> +                                     start_layer, num_layers) != NULL;
>

This assumes that there are no items in the resolve map with a state of
RESOLVED.  That's a fine assumption, but we need to make sure that it's
valid.  I've made a bunch of comments all of this patch about that.


>  }
>
>  void
> @@ -2316,17 +2333,18 @@ intel_miptree_resolve_color(struct brw_context
> *brw,
>     if (!intel_miptree_needs_color_resolve(brw, mt, flags))
>        return false;
>
> -   switch (mt->fast_clear_state) {
> -   case INTEL_FAST_CLEAR_STATE_RESOLVED:
> -      /* No resolve needed */
> +   intel_miptree_check_level_layer(mt, level, layer);
> +
> +   struct intel_resolve_map *item =
> +      intel_resolve_map_get(&mt->color_resolve_map, level, layer);
> +
> +   if (!item || item->fast_clear_state == INTEL_FAST_CLEAR_STATE_
> RESOLVED)
>

This seems to imply that it's not.  Maybe just do

if (!item)
   return false;
assert(item->fast_clear_state != INTEL_FAST_CLEAR_STATE_RESOLVED)


>        return false;
> -   case INTEL_FAST_CLEAR_STATE_UNRESOLVED:
> -   case INTEL_FAST_CLEAR_STATE_CLEAR:
> -      brw_blorp_resolve_color(brw, mt, level, layer);
> -      return true;
> -   default:
> -      unreachable("Invalid fast clear state");
> -   }
> +
> +   brw_blorp_resolve_color(brw, mt, level, layer);
> +   intel_resolve_map_remove(item);
> +
> +   return true;
>  }
>
>  void
> @@ -2334,7 +2352,17 @@ intel_miptree_all_slices_resolve_color(struct
> brw_context *brw,
>                                         struct intel_mipmap_tree *mt,
>                                         int flags)
>  {
> -   intel_miptree_resolve_color(brw, mt, 0, 0, flags);
> +   if (!intel_miptree_needs_color_resolve(brw, mt, flags))
> +      return;
> +
> +   foreach_list_typed_safe(struct intel_resolve_map, map, link,
> +                           &mt->color_resolve_map) {
> +      if (map->fast_clear_state == INTEL_FAST_CLEAR_STATE_RESOLVED)
>

Again, this should be an assert.


> +        continue;
> +
> +      brw_blorp_resolve_color(brw, mt, map->level, map->layer);
> +      intel_resolve_map_remove(map);
> +   }
>  }
>
>  /**
> diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
> b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
> index 1f4ae6c..51ab664 100644
> --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
> +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
> @@ -554,15 +554,20 @@ struct intel_mipmap_tree
>     struct intel_miptree_hiz_buffer *hiz_buf;
>
>     /**
> -    * \brief Map of miptree slices to needed resolves.
> +    * \brief Maps of miptree slices to needed resolves.
>      *
> -    * This is used only when the miptree has a child HiZ miptree.
> +    * 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+).
>      */
>     struct exec_list hiz_map; /* List of intel_resolve_map. */
> +   struct exec_list color_resolve_map; /* List of intel_resolve_map. */
>
>     /**
>      * \brief Stencil miptree for depthstencil textures.
> @@ -606,11 +611,6 @@ struct intel_mipmap_tree
>     struct intel_mipmap_tree *plane[2];
>
>     /**
> -    * Fast clear state for this buffer.
> -    */
> -   enum intel_fast_clear_state fast_clear_state;
> -
> -   /**
>      * The SURFACE_STATE bits associated with the last fast color clear to
> this
>      * color mipmap tree, if any.
>      *
> --
> 2.5.5
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20161123/6f72a5db/attachment.html>


More information about the mesa-dev mailing list