i965: Enable regular fast-clears (CCS_D) on gen9+
authorJason Ekstrand <jason.ekstrand@intel.com>
Thu, 22 Jun 2017 04:35:07 +0000 (21:35 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Sun, 23 Jul 2017 03:59:22 +0000 (20:59 -0700)
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.

This appears to help gl_manhattan31_off by about 2%.

Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
src/mesa/drivers/dri/i965/brw_blorp.c
src/mesa/drivers/dri/i965/brw_draw.c
src/mesa/drivers/dri/i965/brw_meta_util.c
src/mesa/drivers/dri/i965/brw_wm_surface_state.c
src/mesa/drivers/dri/i965/intel_mipmap_tree.c
src/mesa/drivers/dri/i965/intel_mipmap_tree.h

index 36962687c2e6302358290a8d551812c2ccb674b0..36f7ed2a39de05c385b4bc627a4300ea31eb44df 100644 (file)
@@ -317,7 +317,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);
@@ -876,9 +876,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;
@@ -898,8 +898,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;
index 20ff99fff9d525c16e898e628f05cd0467dd56ba..d73a3dc827a4bf9fcc9def24f32e6017914b3457 100644 (file)
@@ -473,7 +473,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));
    }
 }
 
@@ -541,7 +542,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));
    }
 }
 
index ea14f44790f7bc99b965b6bf761314b183378f6e..7ce1fd137f75f76edafe6e35faa134e9b82bb1bb 100644 (file)
@@ -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->surf.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) {
index 5121b98e1a843c7cae44731b6fd4fa1d1b57c33b..250806d28e49d02b6d903edbd8b1744ca6e7f398 100644 (file)
@@ -208,7 +208,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;
@@ -216,7 +216,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);
index 548a081fe226c8744de096d71c8914a32c1af473..ed7cb8e2152042c07c495a6cc2dcb3ce14646579 100644 (file)
@@ -201,13 +201,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
@@ -259,12 +253,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);
 }
 
 /**
@@ -2584,7 +2579,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:
@@ -2592,29 +2587,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:
@@ -2626,10 +2620,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);
 }
@@ -2638,12 +2632,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);
 }
index bc49b6bb07158587806431b7299ad46dc087d24e..3628345c4e940e3c8c79011fd065afff0ec559e4 100644 (file)
@@ -630,17 +630,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,