i965: Enable regular fast-clears (CCS_D) on gen9+
[mesa.git] / src / mesa / drivers / dri / i965 / intel_mipmap_tree.c
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);
 }