i965/meta_util: Re-enable sRGB-encoded fast-clears on CNL
[mesa.git] / src / mesa / drivers / dri / i965 / brw_meta_util.c
index 575f437750bcd8bf84fc2286e325e613ab6fe4f5..d292f5a8e24a503fd25941d38fe7f401207893bf 100644 (file)
@@ -277,6 +277,7 @@ brw_is_color_fast_clear_compatible(struct brw_context *brw,
                                    const struct intel_mipmap_tree *mt,
                                    const union gl_color_union *color)
 {
+   const struct gen_device_info *devinfo = &brw->screen->devinfo;
    const struct gl_context *ctx = &brw->ctx;
 
    /* If we're mapping the render format to a different format than the
@@ -287,25 +288,14 @@ brw_is_color_fast_clear_compatible(struct brw_context *brw,
     * state so the hardware probably legitimately doesn't need to support
     * this case. At least on Gen9 this really does seem to cause problems.
     */
-   if (brw->gen >= 9 &&
+   if (devinfo->gen >= 9 &&
        brw_isl_format_for_mesa_format(mt->format) !=
        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) {
+      if (devinfo->gen >= 8) {
          perf_debug("Integer fast clear not enabled for (%s)",
                     _mesa_get_format_name(format));
       }
@@ -317,7 +307,7 @@ brw_is_color_fast_clear_compatible(struct brw_context *brw,
          continue;
       }
 
-      if (brw->gen < 9 &&
+      if (devinfo->gen < 9 &&
           color->f[i] != 0.0f && color->f[i] != 1.0f) {
          return false;
       }
@@ -364,6 +354,46 @@ brw_meta_convert_fast_clear_color(const struct brw_context *brw,
       break;
    }
 
+   switch (_mesa_get_format_datatype(mt->format)) {
+   case GL_UNSIGNED_NORMALIZED:
+      for (int i = 0; i < 4; i++)
+         override_color.f32[i] = CLAMP(override_color.f32[i], 0.0f, 1.0f);
+      break;
+
+   case GL_SIGNED_NORMALIZED:
+      for (int i = 0; i < 4; i++)
+         override_color.f32[i] = CLAMP(override_color.f32[i], -1.0f, 1.0f);
+      break;
+
+   case GL_UNSIGNED_INT:
+      for (int i = 0; i < 4; i++) {
+         unsigned bits = _mesa_get_format_bits(mt->format, GL_RED_BITS + i);
+         if (bits < 32) {
+            uint32_t max = (1u << bits) - 1;
+            override_color.u32[i] = MIN2(override_color.u32[i], max);
+         }
+      }
+      break;
+
+   case GL_INT:
+      for (int i = 0; i < 4; i++) {
+         unsigned bits = _mesa_get_format_bits(mt->format, GL_RED_BITS + i);
+         if (bits < 32) {
+            int32_t max = (1 << (bits - 1)) - 1;
+            int32_t min = -(1 << (bits - 1));
+            override_color.i32[i] = CLAMP(override_color.i32[i], min, max);
+         }
+      }
+      break;
+
+   case GL_FLOAT:
+      if (!_mesa_is_format_signed(mt->format)) {
+         for (int i = 0; i < 4; i++)
+            override_color.f32[i] = MAX2(override_color.f32[i], 0.0f);
+      }
+      break;
+   }
+
    if (!_mesa_format_has_color_component(mt->format, 3)) {
       if (_mesa_is_format_integer_color(mt->format))
          override_color.u32[3] = 1;