xf86-video-intel: 5 commits - src/i830_batchbuffer.c src/i830_display.c src/i830_display.h src/i830_driver.c src/i830_exa.c src/i830.h src/i830_memory.c src/i830_video.c src/i965_hwmc.c src/i965_render.c src/i965_video.c uxa/uxa-accel.c uxa/uxa.c uxa/uxa-priv.h uxa/uxa-render.c uxa/uxa-unaccel.c

Keith Packard keithp at kemper.freedesktop.org
Tue Jan 6 09:36:08 PST 2009


 src/i830.h             |   28 ++-
 src/i830_batchbuffer.c |    4 
 src/i830_display.c     |   41 +++-
 src/i830_display.h     |    1 
 src/i830_driver.c      |  149 +++++++++++----
 src/i830_exa.c         |   27 ++
 src/i830_memory.c      |  457 ++++++++++++++++++-------------------------------
 src/i830_video.c       |    7 
 src/i965_hwmc.c        |    6 
 src/i965_render.c      |   22 ++
 src/i965_video.c       |  168 +++++++++++-------
 uxa/uxa-accel.c        |   30 +--
 uxa/uxa-priv.h         |    6 
 uxa/uxa-render.c       |   37 ++-
 uxa/uxa-unaccel.c      |  236 ++++++++++++++-----------
 uxa/uxa.c              |   47 +++--
 16 files changed, 714 insertions(+), 552 deletions(-)

New commits:
commit 7736b65be4fb4d5c59d7aedb1e64da976bb10ae9
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Dec 15 15:49:01 2008 -0800

    FatalError on batchbuffer map failure
    
    Yes, it would be nice to do something other than crash here.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c
index 13d939e..b1c8a8d 100644
--- a/src/i830_batchbuffer.c
+++ b/src/i830_batchbuffer.c
@@ -112,7 +112,9 @@ intel_next_batch(ScrnInfoPtr pScrn)
     else
 	pI830->batch_bo = dri_bo_alloc(pI830->bufmgr, "batch", 4096 * 4, 4096);
 
-    dri_bo_map(pI830->batch_bo, 1);
+    if (dri_bo_map(pI830->batch_bo, 1) != 0)
+	FatalError("Failed to map batchbuffer: %s\n", strerror(errno));
+
     pI830->batch_used = 0;
     pI830->batch_ptr = pI830->batch_bo->virtual;
 }
commit 632f816c72cb4b48b690fd92d1cc1d5a9c9285c7
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Dec 15 15:43:34 2008 -0800

    uxa: handle uxa_prepare_access failure
    
    uxa_prepare_access may fail to map the pixmap into user space. Recover from
    this without crashing.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/uxa/uxa-accel.c b/uxa/uxa-accel.c
index b25a8fa..f42e0e2 100644
--- a/uxa/uxa-accel.c
+++ b/uxa/uxa-accel.c
@@ -188,7 +188,8 @@ uxa_do_put_image (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
 	    int	dstXoff, dstYoff;
 
 	    if (!access_prepared) {
-		uxa_prepare_access(pDrawable, UXA_ACCESS_RW);
+		if (!uxa_prepare_access(pDrawable, UXA_ACCESS_RW))
+		    return FALSE;
 		access_prepared = TRUE;
 	    }
 
@@ -237,7 +238,8 @@ uxa_do_shm_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth,
 	if (!pPixmap)
 	    return FALSE;
 
-        uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
+        if (!uxa_prepare_access (pDrawable, UXA_ACCESS_RW))
+	    return FALSE;
 	fbCopyArea((DrawablePtr)pPixmap, pDrawable, pGC, sx, sy, sw, sh, dx, dy);
 	uxa_finish_access(pDrawable);
 
@@ -262,7 +264,8 @@ uxa_shm_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth, unsigned int form
 {
     if (!uxa_do_shm_put_image(pDrawable, pGC, depth, format, w, h, sx, sy, sw, sh,
 			      dx, dy, data)) {
-	uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
+	if (!uxa_prepare_access (pDrawable, UXA_ACCESS_RW))
+	    return;
 	fbShmPutImage(pDrawable, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
 		      data);
 	uxa_finish_access(pDrawable);
@@ -468,12 +471,14 @@ fallback:
     UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
 		  uxa_drawable_location(pSrcDrawable),
 		  uxa_drawable_location(pDstDrawable)));
-    uxa_prepare_access (pDstDrawable, UXA_ACCESS_RW);
-    uxa_prepare_access (pSrcDrawable, UXA_ACCESS_RO);
-    fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse,
-		upsidedown, bitplane, closure);
-    uxa_finish_access (pSrcDrawable);
-    uxa_finish_access (pDstDrawable);
+    if (uxa_prepare_access (pDstDrawable, UXA_ACCESS_RW)) {
+	if (uxa_prepare_access (pSrcDrawable, UXA_ACCESS_RO)) {
+	    fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy,
+			reverse, upsidedown, bitplane, closure);
+	    uxa_finish_access (pSrcDrawable);
+	}
+	uxa_finish_access (pDstDrawable);
+    }
 }
 
 RegionPtr
@@ -1024,9 +1029,10 @@ fallback:
     UXA_FALLBACK(("from %p (%c)\n", pDrawable,
 		  uxa_drawable_location(pDrawable)));
 
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RO);
-    fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RO)) {
+	fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
+	uxa_finish_access (pDrawable);
+    }
 
    return;
 }
diff --git a/uxa/uxa-priv.h b/uxa/uxa-priv.h
index 0f9cfbf..f4b3cee 100644
--- a/uxa/uxa-priv.h
+++ b/uxa/uxa-priv.h
@@ -182,14 +182,14 @@ typedef struct {
   */
 void exaDDXDriverInit (ScreenPtr pScreen);
 
-void
+Bool
 uxa_prepare_access_window(WindowPtr pWin);
 
 void
 uxa_finish_access_window(WindowPtr pWin);
 
 /* uxa-unaccel.c */
-void
+Bool
 uxa_prepare_access_gc(GCPtr pGC);
 
 void
@@ -351,7 +351,7 @@ uxa_check_composite (CARD8      op,
 #endif
 
 /* uxa.c */
-void
+Bool
 uxa_prepare_access(DrawablePtr pDrawable, uxa_access_t access);
 
 void
diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c
index b2d3297..13635f8 100644
--- a/uxa/uxa-render.c
+++ b/uxa/uxa-render.c
@@ -889,12 +889,12 @@ uxa_trapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
 	xoff += pDraw->x;
 	yoff += pDraw->y;
 
-	uxa_prepare_access(pDraw, UXA_ACCESS_RW);
-
-	for (; ntrap; ntrap--, traps++)
-	    (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
-
-	uxa_finish_access(pDraw);
+	if (uxa_prepare_access(pDraw, UXA_ACCESS_RW))
+	{
+	    for (; ntrap; ntrap--, traps++)
+		(*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
+	    uxa_finish_access(pDraw);
+	}
     }
     else if (maskFormat)
     {
@@ -911,11 +911,12 @@ uxa_trapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
 	if (!pPicture)
 	    return;
 
-	uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW);
-	for (; ntrap; ntrap--, traps++)
-	    (*ps->RasterizeTrapezoid) (pPicture, traps,
-				       -bounds.x1, -bounds.y1);
-	uxa_finish_access(pPicture->pDrawable);
+	if (uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW)) {
+	    for (; ntrap; ntrap--, traps++)
+		(*ps->RasterizeTrapezoid) (pPicture, traps,
+					   -bounds.x1, -bounds.y1);
+	    uxa_finish_access(pPicture->pDrawable);
+	}
 
 	xRel = bounds.x1 + xSrc - xDst;
 	yRel = bounds.y1 + ySrc - yDst;
@@ -972,9 +973,10 @@ uxa_triangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
     if (direct)
     {
 	DrawablePtr pDraw = pDst->pDrawable;
-	uxa_prepare_access(pDraw, UXA_ACCESS_RW);
-	(*ps->AddTriangles) (pDst, 0, 0, ntri, tris);
-	uxa_finish_access(pDraw);
+	if (uxa_prepare_access(pDraw, UXA_ACCESS_RW)) {
+	    (*ps->AddTriangles) (pDst, 0, 0, ntri, tris);
+	    uxa_finish_access(pDraw);
+	}
     }
     else if (maskFormat)
     {
@@ -991,9 +993,10 @@ uxa_triangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
 	if (!pPicture)
 	    return;
 
-	uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW);
-	(*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris);
-	uxa_finish_access(pPicture->pDrawable);
+	if (uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW)) {
+	    (*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris);
+	    uxa_finish_access(pPicture->pDrawable);
+	}
 	
 	xRel = bounds.x1 + xSrc - xDst;
 	yRel = bounds.y1 + ySrc - yDst;
diff --git a/uxa/uxa-unaccel.c b/uxa/uxa-unaccel.c
index 01c1322..aba12e8 100644
--- a/uxa/uxa-unaccel.c
+++ b/uxa/uxa-unaccel.c
@@ -41,13 +41,19 @@
  * 1bpp and never in fb, so we don't worry about them.
  * We should worry about them for completeness sake and going forward.
  */
-void
+Bool
 uxa_prepare_access_gc(GCPtr pGC)
 {
     if (pGC->stipple)
-        uxa_prepare_access(&pGC->stipple->drawable, UXA_ACCESS_RO);
+        if (!uxa_prepare_access(&pGC->stipple->drawable, UXA_ACCESS_RO))
+	    return FALSE;
     if (pGC->fillStyle == FillTiled)
-	uxa_prepare_access(&pGC->tile.pixmap->drawable, UXA_ACCESS_RO);
+	if (!uxa_prepare_access(&pGC->tile.pixmap->drawable, UXA_ACCESS_RO)) {
+	    if (pGC->stipple)
+		uxa_finish_access(&pGC->stipple->drawable);
+	    return FALSE;
+	}
+    return TRUE;
 }
 
 /**
@@ -75,11 +81,13 @@ uxa_check_fill_spans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
 		   DDXPointPtr ppt, int *pwidth, int fSorted)
 {
     UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable)));
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-    uxa_prepare_access_gc (pGC);
-    fbFillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
-    uxa_finish_access_gc (pGC);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	if (uxa_prepare_access_gc (pGC)) {
+	    fbFillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
+	    uxa_finish_access_gc (pGC);
+	}
+	uxa_finish_access (pDrawable);
+    }
 }
 
 void
@@ -87,9 +95,10 @@ uxa_check_set_spans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
 		 DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
 {
     UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable)));
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-    fbSetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	fbSetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
+	uxa_finish_access (pDrawable);
+    }
 }
 
 void
@@ -98,25 +107,27 @@ uxa_check_put_image (DrawablePtr pDrawable, GCPtr pGC, int depth,
 		 char *bits)
 {
     UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable)));
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-    fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
+	uxa_finish_access (pDrawable);
+    }
 }
 
 RegionPtr
 uxa_check_copy_area (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
-		 int srcx, int srcy, int w, int h, int dstx, int dsty)
+		     int srcx, int srcy, int w, int h, int dstx, int dsty)
 {
-    RegionPtr ret;
+    RegionPtr ret = NULL;
 
     UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
 		  uxa_drawable_location(pSrc), uxa_drawable_location(pDst)));
-    uxa_prepare_access (pDst, UXA_ACCESS_RW);
-    uxa_prepare_access (pSrc, UXA_ACCESS_RO);
-    ret = fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
-    uxa_finish_access (pSrc);
-    uxa_finish_access (pDst);
-
+    if (uxa_prepare_access (pDst, UXA_ACCESS_RW)) {
+	if (uxa_prepare_access (pSrc, UXA_ACCESS_RO)) {
+	    ret = fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
+	    uxa_finish_access (pSrc);
+	}
+	uxa_finish_access (pDst);
+    }
     return ret;
 }
 
@@ -125,17 +136,18 @@ uxa_check_copy_plane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
 		  int srcx, int srcy, int w, int h, int dstx, int dsty,
 		  unsigned long bitPlane)
 {
-    RegionPtr ret;
+    RegionPtr ret = NULL;
 
     UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
 		  uxa_drawable_location(pSrc), uxa_drawable_location(pDst)));
-    uxa_prepare_access (pDst, UXA_ACCESS_RW);
-    uxa_prepare_access (pSrc, UXA_ACCESS_RO);
-    ret = fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
-		       bitPlane);
-    uxa_finish_access (pSrc);
-    uxa_finish_access (pDst);
-
+    if (uxa_prepare_access (pDst, UXA_ACCESS_RW)) {
+	if (uxa_prepare_access (pSrc, UXA_ACCESS_RO)) {
+	    ret = fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
+			       bitPlane);
+	    uxa_finish_access (pSrc);
+	}
+	uxa_finish_access (pDst);
+    }
     return ret;
 }
 
@@ -144,9 +156,10 @@ uxa_check_poly_point (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
 		  DDXPointPtr pptInit)
 {
     UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable)));
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-    fbPolyPoint (pDrawable, pGC, mode, npt, pptInit);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	fbPolyPoint (pDrawable, pGC, mode, npt, pptInit);
+	uxa_finish_access (pDrawable);
+    }
 }
 
 void
@@ -158,11 +171,13 @@ uxa_check_poly_lines (DrawablePtr pDrawable, GCPtr pGC,
 		  pGC->lineWidth, mode, npt));
 
     if (pGC->lineWidth == 0) {
-	uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-	uxa_prepare_access_gc (pGC);
-	fbPolyLine (pDrawable, pGC, mode, npt, ppt);
-	uxa_finish_access_gc (pGC);
-	uxa_finish_access (pDrawable);
+	if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	    if (uxa_prepare_access_gc (pGC)) {
+		fbPolyLine (pDrawable, pGC, mode, npt, ppt);
+		uxa_finish_access_gc (pGC);
+	    }
+	    uxa_finish_access (pDrawable);
+	}
 	return;
     }
     /* fb calls mi functions in the lineWidth != 0 case. */
@@ -176,11 +191,13 @@ uxa_check_poly_segment (DrawablePtr pDrawable, GCPtr pGC,
     UXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable,
 		  uxa_drawable_location(pDrawable), pGC->lineWidth, nsegInit));
     if (pGC->lineWidth == 0) {
-	uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-	uxa_prepare_access_gc (pGC);
-	fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
-	uxa_finish_access_gc (pGC);
-	uxa_finish_access (pDrawable);
+	if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	    if (uxa_prepare_access_gc (pGC)) {
+		fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
+		uxa_finish_access_gc (pGC);
+	    }
+	    uxa_finish_access (pDrawable);
+	}
 	return;
     }
     /* fb calls mi functions in the lineWidth != 0 case. */
@@ -200,11 +217,13 @@ uxa_check_poly_arc (DrawablePtr pDrawable, GCPtr pGC,
 #if 0
     if (pGC->lineWidth == 0)
     {
-	uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-	uxa_prepare_access_gc (pGC);
-	fbPolyArc (pDrawable, pGC, narcs, pArcs);
-	uxa_finish_access_gc (pGC);
-	uxa_finish_access (pDrawable);
+	if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	    if (uxa_prepare_access_gc (pGC)) {
+		fbPolyArc (pDrawable, pGC, narcs, pArcs);
+		uxa_finish_access_gc (pGC);
+	    }
+	    uxa_finish_access (pDrawable);
+	}
 	return;
     }
 #endif
@@ -217,11 +236,13 @@ uxa_check_poly_fill_rect (DrawablePtr pDrawable, GCPtr pGC,
 {
     UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable)));
 
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-    uxa_prepare_access_gc (pGC);
-    fbPolyFillRect (pDrawable, pGC, nrect, prect);
-    uxa_finish_access_gc (pGC);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	if (uxa_prepare_access_gc (pGC)) {
+	    fbPolyFillRect (pDrawable, pGC, nrect, prect);
+	    uxa_finish_access_gc (pGC);
+	}
+	uxa_finish_access (pDrawable);
+    }
 }
 
 void
@@ -231,11 +252,13 @@ uxa_check_image_glyph_blt (DrawablePtr pDrawable, GCPtr pGC,
 {
     UXA_FALLBACK(("to %p (%c)\n", pDrawable,
 		  uxa_drawable_location(pDrawable)));
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-    uxa_prepare_access_gc (pGC);
-    fbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
-    uxa_finish_access_gc (pGC);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	if (uxa_prepare_access_gc (pGC)) {
+	    fbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+	    uxa_finish_access_gc (pGC);
+	}
+	uxa_finish_access (pDrawable);
+    }
 }
 
 void
@@ -245,11 +268,13 @@ uxa_check_poly_glyph_blt (DrawablePtr pDrawable, GCPtr pGC,
 {
     UXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable,
 		  uxa_drawable_location(pDrawable), pGC->fillStyle, pGC->alu));
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-    uxa_prepare_access_gc (pGC);
-    fbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
-    uxa_finish_access_gc (pGC);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	if (uxa_prepare_access_gc (pGC)) {
+	    fbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+	    uxa_finish_access_gc (pGC);
+	}
+	uxa_finish_access (pDrawable);
+    }
 }
 
 void
@@ -260,13 +285,16 @@ uxa_check_push_pixels (GCPtr pGC, PixmapPtr pBitmap,
     UXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable,
 		  uxa_drawable_location(&pBitmap->drawable),
 		  uxa_drawable_location(pDrawable)));
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RW);
-    uxa_prepare_access (&pBitmap->drawable, UXA_ACCESS_RO);
-    uxa_prepare_access_gc (pGC);
-    fbPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
-    uxa_finish_access_gc (pGC);
-    uxa_finish_access (&pBitmap->drawable);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RW)) {
+	if (uxa_prepare_access (&pBitmap->drawable, UXA_ACCESS_RO)) {
+	    if (uxa_prepare_access_gc (pGC)) {
+		fbPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
+		uxa_finish_access_gc (pGC);
+	    }
+	    uxa_finish_access (&pBitmap->drawable);
+	}
+	uxa_finish_access (pDrawable);
+    }
 }
 
 void
@@ -278,9 +306,10 @@ uxa_check_get_spans (DrawablePtr pDrawable,
 		 char *pdstStart)
 {
     UXA_FALLBACK(("from %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable)));
-    uxa_prepare_access (pDrawable, UXA_ACCESS_RO);
-    fbGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
-    uxa_finish_access (pDrawable);
+    if (uxa_prepare_access (pDrawable, UXA_ACCESS_RO)) {
+	fbGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+	uxa_finish_access (pDrawable);
+    }
 }
 
 void
@@ -300,28 +329,34 @@ uxa_check_composite (CARD8      op,
     UXA_FALLBACK(("from picts %p/%p to pict %p\n",
 		 pSrc, pMask, pDst));
 
-    uxa_prepare_access (pDst->pDrawable, UXA_ACCESS_RW);
-    if (pSrc->pDrawable != NULL)
-	uxa_prepare_access (pSrc->pDrawable, UXA_ACCESS_RO);
-    if (pMask && pMask->pDrawable != NULL)
-	uxa_prepare_access (pMask->pDrawable, UXA_ACCESS_RO);
-    fbComposite (op,
-                 pSrc,
-                 pMask,
-                 pDst,
-                 xSrc,
-                 ySrc,
-                 xMask,
-                 yMask,
-                 xDst,
-                 yDst,
-                 width,
-                 height);
-    if (pMask && pMask->pDrawable != NULL)
-	uxa_finish_access (pMask->pDrawable);
-    if (pSrc->pDrawable != NULL)
-	uxa_finish_access (pSrc->pDrawable);
-    uxa_finish_access (pDst->pDrawable);
+    if (uxa_prepare_access (pDst->pDrawable, UXA_ACCESS_RW))
+    {
+	if (pSrc->pDrawable == NULL ||
+	    uxa_prepare_access (pSrc->pDrawable, UXA_ACCESS_RO))
+	{
+	    if (!pMask || pMask->pDrawable == NULL ||
+		uxa_prepare_access (pMask->pDrawable, UXA_ACCESS_RO))
+	    {
+		fbComposite (op,
+			     pSrc,
+			     pMask,
+			     pDst,
+			     xSrc,
+			     ySrc,
+			     xMask,
+			     yMask,
+			     xDst,
+			     yDst,
+			     width,
+			     height);
+		if (pMask && pMask->pDrawable != NULL)
+		    uxa_finish_access (pMask->pDrawable);
+	    }
+	    if (pSrc->pDrawable != NULL)
+		uxa_finish_access (pSrc->pDrawable);
+	}
+	uxa_finish_access (pDst->pDrawable);
+    }
 }
 
 void
@@ -333,9 +368,10 @@ uxa_check_add_traps (PicturePtr	pPicture,
 {
     UXA_FALLBACK(("to pict %p (%c)\n",
 		  uxa_drawable_location(pPicture->pDrawable)));
-    uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW);
-    fbAddTraps (pPicture, x_off, y_off, ntrap, traps);
-    uxa_finish_access(pPicture->pDrawable);
+    if (uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW)) {
+	fbAddTraps (pPicture, x_off, y_off, ntrap, traps);
+	uxa_finish_access(pPicture->pDrawable);
+    }
 }
 
 /**
@@ -350,7 +386,9 @@ uxa_get_pixmap_first_pixel (PixmapPtr pPixmap)
     CARD32 pixel;
     void *fb;
 
-    uxa_prepare_access (&pPixmap->drawable, UXA_ACCESS_RO);
+    if (!uxa_prepare_access (&pPixmap->drawable, UXA_ACCESS_RO))
+	return 0;
+
     fb = pPixmap->devPrivate.ptr;
 
     switch (pPixmap->drawable.bitsPerPixel) {
diff --git a/uxa/uxa.c b/uxa/uxa.c
index 102717d..4aeb5e4 100644
--- a/uxa/uxa.c
+++ b/uxa/uxa.c
@@ -140,7 +140,7 @@ uxa_get_offscreen_pixmap (DrawablePtr drawable, int *xp, int *yp)
  * It deals with waiting for synchronization with the card, determining if
  * PrepareAccess() is necessary, and working around PrepareAccess() failure.
  */
-void
+Bool
 uxa_prepare_access(DrawablePtr pDrawable, uxa_access_t access)
 {
     ScreenPtr	    pScreen = pDrawable->pScreen;
@@ -149,10 +149,11 @@ uxa_prepare_access(DrawablePtr pDrawable, uxa_access_t access)
     Bool	    offscreen = uxa_pixmap_is_offscreen(pPixmap);
 
     if (!offscreen)
-	return;
+	return TRUE;
 
     if (uxa_screen->info->prepare_access)
-	(*uxa_screen->info->prepare_access) (pPixmap, access);
+	return (*uxa_screen->info->prepare_access) (pPixmap, access);
+    return TRUE;
 }
 
 /**
@@ -209,10 +210,11 @@ uxa_validate_gc (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
 		 * allocated pixmap.  This isn't a problem yet, since we don't
 		 * put pixmaps in FB until at least one accelerated UXA op.
 		 */
-		uxa_prepare_access(&pOldTile->drawable, UXA_ACCESS_RO);
-		pNewTile = fb24_32ReformatTile (pOldTile,
-						pDrawable->bitsPerPixel);
-		uxa_finish_access(&pOldTile->drawable);
+		if (uxa_prepare_access(&pOldTile->drawable, UXA_ACCESS_RO)) {
+		    pNewTile = fb24_32ReformatTile (pOldTile,
+						    pDrawable->bitsPerPixel);
+		    uxa_finish_access(&pOldTile->drawable);
+		}
 	    }
 	    if (pNewTile)
 	    {
@@ -227,9 +229,10 @@ uxa_validate_gc (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
 	if (!pGC->tileIsPixel && FbEvenTile (pGC->tile.pixmap->drawable.width *
 					     pDrawable->bitsPerPixel))
 	{
-	    uxa_prepare_access(&pGC->tile.pixmap->drawable, UXA_ACCESS_RW);
-	    fbPadPixmap (pGC->tile.pixmap);
-	    uxa_finish_access(&pGC->tile.pixmap->drawable);
+	    if (uxa_prepare_access(&pGC->tile.pixmap->drawable, UXA_ACCESS_RW)) {
+		fbPadPixmap (pGC->tile.pixmap);
+		uxa_finish_access(&pGC->tile.pixmap->drawable);
+	    }
 	}
 	/* Mask out the GCTile change notification, now that we've done FB's
 	 * job for it.
@@ -276,14 +279,22 @@ uxa_create_gc (GCPtr pGC)
     return TRUE;
 }
 
-void
+Bool
 uxa_prepare_access_window(WindowPtr pWin)
 {
-    if (pWin->backgroundState == BackgroundPixmap) 
-        uxa_prepare_access(&pWin->background.pixmap->drawable, UXA_ACCESS_RO);
+    if (pWin->backgroundState == BackgroundPixmap) {
+        if (!uxa_prepare_access(&pWin->background.pixmap->drawable, UXA_ACCESS_RO))
+	    return FALSE;
+    }
 
-    if (pWin->borderIsPixel == FALSE)
-        uxa_prepare_access(&pWin->border.pixmap->drawable, UXA_ACCESS_RO);
+    if (pWin->borderIsPixel == FALSE) {
+        if (!uxa_prepare_access(&pWin->border.pixmap->drawable, UXA_ACCESS_RO)) {
+	    if (pWin->backgroundState == BackgroundPixmap)
+		uxa_finish_access(&pWin->background.pixmap->drawable);
+	    return FALSE;
+	}
+    }
+    return TRUE;
 }
 
 void
@@ -301,7 +312,8 @@ uxa_change_window_attributes(WindowPtr pWin, unsigned long mask)
 {
     Bool ret;
 
-    uxa_prepare_access_window(pWin);
+    if (!uxa_prepare_access_window(pWin))
+	return FALSE;
     ret = fbChangeWindowAttributes(pWin, mask);
     uxa_finish_access_window(pWin);
     return ret;
@@ -311,7 +323,8 @@ static RegionPtr
 uxa_bitmap_to_region(PixmapPtr pPix)
 {
   RegionPtr ret;
-  uxa_prepare_access(&pPix->drawable, UXA_ACCESS_RO);
+  if (!uxa_prepare_access(&pPix->drawable, UXA_ACCESS_RO))
+    return NULL;
   ret = fbPixmapToRegion(pPix);
   uxa_finish_access(&pPix->drawable);
   return ret;
commit 90b28a56553d809374fa6d9b9529b7a8b583488c
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Dec 15 15:41:28 2008 -0800

    Handle drm_bo_map failure in 965 video and composite paths.
    
    These two paths allocate a number of objects directly.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/src/i965_render.c b/src/i965_render.c
index 3b0ee35..00cb051 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -1065,7 +1065,13 @@ _emit_batch_header_for_composite_internal (ScrnInfoPtr pScrn, Bool check_twice)
     surface_state_bo = dri_bo_alloc (pI830->bufmgr, "surface_state",
 				     3 * sizeof (brw_surface_state_padded),
 				     4096);
-    dri_bo_map (surface_state_bo, 1);
+    if (dri_bo_map (surface_state_bo, 1) != 0) {
+	dri_bo_unreference (surface_state_bo);
+	dri_bo_unreference (render_state->vertex_buffer_bo);
+	render_state->vertex_buffer_bo = NULL;
+
+	return FALSE;
+    }
     /* Set up the state buffer for the destination surface */
     i965_set_picture_surface_state(surface_state_bo, 0,
 				   pDstPicture, pDst, TRUE);
@@ -1083,7 +1089,15 @@ _emit_batch_header_for_composite_internal (ScrnInfoPtr pScrn, Bool check_twice)
     /* Set up the binding table of surface indices to surface state. */
     binding_table_bo = dri_bo_alloc (pI830->bufmgr, "binding_table",
 				     3 * sizeof (uint32_t), 4096);
-    dri_bo_map (binding_table_bo, 1);
+    if (dri_bo_map (binding_table_bo, 1) != 0) {
+	dri_bo_unreference(binding_table_bo);
+	dri_bo_unreference(surface_state_bo);
+	dri_bo_unreference (render_state->vertex_buffer_bo);
+	render_state->vertex_buffer_bo = NULL;
+
+	return FALSE;
+    }
+
     binding_table = binding_table_bo->virtual;
     binding_table[0] = 0 * sizeof (brw_surface_state_padded) + surface_state_bo->offset;
     dri_bo_emit_reloc (binding_table_bo, I915_GEM_DOMAIN_INSTRUCTION, 0,
@@ -1495,7 +1509,9 @@ i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
 	_emit_batch_header_for_composite (pScrn);
 
     /* Map the vertex_buffer buffer object so we can write to it. */
-    dri_bo_map (render_state->vertex_buffer_bo, 1);
+    if (dri_bo_map (render_state->vertex_buffer_bo, 1) != 0)
+	return;		/* XXX what else to do here? */
+
     vb = render_state->vertex_buffer_bo->virtual;
 
     i = render_state->vb_offset;
diff --git a/src/i965_video.c b/src/i965_video.c
index 7e84ae0..e9f5ced 100644
--- a/src/i965_video.c
+++ b/src/i965_video.c
@@ -343,6 +343,25 @@ intel_emit_reloc(drm_intel_bo *bo, uint32_t offset,
     return target_bo->offset + target_offset;
 }
 
+static int
+intel_alloc_and_map(I830Ptr i830, char *name, int size,
+		    drm_intel_bo **bop, void *virtualp)
+{
+    drm_intel_bo    *bo;
+
+    bo = drm_intel_bo_alloc(i830->bufmgr, name, size, 4096);
+    if (!bo)
+	return -1;
+    if (drm_intel_bo_map(bo, TRUE) != 0) {
+	drm_intel_bo_unreference(bo);
+	return -1;
+    }
+    *bop = bo;
+    *(void **) virtualp = bo->virtual;
+    memset (bo->virtual, 0, size);
+    return 0;
+}
+
 static drm_intel_bo *
 i965_create_dst_surface_state(ScrnInfoPtr scrn,
 			      PixmapPtr pixmap)
@@ -352,13 +371,10 @@ i965_create_dst_surface_state(ScrnInfoPtr scrn,
     drm_intel_bo *pixmap_bo = i830_get_pixmap_bo(pixmap);
     drm_intel_bo *surf_bo;
 
-    surf_bo = drm_intel_bo_alloc(pI830->bufmgr,
-				    "textured video surface state",
-				    4096, 4096);
-    drm_intel_bo_map(surf_bo, TRUE);
-    dest_surf_state = surf_bo->virtual;
+    if (intel_alloc_and_map(pI830, "textured video surface state", 4096,
+			    &surf_bo, &dest_surf_state) != 0)
+	return NULL;
 
-    memset(dest_surf_state, 0, sizeof(*dest_surf_state));
     dest_surf_state->ss0.surface_type = BRW_SURFACE_2D;
     dest_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32;
     if (pI830->cpp == 2) {
@@ -408,14 +424,11 @@ i965_create_src_surface_state(ScrnInfoPtr scrn,
     drm_intel_bo *surface_bo;
     struct brw_surface_state *src_surf_state;
 
-    surface_bo = drm_intel_bo_alloc(pI830->bufmgr,
-				    "textured video surface state",
-				    4096, 4096);
-    drm_intel_bo_map(surface_bo, TRUE);
-    src_surf_state = surface_bo->virtual;
+    if (intel_alloc_and_map(pI830, "textured video surface state", 4096,
+			    &surface_bo, &src_surf_state) != 0)
+	return NULL;
 
     /* Set up the source surface state buffer */
-    memset(src_surf_state, 0, sizeof(struct brw_surface_state));
     src_surf_state->ss0.surface_type = BRW_SURFACE_2D;
     src_surf_state->ss0.surface_format = src_surf_format;
     src_surf_state->ss0.writedisable_alpha = 0;
@@ -449,11 +462,9 @@ i965_create_binding_table(ScrnInfoPtr scrn, drm_intel_bo **surf_bos, int n_surf)
 
     /* Set up a binding table for our surfaces.  Only the PS will use it */
 
-    bind_bo = drm_intel_bo_alloc(pI830->bufmgr,
-				 "textured video binding table",
-				 4096, 4096);
-    drm_intel_bo_map(bind_bo, TRUE);
-    binding_table = bind_bo->virtual;
+    if (intel_alloc_and_map(pI830, "textured video binding table", 4096,
+			    &bind_bo, &binding_table) != 0)
+	return NULL;
 
     for (i = 0; i < n_surf; i++)
 	binding_table[i] = intel_emit_reloc(bind_bo, i * sizeof(uint32_t),
@@ -471,13 +482,9 @@ i965_create_sampler_state(ScrnInfoPtr scrn)
     drm_intel_bo *sampler_bo;
     struct brw_sampler_state *sampler_state;
 
-    sampler_bo = drm_intel_bo_alloc(pI830->bufmgr,
-				    "textured video sampler state",
-				    4096, 4096);
-    drm_intel_bo_map(sampler_bo, TRUE);
-    sampler_state = sampler_bo->virtual;
-
-    memset(sampler_state, 0, sizeof(struct brw_sampler_state));
+    if (intel_alloc_and_map(pI830, "textured video sampler state", 4096,
+			    &sampler_bo, &sampler_state) != 0)
+	return NULL;
 
     sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR;
     sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
@@ -496,13 +503,11 @@ i965_create_vs_state(ScrnInfoPtr scrn)
     drm_intel_bo *vs_bo;
     struct brw_vs_unit_state *vs_state;
 
-    vs_bo = drm_intel_bo_alloc(pI830->bufmgr, "textured video vs state",
-			       4096, 4096);
-    drm_intel_bo_map(vs_bo, TRUE);
-    vs_state = vs_bo->virtual;
+    if (intel_alloc_and_map(pI830, "textured video vs state", 4096,
+			    &vs_bo, &vs_state) != 0)
+	return NULL;
 
     /* Set up the vertex shader to be disabled (passthrough) */
-    memset(vs_state, 0, sizeof(*vs_state));
     vs_state->thread4.nr_urb_entries = URB_VS_ENTRIES;
     vs_state->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1;
     vs_state->vs6.vs_enable = 0;
@@ -521,6 +526,9 @@ i965_create_program(ScrnInfoPtr scrn, const uint32_t *program,
 
     prog_bo = drm_intel_bo_alloc(pI830->bufmgr, "textured video program",
 				 program_size, 4096);
+    if (!prog_bo)
+	return NULL;
+
     drm_intel_bo_subdata(prog_bo, 0, program_size, program);
 
     return prog_bo;
@@ -536,16 +544,20 @@ i965_create_sf_state(ScrnInfoPtr scrn)
     kernel_bo = i965_create_program(scrn, &sf_kernel_static[0][0],
 				    sizeof(sf_kernel_static));
 
-    sf_bo = drm_intel_bo_alloc(pI830->bufmgr, "textured video sf state",
-			       4096, 4096);
-    drm_intel_bo_map(sf_bo, TRUE);
-    sf_state = sf_bo->virtual;
+    if (!kernel_bo)
+	return NULL;
+
+    if (intel_alloc_and_map(pI830, "textured video sf state", 4096,
+			    &sf_bo, &sf_state) != 0)
+    {
+	drm_intel_bo_unreference(kernel_bo);
+	return NULL;
+    }
 
     /* Set up the SF kernel to do coord interp: for each attribute,
      * calculate dA/dx and dA/dy.  Hand these interpolation coefficients
      * back to SF which then hands pixels off to WM.
      */
-    memset(sf_state, 0, sizeof(*sf_state));
     sf_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(SF_KERNEL_NUM_GRF);
     sf_state->thread0.kernel_start_pointer =
 	intel_emit_reloc(sf_bo, offsetof(struct brw_sf_unit_state, thread0),
@@ -595,13 +607,15 @@ i965_create_wm_state(ScrnInfoPtr scrn, drm_intel_bo *sampler_bo, Bool is_packed)
 	kernel_bo = i965_create_program(scrn, &ps_kernel_planar_static[0][0],
 					sizeof(ps_kernel_planar_static));
     }
+    if (!kernel_bo)
+	return NULL;
 
-    wm_bo = drm_intel_bo_alloc(pI830->bufmgr, "textured video wm state",
-			       4096, 4096);
-    drm_intel_bo_map(wm_bo, TRUE);
-    wm_state = wm_bo->virtual;
+    if (intel_alloc_and_map(pI830, "textured video wm state", sizeof (*wm_state),
+			    &wm_bo, &wm_state)) {
+	drm_intel_bo_unreference(kernel_bo);
+	return NULL;
+    }
 
-    memset(wm_state, 0, sizeof (*wm_state));
     wm_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(PS_KERNEL_NUM_GRF);
     wm_state->thread0.kernel_start_pointer =
 	intel_emit_reloc(wm_bo, offsetof(struct brw_wm_unit_state, thread0),
@@ -647,12 +661,10 @@ i965_create_cc_vp_state(ScrnInfoPtr scrn)
     drm_intel_bo *cc_vp_bo;
     struct brw_cc_viewport *cc_viewport;
 
-    cc_vp_bo = drm_intel_bo_alloc(pI830->bufmgr, "textured video cc viewport",
-				  4096, 4096);
-    drm_intel_bo_map(cc_vp_bo, TRUE);
-    cc_viewport = cc_vp_bo->virtual;
+    if (intel_alloc_and_map(pI830, "textured video cc viewport", 4096,
+			    &cc_vp_bo, &cc_viewport) != 0)
+	return NULL;
 
-    memset (cc_viewport, 0, sizeof (*cc_viewport));
     cc_viewport->min_depth = -1.e35;
     cc_viewport->max_depth = 1.e35;
 
@@ -668,11 +680,14 @@ i965_create_cc_state(ScrnInfoPtr scrn)
     struct brw_cc_unit_state *cc_state;
 
     cc_vp_bo = i965_create_cc_vp_state(scrn);
+    if (!cc_vp_bo)
+	return NULL;
 
-    cc_bo = drm_intel_bo_alloc(pI830->bufmgr, "textured video cc state",
-			       4096, 4096);
-    drm_intel_bo_map(cc_bo, TRUE);
-    cc_state = cc_bo->virtual;
+    if (intel_alloc_and_map(pI830, "textured video cc state", sizeof(*cc_state),
+			    &cc_bo, &cc_state) != 0) {
+	drm_intel_bo_unreference(cc_vp_bo);
+	return NULL;
+    }
 
     /* Color calculator state */
     memset(cc_state, 0, sizeof(*cc_state));
@@ -809,44 +824,84 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
 
     /* Upload kernels */
     surf_bos[0] = i965_create_dst_surface_state(pScrn, pPixmap);
+    if (!surf_bos[0])
+	return;
 
     for (src_surf = 0; src_surf < n_src_surf; src_surf++) {
-	surf_bos[src_surf + 1] =
+	drm_intel_bo *surf_bo =
 	    i965_create_src_surface_state(pScrn,
 					  src_surf_base[src_surf],
 					  src_width[src_surf],
 					  src_height[src_surf],
 					  src_pitch[src_surf],
 					  src_surf_format);
+	if (!surf_bo) {
+	    int	q;
+	    for(q = 0; q < src_surf + 1; q++)
+		drm_intel_bo_unreference(surf_bos[q]);
+	    return;
+	}
+	surf_bos[src_surf + 1] = surf_bo;
     }
     bind_bo = i965_create_binding_table(pScrn, surf_bos, n_src_surf + 1);
     for (i = 0; i < n_src_surf + 1; i++) {
 	drm_intel_bo_unreference(surf_bos[i]);
 	surf_bos[i] = NULL;
     }
+    if (!bind_bo)
+	return;
 
     if (pI830->video.gen4_sampler_bo == NULL)
 	pI830->video.gen4_sampler_bo = i965_create_sampler_state(pScrn);
-    if (pI830->video.gen4_sip_kernel_bo == NULL)
+    if (pI830->video.gen4_sip_kernel_bo == NULL) {
 	pI830->video.gen4_sip_kernel_bo =
 	    i965_create_program(pScrn, &sip_kernel_static[0][0],
 				sizeof(sip_kernel_static));
+	if (!pI830->video.gen4_sip_kernel_bo) {
+	    drm_intel_bo_unreference(bind_bo);
+	    return;
+	}
+    }
 
-    if (pI830->video.gen4_vs_bo == NULL)
+    if (pI830->video.gen4_vs_bo == NULL) {
 	pI830->video.gen4_vs_bo = i965_create_vs_state(pScrn);
-    if (pI830->video.gen4_sf_bo == NULL)
+	if (!pI830->video.gen4_vs_bo) {
+	    drm_intel_bo_unreference(bind_bo);
+	    return;
+	}
+    }
+    if (pI830->video.gen4_sf_bo == NULL) {
 	pI830->video.gen4_sf_bo = i965_create_sf_state(pScrn);
+	if (!pI830->video.gen4_sf_bo) {
+	    drm_intel_bo_unreference(bind_bo);
+	    return;
+	}
+    }
     if (pI830->video.gen4_wm_packed_bo == NULL) {
 	pI830->video.gen4_wm_packed_bo =
 	    i965_create_wm_state(pScrn, pI830->video.gen4_sampler_bo, TRUE);
+	if (!pI830->video.gen4_wm_packed_bo) {
+	    drm_intel_bo_unreference(bind_bo);
+	    return;
+	}
     }
+
     if (pI830->video.gen4_wm_planar_bo == NULL) {
 	pI830->video.gen4_wm_planar_bo =
 	    i965_create_wm_state(pScrn, pI830->video.gen4_sampler_bo, FALSE);
+	if (!pI830->video.gen4_wm_planar_bo) {
+	    drm_intel_bo_unreference(bind_bo);
+	    return;
+	}
     }
 
-    if (pI830->video.gen4_cc_bo == NULL)
+    if (pI830->video.gen4_cc_bo == NULL) {
 	pI830->video.gen4_cc_bo = i965_create_cc_state(pScrn);
+	if (!pI830->video.gen4_cc_bo) {
+	    drm_intel_bo_unreference(bind_bo);
+	    return;
+	}
+    }
 
     {
 	BEGIN_BATCH(2);
@@ -1033,11 +1088,10 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
 
 	pbox++;
 
-	vb_bo = drm_intel_bo_alloc(pI830->bufmgr, "textured video vb",
-				   4096, 4096);
-	drm_intel_bo_map(vb_bo, TRUE);
+	if (intel_alloc_and_map(pI830, "textured video vb", 4096,
+				&vb_bo, &vb) != 0)
+	    break;
 
-	vb = vb_bo->virtual;
 	i = 0;
 	vb[i++] = (box_x2 - dxo) * src_scale_x;
 	vb[i++] = (box_y2 - dyo) * src_scale_y;
commit 8237faf8f3ca73ecdf0ef009a7d361b318726f6f
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Dec 15 15:35:35 2008 -0800

    Resize framebuffer on screen size change (requires UXA and DRI2)
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/src/i830.h b/src/i830.h
index a769a1c..25bf482 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -95,6 +95,7 @@ void i830_uxa_block_handler (ScreenPtr pScreen);
 
 #if defined(I830_USE_UXA) || defined(I830_USE_EXA)
 dri_bo *i830_get_pixmap_bo (PixmapPtr pixmap);
+void i830_set_pixmap_bo(PixmapPtr pixmap, dri_bo *bo);
 #endif
 
 #ifdef I830_USE_XAA
@@ -267,6 +268,8 @@ typedef struct _I830CrtcPrivateRec {
     
     int			    dpms_mode;
     
+    int			    x, y;
+
     /* Lookup table values to be set when the CRTC is enabled */
     uint8_t lut_r[256], lut_g[256], lut_b[256];
 
@@ -468,6 +471,8 @@ typedef struct _I830Rec {
    int drmMinor;
    Bool allocate_classic_textures;
 
+   Bool can_resize;
+
    Bool want_vblank_interrupts;
 #ifdef DAMAGE
    DamagePtr pDamage;
@@ -907,6 +912,10 @@ Bool i830_unbind_all_memory(ScrnInfoPtr pScrn);
 Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
 Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
 
+i830_memory *
+i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
+			  Bool secondary);
+
 /* i830_modes.c */
 DisplayModePtr i830_ddc_get_modes(xf86OutputPtr output);
 
diff --git a/src/i830_display.c b/src/i830_display.c
index 4e4ff34..50fbc4d 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -387,12 +387,14 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y)
     I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
     int pipe = intel_crtc->pipe;
     int plane = intel_crtc->plane;
-    unsigned long Start, Offset;
+    unsigned long Start, Offset, Stride;
     int dspbase = (plane == 0 ? DSPABASE : DSPBBASE);
     int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF);
     int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF);
+    int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
 
     Offset = ((y * pScrn->displayWidth + x) * pI830->cpp);
+    Stride = pScrn->displayWidth * pI830->cpp;
     if (pI830->front_buffer == NULL) {
 	/* During startup we may be called as part of monitor detection while
 	 * there is no memory allocation done, so just supply a dummy base
@@ -403,6 +405,7 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y)
 	/* offset is done by shadow painting code, not here */
 	Start = (char *)crtc->rotatedData - (char *)pI830->FbBase;
 	Offset = 0;
+	Stride = intel_crtc->rotate_mem->pitch;
     } else if (I830IsPrimary(pScrn)) {
 	Start = pI830->front_buffer->offset;
     } else {
@@ -410,6 +413,10 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y)
 	Start = pI8301->front_buffer_2->offset;
     }
 
+    crtc->x = x;
+    crtc->y = y;
+
+    OUTREG(dspstride, Stride);
     if (IS_I965G(pI830)) {
         OUTREG(dspbase, Offset);
 	POSTING_READ(dspbase);
@@ -1199,7 +1206,6 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
     int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
     int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
     int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
-    int dspstride_reg = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
     int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS;
     int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE;
     int i, num_outputs = 0;
@@ -1494,7 +1500,6 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
 	((adjusted_mode->CrtcVBlankEnd - 1) << 16));
     OUTREG(vsync_reg, (adjusted_mode->CrtcVSyncStart - 1) |
 	((adjusted_mode->CrtcVSyncEnd - 1) << 16));
-    OUTREG(dspstride_reg, pScrn->displayWidth * pI830->cpp);
     /* pipesrc and dspsize control the size that is scaled from, which should
      * always be the user's requested size.
      */
@@ -1640,10 +1645,28 @@ i830_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
 static void
 i830_crtc_set_origin(xf86CrtcPtr crtc, int x, int y)
 {
-    i830PipeSetBase(crtc, x, y);
+    if (crtc->enabled)
+	i830PipeSetBase(crtc, x, y);
 }
 #endif
 
+/* The screen bo has changed, reset each active crtc to point at
+ * the same location that it currently points at, but in the new bo
+ */
+void
+i830_set_new_crtc_bo(ScrnInfoPtr pScrn)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int			i;
+
+    for (i = 0; i < xf86_config->num_crtc; i++) {
+	xf86CrtcPtr crtc = xf86_config->crtc[i];
+
+	if (crtc->enabled && !crtc->transform_in_use)
+	    i830PipeSetBase(crtc, crtc->x, crtc->y);
+    }
+}
+
 void
 i830DescribeOutputConfiguration(ScrnInfoPtr pScrn)
 {
diff --git a/src/i830_display.h b/src/i830_display.h
index 1eeb7f1..8d767b1 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -31,6 +31,7 @@
 void i830PipeSetBase(xf86CrtcPtr crtc, int x, int y);
 void i830WaitForVblank(ScrnInfoPtr pScrn);
 void i830DescribeOutputConfiguration(ScrnInfoPtr pScrn);
+void i830_set_new_crtc_bo(ScrnInfoPtr pScrn);
 
 xf86CrtcPtr i830GetLoadDetectPipe(xf86OutputPtr output, DisplayModePtr mode, int *dpms_mode);
 void i830ReleaseLoadDetectPipe(xf86OutputPtr output, int dpms_mode);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 27d8694..3e27b07 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1085,11 +1085,108 @@ I830IsPrimary(ScrnInfoPtr pScrn)
    return TRUE;
 }
 
+
+/*
+ * Adjust *width to allow for tiling if possible
+ */
+Bool
+i830_tiled_width(I830Ptr i830, int *width, int cpp)
+{
+    Bool    tiled = FALSE;
+
+    /*
+     * Adjust the display width to allow for front buffer tiling if possible
+     */
+    if (i830->tiling) {
+	if (IS_I965G(i830)) {
+	    int tile_pixels = 512 / cpp;
+	    *width = (*width + tile_pixels - 1) &
+		~(tile_pixels - 1);
+	    tiled = TRUE;
+	} else {
+	    /* Good pitches to allow tiling.  Don't care about pitches < 1024
+	     * pixels.
+	     */
+	    static const int pitches[] = {
+		1024,
+		2048,
+		4096,
+		8192,
+		0
+	    };
+	    int i;
+
+	    for (i = 0; pitches[i] != 0; i++) {
+		if (pitches[i] >= *width) {
+		    *width = pitches[i];
+		    tiled = TRUE;
+		    break;
+		}
+	    }
+	}
+    }
+    return tiled;
+}
+
+/*
+ * Pad to accelerator requirement
+ */
+int
+i830_pad_drawable_width(int width, int cpp)
+{
+    return (width + 63) & ~63;
+}
+
 static Bool
 i830_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 {
+    I830Ptr	i830 = I830PTR(scrn);
+    int		old_x = scrn->virtualX;
+    int		old_y = scrn->virtualY;
+    int		old_width = scrn->displayWidth;
+
+    if (old_x == width && old_y == height)
+	return TRUE;
+
     scrn->virtualX = width;
     scrn->virtualY = height;
+#ifdef DRI2
+    if (i830->can_resize && i830->front_buffer)
+    {
+	i830_memory *new_front, *old_front;
+	BoxRec	    mem_box;
+	Bool	    tiled;
+	ScreenPtr   screen = screenInfo.screens[scrn->scrnIndex];
+
+	scrn->displayWidth = i830_pad_drawable_width(width, i830->cpp);
+	tiled = i830_tiled_width(i830, &scrn->displayWidth, i830->cpp);
+	xf86DrvMsg(scrn->scrnIndex, X_INFO, "Allocate new frame buffer %dx%d stride %d\n",
+		   width, height, scrn->displayWidth);
+	I830Sync(scrn);
+	i830WaitForVblank(scrn);
+	new_front = i830_allocate_framebuffer(scrn, i830, &mem_box, FALSE);
+	if (!new_front) {
+	    scrn->virtualX = old_x;
+	    scrn->virtualY = old_y;
+	    scrn->displayWidth = old_width;
+	    return FALSE;
+	}
+	old_front = i830->front_buffer;
+	i830->front_buffer = new_front;
+	i830_set_pixmap_bo(screen->GetScreenPixmap(screen),
+			   new_front->bo);
+	scrn->fbOffset = i830->front_buffer->offset;
+	screen->ModifyPixmapHeader(screen->GetScreenPixmap(screen),
+				   width, height, -1, -1, scrn->displayWidth * i830->cpp,
+				   NULL);
+	xf86DrvMsg(scrn->scrnIndex, X_INFO, "New front buffer at 0x%lx\n",
+		   i830->front_buffer->offset);
+	i830_set_new_crtc_bo(scrn);
+	I830Sync(scrn);
+	i830WaitForVblank(scrn);
+	i830_free_memory(scrn, old_front);
+    }
+#endif
     return TRUE;
 }
 
@@ -1487,8 +1584,7 @@ I830PreInitCrtcConfig(ScrnInfoPtr pScrn)
     /* See i830_exa.c comments for why we limit the framebuffer size like this.
      */
     if (IS_I965G(pI830)) {
-	max_width = 8192;
-	max_height = 8192;
+	max_height = max_width = min(16384 / pI830->cpp, 8192);
     } else {
 	max_width = 2048;
 	max_height = 2048;
@@ -1595,7 +1691,16 @@ I830AccelMethodInit(ScrnInfoPtr pScrn)
     I830SetupOutputs(pScrn);
 
     SaveHWState(pScrn);
-    if (!xf86InitialConfiguration (pScrn, FALSE))
+    pI830->can_resize = FALSE;
+    if (pI830->accel == ACCEL_UXA && pI830->directRenderingType != DRI_XF86DRI)
+	pI830->can_resize = TRUE;
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "Resizable framebuffer: %s (%d %d)\n",
+	       pI830->can_resize ? "available" : "not available",
+	       pI830->directRenderingType, pI830->accel);
+
+    if (!xf86InitialConfiguration (pScrn, pI830->can_resize))
     {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
 	RestoreHWState(pScrn);
@@ -2729,7 +2834,6 @@ failed:
 	    tiled ? "T" : "Unt");
     return FALSE;
 }
-
 /*
  * Try to allocate memory in several ways:
  *  1) If direct rendering is enabled, try to allocate enough memory for tiled
@@ -2744,39 +2848,9 @@ i830_memory_init(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     int savedDisplayWidth = pScrn->displayWidth;
-    int i;
     Bool tiled = FALSE;
 
-    /*
-     * Adjust the display width to allow for front buffer tiling if possible
-     */
-    if (pI830->tiling) {
-	if (IS_I965G(pI830)) {
-	    int tile_pixels = 512 / pI830->cpp;
-	    pScrn->displayWidth = (pScrn->displayWidth + tile_pixels - 1) &
-		~(tile_pixels - 1);
-	    tiled = TRUE;
-	} else {
-	    /* Good pitches to allow tiling.  Don't care about pitches < 1024
-	     * pixels.
-	     */
-	    static const int pitches[] = {
-		1024,
-		2048,
-		4096,
-		8192,
-		0
-	    };
-
-	    for (i = 0; pitches[i] != 0; i++) {
-		if (pitches[i] >= pScrn->displayWidth) {
-		    pScrn->displayWidth = pitches[i];
-		    tiled = TRUE;
-		    break;
-		}
-	    }
-	}
-    }
+    tiled = i830_tiled_width(pI830, &pScrn->displayWidth, pI830->cpp);
     /* Set up our video memory allocator for the chosen videoRam */
     if (!i830_allocator_init(pScrn, 0, pScrn->videoRam * KB(1))) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -2997,7 +3071,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
    if (!pI830->use_drm_mode)
        hwp = VGAHWPTR(pScrn);
 
-   pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
+   pScrn->displayWidth = i830_pad_drawable_width(pScrn->virtualX, pI830->cpp);
 
    /*
     * The "VideoRam" config file parameter specifies the maximum amount of
@@ -3061,8 +3135,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     */
    if (pI830->directRenderingType == DRI_NONE && pI830->SWCursor)
        pI830->directRenderingType = DRI_DISABLED;
-
-   if (pI830->directRenderingType == DRI_NONE && I830DRIScreenInit(pScreen))
+   if (!pI830->can_resize && pI830->directRenderingType == DRI_NONE && I830DRIScreenInit(pScreen))
        pI830->directRenderingType = DRI_XF86DRI;
 
    if (pI830->directRenderingType == DRI_XF86DRI) {
diff --git a/src/i830_exa.c b/src/i830_exa.c
index aeffedd..b300fdc 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -758,6 +758,32 @@ i830_get_pixmap_bo(PixmapPtr pixmap)
     return NULL;
 }
 
+void
+i830_set_pixmap_bo(PixmapPtr pixmap, dri_bo *bo)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pixmap->drawable.pScreen->myNum];
+    I830Ptr i830 = I830PTR(pScrn);
+    dri_bo  *old_bo = i830_get_pixmap_bo (pixmap);
+
+    if (old_bo)
+	dri_bo_unreference (old_bo);
+#if I830_USE_UXA
+    if (i830->accel == ACCEL_UXA) {
+	dri_bo_reference(bo);
+	dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, bo);
+    }
+#endif
+#ifdef XF86DRM_MODE
+    if (i830->accel == ACCEL_EXA) {
+	struct i830_exa_pixmap_priv *driver_priv =
+	    exaGetPixmapDriverPrivate(pixmap);
+	if (driver_priv) {
+	    dri_bo_reference(bo);
+	    driver_priv->bo = bo;
+	}
+    }
+#endif
+}
 #if defined(I830_USE_UXA)
 
 static void
@@ -893,6 +919,7 @@ void i830_uxa_create_screen_resources(ScreenPtr pScreen)
     if (bo != NULL) {
 	PixmapPtr   pixmap = pScreen->GetScreenPixmap(pScreen);
 	i830_uxa_set_pixmap_bo (pixmap, bo);
+	dri_bo_reference(bo);
     }
 }
 
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 2dee0bf..b6d8026 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1130,7 +1130,7 @@ IsTileable(ScrnInfoPtr pScrn, int pitch)
  * \param pI830 I830Ptr for the screen being allocated.
  * \param FbMemBox
  */
-static i830_memory *
+i830_memory *
 i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
 			  Bool secondary)
 {
@@ -1152,10 +1152,14 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
     /* We'll allocate the fb such that the root window will fit regardless of
      * rotation.
      */
-    if (!pI830->use_drm_mode && pScrn->virtualX > pScrn->virtualY)
-	fb_height = pScrn->virtualX;
-    else
-	fb_height = pScrn->virtualY;
+    fb_height = pScrn->virtualY;
+    if (!pI830->can_resize)
+    {
+	if (!pI830->use_drm_mode && pScrn->virtualX > pScrn->virtualY)
+	    fb_height = pScrn->virtualX;
+	else
+	    fb_height = pScrn->virtualY;
+    }
 
     FbMemBox->x1 = 0;
     FbMemBox->x2 = pScrn->displayWidth;
@@ -2115,114 +2119,8 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
 }
 #endif
 
-#if 0
-static i830_memory *
-i830_allocate_framebuffer_new(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox)
-{
-    unsigned int pitch = pScrn->displayWidth * pI830->cpp;
-    unsigned long minspace, avail;
-    int cacheLines;
-    int align;
-    long size, fb_height;
-    char *name;
-    int flags;
-    i830_memory *front_buffer = NULL;
-    Bool tiling;
-
-    flags = ALLOW_SHARING;
-
-    /* Clear everything first. */
-    memset(FbMemBox, 0, sizeof(*FbMemBox));
-
-    fb_height = pScrn->virtualY;
-
-    FbMemBox->x1 = 0;
-    FbMemBox->x2 = pScrn->displayWidth;
-    FbMemBox->y1 = 0;
-    FbMemBox->y2 = fb_height;
-
-    /* Calculate how much framebuffer memory to allocate.  For the
-     * initial allocation, calculate a reasonable minimum.  This is
-     * enough for the virtual screen size, plus some pixmap cache
-     * space if we're using XAA.
-     */
-    minspace = pitch * pScrn->virtualY;
-    avail = pScrn->videoRam * 1024;
-    cacheLines = 0;
-
-    size = pitch * (fb_height + cacheLines);
-    size = ROUND_TO_PAGE(size);
-
-    name = "front buffer";
-
-    /* Front buffer tiling has to be disabled with G965 XAA because some of the
-     * acceleration operations (non-XY COLOR_BLT) can't be done to tiled
-     * buffers.
-     */
-    if (!(pI830->accel == ACCEL_EXA) && IS_I965G(pI830))
-	tiling = FALSE;
-    else
-	tiling = pI830->tiling;
-
-    if (pI830->use_drm_mode)
-      tiling = FALSE;
-
-    /* Attempt to allocate it tiled first if we have page flipping on. */
-    if (tiling && IsTileable(pScrn, pitch)) {
-	/* XXX: probably not the case on 965 */
-	if (IS_I9XX(pI830))
-	    align = MB(1);
-	else
-	    align = KB(512);
-	front_buffer = i830_allocate_memory_tiled(pScrn, name, size,
-						  pitch, align, flags,
-						  TILE_XMAJOR);
-    }
-
-    /* If not, attempt it linear */
-    if (front_buffer == NULL) {
-	front_buffer = i830_allocate_memory(pScrn, name, size, KB(64), flags);
-    }
-
-    if (front_buffer == NULL) {
-	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
-		   "framebuffer. Is your VideoRAM set too low?\n");
-
-	return NULL;
-    }
-
-    return front_buffer;
-}
-#endif
 uint32_t
 i830_create_new_fb(ScrnInfoPtr pScrn, int width, int height, int *pitch)
 {
     return 0;
-
-#if 0
-    I830Ptr pI830 = I830PTR(pScrn);
-    i830_memory *old_buffer;
-
-    pScrn->virtualX = width;
-    pScrn->virtualY = height;
-    pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
-
-    *pitch = pScrn->displayWidth * pI830->cpp;
-
-    old_buffer = pI830->front_buffer;
-
-    pI830->front_buffer =
-	i830_allocate_framebuffer_new(pScrn, pI830, &pI830->FbMemBox);
-
-    ErrorF("old front size %08lx, new front size %08lx\n",
-	   old_buffer->bo->size, pI830->front_buffer->bo->size);
-    ErrorF("old front offset %08lx, new front offset %08lx\n",
-	   old_buffer->bo->offset, pI830->front_buffer->bo->offset);
-
-    i830_free_memory(pScrn, old_buffer);
-
-    i830_update_front_offset(pScrn);
-
-    return pI830->front_buffer->bo->handle;
-#endif
 }
commit 21bd4e8974e4c0e83f5f95adb0fc17290444caf5
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Dec 15 15:19:00 2008 -0800

    Make i830_allocate_memory take tiling parameters.
    
    This eliminates the separate i830_allocate_memory_tiled function which means
    that all memory objects will have tiling parameters set correctly.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/src/i830.h b/src/i830.h
index 3381c3c..a769a1c 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -141,6 +141,8 @@ enum tile_format {
     TILE_YMAJOR
 };
 
+#define PITCH_NONE 0
+
 /** Record of a linear allocation in the aperture. */
 typedef struct _i830_memory i830_memory;
 struct _i830_memory {
@@ -843,13 +845,9 @@ Bool i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset,
 			 unsigned long size);
 void i830_allocator_fini(ScrnInfoPtr pScrn);
 i830_memory * i830_allocate_memory(ScrnInfoPtr pScrn, const char *name,
-				   unsigned long size, unsigned long alignment,
-				   int flags);
-i830_memory *i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name,
-					unsigned long size,
-					unsigned long pitch,
-					unsigned long alignment, int flags,
-					enum tile_format tile_format);
+				   unsigned long size, unsigned long pitch,
+				   unsigned long alignment, int flags,
+				   enum tile_format tile_format);
 void i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity,
 			       const char *prefix);
 void i830_reset_allocations(ScrnInfoPtr pScrn);
@@ -870,6 +868,13 @@ extern uint32_t i830_create_new_fb(ScrnInfoPtr pScrn, int width, int height,
 				   int *pitch);
 extern Bool I830IsPrimary(ScrnInfoPtr pScrn);
 
+Bool
+i830_tiled_width(I830Ptr i830, int *width, int cpp);
+
+int
+i830_pad_drawable_width(int width, int cpp);
+
+
 extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg,
 			char *name);
 
diff --git a/src/i830_display.c b/src/i830_display.c
index 7a9999a..4e4ff34 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1571,12 +1571,14 @@ i830_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height)
     unsigned long rotate_pitch;
     int align = KB(4), size;
 
-    rotate_pitch = pScrn->displayWidth * pI830->cpp;
+    width = i830_pad_drawable_width(width, pI830->cpp);
+    rotate_pitch = width * pI830->cpp;
     size = rotate_pitch * height;
 
     assert(intel_crtc->rotate_mem == NULL);
     intel_crtc->rotate_mem = i830_allocate_memory(pScrn, "rotated crtc",
-						  size, align, 0);
+						  size, rotate_pitch, align,
+						  0, TILE_NONE);
     if (intel_crtc->rotate_mem == NULL) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "Couldn't allocate shadow memory for rotated CRTC\n");
@@ -1595,13 +1597,13 @@ i830_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
 {
     ScrnInfoPtr pScrn = crtc->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
-    unsigned long rotate_pitch;
+    int rotate_pitch;
     PixmapPtr rotate_pixmap;
 
     if (!data)
 	data = i830_crtc_shadow_allocate (crtc, width, height);
     
-    rotate_pitch = pScrn->displayWidth * pI830->cpp;
+    rotate_pitch = i830_pad_drawable_width(width, pI830->cpp) * pI830->cpp;
 
     rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen,
 					   width, height,
diff --git a/src/i830_memory.c b/src/i830_memory.c
index f3baa60..2dee0bf 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -120,7 +120,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 static i830_memory *
 i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name,
-		       long size, unsigned long alignment, int flags);
+		       unsigned long size, unsigned long pitch,
+		       unsigned long alignment, int flags,
+		       enum tile_format tile_format);
 
 static int i830_set_tiling(ScrnInfoPtr pScrn, unsigned int offset,
 			   unsigned int pitch, unsigned int size,
@@ -493,8 +495,9 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
 	/* Create the aperture allocation */
 	pI830->memory_manager =
 	    i830_allocate_aperture(pScrn, "DRI memory manager",
-				   mmsize, GTT_PAGE_SIZE,
-				   ALIGN_BOTH_ENDS | NEED_NON_STOLEN);
+				   mmsize, 0, GTT_PAGE_SIZE,
+				   ALIGN_BOTH_ENDS | NEED_NON_STOLEN,
+				   TILE_NONE);
 
 	if (pI830->memory_manager != NULL) {
 	    if (!pI830->use_drm_mode) {
@@ -637,7 +640,9 @@ i830_get_stolen_physical(ScrnInfoPtr pScrn, unsigned long offset,
  */
 static i830_memory *
 i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name,
-		       long size, unsigned long alignment, int flags)
+		       unsigned long size, unsigned long pitch,
+		       unsigned long alignment, int flags,
+		       enum tile_format tile_format)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     i830_memory *mem, *scan;
@@ -659,6 +664,9 @@ i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name,
     mem->size = size;
     mem->allocated_size = size;
     mem->alignment = alignment;
+    mem->tiling = tile_format;
+    mem->pitch = pitch;
+    mem->fence_nr = -1;
 
     if (alignment < GTT_PAGE_SIZE)
 	alignment = GTT_PAGE_SIZE;
@@ -753,10 +761,14 @@ i830_allocate_agp_memory(ScrnInfoPtr pScrn, i830_memory *mem, int flags)
 #ifdef XF86DRI
 static i830_memory *
 i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name,
-			unsigned long size, unsigned long align, int flags)
+			unsigned long size, unsigned long pitch,
+			unsigned long align, int flags,
+			enum tile_format tile_format)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     i830_memory *mem;
+    uint32_t bo_tiling_mode = I915_TILING_NONE;
+    int	    ret;
 
     assert((flags & NEED_PHYSICAL_ADDR) == 0);
 
@@ -788,9 +800,33 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name,
     mem->size = size;
     mem->allocated_size = size;
     mem->alignment = align;
+    mem->tiling = tile_format;
+    mem->pitch = pitch;
+    mem->fence_nr = -1;
     if (flags & NEED_LIFETIME_FIXED)
 	mem->lifetime_fixed_offset = TRUE;
 
+    switch (tile_format) {
+    case TILE_XMAJOR:
+	bo_tiling_mode = I915_TILING_X;
+	break;
+    case TILE_YMAJOR:
+	bo_tiling_mode = I915_TILING_Y;
+	break;
+    case TILE_NONE:
+    default:
+	bo_tiling_mode = I915_TILING_NONE;
+	break;
+    }
+
+    ret = dri_bo_set_tiling(mem->bo, &bo_tiling_mode);
+    if (ret != 0 || (bo_tiling_mode == I915_TILING_NONE && tile_format != TILE_NONE)) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "Failed to set tiling on %s: %s\n",
+		   mem->name,
+		   ret == 0 ? "rejected by kernel" : strerror(errno));
+	mem->tiling = TILE_NONE;
+    }
     /* Bind it if we currently control the VT */
     if (pScrn->vtSema || pI830->use_drm_mode) {
 	if (!i830_bind_memory(pScrn, mem)) {
@@ -812,7 +848,7 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name,
 }
 #endif /* XF86DRI */
 
-/* Allocates video memory at the given size and alignment.
+/* Allocates video memory at the given size, pitch, alignment and tile format.
  *
  * The memory will be bound automatically when the driver is in control of the
  * VT.  When the kernel memory manager is available and compatible with flags
@@ -832,22 +868,51 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name,
  */
 i830_memory *
 i830_allocate_memory(ScrnInfoPtr pScrn, const char *name,
-		     unsigned long size, unsigned long alignment, int flags)
+		     unsigned long size, unsigned long pitch,
+		     unsigned long alignment, int flags,
+		     enum tile_format tile_format)
 {
     i830_memory *mem;
-
 #ifdef XF86DRI
     I830Ptr pI830 = I830PTR(pScrn);
+#endif
 
+    /* Manage tile alignment and size constraints */
+    if (tile_format != TILE_NONE) {
+	/* Only allocate page-sized increments. */
+	size = ALIGN(size, GTT_PAGE_SIZE);
+
+	/* Check for maximum tiled region size */
+	if (IS_I9XX(pI830)) {
+	    if (size > MB(128))
+		return NULL;
+	} else {
+	    if (size > MB(64))
+		return NULL;
+	}
+
+	/* round to size necessary for the fence register to work */
+	size = i830_get_fence_size(pScrn, size);
+	if (IS_I965G(pI830)) {
+	    if (alignment < GTT_PAGE_SIZE)
+		alignment = GTT_PAGE_SIZE;
+	} else {
+	    /* The offset has to be aligned to at least the size of the fence
+	     * region.
+	     */
+	    alignment = size;
+	}
+    }
+#ifdef XF86DRI
     if (pI830->use_drm_mode || (pI830->memory_manager &&
 				!(flags & NEED_PHYSICAL_ADDR) &&
 				!(flags & NEED_LIFETIME_FIXED)))
     {
-	return i830_allocate_memory_bo(pScrn, name, size, alignment, flags);
+	return i830_allocate_memory_bo(pScrn, name, size, pitch, alignment, flags, tile_format);
     } else
 #endif /* XF86DRI */
     {
-	mem = i830_allocate_aperture(pScrn, name, size, alignment, flags);
+	mem = i830_allocate_aperture(pScrn, name, size, pitch, alignment, flags, tile_format);
 	if (mem == NULL)
 	    return NULL;
 
@@ -867,88 +932,6 @@ i830_allocate_memory(ScrnInfoPtr pScrn, const char *name,
     return mem;
 }
 
-/* Allocate a tiled region with the given size and pitch.
- *
- * As is, we might miss out on tiling some allocations on older hardware with
- * large framebuffer size and a small aperture size, where the first
- * allocations use a large alignment even though we've got fences to spare, and
- * the later allocations can't find enough aperture space left.  We could do
- * some search across all allocation options to fix this, probably, but that
- * would be another rewrite.
- */
-i830_memory *
-i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name,
-			   unsigned long size, unsigned long pitch,
-			   unsigned long alignment, int flags,
-			   enum tile_format tile_format)
-{
-    I830Ptr pI830 = I830PTR(pScrn);
-    unsigned long aper_size;
-    unsigned long aper_align;
-    i830_memory *mem;
-
-    if (tile_format == TILE_NONE)
-	return i830_allocate_memory(pScrn, name, size, alignment, flags);
-
-    /* Only allocate page-sized increments. */
-    size = ALIGN(size, GTT_PAGE_SIZE);
-
-    /* Check for maximum tiled region size */
-    if (IS_I9XX(pI830)) {
-	if (size > MB(128))
-	    return NULL;
-    } else {
-	if (size > MB(64))
-	    return NULL;
-    }
-
-    aper_size = i830_get_fence_size(pScrn, size);
-    if (IS_I965G(pI830)) {
-	aper_align = GTT_PAGE_SIZE;
-    } else {
-	/* The offset has to be aligned to at least the size of the fence
-	 * region.
-	 */
-	aper_align = aper_size;
-    }
-    if (aper_align < alignment)
-	aper_align = alignment;
-
-    mem = i830_allocate_memory(pScrn, name, aper_size, aper_align, flags);
-    if (mem == NULL)
-	return NULL;
-    mem->size = size;
-    mem->tiling = tile_format;
-    mem->pitch = pitch;
-    mem->fence_nr = -1;
-
-#ifdef XF86DRI
-    if (mem->bo != 0) {
-	uint32_t    tiling_mode = I915_TILING_NONE;
-	int	    ret;
-
-	if (tile_format == TILE_XMAJOR)
-	    tiling_mode = I915_TILING_X;
-	else
-	    tiling_mode = I915_TILING_Y;
-
-	ret = dri_bo_set_tiling(mem->bo, &tiling_mode);
-	if (ret != 0 || tiling_mode == I915_TILING_NONE) {
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			   "Failed to set tiling on %s: %s\n",
-			   mem->name,
-			   ret == 0 ? "rejected by kernel" : strerror(errno));
-		i830_free_memory(pScrn, mem);
-		return i830_allocate_memory(pScrn, name, size, alignment,
-					    flags);
-	    return FALSE;
-	}
-    }
-#endif
-
-    return mem;
-}
-
 void
 i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix)
 {
@@ -1042,9 +1025,9 @@ i830_allocate_ringbuffer(ScrnInfoPtr pScrn)
      * the ringbuffer since init time, so allocate it fixed for its lifetime.
      */
     pI830->LpRing->mem = i830_allocate_memory(pScrn, "ring buffer",
-					      PRIMARY_RINGBUFFER_SIZE,
+					      PRIMARY_RINGBUFFER_SIZE, PITCH_NONE,
 					      GTT_PAGE_SIZE,
-					      NEED_LIFETIME_FIXED);
+					      NEED_LIFETIME_FIXED, TILE_NONE);
     if (pI830->LpRing->mem == NULL) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "Failed to allocate Ring Buffer space\n");
@@ -1080,8 +1063,8 @@ i830_allocate_overlay(ScrnInfoPtr pScrn)
     }
 
     pI830->overlay_regs = i830_allocate_memory(pScrn, "overlay registers",
-					       OVERLAY_SIZE, GTT_PAGE_SIZE,
-					       flags);
+					       OVERLAY_SIZE, PITCH_NONE, GTT_PAGE_SIZE,
+					       flags, TILE_NONE);
     if (pI830->overlay_regs == NULL) {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		   "Failed to allocate Overlay register space.\n");
@@ -1159,7 +1142,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
     char *name;
     int flags;
     i830_memory *front_buffer = NULL;
-    Bool tiling;
+    enum tile_format tile_format = TILE_NONE;
 
     flags = ALLOW_SHARING;
 
@@ -1233,33 +1216,34 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
      * acceleration operations (non-XY COLOR_BLT) can't be done to tiled
      * buffers.
      */
-    if ((pI830->accel <= ACCEL_XAA && IS_I965G(pI830)) || pI830->use_drm_mode)
-	tiling = FALSE;
-    else
-	tiling = pI830->tiling;
+    if (pI830->tiling)
+	tile_format = TILE_XMAJOR;
+    if (pI830->accel == ACCEL_XAA && IS_I965G(pI830))
+	tile_format = TILE_NONE;
+    if (pI830->use_drm_mode)
+	tile_format = TILE_NONE;
+
+    if (!IsTileable(pScrn, pitch))
+	tile_format = TILE_NONE;
 
-    if (!i830_check_display_stride(pScrn, pitch, tiling)) {
+    if (!i830_check_display_stride(pScrn, pitch, tile_format != TILE_NONE)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Front buffer stride %d kB "
 		"exceed display limit\n", pitch/1024);
 	return NULL;
     }
 
     /* Attempt to allocate it tiled first if we have page flipping on. */
-    if (tiling && IsTileable(pScrn, pitch)) {
+    if (tile_format != TILE_NONE) {
 	/* XXX: probably not the case on 965 */
 	if (IS_I9XX(pI830))
 	    align = MB(1);
 	else
 	    align = KB(512);
-	front_buffer = i830_allocate_memory_tiled(pScrn, name, size,
-						  pitch, align, flags,
-						  TILE_XMAJOR);
-    }
-
-    /* If not, attempt it linear */
-    if (front_buffer == NULL) {
-	front_buffer = i830_allocate_memory(pScrn, name, size, KB(64), flags);
-    }
+    } else
+	align = KB(64);
+    front_buffer = i830_allocate_memory(pScrn, name, size,
+					pitch, align, flags,
+					tile_format);
 
     if (front_buffer == NULL) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
@@ -1303,8 +1287,8 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn)
     size = xf86_config->num_crtc * (HWCURSOR_SIZE + HWCURSOR_SIZE_ARGB);
 
     pI830->cursor_mem = i830_allocate_memory(pScrn, "HW cursors",
-					     size, GTT_PAGE_SIZE,
-					     flags);
+					     size, PITCH_NONE, GTT_PAGE_SIZE,
+					     flags, TILE_NONE);
     if (pI830->cursor_mem != NULL)
 	return TRUE;
 
@@ -1318,14 +1302,18 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn)
 	pI830->cursor_mem_classic[i] = i830_allocate_memory (pScrn, 
 							     "Core cursor",
 							     HWCURSOR_SIZE,
+							     PITCH_NONE,
 							     GTT_PAGE_SIZE,
-							     flags);
+							     flags,
+							     TILE_NONE);
 	if (!pI830->cursor_mem_classic[i])
 	    return FALSE;
 	pI830->cursor_mem_argb[i] = i830_allocate_memory (pScrn, "ARGB cursor",
 							  HWCURSOR_SIZE_ARGB,
+							  PITCH_NONE,
 							  GTT_PAGE_SIZE,
-							  flags);
+							  flags,
+							  TILE_NONE);
 	if (!pI830->cursor_mem_argb[i])
 	    return FALSE;
 
@@ -1370,7 +1358,9 @@ static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
      */
     pI830->compressed_front_buffer =
 	i830_allocate_memory(pScrn, "compressed frame buffer",
-			     compressed_size, KB(4), NEED_PHYSICAL_ADDR);
+			     compressed_size, PITCH_NONE,
+			     KB(4), NEED_PHYSICAL_ADDR,
+			     TILE_NONE);
 
     if (!pI830->compressed_front_buffer) {
 	pI830->fb_compression = FALSE;
@@ -1380,8 +1370,10 @@ static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
     if (!IS_GM45(pI830)) {
 	pI830->compressed_ll_buffer =
 	    i830_allocate_memory(pScrn, "compressed ll buffer",
-				 FBC_LL_SIZE + FBC_LL_PAD, KB(4),
-				 NEED_PHYSICAL_ADDR);
+				 FBC_LL_SIZE + FBC_LL_PAD,
+				 PITCH_NONE, KB(4),
+				 NEED_PHYSICAL_ADDR,
+				 TILE_NONE);
 	if (!pI830->compressed_ll_buffer) {
 	    i830_free_memory(pScrn, pI830->compressed_front_buffer);
 	    pI830->fb_compression = FALSE;
@@ -1435,7 +1427,8 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn)
 
     if (pI830->memory_manager == NULL) {
 	pI830->fake_bufmgr_mem = i830_allocate_memory(pScrn, "fake bufmgr",
-						      MB(1), GTT_PAGE_SIZE, 0);
+						      MB(1), PITCH_NONE, GTT_PAGE_SIZE, 0,
+						      TILE_NONE);
 	if (pI830->fake_bufmgr_mem == NULL) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		       "Failed to allocate fake bufmgr space.\n");
@@ -1450,7 +1443,8 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn)
 	pI830->gen4_render_state_mem =
 	    i830_allocate_memory(pScrn, "exa G965 state buffer",
 				 gen4_render_state_size(pScrn),
-				 GTT_PAGE_SIZE, 0);
+				 PITCH_NONE,
+				 GTT_PAGE_SIZE, 0, TILE_NONE);
 	if (pI830->gen4_render_state_mem == NULL) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		    "Failed to allocate exa state buffer for 965.\n");
@@ -1500,7 +1494,8 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn)
 	     */
 	    pI830->exa_offscreen =
 		i830_allocate_memory(pScrn, "exa offscreen",
-				     size, 1, NEED_LIFETIME_FIXED);
+				     size, PITCH_NONE, 1, NEED_LIFETIME_FIXED,
+				     TILE_NONE);
 	    if (pI830->exa_offscreen == NULL) {
 		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 			   "Failed to allocate EXA offscreen memory.\n");
@@ -1517,12 +1512,14 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn)
 	 */
 	pI830->xaa_scratch =
 	    i830_allocate_memory(pScrn, "xaa scratch", MAX_SCRATCH_BUFFER_SIZE,
-				 GTT_PAGE_SIZE, NEED_LIFETIME_FIXED);
+				 PITCH_NONE, GTT_PAGE_SIZE, NEED_LIFETIME_FIXED,
+				 TILE_NONE);
 	if (pI830->xaa_scratch == NULL) {
 	    pI830->xaa_scratch =
 		i830_allocate_memory(pScrn, "xaa scratch",
-				     MIN_SCRATCH_BUFFER_SIZE, GTT_PAGE_SIZE,
-				     NEED_LIFETIME_FIXED);
+				     MIN_SCRATCH_BUFFER_SIZE, PITCH_NONE,
+				     GTT_PAGE_SIZE, NEED_LIFETIME_FIXED,
+				     TILE_NONE);
 	    if (pI830->xaa_scratch == NULL) {
 		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 			   "Failed to allocate scratch buffer space\n");
@@ -1536,13 +1533,15 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn)
 	{
 	    pI830->xaa_scratch_2 =
 		i830_allocate_memory(pScrn, "xaa scratch 2",
-				     MAX_SCRATCH_BUFFER_SIZE, GTT_PAGE_SIZE,
-				     NEED_LIFETIME_FIXED);
+				     MAX_SCRATCH_BUFFER_SIZE, PITCH_NONE,
+				     GTT_PAGE_SIZE, NEED_LIFETIME_FIXED,
+				     TILE_NONE);
 	    if (pI830->xaa_scratch_2 == NULL) {
 		pI830->xaa_scratch_2 =
 		    i830_allocate_memory(pScrn, "xaa scratch 2",
-					 MIN_SCRATCH_BUFFER_SIZE,
-					 GTT_PAGE_SIZE, NEED_LIFETIME_FIXED);
+					 MIN_SCRATCH_BUFFER_SIZE, PITCH_NONE,
+					 GTT_PAGE_SIZE, NEED_LIFETIME_FIXED,
+					 TILE_NONE);
 		if (pI830->xaa_scratch_2 == NULL) {
 		    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 			       "Failed to allocate secondary scratch "
@@ -1577,6 +1576,7 @@ i830_allocate_backbuffer(ScrnInfoPtr pScrn, i830_memory **buffer,
     unsigned int pitch = pScrn->displayWidth * pI830->cpp;
     unsigned long size;
     int height;
+    enum tile_format tile_format = TILE_NONE;;
 
     if (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180))
 	height = pScrn->virtualY;
@@ -1587,22 +1587,18 @@ i830_allocate_backbuffer(ScrnInfoPtr pScrn, i830_memory **buffer,
     if (pI830->tiling && IsTileable(pScrn, pitch))
     {
 	size = ROUND_TO_PAGE(pitch * ALIGN(height, 16));
-	*buffer = i830_allocate_memory_tiled(pScrn, name, size, pitch,
-					     GTT_PAGE_SIZE,
-					     ALIGN_BOTH_ENDS |
-					     ALLOW_SHARING,
-					     TILE_XMAJOR);
+	tile_format = TILE_XMAJOR;
     }
-
-    /* Otherwise, just allocate it linear.  The offset must stay constant
-     * currently because we don't ever update the DRI maps after screen init.
-     */
-    if (*buffer == NULL) {
+    else
+    {
 	size = ROUND_TO_PAGE(pitch * height);
-	*buffer = i830_allocate_memory(pScrn, name, size, GTT_PAGE_SIZE,
-				       ALIGN_BOTH_ENDS |
-				       ALLOW_SHARING);
+	tile_format = TILE_NONE;
     }
+    *buffer = i830_allocate_memory(pScrn, name, size, pitch,
+				   GTT_PAGE_SIZE,
+				   ALIGN_BOTH_ENDS |
+				   ALLOW_SHARING,
+				   tile_format);
 
     if (*buffer == NULL) {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -1620,42 +1616,27 @@ i830_allocate_depthbuffer(ScrnInfoPtr pScrn)
     unsigned long size;
     unsigned int pitch = pScrn->displayWidth * pI830->cpp;
     int height;
+    int flags;
+    enum tile_format tile_format = TILE_NONE;
 
-    /* XXX: this rotation stuff is bogus */
-    if (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180))
-	height = pScrn->virtualY;
-    else
-	height = pScrn->virtualX;
+    height = pScrn->virtualY;
 
     /* First try allocating it tiled */
+    flags = ALLOW_SHARING;
     if (pI830->tiling && IsTileable(pScrn, pitch))
     {
-	enum tile_format tile_format;
-
-	size = ROUND_TO_PAGE(pitch * ALIGN(height, 16));
-
 	/* The 965 requires that the depth buffer be in Y Major format, while
 	 * the rest appear to fail when handed that format.
 	 */
 	tile_format = IS_I965G(pI830) ? TILE_YMAJOR: TILE_XMAJOR;
-
-	pI830->depth_buffer =
-	    i830_allocate_memory_tiled(pScrn, "depth buffer", size, pitch,
-				       GTT_PAGE_SIZE,
-				       ALIGN_BOTH_ENDS |
-				       ALLOW_SHARING,
-				       tile_format);
+	height = ALIGN(height, 16);
+	flags |= ALIGN_BOTH_ENDS;
     }
+    size = ROUND_TO_PAGE(pitch * height);
 
-    /* Otherwise, allocate it linear. The offset must stay constant
-     * currently because we don't ever update the DRI maps after screen init.
-     */
-    if (pI830->depth_buffer == NULL) {
-	size = ROUND_TO_PAGE(pitch * height);
-	pI830->depth_buffer =
-	    i830_allocate_memory(pScrn, "depth buffer", size, GTT_PAGE_SIZE,
-				 ALLOW_SHARING);
-    }
+    pI830->depth_buffer =
+	    i830_allocate_memory(pScrn, "depth buffer", size, pitch,
+				 GTT_PAGE_SIZE, flags, tile_format);
 
     if (pI830->depth_buffer == NULL) {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -1696,9 +1677,11 @@ i830_allocate_texture_memory(ScrnInfoPtr pScrn)
 	 * made conditional on DRM version.
 	 */
 	pI830->textures = i830_allocate_memory(pScrn, "classic textures", size,
+					       PITCH_NONE,
 					       GTT_PAGE_SIZE,
 					       ALLOW_SHARING |
-					       NEED_LIFETIME_FIXED);
+					       NEED_LIFETIME_FIXED,
+					       TILE_NONE);
 	if (pI830->textures == NULL) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		       "Failed to allocate texture space.\n");
@@ -1723,7 +1706,8 @@ i830_allocate_hwstatus(ScrnInfoPtr pScrn)
     if (HWS_NEED_NONSTOLEN(pI830))
 	    flags |= NEED_NON_STOLEN;
     pI830->hw_status = i830_allocate_memory(pScrn, "HW status",
-	    HWSTATUS_PAGE_SIZE, GTT_PAGE_SIZE, flags);
+	    HWSTATUS_PAGE_SIZE, PITCH_NONE, GTT_PAGE_SIZE, flags,
+					    TILE_NONE);
     if (pI830->hw_status == NULL) {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		"Failed to allocate hw status page.\n");
@@ -1738,8 +1722,10 @@ i830_allocate_pwrctx(ScrnInfoPtr pScrn)
     I830Ptr pI830 = I830PTR(pScrn);
 
     pI830->power_context = i830_allocate_memory(pScrn, "power context",
-						PWRCTX_SIZE, GTT_PAGE_SIZE,
-						NEED_LIFETIME_FIXED);
+						PWRCTX_SIZE, PITCH_NONE,
+						GTT_PAGE_SIZE,
+						NEED_LIFETIME_FIXED,
+						TILE_NONE);
     if (!pI830->power_context) {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		"Failed to allocate power context.\n");
@@ -1805,6 +1791,11 @@ i830_set_tiling(ScrnInfoPtr pScrn, unsigned int offset,
 
     assert(tile_format != TILE_NONE);
 
+    if (pI830->need_sync) {
+	I830Sync(pScrn);
+	pI830->need_sync = FALSE;
+    }
+
     if (IS_I965G(pI830))
 	max_fence = FENCE_NEW_NR;
     else
@@ -2108,8 +2099,8 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
                                i830_memory **buffer, unsigned long size,
                                int flags)
 {
-    *buffer = i830_allocate_memory(pScrn, name, size,
-                                   GTT_PAGE_SIZE, flags);
+    *buffer = i830_allocate_memory(pScrn, name, size, PITCH_NONE,
+                                   GTT_PAGE_SIZE, flags, TILE_NONE);
 
     if (!*buffer) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
diff --git a/src/i830_video.c b/src/i830_video.c
index 87fa020..8a3718d 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2389,8 +2389,9 @@ I830PutImage(ScrnInfoPtr pScrn,
     }
 
     if (pPriv->buf == NULL) {
-	pPriv->buf = i830_allocate_memory(pScrn, "xv buffer", alloc_size, 16,
-					  0);
+	pPriv->buf = i830_allocate_memory(pScrn, "xv buffer",
+					  alloc_size, 0, 16,
+					  0, TILE_NONE);
     }
 
     if (pPriv->buf == NULL)
@@ -2724,7 +2725,7 @@ I830AllocateSurface(ScrnInfoPtr pScrn,
     fbpitch = pI830->cpp * pScrn->displayWidth;
     size = pitch * h;
 
-    pPriv->buf = i830_allocate_memory(pScrn, "xv surface buffer", size, 16, 0);
+    pPriv->buf = i830_allocate_memory(pScrn, "xv surface buffer", size, 0, 16, 0, TILE_NONE);
     if (pPriv->buf == NULL) {
 	xfree(surface->pitches);
 	xfree(surface->offsets);
diff --git a/src/i965_hwmc.c b/src/i965_hwmc.c
index 1c293d1..99e86f5 100644
--- a/src/i965_hwmc.c
+++ b/src/i965_hwmc.c
@@ -49,7 +49,7 @@ static int alloc_drm_memory_tiled(ScrnInfoPtr pScrn,
 	char *name, size_t size, unsigned long pitch, unsigned long alignment)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    if ((mem->buffer = i830_allocate_memory_tiled(pScrn, 
+    if ((mem->buffer = i830_allocate_memory(pScrn,
 	    name, size, pitch,
 	    GTT_PAGE_SIZE, ALIGN_BOTH_ENDS, TILE_XMAJOR)) == NULL) {
 	ErrorF("Fail to alloc \n");
@@ -75,8 +75,8 @@ static int alloc_drm_memory(ScrnInfoPtr pScrn,
 {
     I830Ptr pI830 = I830PTR(pScrn);
     if ((mem->buffer = i830_allocate_memory(pScrn, 
-	    name, size, 
-	    GTT_PAGE_SIZE, ALIGN_BOTH_ENDS)) == NULL) {
+	    name, size, PITCH_NONE, GTT_PAGE_SIZE,
+	    ALIGN_BOTH_ENDS, TILE_NONE)) == NULL) {
 	ErrorF("Fail to alloc \n");
 	return BadAlloc;
     }


More information about the xorg-commit mailing list