[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