xserver: Branch 'master'

Tilman Sauerbeck tilman at kemper.freedesktop.org
Tue Sep 25 07:44:46 PDT 2007


 exa/exa.c        |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 exa/exa.h        |   33 ++++++++++++++++++++++++++++++++-
 exa/exa_accel.c  |   45 +++++++++++++++++++++++----------------------
 exa/exa_priv.h   |   15 +++++++++++++++
 exa/exa_render.c |   24 ++++++++++++++----------
 5 files changed, 137 insertions(+), 33 deletions(-)

New commits:
diff-tree ae8b4f7dcf1291a2f5a0d0159f3e6089eea0578a (from 988f446fe00ac2b92c484a4440613dd82191eadd)
Author: Tilman Sauerbeck <tilman at code-monkey.de>
Date:   Mon Sep 24 22:06:52 2007 +0200

    EXA: Added pitch limitations.
    
    Drivers can now specify the max pitches that the accelerator supports.

diff --git a/exa/exa.c b/exa/exa.c
index 6205027..ae6b70f 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -278,6 +278,26 @@ exaCreatePixmap(ScreenPtr pScreen, int w
     REGION_NULL(pScreen, &pExaPixmap->validSys);
     REGION_NULL(pScreen, &pExaPixmap->validFB);
 
+    /* Check whether this pixmap can be used for acceleration. */
+    pExaPixmap->accel_blocked = 0;
+
+    if (pExaScr->info->maxPitchPixels) {
+        int max_pitch = pExaScr->info->maxPitchPixels * (bpp + 7) / 8;
+
+        if (pExaPixmap->fb_pitch > max_pitch)
+            pExaPixmap->accel_blocked |= EXA_RANGE_PITCH;
+    }
+
+    if (pExaScr->info->maxPitchBytes &&
+        pExaPixmap->fb_pitch > pExaScr->info->maxPitchBytes)
+        pExaPixmap->accel_blocked |= EXA_RANGE_PITCH;
+
+    if (w > pExaScr->info->maxX)
+        pExaPixmap->accel_blocked |= EXA_RANGE_WIDTH;
+
+    if (h > pExaScr->info->maxY)
+        pExaPixmap->accel_blocked |= EXA_RANGE_HEIGHT;
+
     return pPixmap;
 }
 
@@ -707,6 +727,39 @@ exaDriverInit (ScreenPtr		pScreen,
 	return FALSE;
     }
 
+    /* If the driver doesn't set any max pitch values, we'll just assume
+     * that there's a limitation by pixels, and that it's the same as
+     * maxX.
+     */
+    if (!pScreenInfo->maxPitchPixels && !pScreenInfo->maxPitchBytes)
+    {
+        pScreenInfo->maxPitchPixels = pScreenInfo->maxX;
+    }
+
+    /* If set, maxPitchPixels must not be smaller than maxX. */
+    if (pScreenInfo->maxPitchPixels &&
+        pScreenInfo->maxPitchPixels < pScreenInfo->maxX)
+    {
+        LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::maxPitchPixels "
+                   "is smaller than ExaDriverRec::maxX\n",
+                   pScreen->myNum);
+	return FALSE;
+    }
+
+    /* If set, maxPitchBytes must not be smaller than maxX * 4.
+     * This is to ensure that a 32bpp pixmap with the maximum width
+     * can be handled wrt the pitch.
+     */
+    if (pScreenInfo->maxPitchBytes &&
+        pScreenInfo->maxPitchBytes < (pScreenInfo->maxX * 4))
+    {
+        LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::maxPitchBytes "
+                   "doesn't allow a 32bpp pixmap with width equal to "
+                   "ExaDriverRec::maxX\n",
+                   pScreen->myNum);
+	return FALSE;
+    }
+
 #ifdef RENDER
     ps = GetPictureScreenIfSet(pScreen);
 #endif
diff --git a/exa/exa.h b/exa/exa.h
index 9ea5933..491e6b1 100644
--- a/exa/exa.h
+++ b/exa/exa.h
@@ -39,7 +39,7 @@
 #include "fb.h"
 
 #define EXA_VERSION_MAJOR   2
-#define EXA_VERSION_MINOR   2
+#define EXA_VERSION_MINOR   3
 #define EXA_VERSION_RELEASE 0
 
 typedef struct _ExaOffscreenArea ExaOffscreenArea;
@@ -671,6 +671,37 @@ typedef struct _ExaDriver {
 	 */
 	#define EXA_PREPARE_MASK	2
 	/** @} */
+
+    /**
+     * maxPitchPixels controls the pitch limitation for rendering from
+     * the card.
+     * The driver should never receive a request for rendering a pixmap
+     * that has a pitch (in pixels) beyond maxPitchPixels.
+     *
+     * Setting this field is optional -- if your hardware doesn't have
+     * a pitch limitation in pixels, don't set this. If neither this value
+     * nor maxPitchBytes is set, then maxPitchPixels is set to maxX.
+     * If set, it must not be smaller than maxX.
+     *
+     * @sa maxPitchBytes
+     */
+    int maxPitchPixels;
+
+    /**
+     * maxPitchBytes controls the pitch limitation for rendering from
+     * the card.
+     * The driver should never receive a request for rendering a pixmap
+     * that has a pitch (in bytes) beyond maxPitchBytes.
+     *
+     * Setting this field is optional -- if your hardware doesn't have
+     * a pitch limitation in bytes, don't set this.
+     * If set, it must not be smaller than maxX * 4.
+     * There's no default value for maxPitchBytes.
+     *
+     * @sa maxPitchPixels
+     */
+    int maxPitchBytes;
+
     /** @} */
 } ExaDriverRec, *ExaDriverPtr;
 
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 2acade2..028d936 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -43,7 +43,8 @@ exaFillSpans(DrawablePtr pDrawable, GCPt
     ScreenPtr	    pScreen = pDrawable->pScreen;
     ExaScreenPriv (pScreen);
     RegionPtr	    pClip = fbGetCompositeClip(pGC);
-    PixmapPtr	    pPixmap;
+    PixmapPtr	    pPixmap = exaGetDrawablePixmap (pDrawable);
+    ExaPixmapPriv (pPixmap);
     BoxPtr	    pextent, pbox;
     int		    nbox;
     int		    extentX1, extentX2, extentY1, extentY2;
@@ -54,13 +55,12 @@ exaFillSpans(DrawablePtr pDrawable, GCPt
 
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = FALSE;
-    pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
+    pixmaps[0].pPix = pPixmap;
     pixmaps[0].pReg = NULL;
 
     if (pExaScr->swappedOut ||
 	pGC->fillStyle != FillSolid ||
-	pPixmap->drawable.width > pExaScr->info->maxX ||
-	pPixmap->drawable.height > pExaScr->info->maxY)
+	pExaPixmap->accel_blocked)
     {
 	ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
 	return;
@@ -480,6 +480,7 @@ exaCopyNtoN (DrawablePtr    pSrcDrawable
 {
     ExaScreenPriv (pDstDrawable->pScreen);
     PixmapPtr pSrcPixmap, pDstPixmap;
+    ExaPixmapPrivPtr pSrcExaPixmap, pDstExaPixmap;
     int	    src_off_x, src_off_y;
     int	    dst_off_x, dst_off_y;
     ExaMigrationRec pixmaps[2];
@@ -527,14 +528,14 @@ exaCopyNtoN (DrawablePtr    pSrcDrawable
     pixmaps[1].pPix = pSrcPixmap;
     pixmaps[1].pReg = NULL;
 
-    /* Respect maxX/maxY in a trivial way: don't set up drawing when we might
-     * violate the limits.  The proper solution would be a temporary pixmap
-     * adjusted so that the drawing happened within limits.
+    pSrcExaPixmap = ExaGetPixmapPriv (pSrcPixmap);
+    pDstExaPixmap = ExaGetPixmapPriv (pDstPixmap);
+
+    /* Check whether the accelerator can use this pixmap.
+     * FIXME: If it cannot, use temporary pixmaps so that the drawing
+     * happens within limits.
      */
-    if (pSrcPixmap->drawable.width > pExaScr->info->maxX ||
-	pSrcPixmap->drawable.height > pExaScr->info->maxY ||
-	pDstPixmap->drawable.width > pExaScr->info->maxX ||
-	pDstPixmap->drawable.height > pExaScr->info->maxY)
+    if (pSrcExaPixmap->accel_blocked || pDstExaPixmap->accel_blocked)
     {
 	goto fallback;
     } else {
@@ -760,6 +761,7 @@ exaPolyFillRect(DrawablePtr pDrawable,
     ExaScreenPriv (pDrawable->pScreen);
     RegionPtr	    pClip = fbGetCompositeClip(pGC);
     PixmapPtr	    pPixmap = exaGetDrawablePixmap(pDrawable);
+    ExaPixmapPriv (pPixmap);
     register BoxPtr pbox;
     BoxPtr	    pextent;
     int		    extentX1, extentX2, extentY1, extentY2;
@@ -786,9 +788,7 @@ exaPolyFillRect(DrawablePtr pDrawable,
 
     exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
 
-    if (pExaScr->swappedOut ||
-	pPixmap->drawable.width > pExaScr->info->maxX ||
-	pPixmap->drawable.height > pExaScr->info->maxY)
+    if (pExaScr->swappedOut || pExaPixmap->accel_blocked)
     {
 	goto fallback;
     }
@@ -1102,21 +1102,21 @@ exaFillRegionSolid (DrawablePtr	pDrawabl
 		    CARD32	alu)
 {
     ExaScreenPriv(pDrawable->pScreen);
-    PixmapPtr pPixmap;
+    PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
+    ExaPixmapPriv (pPixmap);
     int xoff, yoff;
     ExaMigrationRec pixmaps[1];
 
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = FALSE;
-    pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
+    pixmaps[0].pPix = pPixmap;
     pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillSolid,
 					    alu) ? NULL : pRegion;
 
     exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
     REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);
 
-    if (pPixmap->drawable.width > pExaScr->info->maxX ||
-	pPixmap->drawable.height > pExaScr->info->maxY)
+    if (pExaPixmap->accel_blocked)
     {
 	goto fallback;
     } else {
@@ -1193,6 +1193,8 @@ exaFillRegionTiled (DrawablePtr	pDrawabl
 {
     ExaScreenPriv(pDrawable->pScreen);
     PixmapPtr pPixmap;
+    ExaPixmapPrivPtr pExaPixmap;
+    ExaPixmapPrivPtr pTileExaPixmap = ExaGetPixmapPriv(pTile);
     int xoff, yoff, tileXoff, tileYoff;
     int tileWidth, tileHeight;
     ExaMigrationRec pixmaps[2];
@@ -1223,10 +1225,9 @@ exaFillRegionTiled (DrawablePtr	pDrawabl
     exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
     REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);
 
-    if (pPixmap->drawable.width > pExaScr->info->maxX ||
-	pPixmap->drawable.height > pExaScr->info->maxY ||
-	tileWidth > pExaScr->info->maxX ||
-	tileHeight > pExaScr->info->maxY)
+    pExaPixmap = ExaGetPixmapPriv (pPixmap);
+
+    if (pExaPixmap->accel_blocked || pTileExaPixmap->accel_blocked)
     {
 	goto fallback;
     } else {
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 9e4f8bc..a26933d 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -154,6 +154,10 @@ extern int exaPixmapPrivateIndex;
 #define ExaSetPixmapPriv(p,a)	((p)->devPrivates[exaPixmapPrivateIndex].ptr = (pointer) (a))
 #define ExaPixmapPriv(p)	ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p)
 
+#define EXA_RANGE_PITCH (1 << 0)
+#define EXA_RANGE_WIDTH (1 << 1)
+#define EXA_RANGE_HEIGHT (1 << 2)
+
 typedef struct {
     ExaOffscreenArea *area;
     int		    score;	/**< score for the move-in vs move-out heuristic */
@@ -167,6 +171,17 @@ typedef struct {
     unsigned int    fb_size;	/**< size of pixmap in framebuffer memory */
 
     /**
+     * Holds information about whether this pixmap can be used for
+     * acceleration (== 0) or not (> 0).
+     *
+     * Contains a OR'ed combination of the following values:
+     * EXA_RANGE_PITCH - set if the pixmap's pitch is out of range
+     * EXA_RANGE_WIDTH - set if the pixmap's width is out of range
+     * EXA_RANGE_HEIGHT - set if the pixmap's height is out of range
+     */
+    unsigned int    accel_blocked;
+
+    /**
      * The damage record contains the areas of the pixmap's current location
      * (framebuffer or system) that have been damaged compared to the other
      * location.
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 943a4c8..4c93128 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -336,24 +336,28 @@ exaTryDriverComposite(CARD8		op,
     int nbox;
     int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
     PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
+    ExaPixmapPrivPtr pSrcExaPix, pMaskExaPix = NULL, pDstExaPix;
     struct _Pixmap scratch;
     ExaMigrationRec pixmaps[3];
 
     pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
+    pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
+
     pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
-    if (pMask)
+    pDstExaPix = ExaGetPixmapPriv(pDstPix);
+
+    if (pMask) {
 	pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
+        pMaskExaPix = ExaGetPixmapPriv(pMaskPix);
+    }
 
-    /* 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.
+    /* Check whether the accelerator can use these pixmaps.
+     * FIXME: If it cannot, use temporary pixmaps so that the drawing
+     * happens within limits.
      */
-    if (pSrcPix->drawable.width > pExaScr->info->maxX ||
-	pSrcPix->drawable.height > pExaScr->info->maxY ||
-	pDstPix->drawable.width > pExaScr->info->maxX ||
-	pDstPix->drawable.height > pExaScr->info->maxY || 
-	(pMask && (pMaskPix->drawable.width > pExaScr->info->maxX ||
-		   pMaskPix->drawable.height > pExaScr->info->maxY)))
+    if (pSrcExaPix->accel_blocked ||
+	pDstExaPix->accel_blocked ||
+	(pMask && (pMaskExaPix->accel_blocked)))
     {
 	return -1;
     }


More information about the xorg-commit mailing list