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

Eric Anholt eric at anholt.net
Sun Oct 19 23:33:43 CEST 2008


On Sun, 2008-10-19 at 14:20 -0700, Keith Packard wrote:
> 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.

ACK

(looks like this patch isn't against master, though, as the ALWAYS_FLUSH
|| 1 fix was already committed in
6707371176147340fabc9ab6f1e3d6d5ac980662)

> 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;
-- 
Eric Anholt
eric at anholt.net                         eric.anholt at intel.com


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20081019/38b939dd/attachment.sig>


More information about the Intel-gfx mailing list