summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Antognolli <rafael.antognolli@intel.com>2019-06-25 14:14:22 -0700
committerRafael Antognolli <rafael.antognolli@intel.com>2019-07-17 14:53:37 -0700
commit393f659ed83abfc67d2a57ca1d962d53b22ec03f (patch)
treeb299cd3ddb6aa761fd570c29176e49a958f461e8
parent8bbd4f32bffc7cdd4ff37c05efea60ff64135edd (diff)
iris: Enable fast clears on other miplevels and layers than 0.
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>
-rw-r--r--src/gallium/drivers/iris/iris_clear.c56
1 files changed, 48 insertions, 8 deletions
diff --git a/src/gallium/drivers/iris/iris_clear.c b/src/gallium/drivers/iris/iris_clear.c
index 1724a35c54e..8ed37b68eba 100644
--- a/src/gallium/drivers/iris/iris_clear.c
+++ b/src/gallium/drivers/iris/iris_clear.c
@@ -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);