From: Michel Dänzer <[email protected]>

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 <[email protected]>
---
 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


_______________________________________________
xorg-driver-ati mailing list
[email protected]
http://lists.x.org/mailman/listinfo/xorg-driver-ati

Reply via email to