diff options
author | Ben Skeggs <skeggsb@gmail.com> | 2009-01-07 13:32:57 +1100 |
---|---|---|
committer | Ben Skeggs <skeggsb@gmail.com> | 2009-01-07 13:55:48 +1100 |
commit | bbb22bc420d65a367f1ee3cf87773e6b778214fb (patch) | |
tree | 52ad6090fe4693492dea78695e52d5d5b5a9ad83 | |
parent | b71b21604ce4022108621e3096f74433dcd1fcfd (diff) |
nv50/exa: make sure tesla_scratch usage is tracked
Because we were emitting this once during init, and never again, the
bufmgr thought the buffer was unused and kicked it out in low memory
situtations. This caused everything we keep there to get corrupted,
and made the engine very unhappy!
This commit causes PrepareComposite() to be repeated after a flush,
not sure how much of an impact this'll have (hopefully minimal).
After everything's working nicely this may be reworked to have a
less severe reemit.
-rw-r--r-- | src/nv50_exa.c | 51 | ||||
-rw-r--r-- | src/nv_type.h | 8 |
2 files changed, 59 insertions, 0 deletions
diff --git a/src/nv50_exa.c b/src/nv50_exa.c index 5528d7f..71ce07c 100644 --- a/src/nv50_exa.c +++ b/src/nv50_exa.c @@ -449,11 +449,21 @@ NV50EXATexture(PixmapPtr ppix, PicturePtr ppict, unsigned unit) { NV50EXA_LOCALS(ppix); struct nouveau_pixmap *tex = nouveau_pixmap(ppix); + const unsigned tic_tsc_flags = NOUVEAU_BO_RD | NOUVEAU_BO_VRAM; + const unsigned cb_flags = NOUVEAU_BO_WR | NOUVEAU_BO_VRAM; /*XXX: Scanout buffer not tiled, someone needs to figure it out */ if (!tex->bo->tiled) NOUVEAU_FALLBACK("pixmap is scanout buffer\n"); + BEGIN_RING(chan, tesla, NV50TCL_TIC_ADDRESS_HIGH, 3); + OUT_RELOCh(chan, pNv->tesla_scratch, TIC_OFFSET, tic_tsc_flags); + OUT_RELOCl(chan, pNv->tesla_scratch, TIC_OFFSET, tic_tsc_flags); + OUT_RING (chan, 0x00000800); + BEGIN_RING(chan, tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); + OUT_RELOCh(chan, pNv->tesla_scratch, TIC_OFFSET, cb_flags); + OUT_RELOCl(chan, pNv->tesla_scratch, TIC_OFFSET, cb_flags); + OUT_RING (chan, (CB_TIC << NV50TCL_CB_DEF_SET_BUFFER_SHIFT) | 0x4000); BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1); OUT_RING (chan, CB_TIC | ((unit * 8) << NV50TCL_CB_ADDR_ID_SHIFT)); BEGIN_RING(chan, tesla, NV50TCL_CB_DATA(0) | 0x40000000, 8); @@ -511,6 +521,14 @@ NV50EXATexture(PixmapPtr ppix, PicturePtr ppict, unsigned unit) OUT_RING (chan, 0x03000000); OUT_RELOCh(chan, tex->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + BEGIN_RING(chan, tesla, NV50TCL_TSC_ADDRESS_HIGH, 3); + OUT_RELOCh(chan, pNv->tesla_scratch, TSC_OFFSET, tic_tsc_flags); + OUT_RELOCl(chan, pNv->tesla_scratch, TSC_OFFSET, tic_tsc_flags); + OUT_RING (chan, 0x00000000); + BEGIN_RING(chan, tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); + OUT_RELOCh(chan, pNv->tesla_scratch, TSC_OFFSET, cb_flags); + OUT_RELOCl(chan, pNv->tesla_scratch, TSC_OFFSET, cb_flags); + OUT_RING (chan, (CB_TSC << NV50TCL_CB_DEF_SET_BUFFER_SHIFT) | 0x4000); BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1); OUT_RING (chan, CB_TSC | ((unit * 8) << NV50TCL_CB_ADDR_ID_SHIFT)); BEGIN_RING(chan, tesla, NV50TCL_CB_DATA(0) | 0x40000000, 8); @@ -645,13 +663,28 @@ NV50EXACheckComposite(int op, return TRUE; } +static void +NV50EXAState3DReEmit(struct nouveau_channel *chan) +{ + NVPtr pNv = chan->user_private; + + NV50EXAPrepareComposite(pNv->composite_op, pNv->src_picture, + pNv->mask_picture, pNv->dst_picture, + pNv->src_pixmap, pNv->mask_pixmap, + pNv->dst_pixmap); +} + Bool NV50EXAPrepareComposite(int op, PicturePtr pspict, PicturePtr pmpict, PicturePtr pdpict, PixmapPtr pspix, PixmapPtr pmpix, PixmapPtr pdpix) { NV50EXA_LOCALS(pspix); + const unsigned shd_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; + /* Make sure there's enough room for 3D state setup, and to + * at least fit one Composite() call. + */ RING_SPACE(chan, 100); BEGIN_RING(chan, eng2d, 0x0110, 1); @@ -663,6 +696,13 @@ NV50EXAPrepareComposite(int op, NV50EXABlend(pdpix, pdpict, op, pmpict && pmpict->componentAlpha && PICT_FORMAT_RGB(pmpict->format)); + BEGIN_RING(chan, tesla, NV50TCL_VP_ADDRESS_HIGH, 2); + OUT_RELOCh(chan, pNv->tesla_scratch, PVP_OFFSET, shd_flags); + OUT_RELOCl(chan, pNv->tesla_scratch, PVP_OFFSET, shd_flags); + BEGIN_RING(chan, tesla, NV50TCL_FP_ADDRESS_HIGH, 2); + OUT_RELOCh(chan, pNv->tesla_scratch, PFP_OFFSET, shd_flags); + OUT_RELOCl(chan, pNv->tesla_scratch, PFP_OFFSET, shd_flags); + if (pmpict) { if (!NV50EXATexture(pspix, pspict, 0)) NOUVEAU_FALLBACK("src picture invalid\n"); @@ -704,6 +744,14 @@ NV50EXAPrepareComposite(int op, BEGIN_RING(chan, tesla, 0x1458, 1); OUT_RING (chan, 0x203); + chan->flush_notify = NV50EXAState3DReEmit; + pNv->composite_op = op; + pNv->src_pixmap = pspix; + pNv->mask_pixmap = pmpix; + pNv->dst_pixmap = pdpix; + pNv->src_picture = pspict; + pNv->mask_picture = pmpict; + pNv->dst_picture = pdpict; return TRUE; } @@ -736,6 +784,8 @@ NV50EXAComposite(PixmapPtr pdpix, int sx, int sy, int mx, int my, float sX0, sX1, sX2, sX3, sY0, sY1, sY2, sY3; unsigned dX0 = dx, dX1 = dx + w, dY0 = dy, dY1 = dy + h; + RING_SPACE(chan, 6 + 7*4); + NV50EXATransform(state->unit[0].transform, sx, sy, state->unit[0].width, state->unit[0].height, &sX0, &sY0); @@ -788,5 +838,6 @@ NV50EXADoneComposite(PixmapPtr pdpix) { NV50EXA_LOCALS(pdpix); + chan->flush_notify = NULL; } diff --git a/src/nv_type.h b/src/nv_type.h index b642a23..0802a34 100644 --- a/src/nv_type.h +++ b/src/nv_type.h @@ -528,6 +528,14 @@ typedef struct _NVRec { struct nouveau_bo *tesla_scratch; struct nouveau_bo *shader_mem; struct nouveau_bo *xv_filtertable_mem; + + int composite_op; + PixmapPtr src_pixmap; + PixmapPtr mask_pixmap; + PixmapPtr dst_pixmap; + PicturePtr src_picture; + PicturePtr mask_picture; + PicturePtr dst_picture; } NVRec; #define NVPTR(p) ((NVPtr)((p)->driverPrivate)) |