iris: Enable fast clears on other miplevels and layers than 0.
authorRafael Antognolli <rafael.antognolli@intel.com>
Tue, 25 Jun 2019 21:14:22 +0000 (14:14 -0700)
committerRafael Antognolli <rafael.antognolli@intel.com>
Wed, 17 Jul 2019 21:53:37 +0000 (14:53 -0700)
Until now we only supported fast clear colors on the first miplevel and
layer. The main reason for it is that we can't have different fast clear
values at different levels/layers, since the surface state only supports
one clear value.

We can, however, enable it if we make sure we only use the same value
for all levels/layers, and if one of them changes, we resolve all the
others. We already do that for depth fast clears so hopefully it will be
fine for color fast clears too.

v2: Add check for partial clear too (Ken).

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/gallium/drivers/iris/iris_clear.c

index 1724a35c54e400367f5757fe9f187f798c5d9b7b..8ed37b68eba00e81014c9be0ba91ae24cb1bb9f1 100644 (file)
@@ -78,14 +78,6 @@ can_fast_clear_color(struct iris_context *ice,
    if (res->aux.usage == ISL_AUX_USAGE_NONE)
       return false;
 
-   /* Surface state can only record one fast clear color value. Therefore
-    * unless different levels/layers agree on the color it can be used to
-    * represent only single level/layer. Here it will be reserved for the
-    * first slice (level 0, layer 0).
-    */
-   if (level > 0 || box->z > 0 || box->depth > 1)
-      return false;
-
    /* Check for partial clear */
    if (box->x > 0 || box->y > 0 ||
        box->width < p_res->width0 ||
@@ -227,6 +219,54 @@ fast_clear_color(struct iris_context *ice,
       iris_resolve_conditional_render(ice);
       if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
          return;
+
+      /* If we are clearing to a new clear value, we need to resolve fast
+       * clears from other levels/layers first, since we can't have different
+       * levels/layers with different fast clear colors.
+       */
+      for (unsigned res_lvl = 0; res_lvl < res->surf.levels; res_lvl++) {
+         const unsigned level_layers =
+            iris_get_num_logical_layers(res, res_lvl);
+         for (unsigned layer = 0; layer < level_layers; layer++) {
+            if (res_lvl == level &&
+                layer >= box->z &&
+                layer < box->z + box->depth) {
+               /* We're going to clear this layer anyway.  Leave it alone. */
+               continue;
+            }
+
+            enum isl_aux_state aux_state =
+               iris_resource_get_aux_state(res, res_lvl, layer);
+
+            if (aux_state != ISL_AUX_STATE_CLEAR &&
+                aux_state != ISL_AUX_STATE_PARTIAL_CLEAR &&
+                aux_state != ISL_AUX_STATE_COMPRESSED_CLEAR) {
+               /* This slice doesn't have any fast-cleared bits. */
+               continue;
+            }
+
+            /* If we got here, then the level may have fast-clear bits that use
+             * the old clear value.  We need to do a color resolve to get rid
+             * of their use of the clear color before we can change it.
+             * Fortunately, few applications ever change their clear color at
+             * different levels/layers, so this shouldn't happen often.
+             */
+            iris_resource_prepare_access(ice, batch, res,
+                                         res_lvl, 1, layer, 1,
+                                         res->aux.usage,
+                                         false);
+            perf_debug(&ice->dbg,
+                       "Resolving resource (%p) level %d, layer %d: color changing from "
+                       "(%0.2f, %0.2f, %0.2f, %0.2f) to "
+                       "(%0.2f, %0.2f, %0.2f, %0.2f)\n",
+                       res, res_lvl, layer,
+                       res->aux.clear_color.f32[0],
+                       res->aux.clear_color.f32[1],
+                       res->aux.clear_color.f32[2],
+                       res->aux.clear_color.f32[3],
+                       color.f32[0], color.f32[1], color.f32[2], color.f32[3]);
+         }
+      }
    }
 
    iris_resource_set_clear_color(ice, res, color);