iris: Track fast clear color.
authorRafael Antognolli <rafael.antognolli@intel.com>
Tue, 19 Mar 2019 19:47:58 +0000 (12:47 -0700)
committerRafael Antognolli <rafael.antognolli@intel.com>
Wed, 20 Mar 2019 23:46:26 +0000 (16:46 -0700)
v2: Update tracked clear color when we update the surface state.
v3: Update all aux surface states when updating the clear color.

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

index 3349d3eafc0678f1c472571ec50fc97cb01c7744..81715ed06f814043f656d1d724172e01866ae5bc 100644 (file)
@@ -159,6 +159,8 @@ struct iris_sampler_view {
    struct pipe_sampler_view base;
    struct isl_view view;
 
+   union isl_color_value clear_color;
+
    /* A short-cut (not a reference) to the actual resource being viewed.
     * Multi-planar (or depth+stencil) images may have multiple resources
     * chained together; this skips having to traverse base->texture->*.
@@ -178,6 +180,7 @@ struct iris_sampler_view {
 struct iris_surface {
    struct pipe_surface base;
    struct isl_view view;
+   union isl_color_value clear_color;
 
    /** The resource (BO) holding our SURFACE_STATE. */
    struct iris_state_ref surface_state;
index d27de09e2364eff570d34c331dfcad4cf6c7dfc8..c16fa22b42b7c47cf2925a24a9fb21f257ce187d 100644 (file)
@@ -1651,6 +1651,7 @@ fill_surface_state(struct isl_device *isl_dev,
       f.aux_surf = &res->aux.surf;
       f.aux_usage = aux_usage;
       f.aux_address = res->aux.bo->gtt_offset + res->aux.offset;
+      f.clear_color = res->aux.clear_color;
    }
 
    isl_surf_fill_state_s(isl_dev, map, &f);
@@ -1706,6 +1707,8 @@ iris_create_sampler_view(struct pipe_context *ctx,
    const struct iris_format_info fmt =
       iris_format_for_usage(devinfo, tmpl->format, usage);
 
+   isv->clear_color = isv->res->aux.clear_color;
+
    isv->view = (struct isl_view) {
       .format = fmt.fmt,
       .swizzle = (struct isl_swizzle) {
@@ -1822,6 +1825,8 @@ iris_create_surface(struct pipe_context *ctx,
       .usage = usage,
    };
 
+   surf->clear_color = res->aux.clear_color;
+
    /* Bail early for depth/stencil - we don't want SURFACE_STATE for them. */
    if (res->surf.usage & (ISL_SURF_USAGE_DEPTH_BIT |
                           ISL_SURF_USAGE_STENCIL_BIT))
@@ -3747,6 +3752,20 @@ surf_state_update_clear_value(struct iris_batch *batch,
                              isl_dev->ss.clear_value_size);
 }
 
+static void
+update_clear_value(struct iris_batch *batch,
+                   struct iris_resource *res,
+                   struct iris_state_ref *state)
+{
+   unsigned aux_modes = res->aux.possible_usages;
+   aux_modes &= ~ISL_AUX_USAGE_NONE;
+
+   while (aux_modes) {
+      enum isl_aux_usage aux_usage = u_bit_scan(&aux_modes);
+      surf_state_update_clear_value(batch, res, state, aux_usage);
+   }
+}
+
 /**
  * Add a surface to the validation list, as well as the buffer containing
  * the corresponding SURFACE_STATE.
@@ -3768,7 +3787,12 @@ use_surface(struct iris_batch *batch,
    if (res->aux.bo) {
       iris_use_pinned_bo(batch, res->aux.bo, writeable);
       iris_use_pinned_bo(batch, res->aux.clear_color_bo, false);
-      surf_state_update_clear_value(batch, res, &surf->surface_state, aux_usage);
+
+      if (memcmp(&res->aux.clear_color, &surf->clear_color,
+                 sizeof(surf->clear_color)) != 0) {
+         update_clear_value(batch, res, &surf->surface_state);
+         surf->clear_color = res->aux.clear_color;
+      }
    }
 
    return surf->surface_state.offset +
@@ -3790,8 +3814,11 @@ use_sampler_view(struct iris_context *ice,
    if (isv->res->aux.bo) {
       iris_use_pinned_bo(batch, isv->res->aux.bo, false);
       iris_use_pinned_bo(batch, isv->res->aux.clear_color_bo, false);
-      surf_state_update_clear_value(batch, isv->res,
-                                    &isv->surface_state, aux_usage);
+      if (memcmp(&isv->res->aux.clear_color, &isv->clear_color,
+                 sizeof(isv->clear_color)) != 0) {
+         update_clear_value(batch, isv->res, &isv->surface_state);
+         isv->clear_color = isv->res->aux.clear_color;
+      }
    }
 
    return isv->surface_state.offset +