Mesa (main): iris: Don't try to CPU read imported clear color BOs

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Aug 12 20:00:55 UTC 2021


Module: Mesa
Branch: main
Commit: e83da2d8e3b1129d6857bb18cb212fdd08cbc69b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=e83da2d8e3b1129d6857bb18cb212fdd08cbc69b

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Mon Jul 26 12:59:42 2021 -0700

iris: Don't try to CPU read imported clear color BOs

Previously, when importing a resource with modifiers that include
clear color as auxiliary data, we were mapping the clear color BO
on the CPU in order to set res->aux.clear_color to the value stored
there.

We are generally trying to avoid CPU mapping imported buffers, because
in hybrid setups, they could be from a different device, and may not be
mappable.  So we'd like to avoid that here.

This CPU-side knowledge of the clear color is only used in a few cases:

1. Avoiding a resolve due to a partial clear with a changing clear color

2. Avoiding disabling CCS when rendering to a texture view of a resource
   where the only format difference is sRGB vs. linear and the clear
   color is 0/1.

Instead of mapping the clear color BO on the CPU, we instead set a flag
indicating that we don't know the clear color, and reset it to known on
our first clear.

In the first case, the first partial fast clear of a resource would eat
an extra resolve (there is no penalty if we clear the whole resource).

The second case doesn't seem that critical, as it's someone rendering
to an imported BO - when the common case is to texture from it.

Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11888>

---

 src/gallium/drivers/iris/iris_clear.c    | 36 +++++++++++++++++++-------------
 src/gallium/drivers/iris/iris_resolve.c  |  9 +++++---
 src/gallium/drivers/iris/iris_resource.c |  8 +++----
 src/gallium/drivers/iris/iris_resource.h | 11 +++++++++-
 4 files changed, 42 insertions(+), 22 deletions(-)

diff --git a/src/gallium/drivers/iris/iris_clear.c b/src/gallium/drivers/iris/iris_clear.c
index a59ba735cbc..dd0e7db53e1 100644
--- a/src/gallium/drivers/iris/iris_clear.c
+++ b/src/gallium/drivers/iris/iris_clear.c
@@ -114,7 +114,7 @@ can_fast_clear_color(struct iris_context *ice,
     * resource and not the renderbuffer.
     */
    if (!iris_render_formats_color_compatible(render_format, res->surf.format,
-                                             color)) {
+                                             color, false)) {
       return false;
    }
 
@@ -218,8 +218,8 @@ fast_clear_color(struct iris_context *ice,
    struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
    struct pipe_resource *p_res = (void *) res;
 
-   bool color_changed = !!memcmp(&res->aux.clear_color, &color,
-                                 sizeof(color));
+   bool color_changed = res->aux.clear_color_unknown ||
+      memcmp(&res->aux.clear_color, &color, sizeof(color)) != 0;
 
    if (color_changed) {
       /* If we are clearing to a new clear value, we need to resolve fast
@@ -257,16 +257,24 @@ fast_clear_color(struct iris_context *ice,
                                          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]);
+            if (res->aux.clear_color_unknown) {
+               perf_debug(&ice->dbg,
+                          "Resolving resource (%p) level %d, layer %d: color changing from "
+                          "(unknown) to (%0.2f, %0.2f, %0.2f, %0.2f)\n",
+                          res, res_lvl, layer,
+                          color.f32[0], color.f32[1], color.f32[2], color.f32[3]);
+            } else {
+               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]);
+            }
          }
       }
    }
@@ -463,7 +471,7 @@ fast_clear_depth(struct iris_context *ice,
    /* If we're clearing to a new clear value, then we need to resolve any clear
     * flags out of the HiZ buffer into the real depth buffer.
     */
-   if (res->aux.clear_color.f32[0] != depth) {
+   if (res->aux.clear_color_unknown || res->aux.clear_color.f32[0] != depth) {
       for (unsigned res_level = 0; res_level < res->surf.levels; res_level++) {
          const unsigned level_layers =
             iris_get_num_logical_layers(res, res_level);
diff --git a/src/gallium/drivers/iris/iris_resolve.c b/src/gallium/drivers/iris/iris_resolve.c
index 68fadd97f22..cbdfec64cad 100644
--- a/src/gallium/drivers/iris/iris_resolve.c
+++ b/src/gallium/drivers/iris/iris_resolve.c
@@ -957,13 +957,15 @@ iris_resource_prepare_texture(struct iris_context *ice,
  */
 bool
 iris_render_formats_color_compatible(enum isl_format a, enum isl_format b,
-                                     union isl_color_value color)
+                                     union isl_color_value color,
+                                     bool clear_color_unknown)
 {
    if (a == b)
       return true;
 
    /* A difference in color space doesn't matter for 0/1 values. */
-   if (isl_format_srgb_to_linear(a) == isl_format_srgb_to_linear(b) &&
+   if (!clear_color_unknown &&
+       isl_format_srgb_to_linear(a) == isl_format_srgb_to_linear(b) &&
        isl_color_value_is_zero_one(color, a)) {
       return true;
    }
@@ -1014,7 +1016,8 @@ iris_resource_render_aux_usage(struct iris_context *ice,
        */
       if (!iris_render_formats_color_compatible(render_format,
                                                 res->surf.format,
-                                                res->aux.clear_color)) {
+                                                res->aux.clear_color,
+                                                res->aux.clear_color_unknown)) {
          return ISL_AUX_USAGE_NONE;
       }
 
diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c
index 4e38e73b153..cc32a64559c 100644
--- a/src/gallium/drivers/iris/iris_resource.c
+++ b/src/gallium/drivers/iris/iris_resource.c
@@ -940,9 +940,7 @@ iris_resource_finish_aux_import(struct pipe_screen *pscreen,
       iris_bo_reference(r[2]->aux.clear_color_bo);
       r[0]->aux.clear_color_bo = r[2]->aux.clear_color_bo;
       r[0]->aux.clear_color_offset = r[2]->aux.clear_color_offset;
-      memcpy(res->aux.clear_color.f32,
-             iris_bo_map(NULL, res->aux.clear_color_bo, MAP_READ|MAP_RAW) +
-             res->aux.clear_color_offset, sizeof(res->aux.clear_color.f32));
+      r[0]->aux.clear_color_unknown = true;
    } else if (num_main_planes == 2 && num_planes == 4) {
       import_aux_info(r[0], r[2]);
       import_aux_info(r[1], r[3]);
@@ -2373,8 +2371,10 @@ iris_resource_set_clear_color(struct iris_context *ice,
                               struct iris_resource *res,
                               union isl_color_value color)
 {
-   if (memcmp(&res->aux.clear_color, &color, sizeof(color)) != 0) {
+   if (res->aux.clear_color_unknown ||
+       memcmp(&res->aux.clear_color, &color, sizeof(color)) != 0) {
       res->aux.clear_color = color;
+      res->aux.clear_color_unknown = false;
       return true;
    }
 
diff --git a/src/gallium/drivers/iris/iris_resource.h b/src/gallium/drivers/iris/iris_resource.h
index 9e5b5515351..75888a86bd3 100644
--- a/src/gallium/drivers/iris/iris_resource.h
+++ b/src/gallium/drivers/iris/iris_resource.h
@@ -113,9 +113,17 @@ struct iris_resource {
          uint32_t offset;
       } extra_aux;
 
+      /**
+       * When importing resources with a clear color, we may not know the
+       * clear color on the CPU at first.
+       */
+      bool clear_color_unknown;
+
       /**
        * Fast clear color for this surface.  For depth surfaces, the clear
        * value is stored as a float32 in the red component.
+       *
+       * Do not rely on this value if clear_color_unknown is set.
        */
       union isl_color_value clear_color;
 
@@ -516,7 +524,8 @@ bool iris_has_color_unresolved(const struct iris_resource *res,
 
 bool iris_render_formats_color_compatible(enum isl_format a,
                                           enum isl_format b,
-                                          union isl_color_value color);
+                                          union isl_color_value color,
+                                          bool clear_color_unknown);
 enum isl_aux_usage iris_resource_render_aux_usage(struct iris_context *ice,
                                                   struct iris_resource *res,
                                                   uint32_t level,



More information about the mesa-commit mailing list