xf86-video-intel: 2 commits - src/i830_batchbuffer.c src/i830_batchbuffer.h src/i830_driver.c src/i830_exa.c src/i830.h src/i915_render.c

Eric Anholt anholt at kemper.freedesktop.org
Fri Jan 16 17:57:33 PST 2009


 src/i830.h             |   16 +++++++++
 src/i830_batchbuffer.c |    6 +++
 src/i830_batchbuffer.h |   22 +++++++++++++
 src/i830_driver.c      |    2 +
 src/i830_exa.c         |    4 +-
 src/i915_render.c      |   81 ++++++++++++++++++++++++++++++++++++++++---------
 6 files changed, 115 insertions(+), 16 deletions(-)

New commits:
commit db43b7870a37ea273941302096a6f00120dfae71
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jan 15 19:05:52 2009 -0800

    Re-emit i915 composite setup when the batchbuffer wraps.
    
    This also introduces tests to make sure that we asked for enough reserved space
    and that we don't allow wrapping at the wrong time.
    
    This fixes a hang during text rendering with DRI2 and a GL client running,
    but could potentially affect text rendering with GEM in general with an
    exceptional batchbuffer setup.

diff --git a/src/i830.h b/src/i830.h
index 25bf482..fcf8884 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -442,6 +442,10 @@ typedef struct _I830Rec {
    /** Number of bytes to be emitted in the current BEGIN_BATCH. */
    uint32_t batch_emitting;
    dri_bo *batch_bo;
+   /** Whether we're in a section of code that can't tolerate flushing */
+   Bool in_batch_atomic;
+   /** Ending batch_used that was verified by i830_start_batch_atomic() */
+   int batch_atomic_limit;
 
 #ifdef I830_XV
    /* For Xvideo */
@@ -591,6 +595,15 @@ typedef struct _I830Rec {
    uint32_t mapstate[6];
    uint32_t samplerstate[6];
 
+   struct {
+      int op;
+      PicturePtr pSrcPicture, pMaskPicture, pDstPicture;
+      PixmapPtr pSrc, pMask, pDst;
+      uint32_t dst_format;
+      Bool is_nearest;
+      Bool needs_emit;
+   } i915_render_state;
+
    /* 965 render acceleration state */
    struct gen4_render_state *gen4_render_state;
 
@@ -940,6 +953,9 @@ Bool i915_check_composite(int op, PicturePtr pSrc, PicturePtr pMask,
 Bool i915_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMask,
 			    PicturePtr pDst, PixmapPtr pSrcPixmap,
 			    PixmapPtr pMaskPixmap, PixmapPtr pDstPixmap);
+void i915_composite(PixmapPtr pDst, int srcX, int srcY,
+		    int maskX, int maskY, int dstX, int dstY, int w, int h);
+void i915_batch_flush_notify(ScrnInfoPtr pScrn);
 /* i965_render.c */
 unsigned int gen4_render_state_size(ScrnInfoPtr pScrn);
 void gen4_render_state_init(ScrnInfoPtr pScrn);
diff --git a/src/i830_batchbuffer.h b/src/i830_batchbuffer.h
index 0511493..a72786e 100644
--- a/src/i830_batchbuffer.h
+++ b/src/i830_batchbuffer.h
@@ -51,6 +51,28 @@ intel_batch_require_space(ScrnInfoPtr pScrn, I830Ptr pI830, GLuint sz)
 }
 
 static inline void
+intel_batch_start_atomic(ScrnInfoPtr pScrn, unsigned int sz)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    assert(!pI830->in_batch_atomic);
+    intel_batch_require_space(pScrn, pI830, sz);
+
+    pI830->in_batch_atomic = TRUE;
+    pI830->batch_atomic_limit = pI830->batch_used + sz * 4;
+}
+
+static inline void
+intel_batch_end_atomic(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    assert(pI830->in_batch_atomic);
+    assert(pI830->batch_used <= pI830->batch_atomic_limit);
+    pI830->in_batch_atomic = FALSE;
+}
+
+static inline void
 intel_batch_emit_dword(I830Ptr pI830, uint32_t dword)
 {
     assert(pI830->batch_ptr != NULL);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 1ddea00..411d79c 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3406,6 +3406,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 
    if (IS_I965G(pI830))
        pI830->batch_flush_notify = i965_batch_flush_notify;
+   else if (IS_I9XX(pI830))
+       pI830->batch_flush_notify = i915_batch_flush_notify;
    else
        pI830->batch_flush_notify = NULL;
 
diff --git a/src/i830_exa.c b/src/i830_exa.c
index df48dbf..9249074 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -702,7 +702,7 @@ I830EXAInit(ScreenPtr pScreen)
     {
 	pI830->EXADriverPtr->CheckComposite = i915_check_composite;
    	pI830->EXADriverPtr->PrepareComposite = i915_prepare_composite;
-    	pI830->EXADriverPtr->Composite = i830_composite;
+	pI830->EXADriverPtr->Composite = i915_composite;
     	pI830->EXADriverPtr->DoneComposite = i830_done_composite;
     } else {
  	pI830->EXADriverPtr->CheckComposite = i965_check_composite;
@@ -967,7 +967,7 @@ i830_uxa_init (ScreenPtr pScreen)
     {
 	i830->uxa_driver->check_composite = i915_check_composite;
    	i830->uxa_driver->prepare_composite = i915_prepare_composite;
-    	i830->uxa_driver->composite = i830_composite;
+	i830->uxa_driver->composite = i915_composite;
     	i830->uxa_driver->done_composite = i830_done_composite;
     } else {
  	i830->uxa_driver->check_composite = i965_check_composite;
diff --git a/src/i915_render.c b/src/i915_render.c
index ab288e1..8a2bc63 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -315,39 +315,69 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
 {
     ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
-    uint32_t dst_format, dst_pitch;
-    uint32_t blendctl;
-    int out_reg = FS_OC;
-    FS_LOCALS(20);
-    Bool is_affine_src, is_affine_mask;
-    Bool is_nearest = FALSE;
 
     i830_exa_check_pitch_3d(pSrc);
     if (pMask)
 	i830_exa_check_pitch_3d(pMask);
     i830_exa_check_pitch_3d(pDst);
 
-    IntelEmitInvarientState(pScrn);
-    *pI830->last_3d = LAST_3D_RENDER;
-
-    if (!i915_get_dest_format(pDstPicture, &dst_format))
+    if (!i915_get_dest_format(pDstPicture,
+			      &pI830->i915_render_state.dst_format))
 	return FALSE;
-    dst_pitch = intel_get_pixmap_pitch(pDst);
 
+    pI830->i915_render_state.is_nearest = FALSE;
     if (!i915_texture_setup(pSrcPicture, pSrc, 0))
 	I830FALLBACK("fail to setup src texture\n");
     if (pSrcPicture->filter == PictFilterNearest)
-	is_nearest = TRUE;
+	pI830->i915_render_state.is_nearest = TRUE;
     if (pMask != NULL) {
 	if (!i915_texture_setup(pMaskPicture, pMask, 1))
 	    I830FALLBACK("fail to setup mask texture\n");
 	if (pMaskPicture->filter == PictFilterNearest)
-	    is_nearest = TRUE;
+	    pI830->i915_render_state.is_nearest = TRUE;
     } else {
 	pI830->transform[1] = NULL;
 	pI830->scale_units[1][0] = -1;
 	pI830->scale_units[1][1] = -1;
     }
+
+    pI830->i915_render_state.op = op;
+    pI830->i915_render_state.pSrcPicture = pSrcPicture;
+    pI830->i915_render_state.pMaskPicture = pMaskPicture;
+    pI830->i915_render_state.pDstPicture = pDstPicture;
+    pI830->i915_render_state.pSrc = pSrc;
+    pI830->i915_render_state.pMask = pMask;
+    pI830->i915_render_state.pDst = pDst;
+    pI830->i915_render_state.needs_emit = TRUE;
+
+    return TRUE;
+}
+
+static void
+i915_emit_composite_setup(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    int op = pI830->i915_render_state.op;
+    PicturePtr pSrcPicture = pI830->i915_render_state.pSrcPicture;
+    PicturePtr pMaskPicture = pI830->i915_render_state.pMaskPicture;
+    PicturePtr pDstPicture = pI830->i915_render_state.pDstPicture;
+    PixmapPtr pSrc = pI830->i915_render_state.pSrc;
+    PixmapPtr pMask = pI830->i915_render_state.pMask;
+    PixmapPtr pDst = pI830->i915_render_state.pDst;
+    uint32_t dst_format = pI830->i915_render_state.dst_format, dst_pitch;
+    uint32_t blendctl;
+    int out_reg = FS_OC;
+    FS_LOCALS(20);
+    Bool is_affine_src, is_affine_mask;
+    Bool is_nearest = pI830->i915_render_state.is_nearest;
+
+    pI830->i915_render_state.needs_emit = FALSE;
+
+    IntelEmitInvarientState(pScrn);
+    *pI830->last_3d = LAST_3D_RENDER;
+
+    dst_pitch = intel_get_pixmap_pitch(pDst);
+
     is_affine_src = i830_transform_is_affine (pI830->transform[0]);
     is_affine_mask = i830_transform_is_affine (pI830->transform[1]);
 
@@ -503,6 +533,29 @@ i915_prepare_composite(int op, PicturePtr pSrcPicture,
 	i915_fs_mov(FS_OC, i915_fs_operand(out_reg, W, W, W, W));
 
     FS_END();
+}
 
-    return TRUE;
+void
+i915_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
+	       int dstX, int dstY, int w, int h)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    intel_batch_start_atomic(pScrn, 100);
+
+    if (pI830->i915_render_state.needs_emit)
+	i915_emit_composite_setup(pScrn);
+
+    i830_composite(pDst, srcX, srcY, maskX, maskY, dstX, dstY, w, h);
+
+    intel_batch_end_atomic(pScrn);
+}
+
+void
+i915_batch_flush_notify(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    pI830->i915_render_state.needs_emit = TRUE;
 }
commit cab5b7a7b0e17414f98b2363b0961c87f32f9c05
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jan 15 09:31:55 2009 -0800

    Fix invarient state emits for DRI2 (do it per batch, since there's no lock).

diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c
index b1c8a8d..220dda7 100644
--- a/src/i830_batchbuffer.c
+++ b/src/i830_batchbuffer.c
@@ -117,6 +117,12 @@ intel_next_batch(ScrnInfoPtr pScrn)
 
     pI830->batch_used = 0;
     pI830->batch_ptr = pI830->batch_bo->virtual;
+
+    /* If we are using DRI2, we don't know when another client has executed,
+     * so we have to reinitialize our 3D state per batch.
+     */
+    if (pI830->directRenderingType == DRI2)
+	*pI830->last_3d = LAST_3D_OTHER;
 }
 
 void


More information about the xorg-commit mailing list