Mesa (17.0): i965/blorp: Do and end-of-pipe sync on both sides of fast-clear ops

Emil Velikov evelikov at kemper.freedesktop.org
Wed May 31 17:22:32 UTC 2017


Module: Mesa
Branch: 17.0
Commit: 6bc8491252d4f7dc3b25a2b6ed6aa46fa7929307
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=6bc8491252d4f7dc3b25a2b6ed6aa46fa7929307

Author: Jason Ekstrand <jason.ekstrand at intel.com>
Date:   Sat May 13 10:30:19 2017 -0700

i965/blorp: Do and end-of-pipe sync on both sides of fast-clear ops

We've discovered in the Vulkan driver that simply doing the end-of-pipe
sync afterwards is insufficient.  The specific requirement stated in the
PRM is that you have to do one every time you transition between the
tree modes of "clear", "render", and "resolve".  This is GL, so we could
track it but any attempt to do so would most likely get it wrong.  For
now, it's easier to just assume that every fast-clear op is an island
and do the sync both before and after.

This also removes the unneeded flush and stall after slow-clear
operations.

Reviewed-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
Cc: "17.0 17.1" <mesa-stable at lists.freedesktop.org>
(cherry picked from commit 441cd7a81d6fb90dacf8ae441b438d9fe7db19eb)

---

 src/mesa/drivers/dri/i965/brw_blorp.c | 56 ++++++++++++++++++++++++-----------
 1 file changed, 38 insertions(+), 18 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_blorp.c b/src/mesa/drivers/dri/i965/brw_blorp.c
index 3a7cf84db0..a5417e7c58 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.c
+++ b/src/mesa/drivers/dri/i965/brw_blorp.c
@@ -877,6 +877,22 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
       DBG("%s (fast) to mt %p level %d layers %d+%d\n", __FUNCTION__,
           irb->mt, irb->mt_level, irb->mt_layer, num_layers);
 
+      /* Ivybrigde PRM Vol 2, Part 1, "11.7 MCS Buffer for Render Target(s)":
+       *
+       *    "Any transition from any value in {Clear, Render, Resolve} to a
+       *    different value in {Clear, Render, Resolve} requires end of pipe
+       *    synchronization."
+       *
+       * In other words, fast clear ops are not properly synchronized with
+       * other drawing.  We need to use a PIPE_CONTROL to ensure that the
+       * contents of the previous draw hit the render target before we resolve
+       * and again afterwards to ensure that the resolve is complete before we
+       * do any more regular drawing.
+       */
+      brw_emit_pipe_control_flush(brw,
+                                  PIPE_CONTROL_RENDER_TARGET_FLUSH |
+                                  PIPE_CONTROL_CS_STALL);
+
       struct blorp_batch batch;
       blorp_batch_init(&brw->blorp, &batch, brw, 0);
       blorp_fast_clear(&batch, &surf,
@@ -885,6 +901,10 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
                        x0, y0, x1, y1);
       blorp_batch_finish(&batch);
 
+      brw_emit_pipe_control_flush(brw,
+                                  PIPE_CONTROL_RENDER_TARGET_FLUSH |
+                                  PIPE_CONTROL_CS_STALL);
+
       /* Now that the fast clear has occurred, put the buffer in
        * INTEL_FAST_CLEAR_STATE_CLEAR so that we won't waste time doing
        * redundant clears.
@@ -910,17 +930,6 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
       blorp_batch_finish(&batch);
    }
 
-   /*
-    * Ivybrigde PRM Vol 2, Part 1, "11.7 MCS Buffer for Render Target(s)":
-    *
-    *  Any transition from any value in {Clear, Render, Resolve} to a
-    *  different value in {Clear, Render, Resolve} requires end of pipe
-    *  synchronization.
-    */
-   brw_emit_pipe_control_flush(brw,
-                               PIPE_CONTROL_RENDER_TARGET_FLUSH |
-                               PIPE_CONTROL_CS_STALL);
-
    return true;
 }
 
@@ -982,6 +991,23 @@ brw_blorp_resolve_color(struct brw_context *brw, struct intel_mipmap_tree *mt,
       resolve_op = BLORP_FAST_CLEAR_OP_RESOLVE_FULL;
    }
 
+   /* Ivybrigde PRM Vol 2, Part 1, "11.7 MCS Buffer for Render Target(s)":
+    *
+    *    "Any transition from any value in {Clear, Render, Resolve} to a
+    *    different value in {Clear, Render, Resolve} requires end of pipe
+    *    synchronization."
+    *
+    * In other words, fast clear ops are not properly synchronized with
+    * other drawing.  We need to use a PIPE_CONTROL to ensure that the
+    * contents of the previous draw hit the render target before we resolve
+    * and again afterwards to ensure that the resolve is complete before we
+    * do any more regular drawing.
+    */
+   brw_emit_pipe_control_flush(brw,
+                               PIPE_CONTROL_RENDER_TARGET_FLUSH |
+                               PIPE_CONTROL_CS_STALL);
+
+
    struct blorp_batch batch;
    blorp_batch_init(&brw->blorp, &batch, brw, 0);
    blorp_ccs_resolve(&batch, &surf, level, layer,
@@ -989,13 +1015,7 @@ brw_blorp_resolve_color(struct brw_context *brw, struct intel_mipmap_tree *mt,
                      resolve_op);
    blorp_batch_finish(&batch);
 
-   /*
-    * Ivybrigde PRM Vol 2, Part 1, "11.7 MCS Buffer for Render Target(s)":
-    *
-    *  Any transition from any value in {Clear, Render, Resolve} to a
-    *  different value in {Clear, Render, Resolve} requires end of pipe
-    *  synchronization.
-    */
+   /* See comment above */
    brw_emit_pipe_control_flush(brw,
                                PIPE_CONTROL_RENDER_TARGET_FLUSH |
                                PIPE_CONTROL_CS_STALL);




More information about the mesa-commit mailing list