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 <kenn...@whitecape.org> Cc: Eric Anholt <e...@anholt.net> Cc: Carl Worth <cwo...@cworth.org> Cc: Juha-Pekka Heikkilä <juha-pekka.heikk...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev