i965: Introduce an UNKNOWN_RING state.
authorKenneth Graunke <kenneth@whitecape.org>
Thu, 21 Nov 2013 22:07:12 +0000 (14:07 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 21 Nov 2013 23:01:13 +0000 (15:01 -0800)
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.ring (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.

v2: Catch three explicit require_space callers (thanks to Carl and Eric).
v3: Split the boolean -> enum change from the UNKNOWN_RING change.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/intel_batchbuffer.c
src/mesa/drivers/dri/i965/intel_batchbuffer.h

index 7576a22c955d8b8bb336222ab8955e382562d722..fe9e3a8fa08ae7f6031c4dc507dfea9af420a716 100644 (file)
@@ -862,6 +862,7 @@ struct intel_sync_object {
 };
 
 enum brw_gpu_ring {
+   UNKNOWN_RING,
    RENDER_RING,
    BLT_RING,
 };
index 672bc021486d3b6ce1f21e15c09852520bf94f40..d8eb3fc883797921123397f9896929e94d4ee2f6 100644 (file)
@@ -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.
@@ -429,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;
         }
 
index 40b0a296a96abec276ea3e88ee51e940d88c69ff..f7638bcb3d823d75f2b8270a7a11306ecb50f84f 100644 (file)
@@ -93,6 +93,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
@@ -106,17 +107,21 @@ intel_batchbuffer_require_space(struct brw_context *brw, GLuint sz,
                                 enum brw_gpu_ring ring)
 {
    /* If we're switching rings, implicitly flush the batch. */
-   if (unlikely(ring != brw->batch.ring) && brw->batch.used && brw->gen >= 6) {
+   if (unlikely(ring != brw->batch.ring) && brw->batch.ring != UNKNOWN_RING &&
+       brw->gen >= 6) {
       intel_batchbuffer_flush(brw);
    }
 
-   brw->batch.ring = ring;
-
 #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