[Intel-gfx] [PATCH] Reduce incidence of MI_FLUSH usage.

Keith Packard keithp at keithp.com
Sun Oct 19 23:20:20 CEST 2008


This tracks whether the last command in each batch is an MI_FLUSH command
and avoids appending another MI_FLUSH in the non-GEM cases.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 src/i830_accel.c       |    5 ++---
 src/i830_batchbuffer.c |   16 ++++++++++++++--
 src/i830_batchbuffer.h |    8 ++++----
 src/i830_driver.c      |    6 +++++-
 src/i830_exa.c         |   14 +++++++-------
 5 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/src/i830_accel.c b/src/i830_accel.c
index a9b3005..9087690 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -192,7 +192,7 @@ I830Sync(ScrnInfoPtr pScrn)
 
    I830EmitFlush(pScrn);
 
-   intel_batch_flush(pScrn);
+   intel_batch_flush(pScrn, TRUE);
 
    if (pI830->directRenderingEnabled) {
        struct drm_i915_irq_emit emit;
@@ -237,9 +237,8 @@ I830EmitFlush(ScrnInfoPtr pScrn)
       flags = 0;
 
    {
-       BEGIN_BATCH(2);
+       BEGIN_BATCH(1);
        OUT_BATCH(MI_FLUSH | flags);
-       OUT_BATCH(MI_NOOP);		/* pad to quadword */
        ADVANCE_BATCH();
    }
 }
diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c
index cd8f687..a770616 100644
--- a/src/i830_batchbuffer.c
+++ b/src/i830_batchbuffer.c
@@ -156,7 +156,7 @@ intel_batch_teardown(ScrnInfoPtr pScrn)
 }
 
 void
-intel_batch_flush(ScrnInfoPtr pScrn)
+intel_batch_flush(ScrnInfoPtr pScrn, Bool flushed)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     int ret;
@@ -164,6 +164,17 @@ intel_batch_flush(ScrnInfoPtr pScrn)
     if (pI830->batch_used == 0)
 	return;
 
+    /* If we're not using GEM, then emit a flush after each batch buffer */
+    if (pI830->memory_manager == NULL && !flushed) {
+	int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
+
+	if (IS_I965G(pI830))
+	    flags = 0;
+
+	*(uint32_t *)(pI830->batch_ptr + pI830->batch_used) = MI_FLUSH | flags;
+	pI830->batch_used += 4;
+    }
+	
     /* Emit a padding dword if we aren't going to be quad-word aligned. */
     if ((pI830->batch_used & 4) == 0) {
 	*(uint32_t *)(pI830->batch_ptr + pI830->batch_used) = MI_NOOP;
@@ -188,5 +199,6 @@ intel_batch_flush(ScrnInfoPtr pScrn)
      * blockhandler.  We could set this less often, but it's probably not worth
      * the work.
      */
-    pI830->need_mi_flush = TRUE;
+    if (pI830->memory_manager != NULL)
+	pI830->need_mi_flush = TRUE;
 }
diff --git a/src/i830_batchbuffer.h b/src/i830_batchbuffer.h
index 3c7a69b..0511493 100644
--- a/src/i830_batchbuffer.h
+++ b/src/i830_batchbuffer.h
@@ -34,7 +34,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 void intel_batch_init(ScrnInfoPtr pScrn);
 void intel_batch_teardown(ScrnInfoPtr pScrn);
-void intel_batch_flush(ScrnInfoPtr pScrn);
+void intel_batch_flush(ScrnInfoPtr pScrn, Bool flushed);
 
 static inline int
 intel_batch_space(I830Ptr pI830)
@@ -47,7 +47,7 @@ intel_batch_require_space(ScrnInfoPtr pScrn, I830Ptr pI830, GLuint sz)
 {
     assert(sz < pI830->batch_bo->size - 8);
     if (intel_batch_space(pI830) < sz)
-	intel_batch_flush(pScrn);
+	intel_batch_flush(pScrn, FALSE);
 }
 
 static inline void
@@ -119,8 +119,8 @@ do {									\
     if (pI830->batch_emitting != 0)					\
 	FatalError("%s: BEGIN_BATCH called without closing "		\
 		   "ADVANCE_BATCH\n", __FUNCTION__);			\
+    intel_batch_require_space(pScrn, pI830, (n) * 4);			\
     pI830->batch_emitting = (n) * 4;					\
-    intel_batch_require_space(pScrn, pI830, pI830->batch_emitting);	\
     pI830->batch_emit_start = pI830->batch_used;			\
 } while (0)
 
@@ -140,7 +140,7 @@ do {									\
 		   pI830->batch_emitting);				\
     if ((pI830->batch_emitting > 8) && (I810_DEBUG & DEBUG_ALWAYS_SYNC)) { \
 	/* Note: not actually syncing, just flushing each batch. */	\
-	intel_batch_flush(pScrn);					\
+	intel_batch_flush(pScrn, FALSE);					\
     }									\
     pI830->batch_emitting = 0;						\
 } while (0)
diff --git a/src/i830_driver.c b/src/i830_driver.c
index eaf5d27..c18b116 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2674,17 +2674,21 @@ I830BlockHandler(int i,
     pScreen->BlockHandler = I830BlockHandler;
 
     if (pScrn->vtSema && pI830->accel != ACCEL_NONE) {
+       Bool flushed = FALSE;
        /* Emit a flush of the rendering cache, or on the 965 and beyond
 	* rendering results may not hit the framebuffer until significantly
 	* later.
 	*/
        if (pI830->accel != ACCEL_NONE && (pI830->need_mi_flush || pI830->batch_used))
+       {
+	  flushed = TRUE;
 	  I830EmitFlush(pScrn);
+       }
 
        /* Flush the batch, so that any rendering is executed in a timely
 	* fashion.
 	*/
-       intel_batch_flush(pScrn);
+       intel_batch_flush(pScrn, flushed);
 #ifdef XF86DRI
        if (pI830->memory_manager)
 	 drmCommandNone(pI830->drmSubFD, DRM_I915_GEM_THROTTLE);
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 8623159..e1cf24e 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -248,11 +248,11 @@ I830EXASolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
 static void
 I830EXADoneSolid(PixmapPtr pPixmap)
 {
-#if ALWAYS_SYNC || ALWAYS_FLUSH || 1
+#if ALWAYS_SYNC || ALWAYS_FLUSH
     ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
 
-#if ALWAYS_FLUSH || 1
-    intel_batch_flush(pScrn);
+#if ALWAYS_FLUSH
+    intel_batch_flush(pScrn, FALSE);
 #endif
 #if ALWAYS_SYNC
     I830Sync(pScrn);
@@ -353,7 +353,7 @@ I830EXADoneCopy(PixmapPtr pDstPixmap)
     ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
 
 #if ALWAYS_FLUSH
-    intel_batch_flush(pScrn);
+    intel_batch_flush(pScrn, FALSE);
 #endif
 #if ALWAYS_SYNC
     I830Sync(pScrn);
@@ -374,7 +374,7 @@ i830_done_composite(PixmapPtr pDst)
     ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
 
 #if ALWAYS_FLUSH
-    intel_batch_flush(pScrn);
+    intel_batch_flush(pScrn, FALSE);
 #endif
 #if ALWAYS_SYNC
     I830Sync(pScrn);
@@ -530,7 +530,7 @@ static Bool I830EXAPrepareAccess(PixmapPtr pPix, int index)
 	return TRUE;
     }
 
-    intel_batch_flush(scrn);
+    intel_batch_flush(scrn, FALSE);
     if (i830->need_sync) {
 	I830Sync(scrn);
 	i830->need_sync = FALSE;
@@ -771,7 +771,7 @@ i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access)
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 	I830Ptr i830 = I830PTR(scrn);
 	
-	intel_batch_flush(scrn);
+	intel_batch_flush(scrn, FALSE);
 	if (i830->need_sync) {
 	    I830Sync(scrn);
 	    i830->need_sync = FALSE;
-- 
1.5.6.5




More information about the Intel-gfx mailing list