[PATCH] EXA: add PrepareAccess() & FinishAccess() hooks

Benjamin Herrenschmidt benh at kernel.crashing.org
Sat Sep 3 02:22:30 PDT 2005


Hi !

This patch adds PrepareAccess() and FinishAccess() hooks to EXA. Those
driver hooks wrap any direct access to vram. They are necessary for big
endian architectures with swappers on vram access in order to deal with
access to pixmaps of a different bit depth than the main front buffer.
See exa.h for details.

In addition, I added the size of the offscreen pixmaps to the private
structure for use by the drivers. I yet have to add an accessor though.
This is useful for setting up the surface registers on radeon among
others. Note that I still have to verify how to constraint offscreen
pixmap allocations to a driver provided granularity as the radeon
surfaces have alignment constraints.

A very basic implementation for radeon follows with no surface control
(using the fallback to RAM).

Ben.

diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/exa/exa.c xc-HEAD/programs/Xserver/hw/xfree86/exa/exa.c
--- xc-HEAD.orig/programs/Xserver/hw/xfree86/exa/exa.c	2005-09-01 13:10:34.000000000 +1000
+++ xc-HEAD/programs/Xserver/hw/xfree86/exa/exa.c	2005-09-03 19:17:55.000000000 +1000
@@ -1,7 +1,7 @@
 /*
- * Copyright © 2001 Keith Packard
+ * Copyright © 2001 Keith Packard
  *
- * Partly based on code that is Copyright © The XFree86 Project Inc.
+ * Partly based on code that is Copyright © The XFree86 Project Inc.
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -185,6 +185,7 @@
     pitch = (w * bpp / 8) + (pExaScr->info->card.pixmapPitchAlign - 1);
     pitch -= pitch % pExaScr->info->card.pixmapPitchAlign;
 
+    pExaPixmap->size = pitch * h;
     pExaPixmap->devKind = pPixmap->devKind;
     pExaPixmap->devPrivate = pPixmap->devPrivate;
     pExaPixmap->area = exaOffscreenAlloc (pScreen, pitch * h,
@@ -439,6 +440,7 @@
 {
     PixmapPtr	pPixmap;
     STRACE;
+
     if (pDrawable->type == DRAWABLE_WINDOW)
 	pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
     else
@@ -446,6 +448,57 @@
     return exaPixmapIsOffscreen (pPixmap);
 }
 
+void
+exaPrepareAccess(DrawablePtr pDrawable, int index)
+{
+    ScreenPtr	    pScreen = pDrawable->pScreen;
+    ExaScreenPriv  (pScreen);
+    PixmapPtr	    pPixmap;
+    STRACE;
+
+    if (pDrawable->type == DRAWABLE_WINDOW)
+        pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
+    else
+        pPixmap = (PixmapPtr) pDrawable;
+
+    if (index == EXA_PREPARE_DEST)
+        exaDrawableDirty (pDrawable);
+    if (exaPixmapIsOffscreen (pPixmap))
+	exaWaitSync (pDrawable->pScreen);
+    else
+	return;
+
+    if (pExaScr->info->accel.PrepareAccess == NULL)
+        return;
+
+    if (!(*pExaScr->info->accel.PrepareAccess) (pPixmap, index)) {
+	ExaPixmapPriv (pPixmap);
+	assert (pExaPixmap->score != EXA_PIXMAP_SCORE_PINNED);
+        exaMoveOutPixmap (pPixmap);
+    }
+}
+
+Bool
+exaFinishAccess(DrawablePtr pDrawable, int index)
+{
+    ScreenPtr	    pScreen = pDrawable->pScreen;
+    ExaScreenPriv  (pScreen);
+    PixmapPtr	    pPixmap;
+    STRACE;
+
+    if (pExaScr->info->accel.FinishAccess == NULL)
+        return;
+
+    if (pDrawable->type == DRAWABLE_WINDOW)
+        pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
+    else
+        pPixmap = (PixmapPtr) pDrawable;
+    if (!exaPixmapIsOffscreen (pPixmap))
+        return;
+
+    (*pExaScr->info->accel.FinishAccess) (pPixmap, index);
+}
+
 #if 0
 static void
 exaFillTiled(int	dst_x,
@@ -620,10 +673,7 @@
 	    exaPixmapUseMemory ((PixmapPtr) pSrcDrawable);
 	if (pDstDrawable->type == DRAWABLE_PIXMAP)
 	    exaPixmapUseMemory ((PixmapPtr) pDstDrawable);
-	exaWaitSync (pDstDrawable->pScreen);
-	fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
-		    pbox, nbox, dx, dy, reverse, upsidedown,
-		    bitplane, closure);
+	goto fallback;
     }
 
     /* If either drawable is already in framebuffer, try to get both of them
@@ -664,15 +714,17 @@
 	}
 	(*pExaScr->info->accel.DoneCopy) (pDstPixmap);
 	exaMarkSync(pDstDrawable->pScreen);
+	exaDrawableDirty (pDstDrawable);
+	return;
     }
-    else
-    {
-	exaWaitSync (pDstDrawable->pScreen);
-	fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
-		    pbox, nbox, dx, dy, reverse, upsidedown,
-		    bitplane, closure);
-    }
-    exaDrawableDirty (pDstDrawable);
+ fallback:
+    exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST);
+    exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
+    fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
+		pbox, nbox, dx, dy, reverse, upsidedown,
+		bitplane, closure);
+    exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
+    exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
 }
 
 RegionPtr
@@ -822,12 +874,12 @@
         !(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
 	!(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg))
     {
-	exaWaitSync (pDrawable->pScreen);
+        exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
 	fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
 	fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2,
 			   fbAnd (GXcopy, fg, pm),
 			   fbXor (GXcopy, fg, pm));
-	exaDrawableDirty (pDrawable);
+        exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
 	return;
     }
     for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
@@ -949,8 +1001,7 @@
 	opaque = FALSE;
     }
 
-    exaWaitSync (pDrawable->pScreen);
-    exaDrawableDirty (pDrawable);
+    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
 
     ppci = ppciInit;
     while (nglyph--)
@@ -996,6 +1047,7 @@
 	}
 	x += pci->metrics.characterWidth;
     }
+    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
 }
 
 static const GCOps	exaOps = {
@@ -1121,14 +1173,15 @@
 	}
 	(*pExaScr->info->accel.DoneSolid) (pPixmap);
 	exaMarkSync(pDrawable->pScreen);
+        exaDrawableDirty (pDrawable);
     }
     else
     {
-	exaWaitSync (pDrawable->pScreen);
+        exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
 	fbFillRegionSolid (pDrawable, pRegion, 0,
 			   fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
+        exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
     }
-    exaDrawableDirty (pDrawable);
 }
 
 static void
diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/exa/exa.h xc-HEAD/programs/Xserver/hw/xfree86/exa/exa.h
--- xc-HEAD.orig/programs/Xserver/hw/xfree86/exa/exa.h	2005-08-30 13:44:25.000000000 +1000
+++ xc-HEAD/programs/Xserver/hw/xfree86/exa/exa.h	2005-09-03 13:09:43.000000000 +1000
@@ -163,7 +163,7 @@
      * accelerated, a markSync will follow it as with other acceleration
      * hooks.
      */
-    Bool (*DownloadFromScreen)(PixmapPtr pSrc,
+    Bool	(*DownloadFromScreen)(PixmapPtr pSrc,
                                int x,  int y,
                                int w,  int h,
                                char *dst,  int dst_pitch);
@@ -175,6 +175,24 @@
      */
     int		(*MarkSync)   (ScreenPtr pScreen);
     void	(*WaitMarker) (ScreenPtr pScreen, int marker);
+
+    /* These are wrapping all fb or composite operations that will cause
+     * a direct access to the framebuffer. You can use them to update
+     * endian swappers, force migration to RAM, or whatever else you find
+     * useful at this point. EXA can stack up to 3 calls to Prepare/Finish
+     * access, though they will have a different index. If your hardware
+     * doesn't have enough separate configurable swapper, you can return
+     * FALSE from PrepareAccess() to force EXA to migrate the pixmap to RAM.
+     * Note that DownloadFromScreen and UploadToScreen can both be called
+     * between PrepareAccess() and FinishAccess(). If they need to use a
+     * swapper, they should save & restore its setting.
+     */
+    Bool	(*PrepareAccess)(PixmapPtr pPix, int index);
+    void	(*FinishAccess)(PixmapPtr pPix, int index);
+	#define EXA_PREPARE_DEST	0
+	#define EXA_PREPARE_SRC		1
+	#define EXA_PREPARE_MASK	2
+
 } ExaAccelInfoRec, *ExaAccelInfoPtr;
 
 typedef struct _ExaDriver {
diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/exa/exaPriv.h xc-HEAD/programs/Xserver/hw/xfree86/exa/exaPriv.h
--- xc-HEAD.orig/programs/Xserver/hw/xfree86/exa/exaPriv.h	2005-08-30 13:44:25.000000000 +1000
+++ xc-HEAD/programs/Xserver/hw/xfree86/exa/exaPriv.h	2005-09-03 17:49:27.000000000 +1000
@@ -103,6 +103,7 @@
     int		    devKind;
     DevUnion	    devPrivate;
     Bool	    dirty;
+    unsigned int    size;
 } ExaPixmapPrivRec, *ExaPixmapPrivPtr;
 
 
diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/exa/exaasync.c xc-HEAD/programs/Xserver/hw/xfree86/exa/exaasync.c
--- xc-HEAD.orig/programs/Xserver/hw/xfree86/exa/exaasync.c	2005-08-30 13:44:25.000000000 +1000
+++ xc-HEAD/programs/Xserver/hw/xfree86/exa/exaasync.c	2005-09-03 17:40:04.000000000 +1000
@@ -33,18 +33,18 @@
 ExaCheckFillSpans  (DrawablePtr pDrawable, GCPtr pGC, int nspans,
 		   DDXPointPtr ppt, int *pwidth, int fSorted)
 {
-    exaWaitSync (pDrawable->pScreen);
-    exaDrawableDirty (pDrawable);
+    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     fbFillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
+    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
 }
 
 void
 ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
 		 DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
 {
-    exaWaitSync (pDrawable->pScreen);
-    exaDrawableDirty (pDrawable);
+    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     fbSetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
+    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
 }
 
 void
@@ -52,18 +52,24 @@
 		 int x, int y, int w, int h, int leftPad, int format,
 		 char *bits)
 {
-    exaWaitSync (pDrawable->pScreen);
-    exaDrawableDirty (pDrawable);
+    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
+    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
 }
 
 RegionPtr
 ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
 		 int srcx, int srcy, int w, int h, int dstx, int dsty)
 {
-    exaWaitSync (pSrc->pScreen);
-    exaDrawableDirty (pDst);
-    return fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
+    RegionPtr ret;
+
+    exaPrepareAccess (pDst, EXA_PREPARE_DEST);
+    exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+    ret = fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
+    exaFinishAccess (pSrc, EXA_PREPARE_SRC);
+    exaFinishAccess (pDst, EXA_PREPARE_DEST);
+
+    return ret;
 }
 
 RegionPtr
@@ -71,19 +77,25 @@
 		  int srcx, int srcy, int w, int h, int dstx, int dsty,
 		  unsigned long bitPlane)
 {
-    exaWaitSync (pSrc->pScreen);
-    exaDrawableDirty (pDst);
-    return fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
-			bitPlane);
+    RegionPtr ret;
+
+    exaPrepareAccess (pDst, EXA_PREPARE_DEST);
+    exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+    ret = fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
+		       bitPlane);
+    exaFinishAccess (pSrc, EXA_PREPARE_SRC);
+    exaFinishAccess (pDst, EXA_PREPARE_DEST);
+
+    return ret;
 }
 
 void
 ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 		  DDXPointPtr pptInit)
 {
-    exaWaitSync (pDrawable->pScreen);
-    exaDrawableDirty (pDrawable);
+    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     fbPolyPoint (pDrawable, pGC, mode, npt, pptInit);
+    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
 }
 
 void
@@ -92,10 +104,11 @@
 {
 
     if (pGC->lineWidth == 0) {
-	exaWaitSync(pDrawable->pScreen);
-	exaDrawableDirty (pDrawable);
+        exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+        fbPolyLine (pDrawable, pGC, mode, npt, ppt);
+        exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+        return;
     }
-    exaDrawableDirty (pDrawable);
     fbPolyLine (pDrawable, pGC, mode, npt, ppt);
 }
 
@@ -104,10 +117,11 @@
 		    int nsegInit, xSegment *pSegInit)
 {
     if (pGC->lineWidth == 0) {
-	exaWaitSync(pDrawable->pScreen);
-	exaDrawableDirty (pDrawable);
+        exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+        fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
+        exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+        return;
     }
-    exaDrawableDirty (pDrawable);
     fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
 }
 
@@ -116,8 +130,10 @@
 		      int nrects, xRectangle *prect)
 {
     if (pGC->lineWidth == 0) {
-	exaWaitSync(pDrawable->pScreen);
-	exaDrawableDirty (pDrawable);
+        exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+        fbPolyRectangle (pDrawable, pGC, nrects, prect);
+        exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+        return;
     }
     fbPolyRectangle (pDrawable, pGC, nrects, prect);
 }
@@ -128,12 +144,12 @@
 {
     if (pGC->lineWidth == 0)
     {
-	exaWaitSync(pDrawable->pScreen);
-	exaDrawableDirty (pDrawable);
+        exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
 	fbPolyArc (pDrawable, pGC, narcs, pArcs);
+        exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+        return;
     }
-    else
-	miPolyArc (pDrawable, pGC, narcs, pArcs);
+    miPolyArc (pDrawable, pGC, narcs, pArcs);
 }
 
 #if 0
@@ -141,9 +157,9 @@
 ExaCheckFillPolygon (DrawablePtr pDrawable, GCPtr pGC,
 		    int shape, int mode, int count, DDXPointPtr pPts)
 {
-    exaWaitSync(pDrawable->pScreen);
-    exaDrawableDirty (pDrawable);
+    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     fbFillPolygon (pDrawable, pGC, mode, count, pPts);
+    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
 }
 #endif
 
@@ -151,18 +167,18 @@
 ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
 		     int nrect, xRectangle *prect)
 {
-    exaWaitSync(pDrawable->pScreen);
-    exaDrawableDirty (pDrawable);
+    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     fbPolyFillRect (pDrawable, pGC, nrect, prect);
+    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
 }
 
 void
 ExaCheckPolyFillArc (DrawablePtr pDrawable, GCPtr pGC,
 		    int narcs, xArc *pArcs)
 {
-    exaWaitSync(pDrawable->pScreen);
-    exaDrawableDirty (pDrawable);
+    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     fbPolyFillArc (pDrawable, pGC, narcs, pArcs);
+    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
 }
 
 void
@@ -170,9 +186,9 @@
 		      int x, int y, unsigned int nglyph,
 		      CharInfoPtr *ppci, pointer pglyphBase)
 {
-    exaWaitSync(pDrawable->pScreen);
-    exaDrawableDirty (pDrawable);
+    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     fbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
 }
 
 void
@@ -180,9 +196,9 @@
 		     int x, int y, unsigned int nglyph,
 		     CharInfoPtr *ppci, pointer pglyphBase)
 {
-    exaWaitSync(pDrawable->pScreen);
-    exaDrawableDirty (pDrawable);
+    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     fbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
 }
 
 void
@@ -190,9 +206,9 @@
 		   DrawablePtr pDrawable,
 		   int w, int h, int x, int y)
 {
-    exaWaitSync(pDrawable->pScreen);
-    exaDrawableDirty (pDrawable);
+    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     fbPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
+    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
 }
 
 void
@@ -201,8 +217,9 @@
 		 unsigned int format, unsigned long planeMask,
 		 char *d)
 {
-    exaWaitSync(pDrawable->pScreen);
+    exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
     fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
+    exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
 }
 
 void
@@ -213,8 +230,9 @@
 		 int nspans,
 		 char *pdstStart)
 {
-    exaWaitSync(pDrawable->pScreen);
+    exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
     fbGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+    exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
 }
 
 void
@@ -224,9 +242,9 @@
 		  int		yorg,
 		  WindowPtr	pWin)
 {
-    exaWaitSync(pWin->drawable.pScreen);
-    exaDrawableDirty (&pPixmap->drawable);
+    exaPrepareAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
     fbSaveAreas (pPixmap, prgnSave, xorg, yorg, pWin);
+    exaFinishAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
 }
 
 void
@@ -236,17 +254,17 @@
 		     int    	yorg,
 		     WindowPtr	pWin)
 {
-    exaWaitSync(pWin->drawable.pScreen);
-    exaDrawableDirty ((DrawablePtr)pWin);
+    exaPrepareAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
     fbRestoreAreas (pPixmap, prgnSave, xorg, yorg, pWin);
+    exaFinishAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
 }
 
 void
 ExaCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what)
 {
-    exaWaitSync (pWin->drawable.pScreen);
-    exaDrawableDirty ((DrawablePtr)pWin);
+    exaPrepareAccess (&pWin->drawable, EXA_PREPARE_DEST);
     fbPaintWindow (pWin, pRegion, what);
+    exaFinishAccess (&pWin->drawable, EXA_PREPARE_DEST);
 }
 
 void
@@ -263,8 +281,12 @@
                    CARD16     width,
                    CARD16     height)
 {
-    exaWaitSync (pDst->pDrawable->pScreen);
-    exaDrawableDirty (pDst->pDrawable);
+    if (pDst)
+        exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
+    if (pSrc)
+        exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
+    if (pMask)
+        exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
     fbComposite (op,
                  pSrc,
                  pMask,
@@ -277,6 +299,12 @@
                  yDst,
                  width,
                  height);
+    if (pMask)
+        exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK);
+    if (pSrc)
+        exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
+    if (pDst)
+        exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
 }
 
 /*
diff -urN xc-HEAD.orig/programs/Xserver/hw/xfree86/exa/exapict.c xc-HEAD/programs/Xserver/hw/xfree86/exa/exapict.c
--- xc-HEAD.orig/programs/Xserver/hw/xfree86/exa/exapict.c	2005-09-01 13:10:34.000000000 +1000
+++ xc-HEAD/programs/Xserver/hw/xfree86/exa/exapict.c	2005-09-03 19:12:54.000000000 +1000
@@ -262,13 +262,8 @@
     else
 	pSrcPix = (PixmapPtr) (pSrc->pDrawable);
 
-    /* If source is offscreen, we need to sync the accelerator
-     * before accessing it.  We'd prefer for it to be in memory.
-     */
-    if (exaPixmapIsOffscreen(pSrcPix)) {
-	exaWaitSync(pDst->pDrawable->pScreen);
-    }
 
+    exaPrepareAccess(pSrcPix, EXA_PREPARE_SRC);
     pixel = *(CARD32 *)(pSrcPix->devPrivate.ptr);
     if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
 			 pSrc->format))
@@ -276,6 +271,8 @@
 	REGION_UNINIT(pDst->pDrawable->pScreen, &region);
 	return -1;
     }
+    exaFinishAccess(pSrcPix, EXA_PREPARE_SRC);
+
     exaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
 			pDst->format);
 
@@ -327,10 +324,6 @@
     PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
     struct _Pixmap scratch;
 
-    /* Bail if we might exceed coord limits by rendering from/to these.  We
-     * should really be making some scratch pixmaps with offsets and coords
-     * adjusted to deal with this, but it hasn't been done yet.
-     */
     if (pSrc->pDrawable->width > pExaScr->info->card.maxX ||
 	pSrc->pDrawable->height > pExaScr->info->card.maxY ||
 	pDst->pDrawable->width > pExaScr->info->card.maxX ||





More information about the xorg mailing list