diff options
author | Michel Dänzer <michel.daenzer@amd.com> | 2011-10-25 17:43:58 +0200 |
---|---|---|
committer | Michel Dänzer <michel@daenzer.net> | 2011-10-27 19:30:28 +0200 |
commit | a3bb07efb1757c33d70e2e1928219d12a4dd6498 (patch) | |
tree | bd0aa32e5025effe734c5c341aa95f26a76b3656 | |
parent | 23788c4a5e3b6affb9b183e1393edd0e5ca4550e (diff) |
EXA >= R6xx / KMS: Avoid running out of CS space at inconvenient times.
Otherwise we may end up with things not properly set up at the beginning of the
next CS.
Fixes http://bugs.debian.org/645007 .
In contrast to the Composite code for < R6xx, this isn't necessary with UMS,
as the draw packet only uses constant space in the indirect buffer, and nothing
else can mess with the 3D state between indirect buffers.
Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | src/evergreen_exa.c | 147 | ||||
-rw-r--r-- | src/r600_exa.c | 164 | ||||
-rw-r--r-- | src/radeon.h | 3 |
3 files changed, 206 insertions, 108 deletions
diff --git a/src/evergreen_exa.c b/src/evergreen_exa.c index 306e90fe..6becbb32 100644 --- a/src/evergreen_exa.c +++ b/src/evergreen_exa.c @@ -55,9 +55,6 @@ extern int cayman_xv_ps(RADEONChipFamily ChipSet, uint32_t* shader); extern int cayman_comp_vs(RADEONChipFamily ChipSet, uint32_t* vs); extern int cayman_comp_ps(RADEONChipFamily ChipSet, uint32_t* ps); -static void -EVERGREENDoneSolid(PixmapPtr pPix); - static Bool EVERGREENPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) { @@ -205,9 +202,27 @@ EVERGREENPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) if (accel_state->vsync) RADEONVlineHelperClear(pScrn); + accel_state->dst_pix = pPix; + accel_state->fg = fg; + return TRUE; } +static void +EVERGREENDoneSolid(PixmapPtr pPix) +{ + ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + struct radeon_accel_state *accel_state = info->accel_state; + + if (accel_state->vsync) + evergreen_cp_wait_vline_sync(pScrn, pPix, + accel_state->vline_crtc, + accel_state->vline_y1, + accel_state->vline_y2); + + evergreen_finish_op(pScrn, 8); +} static void EVERGREENSolid(PixmapPtr pPix, int x1, int y1, int x2, int y2) @@ -217,6 +232,15 @@ EVERGREENSolid(PixmapPtr pPix, int x1, int y1, int x2, int y2) struct radeon_accel_state *accel_state = info->accel_state; float *vb; + if (CS_FULL(info->cs)) { + EVERGREENDoneSolid(info->accel_state->dst_pix); + radeon_cs_flush_indirect(pScrn); + EVERGREENPrepareSolid(accel_state->dst_pix, + accel_state->rop, + accel_state->planemask, + accel_state->fg); + } + if (accel_state->vsync) RADEONVlineHelperSet(pScrn, x1, y1, x2, y2); @@ -235,22 +259,6 @@ EVERGREENSolid(PixmapPtr pPix, int x1, int y1, int x2, int y2) } static void -EVERGREENDoneSolid(PixmapPtr pPix) -{ - ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum]; - RADEONInfoPtr info = RADEONPTR(pScrn); - struct radeon_accel_state *accel_state = info->accel_state; - - if (accel_state->vsync) - evergreen_cp_wait_vline_sync(pScrn, pPix, - accel_state->vline_crtc, - accel_state->vline_y1, - accel_state->vline_y2); - - evergreen_finish_op(pScrn, 8); -} - -static void EVERGREENDoPrepareCopy(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -510,10 +518,30 @@ EVERGREENPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, if (accel_state->vsync) RADEONVlineHelperClear(pScrn); + accel_state->dst_pix = pDst; + accel_state->src_pix = pSrc; + accel_state->xdir = xdir; + accel_state->ydir = ydir; + return TRUE; } static void +EVERGREENDoneCopy(PixmapPtr pDst) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + struct radeon_accel_state *accel_state = info->accel_state; + + if (!accel_state->same_surface) + EVERGREENDoCopyVline(pDst); + + if (accel_state->copy_area) + accel_state->copy_area = NULL; + +} + +static void EVERGREENCopy(PixmapPtr pDst, int srcX, int srcY, int dstX, int dstY, @@ -526,6 +554,17 @@ EVERGREENCopy(PixmapPtr pDst, if (accel_state->same_surface && (srcX == dstX) && (srcY == dstY)) return; + if (CS_FULL(info->cs)) { + EVERGREENDoneCopy(info->accel_state->dst_pix); + radeon_cs_flush_indirect(pScrn); + EVERGREENPrepareCopy(accel_state->src_pix, + accel_state->dst_pix, + accel_state->xdir, + accel_state->ydir, + accel_state->rop, + accel_state->planemask); + } + if (accel_state->vsync) RADEONVlineHelperSet(pScrn, dstX, dstY, dstX + w, dstY + h); @@ -568,21 +607,6 @@ EVERGREENCopy(PixmapPtr pDst, } -static void -EVERGREENDoneCopy(PixmapPtr pDst) -{ - ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; - RADEONInfoPtr info = RADEONPTR(pScrn); - struct radeon_accel_state *accel_state = info->accel_state; - - if (!accel_state->same_surface) - EVERGREENDoCopyVline(pDst); - - if (accel_state->copy_area) - accel_state->copy_area = NULL; - -} - struct blendinfo { Bool dst_alpha; Bool src_alpha; @@ -1306,9 +1330,34 @@ static Bool EVERGREENPrepareComposite(int op, PicturePtr pSrcPicture, if (accel_state->vsync) RADEONVlineHelperClear(pScrn); + accel_state->composite_op = op; + accel_state->dst_pic = pDstPicture; + accel_state->src_pic = pSrcPicture; + accel_state->dst_pix = pDst; + accel_state->msk_pix = pMask; + accel_state->src_pix = pSrc; + return TRUE; } +static void EVERGREENDoneComposite(PixmapPtr pDst) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + struct radeon_accel_state *accel_state = info->accel_state; + int vtx_size; + + if (accel_state->vsync) + evergreen_cp_wait_vline_sync(pScrn, pDst, + accel_state->vline_crtc, + accel_state->vline_y1, + accel_state->vline_y2); + + vtx_size = accel_state->msk_pic ? 24 : 16; + + evergreen_finish_op(pScrn, vtx_size); +} + static void EVERGREENComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, @@ -1320,6 +1369,18 @@ static void EVERGREENComposite(PixmapPtr pDst, struct radeon_accel_state *accel_state = info->accel_state; float *vb; + if (CS_FULL(info->cs)) { + EVERGREENDoneComposite(info->accel_state->dst_pix); + radeon_cs_flush_indirect(pScrn); + EVERGREENPrepareComposite(info->accel_state->composite_op, + info->accel_state->src_pic, + info->accel_state->msk_pic, + info->accel_state->dst_pic, + info->accel_state->src_pix, + info->accel_state->msk_pix, + info->accel_state->dst_pix); + } + if (accel_state->vsync) RADEONVlineHelperSet(pScrn, dstX, dstY, dstX + w, dstY + h); @@ -1375,24 +1436,6 @@ static void EVERGREENComposite(PixmapPtr pDst, } -static void EVERGREENDoneComposite(PixmapPtr pDst) -{ - ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; - RADEONInfoPtr info = RADEONPTR(pScrn); - struct radeon_accel_state *accel_state = info->accel_state; - int vtx_size; - - if (accel_state->vsync) - evergreen_cp_wait_vline_sync(pScrn, pDst, - accel_state->vline_crtc, - accel_state->vline_y1, - accel_state->vline_y2); - - vtx_size = accel_state->msk_pic ? 24 : 16; - - evergreen_finish_op(pScrn, vtx_size); -} - static Bool EVERGREENUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch) diff --git a/src/r600_exa.c b/src/r600_exa.c index 26735995..71e1393f 100644 --- a/src/r600_exa.c +++ b/src/r600_exa.c @@ -132,6 +132,11 @@ R600SetAccelState(ScrnInfoPtr pScrn, accel_state->dst_size = 0; } +#ifdef XF86DRM_MODE + if (info->cs && CS_FULL(info->cs)) + radeon_cs_flush_indirect(pScrn); +#endif + accel_state->rop = rop; accel_state->planemask = planemask; @@ -170,9 +175,6 @@ R600SetAccelState(ScrnInfoPtr pScrn, return TRUE; } -static void -R600DoneSolid(PixmapPtr pPix); - static Bool R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) { @@ -318,9 +320,27 @@ R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) if (accel_state->vsync) RADEONVlineHelperClear(pScrn); + accel_state->dst_pix = pPix; + accel_state->fg = fg; + return TRUE; } +static void +R600DoneSolid(PixmapPtr pPix) +{ + ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + struct radeon_accel_state *accel_state = info->accel_state; + + if (accel_state->vsync) + r600_cp_wait_vline_sync(pScrn, accel_state->ib, pPix, + accel_state->vline_crtc, + accel_state->vline_y1, + accel_state->vline_y2); + + r600_finish_op(pScrn, 8); +} static void R600Solid(PixmapPtr pPix, int x1, int y1, int x2, int y2) @@ -330,6 +350,17 @@ R600Solid(PixmapPtr pPix, int x1, int y1, int x2, int y2) struct radeon_accel_state *accel_state = info->accel_state; float *vb; +#ifdef XF86DRM_MODE + if (info->cs && CS_FULL(info->cs)) { + R600DoneSolid(info->accel_state->dst_pix); + radeon_cs_flush_indirect(pScrn); + R600PrepareSolid(accel_state->dst_pix, + accel_state->rop, + accel_state->planemask, + accel_state->fg); + } +#endif + if (accel_state->vsync) RADEONVlineHelperSet(pScrn, x1, y1, x2, y2); @@ -348,22 +379,6 @@ R600Solid(PixmapPtr pPix, int x1, int y1, int x2, int y2) } static void -R600DoneSolid(PixmapPtr pPix) -{ - ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum]; - RADEONInfoPtr info = RADEONPTR(pScrn); - struct radeon_accel_state *accel_state = info->accel_state; - - if (accel_state->vsync) - r600_cp_wait_vline_sync(pScrn, accel_state->ib, pPix, - accel_state->vline_crtc, - accel_state->vline_y1, - accel_state->vline_y2); - - r600_finish_op(pScrn, 8); -} - -static void R600DoPrepareCopy(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -653,10 +668,33 @@ R600PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, if (accel_state->vsync) RADEONVlineHelperClear(pScrn); + accel_state->dst_pix = pDst; + accel_state->src_pix = pSrc; + accel_state->xdir = xdir; + accel_state->ydir = ydir; + return TRUE; } static void +R600DoneCopy(PixmapPtr pDst) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + struct radeon_accel_state *accel_state = info->accel_state; + + if (!accel_state->same_surface) + R600DoCopyVline(pDst); + + if (accel_state->copy_area) { + if (!info->cs) + exaOffscreenFree(pDst->drawable.pScreen, accel_state->copy_area); + accel_state->copy_area = NULL; + } + +} + +static void R600Copy(PixmapPtr pDst, int srcX, int srcY, int dstX, int dstY, @@ -669,6 +707,19 @@ R600Copy(PixmapPtr pDst, if (accel_state->same_surface && (srcX == dstX) && (srcY == dstY)) return; +#ifdef XF86DRM_MODE + if (info->cs && CS_FULL(info->cs)) { + R600DoneCopy(info->accel_state->dst_pix); + radeon_cs_flush_indirect(pScrn); + R600PrepareCopy(accel_state->src_pix, + accel_state->dst_pix, + accel_state->xdir, + accel_state->ydir, + accel_state->rop, + accel_state->planemask); + } +#endif + if (accel_state->vsync) RADEONVlineHelperSet(pScrn, dstX, dstY, dstX + w, dstY + h); @@ -723,24 +774,6 @@ R600Copy(PixmapPtr pDst, } -static void -R600DoneCopy(PixmapPtr pDst) -{ - ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; - RADEONInfoPtr info = RADEONPTR(pScrn); - struct radeon_accel_state *accel_state = info->accel_state; - - if (!accel_state->same_surface) - R600DoCopyVline(pDst); - - if (accel_state->copy_area) { - if (!info->cs) - exaOffscreenFree(pDst->drawable.pScreen, accel_state->copy_area); - accel_state->copy_area = NULL; - } - -} - struct blendinfo { Bool dst_alpha; Bool src_alpha; @@ -1452,9 +1485,34 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, if (accel_state->vsync) RADEONVlineHelperClear(pScrn); + accel_state->composite_op = op; + accel_state->dst_pic = pDstPicture; + accel_state->src_pic = pSrcPicture; + accel_state->dst_pix = pDst; + accel_state->msk_pix = pMask; + accel_state->src_pix = pSrc; + return TRUE; } +static void R600DoneComposite(PixmapPtr pDst) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + struct radeon_accel_state *accel_state = info->accel_state; + int vtx_size; + + if (accel_state->vsync) + r600_cp_wait_vline_sync(pScrn, accel_state->ib, pDst, + accel_state->vline_crtc, + accel_state->vline_y1, + accel_state->vline_y2); + + vtx_size = accel_state->msk_pic ? 24 : 16; + + r600_finish_op(pScrn, vtx_size); +} + static void R600Composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, @@ -1469,6 +1527,20 @@ static void R600Composite(PixmapPtr pDst, /* ErrorF("R600Composite (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n", srcX, srcY, maskX, maskY,dstX, dstY, w, h); */ +#ifdef XF86DRM_MODE + if (info->cs && CS_FULL(info->cs)) { + R600DoneComposite(info->accel_state->dst_pix); + radeon_cs_flush_indirect(pScrn); + R600PrepareComposite(info->accel_state->composite_op, + info->accel_state->src_pic, + info->accel_state->msk_pic, + info->accel_state->dst_pic, + info->accel_state->src_pix, + info->accel_state->msk_pix, + info->accel_state->dst_pix); + } +#endif + if (accel_state->vsync) RADEONVlineHelperSet(pScrn, dstX, dstY, dstX + w, dstY + h); @@ -1524,24 +1596,6 @@ static void R600Composite(PixmapPtr pDst, } -static void R600DoneComposite(PixmapPtr pDst) -{ - ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; - RADEONInfoPtr info = RADEONPTR(pScrn); - struct radeon_accel_state *accel_state = info->accel_state; - int vtx_size; - - if (accel_state->vsync) - r600_cp_wait_vline_sync(pScrn, accel_state->ib, pDst, - accel_state->vline_crtc, - accel_state->vline_y1, - accel_state->vline_y2); - - vtx_size = accel_state->msk_pic ? 24 : 16; - - r600_finish_op(pScrn, vtx_size); -} - Bool R600CopyToVRAM(ScrnInfoPtr pScrn, char *src, int src_pitch, diff --git a/src/radeon.h b/src/radeon.h index 50ce62fc..73d6db1e 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -735,12 +735,13 @@ struct radeon_accel_state { // UTS/DFS drmBufPtr scratch; - // copy + // solid/copy ExaOffscreenArea *copy_area; struct radeon_bo *copy_area_bo; Bool same_surface; int rop; uint32_t planemask; + uint32_t fg; // composite Bool component_alpha; |