Mesa (master): ilo: add slice clear value

Chia-I Wu olv at kemper.freedesktop.org
Sat Feb 22 14:48:33 UTC 2014


Module: Mesa
Branch: master
Commit: f57bddc7e431e553e946563d1030e5f239911c8b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=f57bddc7e431e553e946563d1030e5f239911c8b

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Thu Feb 20 14:37:23 2014 +0800

ilo: add slice clear value

It is needed for 3DSTATE_CLEAR_PARAMS, and can also be used to track what
value the slice has been cleared to.

---

 src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c |   11 ++++++---
 src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c |   10 +++++---
 src/gallium/drivers/ilo/ilo_blit.c             |   31 ++++++++++++++++++++++++
 src/gallium/drivers/ilo/ilo_blitter_rectlist.c |    3 +++
 src/gallium/drivers/ilo/ilo_resource.h         |   30 ++++++++++++++++++++++-
 5 files changed, 78 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
index 59623bc..e5ae4f1 100644
--- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
+++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
@@ -725,10 +725,14 @@ gen6_pipeline_wm_depth(struct ilo_3d_pipeline *p,
    if (DIRTY(FB) || session->batch_bo_changed) {
       const struct ilo_zs_surface *zs;
       struct ilo_zs_surface layer;
+      uint32_t clear_params;
 
       if (ilo->fb.state.zsbuf) {
          const struct ilo_surface_cso *surface =
             (const struct ilo_surface_cso *) ilo->fb.state.zsbuf;
+         const struct ilo_texture_slice *slice =
+            ilo_texture_get_slice(ilo_texture(surface->base.texture),
+                  surface->base.u.tex.level, surface->base.u.tex.first_layer);
 
          if (ilo->fb.offset_to_layers) {
             assert(surface->base.u.tex.first_layer ==
@@ -745,9 +749,12 @@ gen6_pipeline_wm_depth(struct ilo_3d_pipeline *p,
             assert(!surface->is_rt);
             zs = &surface->u.zs;
          }
+
+         clear_params = slice->clear_value;
       }
       else {
          zs = &ilo->fb.null_zs;
+         clear_params = 0;
       }
 
       if (p->dev->gen == ILO_GEN(6)) {
@@ -758,9 +765,7 @@ gen6_pipeline_wm_depth(struct ilo_3d_pipeline *p,
       gen6_emit_3DSTATE_DEPTH_BUFFER(p->dev, zs, p->cp);
       gen6_emit_3DSTATE_HIER_DEPTH_BUFFER(p->dev, zs, p->cp);
       gen6_emit_3DSTATE_STENCIL_BUFFER(p->dev, zs, p->cp);
-
-      /* TODO */
-      gen6_emit_3DSTATE_CLEAR_PARAMS(p->dev, 0, p->cp);
+      gen6_emit_3DSTATE_CLEAR_PARAMS(p->dev, clear_params, p->cp);
    }
 }
 
diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
index a1c8519..4263882 100644
--- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
+++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
@@ -545,24 +545,28 @@ gen7_pipeline_wm(struct ilo_3d_pipeline *p,
    /* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */
    if (DIRTY(FB) || session->batch_bo_changed) {
       const struct ilo_zs_surface *zs;
+      uint32_t clear_params;
 
       if (ilo->fb.state.zsbuf) {
          const struct ilo_surface_cso *surface =
             (const struct ilo_surface_cso *) ilo->fb.state.zsbuf;
+         const struct ilo_texture_slice *slice =
+            ilo_texture_get_slice(ilo_texture(surface->base.texture),
+                  surface->base.u.tex.level, surface->base.u.tex.first_layer);
 
          assert(!surface->is_rt);
          zs = &surface->u.zs;
+         clear_params = slice->clear_value;
       }
       else {
          zs = &ilo->fb.null_zs;
+         clear_params = 0;
       }
 
       gen6_emit_3DSTATE_DEPTH_BUFFER(p->dev, zs, p->cp);
       gen6_emit_3DSTATE_HIER_DEPTH_BUFFER(p->dev, zs, p->cp);
       gen6_emit_3DSTATE_STENCIL_BUFFER(p->dev, zs, p->cp);
-
-      /* TODO */
-      gen7_emit_3DSTATE_CLEAR_PARAMS(p->dev, 0, p->cp);
+      gen7_emit_3DSTATE_CLEAR_PARAMS(p->dev, clear_params, p->cp);
    }
 }
 
diff --git a/src/gallium/drivers/ilo/ilo_blit.c b/src/gallium/drivers/ilo/ilo_blit.c
index 74bb355..ad304c7 100644
--- a/src/gallium/drivers/ilo/ilo_blit.c
+++ b/src/gallium/drivers/ilo/ilo_blit.c
@@ -163,10 +163,26 @@ ilo_blit_resolve_slices_for_hiz(struct ilo_context *ilo,
        * When ILO_TEXTURE_RENDER_WRITE is set, there can be no reader.  We
        * need to perform a HiZ Buffer Resolve in case the resource was
        * previously written by another writer, unless this is a clear.
+       *
+       * When slices have different clear values, we perform a Depth Buffer
+       * Resolve on all slices not sharing the clear value of the first slice.
+       * After resolving, those slices do not use 3DSTATE_CLEAR_PARAMS and can
+       * be made to have the same clear value as the first slice does.  This
+       * way,
+       *
+       *  - 3DSTATE_CLEAR_PARAMS can be set to the clear value of any slice
+       *  - we will not resolve unnecessarily next time this function is
+       *    called
+       *
+       * Since slice clear value is the value the slice is cleared to when
+       * ILO_TEXTURE_CLEAR is set, the bit needs to be unset.
        */
       assert(!(resolve_flags & (other_writers | any_reader)));
 
       if (!(resolve_flags & ILO_TEXTURE_CLEAR)) {
+         bool set_clear_value = false;
+         uint32_t first_clear_value;
+
          for (i = 0; i < num_slices; i++) {
             const struct ilo_texture_slice *slice =
                ilo_texture_get_slice(tex, level, first_slice + i);
@@ -175,6 +191,21 @@ ilo_blit_resolve_slices_for_hiz(struct ilo_context *ilo,
                ilo_blitter_rectlist_resolve_hiz(ilo->blitter,
                      res, level, first_slice + i);
             }
+            else if (i == 0) {
+               first_clear_value = slice->clear_value;
+            }
+            else if (slice->clear_value != first_clear_value &&
+                     (slice->flags & ILO_TEXTURE_RENDER_WRITE)) {
+               ilo_blitter_rectlist_resolve_z(ilo->blitter,
+                     res, level, first_slice + i);
+               set_clear_value = true;
+            }
+         }
+
+         if (set_clear_value) {
+            /* ILO_TEXTURE_CLEAR will be cleared later */
+            ilo_texture_set_slice_clear_value(tex, level,
+                  first_slice, num_slices, first_clear_value);
          }
       }
    }
diff --git a/src/gallium/drivers/ilo/ilo_blitter_rectlist.c b/src/gallium/drivers/ilo/ilo_blitter_rectlist.c
index 472ab6a..534764f 100644
--- a/src/gallium/drivers/ilo/ilo_blitter_rectlist.c
+++ b/src/gallium/drivers/ilo/ilo_blitter_rectlist.c
@@ -472,6 +472,8 @@ ilo_blitter_rectlist_resolve_z(struct ilo_blitter *blitter,
 {
    struct ilo_texture *tex = ilo_texture(res);
    struct pipe_depth_stencil_alpha_state dsa_state;
+   const struct ilo_texture_slice *s =
+      ilo_texture_get_slice(tex, level, slice);
 
    if (!ilo_texture_can_enable_hiz(tex, level, slice, 1))
       return;
@@ -492,6 +494,7 @@ ilo_blitter_rectlist_resolve_z(struct ilo_blitter *blitter,
    ilo_blitter_set_op(blitter, ILO_BLITTER_RECTLIST_RESOLVE_Z);
 
    ilo_blitter_set_dsa(blitter, &dsa_state);
+   ilo_blitter_set_clear_values(blitter, s->clear_value, 0);
    ilo_blitter_set_fb_from_resource(blitter, res, res->format, level, slice);
    ilo_blitter_set_uses(blitter,
          ILO_BLITTER_USE_DSA | ILO_BLITTER_USE_FB_DEPTH);
diff --git a/src/gallium/drivers/ilo/ilo_resource.h b/src/gallium/drivers/ilo/ilo_resource.h
index d7bc5f9..cba425c 100644
--- a/src/gallium/drivers/ilo/ilo_resource.h
+++ b/src/gallium/drivers/ilo/ilo_resource.h
@@ -61,7 +61,7 @@ enum ilo_texture_flags {
     * Set when the texture is cleared.
     *
     * When set in resolve flags, the new writer will clear.  When set in slice
-    * flags, the slice has been cleared.
+    * flags, the slice has been cleared to ilo_texture_slice::clear_value.
     */
    ILO_TEXTURE_CLEAR          = 1 << 6,
 
@@ -91,6 +91,18 @@ struct ilo_texture_slice {
    /* 2D offset to the slice */
    unsigned x, y;
    unsigned flags;
+
+   /*
+    * Slice clear value.  It is served for two purposes
+    *
+    *  - the clear value used in commands such as 3DSTATE_CLEAR_PARAMS
+    *  - the clear value when ILO_TEXTURE_CLEAR is set
+    *
+    * Since commands such as 3DSTATE_CLEAR_PARAMS expect a single clear value
+    * for all slices, ilo_blit_resolve_slices() will silently make all slices
+    * to have the same clear value.
+    */
+   uint32_t clear_value;
 };
 
 struct ilo_texture {
@@ -189,6 +201,22 @@ ilo_texture_set_slice_flags(struct ilo_texture *tex, unsigned level,
    }
 }
 
+static inline void
+ilo_texture_set_slice_clear_value(struct ilo_texture *tex, unsigned level,
+                                  unsigned first_slice, unsigned num_slices,
+                                  uint32_t clear_value)
+{
+   const struct ilo_texture_slice *last =
+      ilo_texture_get_slice(tex, level, first_slice + num_slices - 1);
+   struct ilo_texture_slice *slice =
+      ilo_texture_get_slice(tex, level, first_slice);
+
+   while (slice <= last) {
+      slice->clear_value = clear_value;
+      slice++;
+   }
+}
+
 static inline bool
 ilo_texture_can_enable_hiz(const struct ilo_texture *tex, unsigned level,
                            unsigned first_slice, unsigned num_slices)




More information about the mesa-commit mailing list