Mesa (gallium-0.2): i915: fix crash in flush_prim -> wait_flips -> flush_batch -> flush_prim.

Keith Whitwell keithw at kemper.freedesktop.org
Tue Sep 23 22:53:38 UTC 2008


Module: Mesa
Branch: gallium-0.2
Commit: b9532f078a2fbf459b0403b6f656711f80ff83c2
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=b9532f078a2fbf459b0403b6f656711f80ff83c2

Author: Eric Anholt <eric at anholt.net>
Date:   Sat Sep 20 18:07:17 2008 -0700

i915: fix crash in flush_prim -> wait_flips -> flush_batch -> flush_prim.

---

 src/mesa/drivers/dri/i915/intel_tris.c |   35 ++++++++++++++++---------------
 1 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c
index 723cc70..0621003 100644
--- a/src/mesa/drivers/dri/i915/intel_tris.c
+++ b/src/mesa/drivers/dri/i915/intel_tris.c
@@ -109,6 +109,7 @@ void intel_flush_prim(struct intel_context *intel)
    BATCH_LOCALS;
    dri_bo *aper_array[2];
    dri_bo *vb_bo;
+   unsigned int offset, count;
 
    /* Must be called after an intel_start_prim. */
    assert(intel->prim.primitive != ~0);
@@ -116,11 +117,19 @@ void intel_flush_prim(struct intel_context *intel)
    if (intel->prim.count == 0)
       return;
 
-   /* Keep a reference on the BO as it may get finished as we start the
-    * batch emit.
+   /* Clear the current prims out of the context state so that a batch flush
+    * flush triggered by wait_flips or emit_state doesn't loop back to
+    * flush_prim again.
     */
    vb_bo = intel->prim.vb_bo;
    dri_bo_reference(vb_bo);
+   count = intel->prim.count;
+   intel->prim.count = 0;
+   offset = intel->prim.start_offset;
+   intel->prim.start_offset = intel->prim.current_offset;
+   if (!IS_9XX(intel->intelScreen->deviceID))
+      intel->prim.start_offset = ALIGN(intel->prim.start_offset, 128);
+   intel->prim.flush = NULL;
 
    intel_wait_flips(intel);
 
@@ -145,7 +154,7 @@ void intel_flush_prim(struct intel_context *intel)
    assert((intel->batch->dirty_state & (1<<1)) == 0);
 
 #if 0
-   printf("emitting %d..%d=%d vertices size %d\n", intel->prim.start_offset,
+   printf("emitting %d..%d=%d vertices size %d\n", offset,
 	  intel->prim.current_offset, intel->prim.count,
 	  intel->vertex_size * 4);
 #endif
@@ -154,9 +163,8 @@ void intel_flush_prim(struct intel_context *intel)
       BEGIN_BATCH(5, LOOP_CLIPRECTS);
       OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
 		I1_LOAD_S(0) | I1_LOAD_S(1) | 1);
-      assert((intel->prim.start_offset & !S0_VB_OFFSET_MASK) == 0);
-      OUT_RELOC(vb_bo, I915_GEM_DOMAIN_VERTEX, 0,
-		intel->prim.start_offset);
+      assert((offset & !S0_VB_OFFSET_MASK) == 0);
+      OUT_RELOC(vb_bo, I915_GEM_DOMAIN_VERTEX, 0, offset);
       OUT_BATCH((intel->vertex_size << S1_VERTEX_WIDTH_SHIFT) |
 		(intel->vertex_size << S1_VERTEX_PITCH_SHIFT));
 
@@ -164,7 +172,7 @@ void intel_flush_prim(struct intel_context *intel)
 		PRIM_INDIRECT |
 		PRIM_INDIRECT_SEQUENTIAL |
 		intel->prim.primitive |
-		intel->prim.count);
+		count);
       OUT_BATCH(0); /* Beginning vertex index */
       ADVANCE_BATCH();
    } else {
@@ -174,10 +182,9 @@ void intel_flush_prim(struct intel_context *intel)
       OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
 		I1_LOAD_S(0) | I1_LOAD_S(2) | 1);
       /* S0 */
-      assert((intel->prim.start_offset & !S0_VB_OFFSET_MASK_830) == 0);
+      assert((offset & !S0_VB_OFFSET_MASK_830) == 0);
       OUT_RELOC(vb_bo, I915_GEM_DOMAIN_VERTEX, 0,
-		intel->prim.start_offset |
-		(intel->vertex_size << S0_VB_PITCH_SHIFT_830) |
+		offset | (intel->vertex_size << S0_VB_PITCH_SHIFT_830) |
 		S0_VB_ENABLE_830);
       /* S1
        * This is somewhat unfortunate -- VB width is tied up with
@@ -194,19 +201,13 @@ void intel_flush_prim(struct intel_context *intel)
 		PRIM_INDIRECT |
 		PRIM_INDIRECT_SEQUENTIAL |
 		intel->prim.primitive |
-		intel->prim.count);
+		count);
       OUT_BATCH(0); /* Beginning vertex index */
       ADVANCE_BATCH();
    }
 
    intel->no_batch_wrap = GL_FALSE;
 
-   intel->prim.flush = NULL;
-   intel->prim.start_offset = intel->prim.current_offset;
-   if (!IS_9XX(intel->intelScreen->deviceID))
-      intel->prim.start_offset = ALIGN(intel->prim.start_offset, 128);
-   intel->prim.count = 0;
-
    dri_bo_unreference(vb_bo);
 }
 




More information about the mesa-commit mailing list