From db43b7870a37ea273941302096a6f00120dfae71 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 15 Jan 2009 19:05:52 -0800 Subject: 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. --- src/i830.h | 16 ++++++++++ src/i830_batchbuffer.h | 22 ++++++++++++++ src/i830_driver.c | 2 ++ src/i830_exa.c | 4 +-- src/i915_render.c | 81 +++++++++++++++++++++++++++++++++++++++++--------- 5 files changed, 109 insertions(+), 16 deletions(-) diff --git a/src/i830.h b/src/i830.h index 25bf4823..fcf88843 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 05114936..a72786e5 100644 --- a/src/i830_batchbuffer.h +++ b/src/i830_batchbuffer.h @@ -50,6 +50,28 @@ intel_batch_require_space(ScrnInfoPtr pScrn, I830Ptr pI830, GLuint sz) intel_batch_flush(pScrn, FALSE); } +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) { diff --git a/src/i830_driver.c b/src/i830_driver.c index 1ddea002..411d79c5 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 df48dbf4..92490741 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 ab288e1c..8a2bc635 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; } -- cgit v1.2.3