diff options
author | Eric Anholt <eric@anholt.net> | 2009-07-15 14:15:10 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-07-15 15:11:21 -0700 |
commit | a1e6abb5ca89d699144d10fdc4309b3b78f2f7a9 (patch) | |
tree | b8586f74da6f0fde4dbeba5059e73b0a717790bb | |
parent | e386e7b14b139f15205e14b173e8222bf38d9e18 (diff) |
Use batch_start_atomic to fix batchbuffer wrapping problems with 8xx render.
Bug #22483.
-rw-r--r-- | src/i830.h | 9 | ||||
-rw-r--r-- | src/i830_driver.c | 2 | ||||
-rw-r--r-- | src/i830_render.c | 201 |
3 files changed, 123 insertions, 89 deletions
@@ -468,6 +468,14 @@ typedef struct _I830Rec { /** Transform pointers for src/mask, or NULL if identity */ PictTransform *transform[2]; float coord_adjust; + + /* i830 render accel state */ + PixmapPtr render_src, render_mask, render_dst; + PicturePtr render_src_picture, render_mask_picture, render_dst_picture; + uint32_t render_dst_format; + Bool needs_render_state_emit; + uint32_t cblend, ablend, s8_blendctl; + /* i915 render accel state */ uint32_t mapstate[6]; uint32_t samplerstate[6]; @@ -790,6 +798,7 @@ Bool i915_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMask, 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); +void i830_batch_flush_notify(ScrnInfoPtr scrn); /* i965_render.c */ unsigned int gen4_render_state_size(ScrnInfoPtr pScrn); void gen4_render_state_init(ScrnInfoPtr pScrn); diff --git a/src/i830_driver.c b/src/i830_driver.c index dfc2bdf6..33079fea 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2757,7 +2757,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) else if (IS_I9XX(pI830)) pI830->batch_flush_notify = i915_batch_flush_notify; else - pI830->batch_flush_notify = NULL; + pI830->batch_flush_notify = i830_batch_flush_notify; miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); diff --git a/src/i830_render.c b/src/i830_render.c index b1d6f508..ecee6f2a 100644 --- a/src/i830_render.c +++ b/src/i830_render.c @@ -255,7 +255,7 @@ i8xx_get_card_format(PicturePtr pPict) FatalError("Unsupported format type %d\n", pPict->format); } -static Bool +static void i830_texture_setup(PicturePtr pPict, PixmapPtr pPix, int unit) { @@ -299,7 +299,7 @@ i830_texture_setup(PicturePtr pPict, PixmapPtr pPix, int unit) break; default: filter = 0; - I830FALLBACK("Bad filter 0x%x\n", pPict->filter); + FatalError("Bad filter 0x%x\n", pPict->filter); } filter |= (MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT); @@ -344,10 +344,6 @@ i830_texture_setup(PicturePtr pPict, PixmapPtr pPix, int unit) TEX_STREAM_MAP_IDX(unit)); ADVANCE_BATCH(); } - - i830_debug_sync(pScrn); - - return TRUE; } Bool @@ -391,29 +387,27 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture, { ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); - uint32_t dst_format, dst_pitch; Bool is_affine_src, is_affine_mask; Bool is_nearest = FALSE; + pI830->render_src_picture = pSrcPicture; + pI830->render_src = pSrc; + pI830->render_mask_picture = pMaskPicture; + pI830->render_mask = pMask; + pI830->render_dst_picture = pDstPicture; + pI830->render_dst = pDst; + 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 (!i830_get_dest_format(pDstPicture, &dst_format)) + if (!i830_get_dest_format(pDstPicture, &pI830->render_dst_format)) return FALSE; - dst_pitch = intel_get_pixmap_pitch(pDst); - if (!i830_texture_setup(pSrcPicture, pSrc, 0)) - I830FALLBACK("fail to setup src texture\n"); if (pSrcPicture->filter == PictFilterNearest) is_nearest = TRUE; if (pMask != NULL) { - if (!i830_texture_setup(pMaskPicture, pMask, 1)) - I830FALLBACK("fail to setup mask texture\n"); if (pMaskPicture->filter == PictFilterNearest) is_nearest = TRUE; } else { @@ -434,45 +428,7 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture, I830FALLBACK("non-affine transform unsupported on 8xx hardware\n"); { - uint32_t cblend, ablend, blendctl, vf2; - - BEGIN_BATCH(30); - - /* color buffer */ - OUT_BATCH(_3DSTATE_BUF_INFO_CMD); - OUT_BATCH(BUF_3D_ID_COLOR_BACK| BUF_3D_USE_FENCE | - BUF_3D_PITCH(dst_pitch)); - OUT_RELOC_PIXMAP(pDst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); - OUT_BATCH(MI_NOOP); - - OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); - OUT_BATCH(dst_format); - - /* defaults */ - OUT_BATCH(_3DSTATE_DFLT_Z_CMD); - OUT_BATCH(0); - - OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); - OUT_BATCH(0); - - OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD); - OUT_BATCH(0); - - OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); - OUT_BATCH(0); - OUT_BATCH(0); /* ymin, xmin */ - OUT_BATCH(DRAW_YMAX(pDst->drawable.height - 1) | - DRAW_XMAX(pDst->drawable.width - 1)); - OUT_BATCH(0); /* yorig, xorig */ - - OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | - I1_LOAD_S(3) | 1); - if (pMask) - vf2 = 2 << 12; /* 2 texture coord sets */ - else - vf2 = 1 << 12; - OUT_BATCH(vf2); /* TEXCOORDFMT_2D */ - OUT_BATCH(S3_CULLMODE_NONE | S3_VERTEXHAS_XY); + uint32_t cblend, ablend, blendctl; /* If component alpha is active in the mask and the blend operation * uses the source alpha, then we know we don't need the source @@ -541,36 +497,90 @@ i830_prepare_composite(int op, PicturePtr pSrcPicture, ablend |= TB0A_ARG2_SEL_ONE; } - OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | - LOAD_TEXTURE_BLEND_STAGE(0)|1); - OUT_BATCH(cblend); - OUT_BATCH(ablend); - OUT_BATCH(0); - blendctl = i830_get_blend_cntl(op, pMaskPicture, pDstPicture->format); - OUT_BATCH(_3DSTATE_INDPT_ALPHA_BLEND_CMD | DISABLE_INDPT_ALPHA_BLEND); - OUT_BATCH(MI_NOOP); - OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(8) | 0); - OUT_BATCH(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD | blendctl | - S8_ENABLE_COLOR_BUFFER_WRITE); - - OUT_BATCH(_3DSTATE_ENABLES_1_CMD | DISABLE_LOGIC_OP | - DISABLE_STENCIL_TEST | DISABLE_DEPTH_BIAS | - DISABLE_SPEC_ADD | DISABLE_FOG | DISABLE_ALPHA_TEST | - ENABLE_COLOR_BLEND | DISABLE_DEPTH_TEST); - /* We have to explicitly say we don't want write disabled */ - OUT_BATCH(_3DSTATE_ENABLES_2_CMD | ENABLE_COLOR_MASK | - DISABLE_STENCIL_WRITE | ENABLE_TEX_CACHE | - DISABLE_DITHER | ENABLE_COLOR_WRITE | - DISABLE_DEPTH_WRITE); - ADVANCE_BATCH(); + + pI830->cblend = cblend; + pI830->ablend = ablend; + pI830->s8_blendctl = blendctl; } i830_debug_sync(pScrn); + pI830->needs_render_state_emit = TRUE; + return TRUE; } +static void +i830_emit_composite_state(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + uint32_t vf2; + + pI830->needs_render_state_emit = FALSE; + + IntelEmitInvarientState(pScrn); + pI830->last_3d = LAST_3D_RENDER; + + BEGIN_BATCH(24); + + OUT_BATCH(_3DSTATE_BUF_INFO_CMD); + OUT_BATCH(BUF_3D_ID_COLOR_BACK| BUF_3D_USE_FENCE | + BUF_3D_PITCH(intel_get_pixmap_pitch(pI830->render_dst))); + OUT_RELOC_PIXMAP(pI830->render_dst, + I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); + OUT_BATCH(MI_NOOP); + + OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); + OUT_BATCH(pI830->render_dst_format); + + OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); + OUT_BATCH(0); + OUT_BATCH(0); /* ymin, xmin */ + OUT_BATCH(DRAW_YMAX(pI830->render_dst->drawable.height - 1) | + DRAW_XMAX(pI830->render_dst->drawable.width - 1)); + OUT_BATCH(0); /* yorig, xorig */ + + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | + I1_LOAD_S(2) | + I1_LOAD_S(3) | 1); + if (pI830->render_mask) + vf2 = 2 << 12; /* 2 texture coord sets */ + else + vf2 = 1 << 12; + OUT_BATCH(vf2); /* TEXCOORDFMT_2D */ + OUT_BATCH(S3_CULLMODE_NONE | S3_VERTEXHAS_XY); + + OUT_BATCH(_3DSTATE_INDPT_ALPHA_BLEND_CMD | DISABLE_INDPT_ALPHA_BLEND); + OUT_BATCH(MI_NOOP); + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(8) | 0); + OUT_BATCH(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD | pI830->s8_blendctl | + S8_ENABLE_COLOR_BUFFER_WRITE); + + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | + LOAD_TEXTURE_BLEND_STAGE(0)|1); + OUT_BATCH(pI830->cblend); + OUT_BATCH(pI830->ablend); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_ENABLES_1_CMD | DISABLE_LOGIC_OP | + DISABLE_STENCIL_TEST | DISABLE_DEPTH_BIAS | + DISABLE_SPEC_ADD | DISABLE_FOG | DISABLE_ALPHA_TEST | + ENABLE_COLOR_BLEND | DISABLE_DEPTH_TEST); + /* We have to explicitly say we don't want write disabled */ + OUT_BATCH(_3DSTATE_ENABLES_2_CMD | ENABLE_COLOR_MASK | + DISABLE_STENCIL_WRITE | ENABLE_TEX_CACHE | + DISABLE_DITHER | ENABLE_COLOR_WRITE | + DISABLE_DEPTH_WRITE); + ADVANCE_BATCH(); + + i830_texture_setup(pI830->render_src_picture, pI830->render_src, 0); + if (pI830->render_mask) { + i830_texture_setup(pI830->render_mask_picture, + pI830->render_mask, 1); + } +} + /** * Do a single rectangle composite operation. * @@ -582,7 +592,6 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, { ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); - Bool has_mask; Bool is_affine_src, is_affine_mask; int per_vertex, num_floats; float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3]; @@ -590,12 +599,6 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, is_affine_src = i830_transform_is_affine (pI830->transform[0]); is_affine_mask = i830_transform_is_affine (pI830->transform[1]); - if (pI830->scale_units[1][0] == -1 || pI830->scale_units[1][1] == -1) { - has_mask = FALSE; - } else { - has_mask = TRUE; - } - per_vertex = 2; /* dest x/y */ if (is_affine_src) { @@ -630,7 +633,7 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, return; per_vertex += 4; /* src x/y/z/w */ } - if (has_mask) { + if (pI830->render_mask) { if (is_affine_mask) { if (!i830_get_transformed_coordinates(maskX, maskY, pI830->transform[1], @@ -666,6 +669,16 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, } num_floats = 3 * per_vertex; + + intel_batch_start_atomic(pScrn, + 58 + /* invarient */ + 24 + /* setup */ + 20 + /* 2 * setup_texture */ + 6 + num_floats /* verts */); + + if (pI830->needs_render_state_emit) + i830_emit_composite_state(pScrn); + BEGIN_BATCH(6 + num_floats); OUT_BATCH(MI_NOOP); @@ -683,7 +696,7 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, OUT_BATCH_F(0.0); OUT_BATCH_F(src_w[2]); } - if (has_mask) { + if (pI830->render_mask) { OUT_BATCH_F(mask_x[2] / pI830->scale_units[1][0]); OUT_BATCH_F(mask_y[2] / pI830->scale_units[1][1]); if (!is_affine_mask) { @@ -700,7 +713,7 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, OUT_BATCH_F(0.0); OUT_BATCH_F(src_w[1]); } - if (has_mask) { + if (pI830->render_mask) { OUT_BATCH_F(mask_x[1] / pI830->scale_units[1][0]); OUT_BATCH_F(mask_y[1] / pI830->scale_units[1][1]); if (!is_affine_mask) { @@ -717,7 +730,7 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, OUT_BATCH_F(0.0); OUT_BATCH_F(src_w[0]); } - if (has_mask) { + if (pI830->render_mask) { OUT_BATCH_F(mask_x[0] / pI830->scale_units[1][0]); OUT_BATCH_F(mask_y[0] / pI830->scale_units[1][1]); if (!is_affine_mask) { @@ -727,4 +740,16 @@ i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, } ADVANCE_BATCH(); + + intel_batch_end_atomic(pScrn); + + i830_debug_sync(pScrn); +} + +void +i830_batch_flush_notify(ScrnInfoPtr scrn) +{ + I830Ptr i830 = I830PTR(scrn); + + i830->needs_render_state_emit = TRUE; } |