[Mesa-dev] [PATCH 03/27] i965: Convert brw->batch.is_blit to a tri-state "ring" enum.

Kenneth Graunke kenneth at whitecape.org
Wed Nov 13 17:52:08 PST 2013


When we first create a batch buffer, it's empty.  We don't actually
know what ring it will be targeted at until the first BEGIN_BATCH or
BEGIN_BATCH_BLT macro.

Previously, one could determine the state of the batch by checking
brw->batch.is_blit (blit vs. render) and brw->batch.used != 0 (known vs.
unknown).

This should be functionally equivalent, but the tri-state enum is a bit
clearer.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
Cc: Eric Anholt <eric at anholt.net>
Cc: Carl Worth <cworth at cworth.org>
Cc: Juha-Pekka Heikkilä <juha-pekka.heikkila at intel.com>
---
 src/mesa/drivers/dri/i965/brw_blorp.cpp       |  2 +-
 src/mesa/drivers/dri/i965/brw_context.h       |  8 +++++++-
 src/mesa/drivers/dri/i965/intel_batchbuffer.c | 23 +++++++++++++++--------
 src/mesa/drivers/dri/i965/intel_batchbuffer.h | 27 +++++++++++++++++----------
 src/mesa/drivers/dri/i965/intel_blit.c        |  2 +-
 5 files changed, 41 insertions(+), 21 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_blorp.cpp b/src/mesa/drivers/dri/i965/brw_blorp.cpp
index 4cbcebe..e555f46 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/brw_blorp.cpp
@@ -210,7 +210,7 @@ brw_blorp_exec(struct brw_context *brw, const brw_blorp_params *params)
    intel_batchbuffer_emit_mi_flush(brw);
 
 retry:
-   intel_batchbuffer_require_space(brw, estimated_max_batch_usage, false);
+   intel_batchbuffer_require_space(brw, estimated_max_batch_usage, RENDER_RING);
    intel_batchbuffer_save_state(brw);
    drm_intel_bo *saved_bo = brw->batch.bo;
    uint32_t saved_used = brw->batch.used;
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 8b1cbb3..45fe3c3 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -861,6 +861,12 @@ struct intel_sync_object {
    drm_intel_bo *bo;
 };
 
+enum brw_gpu_ring {
+   UNKNOWN_RING,
+   RENDER_RING,
+   BLT_RING,
+};
+
 struct intel_batchbuffer {
    /** Current batchbuffer being queued up. */
    drm_intel_bo *bo;
@@ -879,7 +885,7 @@ struct intel_batchbuffer {
 #define BATCH_SZ (8192*sizeof(uint32_t))
 
    uint32_t state_batch_offset;
-   bool is_blit;
+   enum brw_gpu_ring ring;
    bool needs_sol_reset;
 
    struct {
diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
index fb0b45b..ab01c02 100644
--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
@@ -100,6 +100,11 @@ intel_batchbuffer_reset(struct brw_context *brw)
    brw->batch.state_batch_offset = brw->batch.bo->size;
    brw->batch.used = 0;
    brw->batch.needs_sol_reset = false;
+
+   /* We don't know what ring the new batch will be sent to until we see the
+    * first BEGIN_BATCH or BEGIN_BATCH_BLT.  Mark it as unknown.
+    */
+   brw->batch.ring = UNKNOWN_RING;
 }
 
 void
@@ -116,6 +121,8 @@ intel_batchbuffer_reset_to_saved(struct brw_context *brw)
    drm_intel_gem_bo_clear_relocs(brw->batch.bo, brw->batch.saved.reloc_count);
 
    brw->batch.used = brw->batch.saved.used;
+   if (brw->batch.used == 0)
+      brw->batch.ring = UNKNOWN_RING;
 
    /* Cached batch state is dead, since we just cleared some unknown part of the
     * batchbuffer.  Assume that the caller resets any other state necessary.
@@ -260,19 +267,18 @@ do_flush_locked(struct brw_context *brw)
    if (!brw->intelScreen->no_hw) {
       int flags;
 
-      if (brw->gen < 6 || !batch->is_blit) {
-	 flags = I915_EXEC_RENDER;
+      if (brw->gen >= 6 && batch->ring == BLT_RING) {
+         flags = I915_EXEC_BLT;
       } else {
-	 flags = I915_EXEC_BLT;
+         flags = I915_EXEC_RENDER;
       }
-
       if (batch->needs_sol_reset)
 	 flags |= I915_EXEC_GEN7_SOL_RESET;
 
       if (ret == 0) {
          if (unlikely(INTEL_DEBUG & DEBUG_AUB))
             brw_annotate_aub(brw);
-	 if (brw->hw_ctx == NULL || batch->is_blit) {
+	 if (brw->hw_ctx == NULL || batch->ring != RENDER_RING) {
 	    ret = drm_intel_bo_mrb_exec(batch->bo, 4 * batch->used, NULL, 0, 0,
 					flags);
 	 } else {
@@ -401,10 +407,10 @@ intel_batchbuffer_emit_reloc_fenced(struct brw_context *brw,
 
 void
 intel_batchbuffer_data(struct brw_context *brw,
-                       const void *data, GLuint bytes, bool is_blit)
+                       const void *data, GLuint bytes, enum brw_gpu_ring ring)
 {
    assert((bytes & 3) == 0);
-   intel_batchbuffer_require_space(brw, bytes, is_blit);
+   intel_batchbuffer_require_space(brw, bytes, ring);
    __memcpy(brw->batch.map + brw->batch.used, data, bytes);
    brw->batch.used += bytes >> 2;
 }
@@ -430,6 +436,7 @@ intel_batchbuffer_cached_advance(struct brw_context *brw)
 	       brw->batch.cached_items = item;
 	    }
 	    brw->batch.used = brw->batch.emit;
+            assert(brw->batch.used > 0);
 	    return;
 	 }
 
@@ -583,7 +590,7 @@ void
 intel_batchbuffer_emit_mi_flush(struct brw_context *brw)
 {
    if (brw->gen >= 6) {
-      if (brw->batch.is_blit) {
+      if (brw->batch.ring == BLT_RING) {
 	 BEGIN_BATCH_BLT(4);
 	 OUT_BATCH(MI_FLUSH_DW);
 	 OUT_BATCH(0);
diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.h b/src/mesa/drivers/dri/i965/intel_batchbuffer.h
index d46f48e..170211b 100644
--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.h
+++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.h
@@ -43,7 +43,8 @@ int _intel_batchbuffer_flush(struct brw_context *brw,
  * intel_buffer_dword() calls.
  */
 void intel_batchbuffer_data(struct brw_context *brw,
-                            const void *data, GLuint bytes, bool is_blit);
+                            const void *data, GLuint bytes,
+                            enum brw_gpu_ring ring);
 
 bool intel_batchbuffer_emit_reloc(struct brw_context *brw,
                                        drm_intel_bo *buffer,
@@ -91,6 +92,7 @@ intel_batchbuffer_emit_dword(struct brw_context *brw, GLuint dword)
    assert(intel_batchbuffer_space(brw) >= 4);
 #endif
    brw->batch.map[brw->batch.used++] = dword;
+   assert(brw->batch.ring != UNKNOWN_RING);
 }
 
 static INLINE void
@@ -100,26 +102,31 @@ intel_batchbuffer_emit_float(struct brw_context *brw, float f)
 }
 
 static INLINE void
-intel_batchbuffer_require_space(struct brw_context *brw, GLuint sz, int is_blit)
+intel_batchbuffer_require_space(struct brw_context *brw, GLuint sz,
+                                enum brw_gpu_ring ring)
 {
-   if (brw->gen >= 6 &&
-       brw->batch.is_blit != is_blit && brw->batch.used) {
+   /* If we're switching rings, implicitly flush the batch. */
+   if (unlikely(ring != brw->batch.ring && brw->batch.ring != UNKNOWN_RING) &&
+       brw->gen >= 6) {
       intel_batchbuffer_flush(brw);
    }
 
-   brw->batch.is_blit = is_blit;
-
 #ifdef DEBUG
    assert(sz < BATCH_SZ - BATCH_RESERVED);
 #endif
    if (intel_batchbuffer_space(brw) < sz)
       intel_batchbuffer_flush(brw);
+
+   /* The intel_batchbuffer_flush() calls above might have changed
+    * brw->batch.ring to UNKNOWN_RING, so we need to set it here at the end.
+    */
+   brw->batch.ring = ring;
 }
 
 static INLINE void
-intel_batchbuffer_begin(struct brw_context *brw, int n, bool is_blit)
+intel_batchbuffer_begin(struct brw_context *brw, int n, enum brw_gpu_ring ring)
 {
-   intel_batchbuffer_require_space(brw, n * 4, is_blit);
+   intel_batchbuffer_require_space(brw, n * 4, ring);
 
    brw->batch.emit = brw->batch.used;
 #ifdef DEBUG
@@ -145,8 +152,8 @@ intel_batchbuffer_advance(struct brw_context *brw)
 
 void intel_batchbuffer_cached_advance(struct brw_context *brw);
 
-#define BEGIN_BATCH(n) intel_batchbuffer_begin(brw, n, false)
-#define BEGIN_BATCH_BLT(n) intel_batchbuffer_begin(brw, n, true)
+#define BEGIN_BATCH(n) intel_batchbuffer_begin(brw, n, RENDER_RING)
+#define BEGIN_BATCH_BLT(n) intel_batchbuffer_begin(brw, n, BLT_RING)
 #define OUT_BATCH(d) intel_batchbuffer_emit_dword(brw, d)
 #define OUT_BATCH_F(f) intel_batchbuffer_emit_float(brw, f)
 #define OUT_RELOC(buf, read_domains, write_domain, delta) do {		\
diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c
index 0a03859..aa64f39 100644
--- a/src/mesa/drivers/dri/i965/intel_blit.c
+++ b/src/mesa/drivers/dri/i965/intel_blit.c
@@ -461,7 +461,7 @@ intelEmitImmediateColorExpandBlit(struct brw_context *brw,
    OUT_BATCH(((y + h) << 16) | (x + w));
    ADVANCE_BATCH();
 
-   intel_batchbuffer_data(brw, src_bits, dwords * 4, true);
+   intel_batchbuffer_data(brw, src_bits, dwords * 4, BLT_RING);
 
    intel_batchbuffer_emit_mi_flush(brw);
 
-- 
1.8.3.2



More information about the mesa-dev mailing list