i965/gen9: Optimize slice and subslice load balancing behavior.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_meta_util.c
index 575f437750bcd8bf84fc2286e325e613ab6fe4f5..6a6d68425fad878d55f99068dfdd64c971b190aa 100644 (file)
@@ -220,6 +220,10 @@ brw_meta_mirror_clip_and_scissor(const struct gl_context *ctx,
     * 4 * 2 = 8 > 5 in the src.
     */
 
+   if (*srcX0 == *srcX1 || *srcY0 == *srcY1
+       || *dstX0 == *dstX1 || *dstY0 == *dstY1)
+      return true;
+
    float scaleX = (float) (*srcX1 - *srcX0) / (*dstX1 - *dstX0);
    float scaleY = (float) (*srcY1 - *srcY0) / (*dstY1 - *dstY0);
 
@@ -250,20 +254,24 @@ brw_meta_mirror_clip_and_scissor(const struct gl_context *ctx,
    /* Account for the fact that in the system framebuffer, the origin is at
     * the lower left.
     */
-   if (_mesa_is_winsys_fbo(read_fb)) {
+   if (read_fb->FlipY) {
       GLint tmp = read_fb->Height - *srcY0;
       *srcY0 = read_fb->Height - *srcY1;
       *srcY1 = tmp;
       *mirror_y = !*mirror_y;
    }
-   if (_mesa_is_winsys_fbo(draw_fb)) {
+   if (draw_fb->FlipY) {
       GLint tmp = draw_fb->Height - *dstY0;
       *dstY0 = draw_fb->Height - *dstY1;
       *dstY1 = tmp;
       *mirror_y = !*mirror_y;
    }
 
-   return false;
+   /* Check for invalid bounds
+    * Can't blit for 0-dimensions
+    */
+   return *srcX0 == *srcX1 || *srcY0 == *srcY1
+      || *dstX0 == *dstX1 || *dstY0 == *dstY1;
 }
 
 /**
@@ -277,6 +285,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 +296,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 +315,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 +362,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;