<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Nov 23, 2016 at 1:16 AM, Topi Pohjolainen <span dir="ltr"><<a href="mailto:topi.pohjolainen@gmail.com" target="_blank">topi.pohjolainen@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">v2: Added intel_resolve_map_clear() into intel_miptree_release()<br>
<br>
Signed-off-by: Topi Pohjolainen <<a href="mailto:topi.pohjolainen@intel.com">topi.pohjolainen@intel.com</a>><br>
Reviewed-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>> (v1)<br>
---<br>
 src/mesa/drivers/dri/i965/<wbr>intel_mipmap_tree.c | 64 +++++++++++++++++++--------<br>
 src/mesa/drivers/dri/i965/<wbr>intel_mipmap_tree.h | 14 +++---<br>
 2 files changed, 53 insertions(+), 25 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/<wbr>intel_mipmap_tree.c<br>
index 3895b2e..a4a7ee0 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>intel_mipmap_tree.c<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>intel_mipmap_tree.c<br>
@@ -397,11 +397,11 @@ intel_miptree_create_layout(<wbr>struct brw_context *brw,<br>
    mt->logical_width0 = width0;<br>
    mt->logical_height0 = height0;<br>
    mt->logical_depth0 = depth0;<br>
-   mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_<wbr>RESOLVED;<br>
    mt->disable_aux_buffers = (layout_flags & MIPTREE_LAYOUT_DISABLE_AUX) != 0;<br>
    mt->no_ccs = true;<br>
    mt->is_scanout = (layout_flags & MIPTREE_LAYOUT_FOR_SCANOUT) != 0;<br>
    exec_list_make_empty(&mt->hiz_<wbr>map);<br>
+   exec_list_make_empty(&mt-><wbr>color_resolve_map);<br>
    mt->cpp = _mesa_get_format_bytes(format)<wbr>;<br>
    mt->num_samples = num_samples;<br>
    mt->compressed = _mesa_is_format_compressed(<wbr>format);<br>
@@ -933,7 +933,7 @@ intel_update_winsys_<wbr>renderbuffer_miptree(struct brw_context *intel,<br>
     */<br>
    if (intel_tiling_supports_non_<wbr>msrt_mcs(intel, singlesample_mt->tiling) &&<br>
        intel_miptree_supports_non_<wbr>msrt_fast_clear(intel, singlesample_mt)) {<br>
-      singlesample_mt->fast_clear_<wbr>state = INTEL_FAST_CLEAR_STATE_<wbr>RESOLVED;<br>
+      singlesample_mt->no_ccs = false;<br>
    }<br>
<br>
    if (num_samples == 0) {<br>
@@ -1048,6 +1048,7 @@ intel_miptree_release(struct intel_mipmap_tree **mt)<br>
          free((*mt)->mcs_buf);<br>
       }<br>
       intel_resolve_map_clear(&(*mt)<wbr>->hiz_map);<br>
+      intel_resolve_map_clear(&(*mt)<wbr>->color_resolve_map);<br>
<br>
       intel_miptree_release(&(*mt)-><wbr>plane[0]);<br>
       intel_miptree_release(&(*mt)-><wbr>plane[1]);<br>
@@ -1633,7 +1634,12 @@ intel_miptree_alloc_mcs(struct brw_context *brw,<br>
       return false;<br>
<br>
    intel_miptree_init_mcs(brw, mt, 0xFF);<br>
-   mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_CLEAR;<br>
+<br>
+   /* Multisampled miptrees are only supported for single level. */<br>
+   assert(mt->first_level == 0);<br>
+   intel_miptree_set_fast_clear_<wbr>state(mt, mt->first_level, 0,<br>
+                                      mt->logical_depth0,<br>
+                                      INTEL_FAST_CLEAR_STATE_CLEAR);<br>
<br>
    return true;<br>
 }<br>
@@ -1713,7 +1719,6 @@ intel_miptree_alloc_non_msrt_<wbr>mcs(struct brw_context *brw,<br>
        *    Software needs to initialize MCS with zeros."<br>
        */<br>
       intel_miptree_init_mcs(brw, mt, 0);<br>
-      mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_<wbr>RESOLVED;<br>
       mt->msaa_layout = INTEL_MSAA_LAYOUT_CMS;<br>
    }<br>
<br>
@@ -2209,7 +2214,15 @@ enum intel_fast_clear_state<br>
 intel_miptree_get_fast_clear_<wbr>state(const struct intel_mipmap_tree *mt,<br>
                                    unsigned level, unsigned layer)<br>
 {<br>
-   return mt->fast_clear_state;<br>
+   intel_miptree_check_level_<wbr>layer(mt, level, layer);<br>
+<br>
+   const struct intel_resolve_map *item =<br>
+      intel_resolve_map_const_get(&<wbr>mt->color_resolve_map, level, layer);<br>
+<br>
+   if (!item)<br>
+      return INTEL_FAST_CLEAR_STATE_<wbr>RESOLVED;<br>
+<br>
+   return item->fast_clear_state;<br>
 }<br>
<br>
 static void<br>
@@ -2244,7 +2257,9 @@ intel_miptree_set_fast_clear_<wbr>state(struct intel_mipmap_tree *mt,<br>
<br>
    assert(first_layer + num_layers <= mt->physical_depth0);<br>
<br>
-   mt->fast_clear_state = new_state;<br>
+   while (num_layers--)<br></blockquote><div><br></div><div>nitpick:  I think I'd rather a simple "for (unsigned i = 0; i < num_layers; i++)"  It's a bit more obvious<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      intel_resolve_map_set(&mt-><wbr>color_resolve_map, level,<br>
+                            first_layer++, new_state);<br></blockquote><div><br></div><div>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.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 }<br>
<br>
 bool<br>
@@ -2252,7 +2267,9 @@ intel_miptree_has_color_<wbr>unresolved(const struct intel_mipmap_tree *mt,<br>
                                    unsigned start_level, unsigned num_levels,<br>
                                    unsigned start_layer, unsigned num_layers)<br>
 {<br>
-   return mt->fast_clear_state != INTEL_FAST_CLEAR_STATE_<wbr>RESOLVED;<br>
+   return intel_resolve_map_find_any(&<wbr>mt->color_resolve_map,<br>
+                                     start_level, num_levels,<br>
+                                     start_layer, num_layers) != NULL;<br></blockquote><div><br></div><div>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.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 }<br>
<br>
 void<br>
@@ -2316,17 +2333,18 @@ intel_miptree_resolve_color(<wbr>struct brw_context *brw,<br>
    if (!intel_miptree_needs_color_<wbr>resolve(brw, mt, flags))<br>
       return false;<br>
<br>
-   switch (mt->fast_clear_state) {<br>
-   case INTEL_FAST_CLEAR_STATE_<wbr>RESOLVED:<br>
-      /* No resolve needed */<br>
+   intel_miptree_check_level_<wbr>layer(mt, level, layer);<br>
+<br>
+   struct intel_resolve_map *item =<br>
+      intel_resolve_map_get(&mt-><wbr>color_resolve_map, level, layer);<br>
+<br>
+   if (!item || item->fast_clear_state == INTEL_FAST_CLEAR_STATE_<wbr>RESOLVED)<br></blockquote><div><br></div><div>This seems to imply that it's not.  Maybe just do<br><br></div><div>if (!item)<br></div><div>   return false;<br></div><div>assert(item->fast_clear_state != INTEL_FAST_CLEAR_STATE_RESOLVED)<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
       return false;<br>
-   case INTEL_FAST_CLEAR_STATE_<wbr>UNRESOLVED:<br>
-   case INTEL_FAST_CLEAR_STATE_CLEAR:<br>
-      brw_blorp_resolve_color(brw, mt, level, layer);<br>
-      return true;<br>
-   default:<br>
-      unreachable("Invalid fast clear state");<br>
-   }<br>
+<br>
+   brw_blorp_resolve_color(brw, mt, level, layer);<br>
+   intel_resolve_map_remove(item)<wbr>;<br>
+<br>
+   return true;<br>
 }<br>
<br>
 void<br>
@@ -2334,7 +2352,17 @@ intel_miptree_all_slices_<wbr>resolve_color(struct brw_context *brw,<br>
                                        struct intel_mipmap_tree *mt,<br>
                                        int flags)<br>
 {<br>
-   intel_miptree_resolve_color(<wbr>brw, mt, 0, 0, flags);<br>
+   if (!intel_miptree_needs_color_<wbr>resolve(brw, mt, flags))<br>
+      return;<br>
+<br>
+   foreach_list_typed_safe(struct intel_resolve_map, map, link,<br>
+                           &mt->color_resolve_map) {<br>
+      if (map->fast_clear_state == INTEL_FAST_CLEAR_STATE_<wbr>RESOLVED)<br></blockquote><div><br></div><div>Again, this should be an assert.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+        continue;<br>
+<br>
+      brw_blorp_resolve_color(brw, mt, map->level, map->layer);<br>
+      intel_resolve_map_remove(map);<br>
+   }<br>
 }<br>
<br>
 /**<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/<wbr>intel_mipmap_tree.h<br>
index 1f4ae6c..51ab664 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>intel_mipmap_tree.h<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>intel_mipmap_tree.h<br>
@@ -554,15 +554,20 @@ struct intel_mipmap_tree<br>
    struct intel_miptree_hiz_buffer *hiz_buf;<br>
<br>
    /**<br>
-    * \brief Map of miptree slices to needed resolves.<br>
+    * \brief Maps of miptree slices to needed resolves.<br>
     *<br>
-    * This is used only when the miptree has a child HiZ miptree.<br>
+    * hiz_map is used only when the miptree has a child HiZ miptree.<br>
     *<br>
     * Let \c mt be a depth miptree with HiZ enabled. Then the resolve map is<br>
     * \c mt->hiz_map. The resolve map of the child HiZ miptree, \c<br>
     * mt->hiz_mt->hiz_map, is unused.<br>
+    *<br>
+    *<br>
+    * color_resolve_map is used only when the miptree uses fast clear (Gen7+)<br>
+    * lossless compression (Gen9+).<br>
     */<br>
    struct exec_list hiz_map; /* List of intel_resolve_map. */<br>
+   struct exec_list color_resolve_map; /* List of intel_resolve_map. */<br>
<br>
    /**<br>
     * \brief Stencil miptree for depthstencil textures.<br>
@@ -606,11 +611,6 @@ struct intel_mipmap_tree<br>
    struct intel_mipmap_tree *plane[2];<br>
<br>
    /**<br>
-    * Fast clear state for this buffer.<br>
-    */<br>
-   enum intel_fast_clear_state fast_clear_state;<br>
-<br>
-   /**<br>
     * The SURFACE_STATE bits associated with the last fast color clear to this<br>
     * color mipmap tree, if any.<br>
     *<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.5.5<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>