[Mesa-dev] [PATCH 04/30] i965/miptree: Store fast clear colors in an isl_color_value

Jason Ekstrand jason at jlekstrand.net
Fri May 26 23:30:08 UTC 2017


This commit, out of necessity, makes a number of changes at once:

 1) Changes intel_mipmap_tree to store the clear color for both color
    and depth as an isl_color_value.

 2) Changes the depth/stencil emit code to do the format conversion of
    the depth clear value on Haswell and earlier instead of pulling a
    uint32_t directly from the miptree.

 3) Changes ISL's depth/stencil emit code to perform the format
    conversion of the depth clear value on Haswell and earlier instead
    of assuming that the depth value in the float is pre-converted.

 4) Changes blorp to pass the depth value through as a float.
---
 src/intel/blorp/blorp_genX_exec.h                |  2 +-
 src/intel/isl/isl_emit_depth_stencil.c           | 19 ++++++++
 src/mesa/drivers/dri/i965/brw_blorp.c            | 18 +++-----
 src/mesa/drivers/dri/i965/brw_clear.c            | 15 ++-----
 src/mesa/drivers/dri/i965/brw_meta_util.c        | 56 +++++++-----------------
 src/mesa/drivers/dri/i965/brw_meta_util.h        |  7 +--
 src/mesa/drivers/dri/i965/brw_misc_state.c       | 23 +++++++++-
 src/mesa/drivers/dri/i965/brw_state.h            |  3 ++
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c |  2 +-
 src/mesa/drivers/dri/i965/gen6_depth_state.c     |  7 ++-
 src/mesa/drivers/dri/i965/gen7_misc_state.c      |  7 ++-
 src/mesa/drivers/dri/i965/gen8_depth_state.c     |  2 +-
 src/mesa/drivers/dri/i965/intel_mipmap_tree.c    | 31 -------------
 src/mesa/drivers/dri/i965/intel_mipmap_tree.h    | 34 ++------------
 14 files changed, 90 insertions(+), 136 deletions(-)

diff --git a/src/intel/blorp/blorp_genX_exec.h b/src/intel/blorp/blorp_genX_exec.h
index 8b9b8d2..8dd0f98 100644
--- a/src/intel/blorp/blorp_genX_exec.h
+++ b/src/intel/blorp/blorp_genX_exec.h
@@ -1388,7 +1388,7 @@ blorp_emit_depth_stencil_config(struct blorp_batch *batch,
             blorp_emit_reloc(batch, dw + isl_dev->ds.hiz_offset / 4,
                              params->depth.aux_addr, 0);
 
-         info.depth_clear_value = params->depth.clear_color.u32[0];
+         info.depth_clear_value = params->depth.clear_color.f32[0];
       }
    }
 
diff --git a/src/intel/isl/isl_emit_depth_stencil.c b/src/intel/isl/isl_emit_depth_stencil.c
index 41a01be..339da28 100644
--- a/src/intel/isl/isl_emit_depth_stencil.c
+++ b/src/intel/isl/isl_emit_depth_stencil.c
@@ -177,7 +177,26 @@ isl_genX(emit_depth_stencil_hiz_s)(const struct isl_device *dev, void *batch,
 #endif
 
       clear.DepthClearValueValid = true;
+#if GEN_GEN >= 8
       clear.DepthClearValue = info->depth_clear_value;
+#else
+      switch (info->depth_surf->format) {
+      case ISL_FORMAT_R32_FLOAT: {
+         union { float f; uint32_t u; } fu;
+         fu.f = info->depth_clear_value;
+         clear.DepthClearValue = fu.u;
+         break;
+      }
+      case ISL_FORMAT_R24_UNORM_X8_TYPELESS:
+         clear.DepthClearValue = info->depth_clear_value * ((1u << 24) - 1);
+         break;
+      case ISL_FORMAT_R16_UNORM:
+         clear.DepthClearValue = info->depth_clear_value * ((1u << 16) - 1);
+         break;
+      default:
+         unreachable("Invalid depth type");
+      }
+#endif
    }
 #endif /* GEN_GEN >= 6 */
 
diff --git a/src/mesa/drivers/dri/i965/brw_blorp.c b/src/mesa/drivers/dri/i965/brw_blorp.c
index 7ffe8b8..0b04ea0 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.c
+++ b/src/mesa/drivers/dri/i965/brw_blorp.c
@@ -241,7 +241,7 @@ blorp_surf_for_miptree(struct brw_context *brw,
       /* We only really need a clear color if we also have an auxiliary
        * surface.  Without one, it does nothing.
        */
-      surf->clear_color = intel_miptree_get_isl_clear_color(brw, mt);
+      surf->clear_color = mt->fast_clear_color;
 
       surf->aux_surf = aux_surf;
       surf->aux_addr = (struct blorp_address) {
@@ -852,24 +852,20 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
       can_fast_clear = false;
 
    if (can_fast_clear) {
-      union gl_color_union override_color =
+      union isl_color_value clear_color =
          brw_meta_convert_fast_clear_color(brw, irb->mt,
                                            &ctx->Color.ClearColor);
 
-      /* Record the clear color in the miptree so that it will be
-       * programmed in SURFACE_STATE by later rendering and resolve
-       * operations.
-       */
-      const bool color_updated = brw_meta_set_fast_clear_color(
-                                    brw, &irb->mt->gen9_fast_clear_color,
-                                    &override_color);
-
       /* If the buffer is already in INTEL_FAST_CLEAR_STATE_CLEAR, the clear
        * is redundant and can be skipped.
        */
-      if (!color_updated && fast_clear_state == INTEL_FAST_CLEAR_STATE_CLEAR)
+      if (fast_clear_state == INTEL_FAST_CLEAR_STATE_CLEAR &&
+          memcmp(&irb->mt->fast_clear_color,
+                 &clear_color, sizeof(clear_color)) == 0)
          return true;
 
+      irb->mt->fast_clear_color = clear_color;
+
       /* If the MCS buffer hasn't been allocated yet, we need to allocate
        * it now.
        */
diff --git a/src/mesa/drivers/dri/i965/brw_clear.c b/src/mesa/drivers/dri/i965/brw_clear.c
index 664342d..adaf250 100644
--- a/src/mesa/drivers/dri/i965/brw_clear.c
+++ b/src/mesa/drivers/dri/i965/brw_clear.c
@@ -125,7 +125,6 @@ brw_fast_clear_depth(struct gl_context *ctx)
       return false;
    }
 
-   uint32_t depth_clear_value;
    switch (mt->format) {
    case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
    case MESA_FORMAT_Z24_UNORM_S8_UINT:
@@ -139,10 +138,6 @@ brw_fast_clear_depth(struct gl_context *ctx)
        */
       return false;
 
-   case MESA_FORMAT_Z_FLOAT32:
-      depth_clear_value = float_as_int(ctx->Depth.Clear);
-      break;
-
    case MESA_FORMAT_Z_UNORM16:
       /* From the Sandy Bridge PRM, volume 2 part 1, page 314:
        *
@@ -157,22 +152,18 @@ brw_fast_clear_depth(struct gl_context *ctx)
           (minify(mt->physical_width0,
                   depth_irb->mt_level - mt->first_level) % 16) != 0)
 	 return false;
-      /* FALLTHROUGH */
+      break;
 
    default:
-      if (brw->gen >= 8)
-         depth_clear_value = float_as_int(ctx->Depth.Clear);
-      else
-         depth_clear_value = fb->_DepthMax * ctx->Depth.Clear;
       break;
    }
 
    /* If we're clearing to a new clear value, then we need to resolve any clear
     * flags out of the HiZ buffer into the real depth buffer.
     */
-   if (mt->depth_clear_value != depth_clear_value) {
+   if (mt->fast_clear_color.f32[0] != ctx->Depth.Clear) {
       intel_miptree_all_slices_resolve_depth(brw, mt);
-      mt->depth_clear_value = depth_clear_value;
+      mt->fast_clear_color.f32[0] = ctx->Depth.Clear;
    }
 
    if (brw->gen == 6) {
diff --git a/src/mesa/drivers/dri/i965/brw_meta_util.c b/src/mesa/drivers/dri/i965/brw_meta_util.c
index cbc2ded..2416079 100644
--- a/src/mesa/drivers/dri/i965/brw_meta_util.c
+++ b/src/mesa/drivers/dri/i965/brw_meta_util.c
@@ -329,12 +329,19 @@ brw_is_color_fast_clear_compatible(struct brw_context *brw,
  * Convert the given color to a bitfield suitable for ORing into DWORD 7 of
  * SURFACE_STATE (DWORD 12-15 on SKL+).
  */
-union gl_color_union
+union isl_color_value
 brw_meta_convert_fast_clear_color(const struct brw_context *brw,
                                   const struct intel_mipmap_tree *mt,
                                   const union gl_color_union *color)
 {
-   union gl_color_union override_color = *color;
+   union isl_color_value override_color = {
+      .u32 = {
+         color->ui[0],
+         color->ui[1],
+         color->ui[2],
+         color->ui[3],
+      },
+   };
 
    /* The sampler doesn't look at the format of the surface when the fast
     * clear color is used so we need to implement luminance, intensity and
@@ -342,65 +349,36 @@ brw_meta_convert_fast_clear_color(const struct brw_context *brw,
     */
    switch (_mesa_get_format_base_format(mt->format)) {
    case GL_INTENSITY:
-      override_color.ui[3] = override_color.ui[0];
+      override_color.u32[3] = override_color.u32[0];
       /* flow through */
    case GL_LUMINANCE:
    case GL_LUMINANCE_ALPHA:
-      override_color.ui[1] = override_color.ui[0];
-      override_color.ui[2] = override_color.ui[0];
+      override_color.u32[1] = override_color.u32[0];
+      override_color.u32[2] = override_color.u32[0];
       break;
    default:
       for (int i = 0; i < 3; i++) {
          if (!_mesa_format_has_color_component(mt->format, i))
-            override_color.ui[i] = 0;
+            override_color.u32[i] = 0;
       }
       break;
    }
 
    if (!_mesa_format_has_color_component(mt->format, 3)) {
       if (_mesa_is_format_integer_color(mt->format))
-         override_color.ui[3] = 1;
+         override_color.u32[3] = 1;
       else
-         override_color.f[3] = 1.0f;
+         override_color.f32[3] = 1.0f;
    }
 
    /* Handle linear to SRGB conversion */
    if (brw->ctx.Color.sRGBEnabled &&
        _mesa_get_srgb_format_linear(mt->format) != mt->format) {
       for (int i = 0; i < 3; i++) {
-         override_color.f[i] =
-            util_format_linear_to_srgb_float(override_color.f[i]);
+         override_color.f32[i] =
+            util_format_linear_to_srgb_float(override_color.f32[i]);
       }
    }
 
    return override_color;
 }
-
-/* Returned boolean tells if the given color differs from the current. */
-bool
-brw_meta_set_fast_clear_color(struct brw_context *brw,
-                              union gl_color_union *curr_color,
-                              const union gl_color_union *new_color)
-{
-   bool updated;
-
-   if (brw->gen >= 9) {
-      updated = memcmp(curr_color, new_color, sizeof(*curr_color));
-      *curr_color = *new_color;
-   } else {
-      const uint32_t old_color_value = *(uint32_t *)curr_color;
-      uint32_t adjusted = 0;
-
-      for (int i = 0; i < 4; i++) {
-         /* Testing for non-0 works for integer and float colors */
-         if (new_color->f[i] != 0.0f) {
-            adjusted |= 1 << (GEN7_SURFACE_CLEAR_COLOR_SHIFT + (3 - i));
-         }
-      }
-
-      updated = (old_color_value != adjusted);
-      *(uint32_t *)curr_color = adjusted;
-   }
-
-   return updated;
-}
diff --git a/src/mesa/drivers/dri/i965/brw_meta_util.h b/src/mesa/drivers/dri/i965/brw_meta_util.h
index 207a54b..4b3408d 100644
--- a/src/mesa/drivers/dri/i965/brw_meta_util.h
+++ b/src/mesa/drivers/dri/i965/brw_meta_util.h
@@ -42,17 +42,12 @@ brw_meta_mirror_clip_and_scissor(const struct gl_context *ctx,
                                  GLfloat *dstX1, GLfloat *dstY1,
                                  bool *mirror_x, bool *mirror_y);
 
-union gl_color_union
+union isl_color_value
 brw_meta_convert_fast_clear_color(const struct brw_context *brw,
                                   const struct intel_mipmap_tree *mt,
                                   const union gl_color_union *color);
 
 bool
-brw_meta_set_fast_clear_color(struct brw_context *brw,
-                              union gl_color_union *curr_color,
-                              const union gl_color_union *new_color);
-
-bool
 brw_is_color_fast_clear_compatible(struct brw_context *brw,
                                    const struct intel_mipmap_tree *mt,
                                    const union gl_color_union *color);
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index afa7e08..79bdda9 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -42,6 +42,7 @@
 
 #include "main/framebuffer.h"
 #include "main/fbobject.h"
+#include "main/format_utils.h"
 #include "main/glformats.h"
 
 /**
@@ -523,6 +524,21 @@ brw_emit_depthbuffer(struct brw_context *brw)
                                     width, height, tile_x, tile_y);
 }
 
+uint32_t
+brw_convert_depth_value(mesa_format format, float value)
+{
+   switch (format) {
+   case MESA_FORMAT_Z_FLOAT32:
+      return float_as_int(value);
+   case MESA_FORMAT_Z_UNORM16:
+      return value * ((1u << 16) - 1);
+   case MESA_FORMAT_Z24_UNORM_X8_UINT:
+      return value * ((1u << 24) - 1);
+   default:
+      unreachable("Invalid depth format");
+   }
+}
+
 void
 brw_emit_depth_stencil_hiz(struct brw_context *brw,
                            struct intel_mipmap_tree *depth_mt,
@@ -656,7 +672,12 @@ brw_emit_depth_stencil_hiz(struct brw_context *brw,
       OUT_BATCH(_3DSTATE_CLEAR_PARAMS << 16 |
 		GEN5_DEPTH_CLEAR_VALID |
 		(2 - 2));
-      OUT_BATCH(depth_mt ? depth_mt->depth_clear_value : 0);
+      if (depth_mt) {
+         OUT_BATCH(brw_convert_depth_value(depth_mt->format,
+                                           depth_mt->fast_clear_color.f32[0]));
+      } else {
+         OUT_BATCH(0);
+      }
       ADVANCE_BATCH();
    }
 }
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 954969c..51296c8 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -133,6 +133,9 @@ void brw_upload_invariant_state(struct brw_context *brw);
 uint32_t
 brw_depthbuffer_format(struct brw_context *brw);
 
+uint32_t
+brw_convert_depth_value(mesa_format format, float value);
+
 void brw_upload_state_base_address(struct brw_context *brw);
 
 /* gen8_depth_state.c */
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 f37dd93..d2af38b 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -153,7 +153,7 @@ brw_emit_surface_state(struct brw_context *brw,
       /* We only really need a clear color if we also have an auxiliary
        * surface.  Without one, it does nothing.
        */
-      clear_color = intel_miptree_get_isl_clear_color(brw, mt);
+      clear_color = mt->fast_clear_color;
    }
 
    void *state = brw_state_batch(brw,
diff --git a/src/mesa/drivers/dri/i965/gen6_depth_state.c b/src/mesa/drivers/dri/i965/gen6_depth_state.c
index 0ff2407..ae4f681 100644
--- a/src/mesa/drivers/dri/i965/gen6_depth_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_depth_state.c
@@ -234,6 +234,11 @@ gen6_emit_depth_stencil_hiz(struct brw_context *brw,
    OUT_BATCH(_3DSTATE_CLEAR_PARAMS << 16 |
              GEN5_DEPTH_CLEAR_VALID |
              (2 - 2));
-   OUT_BATCH(depth_mt ? depth_mt->depth_clear_value : 0);
+   if (depth_mt) {
+      OUT_BATCH(brw_convert_depth_value(depth_mt->format,
+                                        depth_mt->fast_clear_color.f32[0]));
+   } else {
+      OUT_BATCH(0);
+   }
    ADVANCE_BATCH();
 }
diff --git a/src/mesa/drivers/dri/i965/gen7_misc_state.c b/src/mesa/drivers/dri/i965/gen7_misc_state.c
index af9be66..16b08ed 100644
--- a/src/mesa/drivers/dri/i965/gen7_misc_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_misc_state.c
@@ -192,7 +192,12 @@ gen7_emit_depth_stencil_hiz(struct brw_context *brw,
 
    BEGIN_BATCH(3);
    OUT_BATCH(GEN7_3DSTATE_CLEAR_PARAMS << 16 | (3 - 2));
-   OUT_BATCH(depth_mt ? depth_mt->depth_clear_value : 0);
+   if (depth_mt) {
+      OUT_BATCH(brw_convert_depth_value(depth_mt->format,
+                                        depth_mt->fast_clear_color.f32[0]));
+   } else {
+      OUT_BATCH(0);
+   }
    OUT_BATCH(1);
    ADVANCE_BATCH();
 
diff --git a/src/mesa/drivers/dri/i965/gen8_depth_state.c b/src/mesa/drivers/dri/i965/gen8_depth_state.c
index 2a19b79..0fafd7c 100644
--- a/src/mesa/drivers/dri/i965/gen8_depth_state.c
+++ b/src/mesa/drivers/dri/i965/gen8_depth_state.c
@@ -136,7 +136,7 @@ emit_depth_packets(struct brw_context *brw,
 
    BEGIN_BATCH(3);
    OUT_BATCH(GEN7_3DSTATE_CLEAR_PARAMS << 16 | (3 - 2));
-   OUT_BATCH(depth_mt ? depth_mt->depth_clear_value : 0);
+   OUT_BATCH(depth_mt ? depth_mt->fast_clear_color.u32[0] : 0);
    OUT_BATCH(1);
    ADVANCE_BATCH();
 
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
index 6acf48e..2701201 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -3409,34 +3409,3 @@ intel_miptree_get_aux_isl_surf(struct brw_context *brw,
    surf->array_pitch_el_rows =
       aux_qpitch / isl_format_get_layout(surf->format)->bh;
 }
-
-union isl_color_value
-intel_miptree_get_isl_clear_color(struct brw_context *brw,
-                                  const struct intel_mipmap_tree *mt)
-{
-   union isl_color_value clear_color;
-
-   if (_mesa_get_format_base_format(mt->format) == GL_DEPTH_COMPONENT) {
-      clear_color.i32[0] = mt->depth_clear_value;
-      clear_color.i32[1] = 0;
-      clear_color.i32[2] = 0;
-      clear_color.i32[3] = 0;
-   } else if (brw->gen >= 9) {
-      clear_color.i32[0] = mt->gen9_fast_clear_color.i[0];
-      clear_color.i32[1] = mt->gen9_fast_clear_color.i[1];
-      clear_color.i32[2] = mt->gen9_fast_clear_color.i[2];
-      clear_color.i32[3] = mt->gen9_fast_clear_color.i[3];
-   } else if (_mesa_is_format_integer(mt->format)) {
-      clear_color.i32[0] = (mt->fast_clear_color_value & (1u << 31)) != 0;
-      clear_color.i32[1] = (mt->fast_clear_color_value & (1u << 30)) != 0;
-      clear_color.i32[2] = (mt->fast_clear_color_value & (1u << 29)) != 0;
-      clear_color.i32[3] = (mt->fast_clear_color_value & (1u << 28)) != 0;
-   } else {
-      clear_color.f32[0] = (mt->fast_clear_color_value & (1u << 31)) != 0;
-      clear_color.f32[1] = (mt->fast_clear_color_value & (1u << 30)) != 0;
-      clear_color.f32[2] = (mt->fast_clear_color_value & (1u << 29)) != 0;
-      clear_color.f32[3] = (mt->fast_clear_color_value & (1u << 28)) != 0;
-   }
-
-   return clear_color;
-}
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
index 7aabac0..8c82094 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
@@ -516,15 +516,6 @@ struct intel_mipmap_tree
    GLuint total_width;
    GLuint total_height;
 
-   /**
-    * The depth value used during the most recent fast depth clear performed
-    * on the surface. This field is invalid only if surface has never
-    * underwent a fast depth clear.
-    *
-    * @see 3DSTATE_CLEAR_PARAMS.DepthClearValue
-    */
-   uint32_t depth_clear_value;
-
    /* Includes image offset tables: */
    struct intel_mipmap_level level[MAX_TEXTURE_LEVELS];
 
@@ -610,25 +601,10 @@ struct intel_mipmap_tree
    struct intel_mipmap_tree *plane[2];
 
    /**
-    * The SURFACE_STATE bits associated with the last fast color clear to this
-    * color mipmap tree, if any.
-    *
-    * Prior to GEN9 there is a single bit for RGBA clear values which gives you
-    * the option of 2^4 clear colors. Each bit determines if the color channel
-    * is fully saturated or unsaturated (Cherryview does add a 32b value per
-    * channel, but it is globally applied instead of being part of the render
-    * surface state). Starting with GEN9, the surface state accepts a 32b value
-    * for each color channel.
-    *
-    * @see RENDER_SURFACE_STATE.RedClearColor
-    * @see RENDER_SURFACE_STATE.GreenClearColor
-    * @see RENDER_SURFACE_STATE.BlueClearColor
-    * @see RENDER_SURFACE_STATE.AlphaClearColor
+    * Fast clear color for this surface.  For depth surfaces, the clear value
+    * is stored as a float32 in the red component.
     */
-   union {
-      uint32_t fast_clear_color_value;
-      union gl_color_union gen9_fast_clear_color;
-   };
+   union isl_color_value fast_clear_color;
 
    /**
     * Disable allocation of auxiliary buffers, such as the HiZ buffer and MCS
@@ -784,10 +760,6 @@ intel_miptree_get_aux_isl_surf(struct brw_context *brw,
                                struct isl_surf *surf,
                                enum isl_aux_usage *usage);
 
-union isl_color_value
-intel_miptree_get_isl_clear_color(struct brw_context *brw,
-                                  const struct intel_mipmap_tree *mt);
-
 void
 intel_get_image_dims(struct gl_texture_image *image,
                      int *width, int *height, int *depth);
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list