[Intel-gfx] [PATCH 1/2] Try to ensure that batches emitted actually complete.

Eric Anholt eric at anholt.net
Mon Feb 20 21:10:50 CET 2012


---
 src/mesa/drivers/dri/i965/brw_state_upload.c   |    2 +
 src/mesa/drivers/dri/intel/intel_batchbuffer.c |   73 ++++++++++++++++++++++++
 src/mesa/drivers/dri/intel/intel_batchbuffer.h |    2 +
 3 files changed, 77 insertions(+), 0 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index f5e6fdc..4655e75 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -435,6 +435,8 @@ void brw_upload_state(struct brw_context *brw)
    int i;
    static int dirty_count = 0;
 
+   record_batch(intel);
+
    state->mesa |= brw->intel.NewGLState;
    brw->intel.NewGLState = 0;
 
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index d10e008..3ae2515 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -51,6 +51,13 @@ static void clear_cache( struct intel_context *intel )
    intel->batch.cached_items = NULL;
 }
 
+static struct {
+   drm_intel_bo *bo;
+   int max_batches;
+   int next_batch;
+   bool needs_record;
+} batch_watch;
+
 void
 intel_batchbuffer_init(struct intel_context *intel)
 {
@@ -65,9 +72,73 @@ intel_batchbuffer_init(struct intel_context *intel)
 						      "pipe_control workaround",
 						      4096, 4096);
    }
+
+   batch_watch.max_batches = 1000;
+   batch_watch.bo = drm_intel_bo_alloc(intel->bufmgr,
+				       "watch",
+				       batch_watch.max_batches * 8,
+				       4096);
+   batch_watch.next_batch = 0;
+
+   drm_intel_bo_map(batch_watch.bo, true);
+   memset(batch_watch.bo->virtual, 0xd0, batch_watch.bo->size);
+   drm_intel_bo_unmap(batch_watch.bo);
 }
 
 void
+record_batch(struct intel_context *intel)
+{
+   if (!batch_watch.needs_record)
+      return;
+
+   batch_watch.needs_record = false;
+
+   assert(batch_watch.next_batch < batch_watch.max_batches);
+
+   BEGIN_BATCH(4);
+   OUT_BATCH(_3DSTATE_PIPE_CONTROL);
+   OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE);
+   OUT_RELOC(batch_watch.bo,
+	     I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
+	     batch_watch.next_batch * 8);
+   OUT_BATCH(batch_watch.next_batch); /* write data */
+   ADVANCE_BATCH();
+
+   batch_watch.next_batch++;
+}
+
+static void
+check_batches(struct intel_context *intel)
+{
+   batch_watch.needs_record = true;
+
+   if (batch_watch.next_batch == batch_watch.max_batches) {
+      int i;
+      int fails = 0;
+      uint32_t *map;
+
+      drm_intel_bo_map(batch_watch.bo, true);
+      map = batch_watch.bo->virtual;
+      for (i = 0; i < batch_watch.next_batch; i ++) {
+	 if (map[i * 2] != i) {
+	    printf("batch %d didn't report: 0x%08x instead of 0x%08x\n",
+		   i, map[i * 2], i);
+
+	    if (fails++ > 10) {
+	       printf("shutting up\n");
+	       break;
+	    }
+	 }
+      }
+
+      memset(batch_watch.bo->virtual, 0xd0, batch_watch.bo->size);
+      batch_watch.next_batch = 0;
+      drm_intel_bo_unmap(batch_watch.bo);
+   }
+}
+
+
+void
 intel_batchbuffer_reset(struct intel_context *intel)
 {
    if (intel->batch.last_bo != NULL) {
@@ -248,6 +319,8 @@ _intel_batchbuffer_flush(struct intel_context *intel,
     */
    intel_batchbuffer_reset(intel);
 
+   check_batches(intel);
+
    return ret;
 }
 
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.h b/src/mesa/drivers/dri/intel/intel_batchbuffer.h
index 751ec99..c36fd0b 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.h
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.h
@@ -132,6 +132,8 @@ intel_batchbuffer_advance(struct intel_context *intel)
 
 void intel_batchbuffer_cached_advance(struct intel_context *intel);
 
+void record_batch(struct intel_context *intel);
+
 /* Here are the crusty old macros, to be removed:
  */
 #define BATCH_LOCALS
-- 
1.7.9




More information about the Intel-gfx mailing list