i965: Create a helper function for emitting PIPE_CONTROL flushes.
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 11 Dec 2013 22:44:45 +0000 (14:44 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Mon, 20 Jan 2014 23:38:16 +0000 (15:38 -0800)
These days, we need to emit PIPE_CONTROL flushes all over the place.
Being able to do that via a single function call seems convenient.

Broadwell will also increase the length of these packets by 1; with the
refactoring, we should have to do this in substantially fewer places.

v2: Add back forgotten intel_emit_post_sync_nonzero_flush (caught by
    Eric Anholt).  Drop unlikely() from BLT_RING check.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_queryobj.c
src/mesa/drivers/dri/i965/gen6_vs_state.c
src/mesa/drivers/dri/i965/intel_batchbuffer.c
src/mesa/drivers/dri/i965/intel_batchbuffer.h

index 64c602fb53e9ca87285bd6d190802a149266a7b2..9f839379bff0703802bce0d19c5dc63db4be7980 100644 (file)
@@ -52,16 +52,9 @@ brw_write_timestamp(struct brw_context *brw, drm_intel_bo *query_bo, int idx)
    if (brw->gen >= 6) {
       /* Emit workaround flushes: */
       if (brw->gen == 6) {
-         /* The timestamp write below is a non-zero post-sync op, which on
-          * Gen6 necessitates a CS stall.  CS stalls need stall at scoreboard
-          * set.  See the comments for intel_emit_post_sync_nonzero_flush().
-          */
-         BEGIN_BATCH(4);
-         OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
-         OUT_BATCH(PIPE_CONTROL_CS_STALL | PIPE_CONTROL_STALL_AT_SCOREBOARD);
-         OUT_BATCH(0);
-         OUT_BATCH(0);
-         ADVANCE_BATCH();
+         brw_emit_pipe_control_flush(brw,
+                                     PIPE_CONTROL_CS_STALL |
+                                     PIPE_CONTROL_STALL_AT_SCOREBOARD);
       }
 
       BEGIN_BATCH(5);
index 80129cdf1687926133d83ac759cab6cc3161c02d..ac58e9759c2ce0a46c3c599dd124211d473e53fd 100644 (file)
@@ -205,15 +205,10 @@ upload_vs_state(struct brw_context *brw)
     * what is strictly required to avoid the issue.
     */
    intel_emit_post_sync_nonzero_flush(brw);
-
-   BEGIN_BATCH(4);
-   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
-   OUT_BATCH(PIPE_CONTROL_DEPTH_STALL |
-            PIPE_CONTROL_INSTRUCTION_FLUSH |
-            PIPE_CONTROL_STATE_CACHE_INVALIDATE);
-   OUT_BATCH(0); /* address */
-   OUT_BATCH(0); /* write data */
-   ADVANCE_BATCH();
+   brw_emit_pipe_control_flush(brw,
+                               PIPE_CONTROL_DEPTH_STALL |
+                               PIPE_CONTROL_INSTRUCTION_FLUSH |
+                               PIPE_CONTROL_STATE_CACHE_INVALIDATE);
 }
 
 const struct brw_tracked_state gen6_vs_state = {
index 59d03f68b29abba47fb3492029d0b1f3cea0b250..041b18dd34bb8d192633a998fa1866525f711894 100644 (file)
@@ -431,6 +431,32 @@ intel_batchbuffer_data(struct brw_context *brw,
    brw->batch.used += bytes >> 2;
 }
 
+/**
+ * Emit a PIPE_CONTROL with various flushing flags.
+ *
+ * The caller is responsible for deciding what flags are appropriate for the
+ * given generation.
+ */
+void
+brw_emit_pipe_control_flush(struct brw_context *brw, uint32_t flags)
+{
+   if (brw->gen >= 6) {
+      BEGIN_BATCH(4);
+      OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
+      OUT_BATCH(flags);
+      OUT_BATCH(0);
+      OUT_BATCH(0);
+      ADVANCE_BATCH();
+   } else {
+      BEGIN_BATCH(4);
+      OUT_BATCH(_3DSTATE_PIPE_CONTROL | flags | (4 - 2));
+      OUT_BATCH(0);
+      OUT_BATCH(0);
+      OUT_BATCH(0);
+      ADVANCE_BATCH();
+   }
+}
+
 /**
  * Restriction [DevSNB, DevIVB]:
  *
@@ -448,26 +474,9 @@ intel_emit_depth_stall_flushes(struct brw_context *brw)
 {
    assert(brw->gen >= 6 && brw->gen <= 7);
 
-   BEGIN_BATCH(4);
-   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
-   OUT_BATCH(PIPE_CONTROL_DEPTH_STALL);
-   OUT_BATCH(0); /* address */
-   OUT_BATCH(0); /* write data */
-   ADVANCE_BATCH()
-
-   BEGIN_BATCH(4);
-   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
-   OUT_BATCH(PIPE_CONTROL_DEPTH_CACHE_FLUSH);
-   OUT_BATCH(0); /* address */
-   OUT_BATCH(0); /* write data */
-   ADVANCE_BATCH();
-
-   BEGIN_BATCH(4);
-   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
-   OUT_BATCH(PIPE_CONTROL_DEPTH_STALL);
-   OUT_BATCH(0); /* address */
-   OUT_BATCH(0); /* write data */
-   ADVANCE_BATCH();
+   brw_emit_pipe_control_flush(brw, PIPE_CONTROL_DEPTH_STALL);
+   brw_emit_pipe_control_flush(brw, PIPE_CONTROL_DEPTH_CACHE_FLUSH);
+   brw_emit_pipe_control_flush(brw, PIPE_CONTROL_DEPTH_STALL);
 }
 
 /**
@@ -565,13 +574,9 @@ intel_emit_post_sync_nonzero_flush(struct brw_context *brw)
    if (!brw->batch.need_workaround_flush)
       return;
 
-   BEGIN_BATCH(4);
-   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
-   OUT_BATCH(PIPE_CONTROL_CS_STALL |
-            PIPE_CONTROL_STALL_AT_SCOREBOARD);
-   OUT_BATCH(0); /* address */
-   OUT_BATCH(0); /* write data */
-   ADVANCE_BATCH();
+   brw_emit_pipe_control_flush(brw,
+                               PIPE_CONTROL_CS_STALL |
+                               PIPE_CONTROL_STALL_AT_SCOREBOARD);
 
    BEGIN_BATCH(4);
    OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
@@ -593,46 +598,32 @@ intel_emit_post_sync_nonzero_flush(struct brw_context *brw)
 void
 intel_batchbuffer_emit_mi_flush(struct brw_context *brw)
 {
-   if (brw->gen >= 6) {
-      if (brw->batch.ring == BLT_RING) {
-        BEGIN_BATCH_BLT(4);
-        OUT_BATCH(MI_FLUSH_DW);
-        OUT_BATCH(0);
-        OUT_BATCH(0);
-        OUT_BATCH(0);
-        ADVANCE_BATCH();
-      } else {
-        if (brw->gen == 6) {
-           /* Hardware workaround: SNB B-Spec says:
-            *
-            * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache
-            * Flush Enable =1, a PIPE_CONTROL with any non-zero
-            * post-sync-op is required.
-            */
-           intel_emit_post_sync_nonzero_flush(brw);
-        }
-
-        BEGIN_BATCH(4);
-        OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
-        OUT_BATCH(PIPE_CONTROL_INSTRUCTION_FLUSH |
-                  PIPE_CONTROL_WRITE_FLUSH |
-                  PIPE_CONTROL_DEPTH_CACHE_FLUSH |
-                   PIPE_CONTROL_VF_CACHE_INVALIDATE |
-                  PIPE_CONTROL_TC_FLUSH |
-                  PIPE_CONTROL_NO_WRITE |
-                   PIPE_CONTROL_CS_STALL);
-        OUT_BATCH(0); /* write address */
-        OUT_BATCH(0); /* write data */
-        ADVANCE_BATCH();
-      }
-   } else {
-      BEGIN_BATCH(4);
-      OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2) |
-               PIPE_CONTROL_WRITE_FLUSH |
-               PIPE_CONTROL_NO_WRITE);
-      OUT_BATCH(0); /* write address */
-      OUT_BATCH(0); /* write data */
-      OUT_BATCH(0); /* write data */
+   if (brw->batch.ring == BLT_RING && brw->gen >= 6) {
+      BEGIN_BATCH_BLT(4);
+      OUT_BATCH(MI_FLUSH_DW);
+      OUT_BATCH(0);
+      OUT_BATCH(0);
+      OUT_BATCH(0);
       ADVANCE_BATCH();
+   } else {
+      int flags = PIPE_CONTROL_NO_WRITE | PIPE_CONTROL_WRITE_FLUSH;
+      if (brw->gen >= 6) {
+         flags |= PIPE_CONTROL_INSTRUCTION_FLUSH |
+                  PIPE_CONTROL_DEPTH_CACHE_FLUSH |
+                  PIPE_CONTROL_VF_CACHE_INVALIDATE |
+                  PIPE_CONTROL_TC_FLUSH |
+                  PIPE_CONTROL_CS_STALL;
+
+         if (brw->gen == 6) {
+            /* Hardware workaround: SNB B-Spec says:
+             *
+             * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache
+             * Flush Enable =1, a PIPE_CONTROL with any non-zero
+             * post-sync-op is required.
+             */
+            intel_emit_post_sync_nonzero_flush(brw);
+         }
+      }
+      brw_emit_pipe_control_flush(brw, flags);
    }
 }
index 2b2693f8ee2d9e6d24d287f383af8e0646c62cbf..5ed2089049bc83a287b73ae0830332d17013b02f 100644 (file)
@@ -64,6 +64,7 @@ bool intel_batchbuffer_emit_reloc64(struct brw_context *brw,
                                     uint32_t read_domains,
                                     uint32_t write_domain,
                                     uint32_t offset);
+void brw_emit_pipe_control_flush(struct brw_context *brw, uint32_t flags);
 void intel_batchbuffer_emit_mi_flush(struct brw_context *brw);
 void intel_emit_post_sync_nonzero_flush(struct brw_context *brw);
 void intel_emit_depth_stall_flushes(struct brw_context *brw);