[Mesa-dev] [PATCH 02/16] i965/gen6+: Implement end-of-pipe sync

Topi Pohjolainen topi.pohjolainen at gmail.com
Fri Feb 17 19:32:05 UTC 2017


Implementation for gen < 6 is taken as copy-paste from
brw_emit_mi_flush() in order to preserve the behavior in later
patches.

Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 src/mesa/drivers/dri/i965/brw_context.h      |  1 +
 src/mesa/drivers/dri/i965/brw_pipe_control.c | 91 ++++++++++++++++++++++++++++
 2 files changed, 92 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 01e651b..34aea56 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -1704,6 +1704,7 @@ void brw_emit_pipe_control_write(struct brw_context *brw, uint32_t flags,
                                  uint32_t imm_lower, uint32_t imm_upper);
 void brw_emit_mi_flush(struct brw_context *brw);
 void brw_emit_post_sync_nonzero_flush(struct brw_context *brw);
+void brw_end_of_pipe_sync(struct brw_context *brw);
 void brw_emit_depth_stall_flushes(struct brw_context *brw);
 void gen7_emit_vs_workaround_flush(struct brw_context *brw);
 void gen7_emit_cs_stall_flush(struct brw_context *brw);
diff --git a/src/mesa/drivers/dri/i965/brw_pipe_control.c b/src/mesa/drivers/dri/i965/brw_pipe_control.c
index b8f7406..4fbd401 100644
--- a/src/mesa/drivers/dri/i965/brw_pipe_control.c
+++ b/src/mesa/drivers/dri/i965/brw_pipe_control.c
@@ -331,6 +331,97 @@ brw_emit_post_sync_nonzero_flush(struct brw_context *brw)
                                brw->workaround_bo, 0, 0, 0);
 }
 
+/*
+ * From Sandybridge PRM, volume 2, "1.7.2 End-of-Pipe Synchronization":
+ *
+ *  Write synchronization is a special case of end-of-pipe
+ *  synchronization that requires that the render cache and/or depth
+ *  related caches are flushed to memory, where the data will become
+ *  globally visible. This type of synchronization is required prior to
+ *  SW (CPU) actually reading the result data from memory, or initiating
+ *  an operation that will use as a read surface (such as a texture
+ *  surface) a previous render target and/or depth/stencil buffer
+ *
+ *
+ * From Haswell PRM, volume 2, part 1, "End-of-Pipe Synchronization":
+ *
+ *  Exercising the write cache flush bits (Render Target Cache Flush
+ *  Enable, Depth Cache Flush Enable, DC Flush) in PIPE_CONTROL only
+ *  ensures the write caches are flushed and doesn't guarantee the data
+ *  is globally visible.
+ *
+ *  SW can track the completion of the end-of-pipe-synchronization by
+ *  using "Notify Enable" and "PostSync Operation - Write Immediate
+ *  Data" in the PIPE_CONTROL command. 
+ */
+static void
+gen6_end_of_pipe_sync(struct brw_context *brw)
+{
+   /*
+    * From Sandybridge PRM, volume 2, "1.7.3.1 Writing a Value to Memory":
+    *
+    *  The most common action to perform upon reaching a synchronization
+    *  point is to write a value out to memory. An immediate value (included
+    *  with the synchronization command) may be written. 
+    *
+    *
+    * From Broadwell PRM, volume 7, "End-of-Pipe Synchronization":
+    *
+    *  In case the data flushed out by the render engine is to be read back in
+    *  to the render engine in coherent manner, then the render engine has to
+    *  wait for the fence completion before accessing the flushed data. This
+    *  can be achieved by following means on various products:
+    *  PIPE_CONTROL command with CS Stall and the required write caches
+    *  flushed with Post-Sync-Operation as Write Immediate Data.
+    *
+    *  Example:
+    *     - Workload-1 (3D/GPGPU/MEDIA)
+    *     - PIPE_CONTROL (CS Stall, Post-Sync-Operation Write Immediate Data,
+    *       Required Write Cache Flush bits set)
+    *     - Workload-2 (Can use the data produce or output by Workload-1)
+    */
+   brw_emit_pipe_control_write(brw,
+                               PIPE_CONTROL_CS_STALL |
+                               PIPE_CONTROL_DATA_CACHE_FLUSH |
+                               PIPE_CONTROL_DEPTH_CACHE_FLUSH |
+                               PIPE_CONTROL_RENDER_TARGET_FLUSH |
+                               PIPE_CONTROL_WRITE_IMMEDIATE,
+                               brw->workaround_bo, 0, 0, 0);
+
+   if (!brw->is_haswell)
+      return;
+
+   /*
+    * Haswell needs additionally:
+    *
+    * From Haswell PRM, volume 2, part 1, "End-of-Pipe Synchronization":
+    *
+    *  Option 1:
+    *  PIPE_CONTROL command with the CS Stall and the required write caches
+    *  flushed with Post-SyncOperation as Write Immediate Data followed by
+    *  eight dummy MI_STORE_DATA_IMM (write to scratch spce) commands.
+    *
+    *  Example:
+    *     - Workload-1
+    *     - PIPE_CONTROL (CS Stall, Post-Sync-Operation Write Immediate Data,
+    *       Required Write Cache Flush bits set)
+    *     - MI_STORE_DATA_IMM (8 times) (Dummy data, Scratch Address)
+    *     - Workload-2 (Can use the data produce or output by Workload-1)
+    */
+   for (unsigned i = 0; i < 8; ++i) {
+      brw_store_data_imm32(brw, brw->workaround_bo, 0, 0);
+   }
+}
+
+void
+brw_end_of_pipe_sync(struct brw_context *brw)
+{
+   if (brw->gen >= 6)
+      gen6_end_of_pipe_sync(brw);
+   else
+      brw_emit_pipe_control_flush(brw, PIPE_CONTROL_RENDER_TARGET_FLUSH);
+}
+
 /* Emit a pipelined flush to either flush render and texture cache for
  * reading from a FBO-drawn texture, or flush so that frontbuffer
  * render appears on the screen in DRI1.
-- 
2.5.5



More information about the mesa-dev mailing list