[Mesa-dev] [PATCH 32/32] i965: Enable regular fast-clears (CCS_D) on gen9+

Jason Ekstrand jason at jlekstrand.net
Wed Jul 19 21:01:58 UTC 2017


The set of formats which supports CCS_E is actually fairly small on
gen9.  However, everything that supports fast-clears on gen8 also
supports fast-clears on gen9+.  The one very annoying exception is
that blending is broken for non-0/1 clear colors with sRGB formats.
In order to solve that problem, we do a resolve to get rid of the
clear color.  Another option would be to just not fast-clear with
non-0/1 clear colors however non-0/1 + blending + sRGB is uncommon
enough that this shouldn't be a significant performance problem.
---
 src/mesa/drivers/dri/i965/brw_blorp.c            | 10 ++--
 src/mesa/drivers/dri/i965/brw_draw.c             |  6 ++-
 src/mesa/drivers/dri/i965/brw_meta_util.c        | 11 ----
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c |  5 +-
 src/mesa/drivers/dri/i965/intel_mipmap_tree.c    | 66 +++++++++++-------------
 src/mesa/drivers/dri/i965/intel_mipmap_tree.h    |  6 +--
 6 files changed, 45 insertions(+), 59 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_blorp.c b/src/mesa/drivers/dri/i965/brw_blorp.c
index 43745d2..b799972 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.c
+++ b/src/mesa/drivers/dri/i965/brw_blorp.c
@@ -324,7 +324,7 @@ brw_blorp_blit_miptrees(struct brw_context *brw,
                                 src_aux_usage, src_clear_supported);
 
    enum isl_aux_usage dst_aux_usage =
-      intel_miptree_render_aux_usage(brw, dst_mt, encode_srgb);
+      intel_miptree_render_aux_usage(brw, dst_mt, encode_srgb, false);
    const bool dst_clear_supported = dst_aux_usage != ISL_AUX_USAGE_NONE;
    intel_miptree_prepare_access(brw, dst_mt, dst_level, 1, dst_layer, 1,
                                 dst_aux_usage, dst_clear_supported);
@@ -885,9 +885,9 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
           irb->mt, irb->mt_level, irb->mt_layer, num_layers);
 
       enum isl_aux_usage aux_usage =
-         intel_miptree_render_aux_usage(brw, irb->mt, encode_srgb);
+         intel_miptree_render_aux_usage(brw, irb->mt, encode_srgb, false);
       intel_miptree_prepare_render(brw, irb->mt, level, irb->mt_layer,
-                                   num_layers, encode_srgb);
+                                   num_layers, encode_srgb, false);
 
       struct isl_surf isl_tmp[2];
       struct blorp_surf surf;
@@ -907,8 +907,8 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
                   clear_color, color_write_disable);
       blorp_batch_finish(&batch);
 
-      intel_miptree_finish_render(brw, irb->mt, level,
-                                  irb->mt_layer, num_layers, encode_srgb);
+      intel_miptree_finish_render(brw, irb->mt, level, irb->mt_layer,
+                                  num_layers, encode_srgb, false);
    }
 
    return;
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index 01b618c..8e0a4ae 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -474,7 +474,8 @@ brw_predraw_resolve_framebuffer(struct brw_context *brw)
 
       intel_miptree_prepare_render(brw, irb->mt, irb->mt_level,
                                    irb->mt_layer, irb->layer_count,
-                                   ctx->Color.sRGBEnabled);
+                                   ctx->Color.sRGBEnabled,
+                                   ctx->Color.BlendEnabled & (1 << i));
    }
 }
 
@@ -542,7 +543,8 @@ brw_postdraw_set_buffers_need_resolve(struct brw_context *brw)
       brw_render_cache_set_add_bo(brw, irb->mt->bo);
       intel_miptree_finish_render(brw, irb->mt, irb->mt_level,
                                   irb->mt_layer, irb->layer_count,
-                                  ctx->Color.sRGBEnabled);
+                                  ctx->Color.sRGBEnabled,
+                                  ctx->Color.BlendEnabled & (1 << i));
    }
 }
 
diff --git a/src/mesa/drivers/dri/i965/brw_meta_util.c b/src/mesa/drivers/dri/i965/brw_meta_util.c
index f9fd350..7ce1fd1 100644
--- a/src/mesa/drivers/dri/i965/brw_meta_util.c
+++ b/src/mesa/drivers/dri/i965/brw_meta_util.c
@@ -292,17 +292,6 @@ brw_is_color_fast_clear_compatible(struct brw_context *brw,
        brw->mesa_to_isl_render_format[mt->format])
       return false;
 
-   /* Gen9 doesn't support fast clear on single-sampled SRGB buffers. When
-    * GL_FRAMEBUFFER_SRGB is enabled any color renderbuffers will be
-    * resolved in intel_update_state. In that case it's pointless to do a
-    * fast clear because it's very likely to be immediately resolved.
-    */
-   if (brw->gen >= 9 &&
-       mt->num_samples <= 1 &&
-       ctx->Color.sRGBEnabled &&
-       _mesa_get_srgb_format_linear(mt->format) != mt->format)
-      return false;
-
    const mesa_format format = _mesa_get_render_format(ctx, mt->format);
    if (_mesa_is_format_integer_color(format)) {
       if (brw->gen >= 8) {
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index 2fefba5..0d32945 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -200,7 +200,7 @@ brw_emit_surface_state(struct brw_context *brw,
 uint32_t
 brw_update_renderbuffer_surface(struct brw_context *brw,
                                 struct gl_renderbuffer *rb,
-                                uint32_t flags, unsigned unit /* unused */,
+                                uint32_t flags, unsigned unit,
                                 uint32_t surf_index)
 {
    struct gl_context *ctx = &brw->ctx;
@@ -208,7 +208,8 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
    struct intel_mipmap_tree *mt = irb->mt;
 
    enum isl_aux_usage aux_usage =
-      intel_miptree_render_aux_usage(brw, mt, ctx->Color.sRGBEnabled);
+      intel_miptree_render_aux_usage(brw, mt, ctx->Color.sRGBEnabled,
+                                     ctx->Color.BlendEnabled & (1 << unit));
 
    if (flags & INTEL_AUX_BUFFER_DISABLED) {
       assert(brw->gen >= 9);
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
index ebc414c..1cba7e7 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -242,13 +242,7 @@ intel_miptree_supports_ccs(struct brw_context *brw,
    if (!brw->mesa_format_supports_render[mt->format])
       return false;
 
-   if (brw->gen >= 9) {
-      mesa_format linear_format = _mesa_get_srgb_format_linear(mt->format);
-      const enum isl_format isl_format =
-         brw_isl_format_for_mesa_format(linear_format);
-      return isl_format_supports_ccs_e(&brw->screen->devinfo, isl_format);
-   } else
-      return true;
+   return true;
 }
 
 static bool
@@ -299,12 +293,13 @@ intel_miptree_supports_ccs_e(struct brw_context *brw,
    if (!intel_miptree_supports_ccs(brw, mt))
       return false;
 
-   /* Fast clear can be also used to clear srgb surfaces by using equivalent
-    * linear format. This trick, however, can't be extended to be used with
-    * lossless compression and therefore a check is needed to see if the format
-    * really is linear.
+   /* Many window system buffers are sRGB even if they are never rendered as
+    * sRGB.  For those, we want CCS_E for when sRGBEncode is false.  When the
+    * surface is used as sRGB, we fall back to CCS_D.
     */
-   return _mesa_get_srgb_format_linear(mt->format) == mt->format;
+   mesa_format linear_format = _mesa_get_srgb_format_linear(mt->format);
+   enum isl_format isl_format = brw_isl_format_for_mesa_format(linear_format);
+   return isl_format_supports_ccs_e(&brw->screen->devinfo, isl_format);
 }
 
 /**
@@ -2839,7 +2834,7 @@ intel_miptree_prepare_fb_fetch(struct brw_context *brw,
 enum isl_aux_usage
 intel_miptree_render_aux_usage(struct brw_context *brw,
                                struct intel_mipmap_tree *mt,
-                               bool srgb_enabled)
+                               bool srgb_enabled, bool blend_enabled)
 {
    switch (mt->aux_usage) {
    case ISL_AUX_USAGE_MCS:
@@ -2847,29 +2842,28 @@ intel_miptree_render_aux_usage(struct brw_context *brw,
       return ISL_AUX_USAGE_MCS;
 
    case ISL_AUX_USAGE_CCS_D:
-      /* If FRAMEBUFFER_SRGB is used on Gen9+ then we need to resolve any of
-       * the single-sampled color renderbuffers because the CCS buffer isn't
-       * supported for SRGB formats. This only matters if FRAMEBUFFER_SRGB is
-       * enabled because otherwise the surface state will be programmed with
-       * the linear equivalent format anyway.
-       */
-      if (srgb_enabled &&
-          _mesa_get_srgb_format_linear(mt->format) != mt->format) {
-         return ISL_AUX_USAGE_NONE;
-      } else if (!mt->mcs_buf) {
-         return ISL_AUX_USAGE_NONE;
-      } else {
-         return ISL_AUX_USAGE_CCS_D;
-      }
+      return mt->mcs_buf ? ISL_AUX_USAGE_CCS_D : ISL_AUX_USAGE_NONE;
 
    case ISL_AUX_USAGE_CCS_E: {
-      /* Lossless compression is not supported for SRGB formats, it
-       * should be impossible to get here with such surfaces.
+      mesa_format mesa_format =
+         srgb_enabled ? mt->format :_mesa_get_srgb_format_linear(mt->format);
+      enum isl_format isl_format = brw_isl_format_for_mesa_format(mesa_format);
+
+      /* If the format supports CCS_E, then we can just use it */
+      if (isl_format_supports_ccs_e(&brw->screen->devinfo, isl_format))
+         return ISL_AUX_USAGE_CCS_E;
+
+      /* Otherwise, we have to fall back to CCS_D */
+
+      /* gen9 hardware technically supports non-0/1 clear colors with sRGB
+       * formats.  However, there are issues with blending where it doesn't
+       * properly apply the sRGB curve to the clear color when blending.
        */
-      assert(!srgb_enabled ||
-             _mesa_get_srgb_format_linear(mt->format) == mt->format);
+      if (blend_enabled && isl_format_is_srgb(isl_format) &&
+          !isl_color_value_is_zero_one(mt->fast_clear_color, isl_format))
+         return ISL_AUX_USAGE_NONE;
 
-      return ISL_AUX_USAGE_CCS_E;
+      return ISL_AUX_USAGE_CCS_D;
    }
 
    default:
@@ -2881,10 +2875,10 @@ void
 intel_miptree_prepare_render(struct brw_context *brw,
                              struct intel_mipmap_tree *mt, uint32_t level,
                              uint32_t start_layer, uint32_t layer_count,
-                             bool srgb_enabled)
+                             bool srgb_enabled, bool blend_enabled)
 {
    enum isl_aux_usage aux_usage =
-      intel_miptree_render_aux_usage(brw, mt, srgb_enabled);
+      intel_miptree_render_aux_usage(brw, mt, srgb_enabled, blend_enabled);
    intel_miptree_prepare_access(brw, mt, level, 1, start_layer, layer_count,
                                 aux_usage, aux_usage != ISL_AUX_USAGE_NONE);
 }
@@ -2893,12 +2887,12 @@ void
 intel_miptree_finish_render(struct brw_context *brw,
                             struct intel_mipmap_tree *mt, uint32_t level,
                             uint32_t start_layer, uint32_t layer_count,
-                            bool srgb_enabled)
+                            bool srgb_enabled, bool blend_enabled)
 {
    assert(_mesa_is_format_color_format(mt->format));
 
    enum isl_aux_usage aux_usage =
-      intel_miptree_render_aux_usage(brw, mt, srgb_enabled);
+      intel_miptree_render_aux_usage(brw, mt, srgb_enabled, blend_enabled);
    intel_miptree_finish_write(brw, mt, level, start_layer, layer_count,
                               aux_usage);
 }
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
index df413b1..48d488e 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
@@ -943,17 +943,17 @@ intel_miptree_prepare_fb_fetch(struct brw_context *brw,
 enum isl_aux_usage
 intel_miptree_render_aux_usage(struct brw_context *brw,
                                struct intel_mipmap_tree *mt,
-                               bool srgb_enabled);
+                               bool srgb_enabled, bool blend_enabled);
 void
 intel_miptree_prepare_render(struct brw_context *brw,
                              struct intel_mipmap_tree *mt, uint32_t level,
                              uint32_t start_layer, uint32_t layer_count,
-                             bool srgb_enabled);
+                             bool srgb_enabled, bool blend_enabled);
 void
 intel_miptree_finish_render(struct brw_context *brw,
                             struct intel_mipmap_tree *mt, uint32_t level,
                             uint32_t start_layer, uint32_t layer_count,
-                            bool srgb_enabled);
+                            bool srgb_enabled, bool blend_enabled);
 void
 intel_miptree_prepare_depth(struct brw_context *brw,
                             struct intel_mipmap_tree *mt, uint32_t level,
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list