[PATCH] EXA >= R6xx / KMS: Avoid running out of CS space at inconvenient times.
Michel Dänzer
michel at daenzer.net
Thu Oct 27 10:41:29 PDT 2011
From: Michel Dänzer <michel.daenzer at amd.com>
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 at amd.com>
---
src/evergreen_exa.c | 147 +++++++++++++++++++++++++++++----------------
src/r600_exa.c | 164 ++++++++++++++++++++++++++++++++++-----------------
src/radeon.h | 3 +-
3 files changed, 206 insertions(+), 108 deletions(-)
diff --git a/src/evergreen_exa.c b/src/evergreen_exa.c
index 306e90f..6becbb3 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 2673599..71e1393 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 50ce62f..73d6db1 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;
--
1.7.7.1
More information about the xorg-driver-ati
mailing list