Mesa (master): intel: Move finish_batch() call before MI_BATCH_BUFFER_END and padding.

Kenneth Graunke kwg at kemper.freedesktop.org
Mon Aug 13 03:12:42 UTC 2012


Module: Mesa
Branch: master
Commit: 9da50667f490ba2c6240f4c91c9707e3f181adae
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9da50667f490ba2c6240f4c91c9707e3f181adae

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Fri Aug 10 10:26:03 2012 -0700

intel: Move finish_batch() call before MI_BATCH_BUFFER_END and padding.

On Gen4+, brw_finish_batch() calls brw_emit_query_end(), which emits
some extra PIPE_CONTROLs to capture the current occlusion query data.
Unfortunately, it was being called *after* _intel_batchbuffer_flush
added the MI_BATCH_BUFFER_END, meaning those PIPE_CONTROLs didn't get
inside the batch.

Not only does this likely cause bogus occlusion query values, it can
also cause crashes: with the recent change to use 64-bit depth count
writes on Gen6+, we started emitting an odd-length PIPE_CONTROL, which
happened after the MI_NOOP padding.  This resulted in an odd-length
batch buffer, which resulted in execbuf2 returning -EINVAL and the
application dying with an intel_do_flush_locked failure.

On older generations, finish_batch() doesn't emit any state, so this
change shouldn't have any effect.

Huge thanks to Chris Wilson for helping me figure this out.

NOTE: This is a candidate for stable release branches.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=53311
Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
Reviewed-by: Eric Anholt <eric at anholt.net>

---

 src/mesa/drivers/dri/intel/intel_batchbuffer.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index ac133ee..06cbaec 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -230,6 +230,9 @@ _intel_batchbuffer_flush(struct intel_context *intel,
 
    intel->batch.reserved_space = 0;
 
+   if (intel->vtbl.finish_batch)
+      intel->vtbl.finish_batch(intel);
+
    /* Mark the end of the buffer. */
    intel_batchbuffer_emit_dword(intel, MI_BATCH_BUFFER_END);
    if (intel->batch.used & 1) {
@@ -237,9 +240,6 @@ _intel_batchbuffer_flush(struct intel_context *intel,
       intel_batchbuffer_emit_dword(intel, MI_NOOP);
    }
 
-   if (intel->vtbl.finish_batch)
-      intel->vtbl.finish_batch(intel);
-
    intel_upload_finish(intel);
 
    /* Check that we didn't just wrap our batchbuffer at a bad time. */




More information about the mesa-commit mailing list