Use batch_start_atomic to fix batchbuffer wrapping problems with 8xx render.

Bug #22483.
This commit is contained in:
Eric Anholt 2009-07-15 14:15:10 -07:00
parent e386e7b14b
commit a1e6abb5ca
3 changed files with 122 additions and 88 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;
}