xf86-video-intel: 2 commits - src/i830_exa.c src/i830_uxa.c src/Makefile.am uxa/uxa-render.c

Carl Worth cworth at kemper.freedesktop.org
Tue Jun 9 19:08:07 PDT 2009


 src/Makefile.am  |    2 
 src/i830_exa.c   |  743 -------------------------------------------------------
 src/i830_uxa.c   |  743 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 uxa/uxa-render.c |   53 +++
 4 files changed, 790 insertions(+), 751 deletions(-)

New commits:
commit accdbd23676d812d2345f86d8e3ee62f108841ff
Author: Carl Worth <cworth at cworth.org>
Date:   Fri May 29 15:34:20 2009 -0700

    UXA: Rasterize trapezoids to system memory, not a pixmap
    
    Since we're only doing software rasterization right now, anyway, it
    makes more sense to just rasterize to system memory and then upload
    to a pixmap once complete. This avoids expensive read-modify-write
    cycles.
    
    This results in a 2.4x speedup for a real-world test case that's
    heavy on trapezoids, which is swfdec running on the following file:
    
    http://michalevy.com/wp-content/uploads/Giant%20Steps%202007.swf
    
    Many thanks to Chris Wilson for his cairo-traces repository and
    cairo-perf-trace tool which makes it so easy to measure things
    like this.

diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c
index b377bf5..2d81ac4 100644
--- a/uxa/uxa-render.c
+++ b/uxa/uxa-render.c
@@ -897,23 +897,62 @@ uxa_trapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
 	PicturePtr	pPicture;
 	INT16		xDst, yDst;
 	INT16		xRel, yRel;
+	int		width, height, stride;
+	PixmapPtr	pPixmap;
+	GCPtr		pGC;
+	pixman_image_t	*image;
 
 	xDst = traps[0].left.p1.x >> 16;
 	yDst = traps[0].left.p1.y >> 16;
 
+	width = bounds.x2 - bounds.x1;
+	height = bounds.y2 - bounds.y1;
+	stride = (width * BitsPerPixel (maskFormat->depth) + 7) / 8;
+
 	pPicture = uxa_create_alpha_picture (pScreen, pDst, maskFormat,
-	                                  bounds.x2 - bounds.x1,
-	                                  bounds.y2 - bounds.y1);
+					     width, height);
 	if (!pPicture)
 	    return;
 
-	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);
+	image = pixman_image_create_bits (pPicture->format,
+					  width, height,
+					  NULL, stride);
+	if (!image) {
+	    FreePicture (pPicture, 0);
+	    return;
 	}
 
+	for (; ntrap; ntrap--, traps++)
+	    pixman_rasterize_trapezoid (image, (pixman_trapezoid_t *) traps,
+					-bounds.x1, -bounds.y1);
+
+	pPixmap = GetScratchPixmapHeader(pScreen, width, height,
+					 maskFormat->depth,
+					 BitsPerPixel (maskFormat->depth),
+					 PixmapBytePad (width, maskFormat->depth),
+					 pixman_image_get_data (image));
+	if (!pPixmap) {
+	    FreePicture (pPicture, 0);
+	    pixman_image_unref (image);
+	    return;
+	}
+
+	pGC = GetScratchGC (pPicture->pDrawable->depth, pScreen);
+	if (!pGC)
+	{
+	    FreeScratchPixmapHeader (pPixmap);
+	    pixman_image_unref (image);
+	    FreePicture (pPicture, 0);
+	    return;
+	}
+
+	(*pGC->ops->CopyArea) (&pPixmap->drawable, pPicture->pDrawable,
+			       pGC, 0, 0, width, height, 0, 0);
+
+	FreeScratchGC (pGC);
+	FreeScratchPixmapHeader (pPixmap);
+	pixman_image_unref (image);
+
 	xRel = bounds.x1 + xSrc - xDst;
 	yRel = bounds.y1 + ySrc - yDst;
 	CompositePicture (op, pSrc, pPicture, pDst,
commit b5e32c9cf896a0b93d193d797a8e83b4aa4691fb
Author: Carl Worth <cworth at cworth.org>
Date:   Fri May 1 13:51:39 2009 -0700

    Rename i830_exa.c to i830_uxa.c
    
    It was just confusing otherwise, (since the EXA code has all been
    removed now).

diff --git a/src/Makefile.am b/src/Makefile.am
index 3f42e16..6496dec 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -104,7 +104,7 @@ intel_drv_la_SOURCES = \
 	 i915_reg.h \
 	 i915_video.c \
 	 i965_video.c \
-	 i830_exa.c \
+	 i830_uxa.c \
 	 i830_render.c \
 	 i915_render.c \
 	 i965_render.c \
diff --git a/src/i830_exa.c b/src/i830_exa.c
deleted file mode 100644
index eb35014..0000000
--- a/src/i830_exa.c
+++ /dev/null
@@ -1,743 +0,0 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-All Rights Reserved.
-Copyright (c) 2005 Jesse Barnes <jbarnes at virtuousgeek.org>
-  Based on code from i830_xaa.c.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "xf86.h"
-#include "xaarop.h"
-#include "i830.h"
-#include "i810_reg.h"
-#include "i915_drm.h"
-#include <string.h>
-#include <sys/mman.h>
-
-const int I830CopyROP[16] =
-{
-   ROP_0,               /* GXclear */
-   ROP_DSa,             /* GXand */
-   ROP_SDna,            /* GXandReverse */
-   ROP_S,               /* GXcopy */
-   ROP_DSna,            /* GXandInverted */
-   ROP_D,               /* GXnoop */
-   ROP_DSx,             /* GXxor */
-   ROP_DSo,             /* GXor */
-   ROP_DSon,            /* GXnor */
-   ROP_DSxn,            /* GXequiv */
-   ROP_Dn,              /* GXinvert*/
-   ROP_SDno,            /* GXorReverse */
-   ROP_Sn,              /* GXcopyInverted */
-   ROP_DSno,            /* GXorInverted */
-   ROP_DSan,            /* GXnand */
-   ROP_1                /* GXset */
-};
-
-const int I830PatternROP[16] =
-{
-    ROP_0,
-    ROP_DPa,
-    ROP_PDna,
-    ROP_P,
-    ROP_DPna,
-    ROP_D,
-    ROP_DPx,
-    ROP_DPo,
-    ROP_DPon,
-    ROP_PDxn,
-    ROP_Dn,
-    ROP_PDno,
-    ROP_Pn,
-    ROP_DPno,
-    ROP_DPan,
-    ROP_1
-};
-
-static int uxa_pixmap_index;
-
-/**
- * Returns whether a given pixmap is tiled or not.
- *
- * Currently, we only have one pixmap that might be tiled, which is the front
- * buffer.  At the point where we are tiling some pixmaps managed by the
- * general allocator, we should move this to using pixmap privates.
- */
-Bool
-i830_pixmap_tiled(PixmapPtr pPixmap)
-{
-    ScreenPtr pScreen = pPixmap->drawable.pScreen;
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    I830Ptr pI830 = I830PTR(pScrn);
-    unsigned long offset;
-    dri_bo *bo;
-
-    bo = i830_get_pixmap_bo(pPixmap);
-    if (bo != NULL) {
-	uint32_t tiling_mode, swizzle_mode;
-	int ret;
-
-	ret = drm_intel_bo_get_tiling(bo, &tiling_mode, &swizzle_mode);
-	if (ret != 0) {
-	    FatalError("Couldn't get tiling on bo %p: %s\n",
-		       bo, strerror(-ret));
-	}
-
-	return tiling_mode != I915_TILING_NONE;
-    }
-
-    offset = intel_get_pixmap_offset(pPixmap);
-    if (offset == pI830->front_buffer->offset &&
-	pI830->front_buffer->tiling != TILE_NONE)
-    {
-	return TRUE;
-    }
-
-    return FALSE;
-}
-
-Bool
-i830_get_aperture_space(ScrnInfoPtr pScrn, drm_intel_bo **bo_table, int num_bos)
-{
-    I830Ptr pI830 = I830PTR(pScrn);
-
-    if (pI830->batch_bo == NULL)
-	I830FALLBACK("VT inactive\n");
-
-    bo_table[0] = pI830->batch_bo;
-    if (drm_intel_bufmgr_check_aperture_space(bo_table, num_bos) != 0) {
-	intel_batch_flush(pScrn, FALSE);
-	bo_table[0] = pI830->batch_bo;
-	if (drm_intel_bufmgr_check_aperture_space(bo_table, num_bos) != 0)
-	    I830FALLBACK("Couldn't get aperture space for BOs\n");
-    }
-    return TRUE;
-}
-
-static unsigned long
-i830_pixmap_pitch(PixmapPtr pixmap)
-{
-    return pixmap->devKind;
-}
-
-static int
-i830_pixmap_pitch_is_aligned(PixmapPtr pixmap)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pixmap->drawable.pScreen->myNum];
-    I830Ptr pI830 = I830PTR(pScrn);
-
-    return i830_pixmap_pitch(pixmap) % pI830->accel_pixmap_pitch_alignment == 0;
-}
-
-/**
- * Sets up hardware state for a series of solid fills.
- */
-static Bool
-i830_uxa_prepare_solid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
-    I830Ptr pI830 = I830PTR(pScrn);
-    unsigned long pitch;
-    drm_intel_bo *bo_table[] = {
-	NULL, /* batch_bo */
-	i830_get_pixmap_bo(pPixmap),
-    };
-
-    if (!UXA_PM_IS_SOLID(&pPixmap->drawable, planemask))
-	I830FALLBACK("planemask is not solid");
-
-    if (pPixmap->drawable.bitsPerPixel == 24)
-	I830FALLBACK("solid 24bpp unsupported!\n");
-
-    if (pPixmap->drawable.bitsPerPixel < 8)
-	I830FALLBACK("under 8bpp pixmaps unsupported\n");
-
-    i830_exa_check_pitch_2d(pPixmap);
-
-    pitch = i830_pixmap_pitch(pPixmap);
-
-    if (!i830_pixmap_pitch_is_aligned(pPixmap))
-	I830FALLBACK("pixmap pitch not aligned");
-
-    if (!i830_get_aperture_space(pScrn, bo_table, ARRAY_SIZE(bo_table)))
-	return FALSE;
-
-    pI830->BR[13] = (I830PatternROP[alu] & 0xff) << 16 ;
-    switch (pPixmap->drawable.bitsPerPixel) {
-	case 8:
-	    break;
-	case 16:
-	    /* RGB565 */
-	    pI830->BR[13] |= (1 << 24);
-	    break;
-	case 32:
-	    /* RGB8888 */
-	    pI830->BR[13] |= ((1 << 24) | (1 << 25));
-	    break;
-    }
-    pI830->BR[16] = fg;
-    return TRUE;
-}
-
-static void
-i830_uxa_solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
-    I830Ptr pI830 = I830PTR(pScrn);
-    unsigned long pitch;
-    uint32_t cmd;
-
-    pitch = i830_pixmap_pitch(pPixmap);
-
-    {
-	BEGIN_BATCH(6);
-
-	cmd = XY_COLOR_BLT_CMD;
-
-	if (pPixmap->drawable.bitsPerPixel == 32)
-	    cmd |= XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB;
-
-	if (IS_I965G(pI830) && i830_pixmap_tiled(pPixmap)) {
-	    assert((pitch % 512) == 0);
-	    pitch >>= 2;
-	    cmd |= XY_COLOR_BLT_TILED;
-	}
-
-	OUT_BATCH(cmd);
-
-	OUT_BATCH(pI830->BR[13] | pitch);
-	OUT_BATCH((y1 << 16) | (x1 & 0xffff));
-	OUT_BATCH((y2 << 16) | (x2 & 0xffff));
-	OUT_RELOC_PIXMAP(pPixmap, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
-	OUT_BATCH(pI830->BR[16]);
-	ADVANCE_BATCH();
-    }
-}
-
-static void
-i830_uxa_done_solid(PixmapPtr pPixmap)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
-
-    i830_debug_sync(pScrn);
-}
-
-/**
- * TODO:
- *   - support planemask using FULL_BLT_CMD?
- */
-static Bool
-i830_uxa_prepare_copy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
-		      int ydir, int alu, Pixel planemask)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
-    I830Ptr pI830 = I830PTR(pScrn);
-    drm_intel_bo *bo_table[] = {
-	NULL, /* batch_bo */
-	i830_get_pixmap_bo(pSrcPixmap),
-	i830_get_pixmap_bo(pDstPixmap),
-    };
-
-    if (!UXA_PM_IS_SOLID(&pSrcPixmap->drawable, planemask))
-	I830FALLBACK("planemask is not solid");
-
-    if (pDstPixmap->drawable.bitsPerPixel < 8)
-	I830FALLBACK("under 8bpp pixmaps unsupported\n");
-
-    if (!i830_get_aperture_space(pScrn, bo_table, ARRAY_SIZE(bo_table)))
-	return FALSE;
-
-    i830_exa_check_pitch_2d(pSrcPixmap);
-    i830_exa_check_pitch_2d(pDstPixmap);
-
-    pI830->pSrcPixmap = pSrcPixmap;
-
-    pI830->BR[13] = I830CopyROP[alu] << 16;
-
-    switch (pSrcPixmap->drawable.bitsPerPixel) {
-    case 8:
-	break;
-    case 16:
-	pI830->BR[13] |= (1 << 24);
-	break;
-    case 32:
-	pI830->BR[13] |= ((1 << 25) | (1 << 24));
-	break;
-    }
-    return TRUE;
-}
-
-static void
-i830_uxa_copy(PixmapPtr pDstPixmap, int src_x1, int src_y1, int dst_x1,
-	      int dst_y1, int w, int h)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
-    I830Ptr pI830 = I830PTR(pScrn);
-    uint32_t cmd;
-    int dst_x2, dst_y2;
-    unsigned int dst_pitch, src_pitch;
-
-    dst_x2 = dst_x1 + w;
-    dst_y2 = dst_y1 + h;
-
-    dst_pitch = i830_pixmap_pitch(pDstPixmap);
-    src_pitch = i830_pixmap_pitch(pI830->pSrcPixmap);
-
-    {
-	BEGIN_BATCH(8);
-
-	cmd = XY_SRC_COPY_BLT_CMD;
-
-	if (pDstPixmap->drawable.bitsPerPixel == 32)
-	    cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB;
-
-	if (IS_I965G(pI830)) {
-	    if (i830_pixmap_tiled(pDstPixmap)) {
-		assert((dst_pitch % 512) == 0);
-		dst_pitch >>= 2;
-		cmd |= XY_SRC_COPY_BLT_DST_TILED;
-	    }
-
-	    if (i830_pixmap_tiled(pI830->pSrcPixmap)) {
-		assert((src_pitch % 512) == 0);
-		src_pitch >>= 2;
-		cmd |= XY_SRC_COPY_BLT_SRC_TILED;
-	    }
-	}
-
-	OUT_BATCH(cmd);
-
-	OUT_BATCH(pI830->BR[13] | dst_pitch);
-	OUT_BATCH((dst_y1 << 16) | (dst_x1 & 0xffff));
-	OUT_BATCH((dst_y2 << 16) | (dst_x2 & 0xffff));
-	OUT_RELOC_PIXMAP(pDstPixmap, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
-	OUT_BATCH((src_y1 << 16) | (src_x1 & 0xffff));
-	OUT_BATCH(src_pitch);
-	OUT_RELOC_PIXMAP(pI830->pSrcPixmap, I915_GEM_DOMAIN_RENDER, 0, 0);
-
-	ADVANCE_BATCH();
-    }
-}
-
-static void
-i830_uxa_done_copy(PixmapPtr pDstPixmap)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
-
-    i830_debug_sync(pScrn);
-}
-
-
-/**
- * Do any cleanup from the Composite operation.
- *
- * This is shared between i830 through i965.
- */
-void
-i830_done_composite(PixmapPtr pDst)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
-
-    i830_debug_sync(pScrn);
-}
-
-#define xFixedToFloat(val) \
-	((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0))
-
-static Bool
-_i830_transform_point (PictTransformPtr transform,
-		       float		x,
-		       float		y,
-		       float		result[3])
-{
-    int		    j;
-
-    for (j = 0; j < 3; j++)
-    {
-	result[j] = (xFixedToFloat (transform->matrix[j][0]) * x +
-		     xFixedToFloat (transform->matrix[j][1]) * y +
-		     xFixedToFloat (transform->matrix[j][2]));
-    }
-    if (!result[2])
-	return FALSE;
-    return TRUE;
-}
-
-/**
- * Returns the floating-point coordinates transformed by the given transform.
- *
- * transform may be null.
- */
-Bool
-i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
-				 float *x_out, float *y_out)
-{
-    if (transform == NULL) {
-	*x_out = x;
-	*y_out = y;
-    } else {
-	float	result[3];
-
-	if (!_i830_transform_point (transform, (float) x, (float) y, result))
-	    return FALSE;
-	*x_out = result[0] / result[2];
-	*y_out = result[1] / result[2];
-    }
-    return TRUE;
-}
-
-/**
- * Returns the un-normalized floating-point coordinates transformed by the given transform.
- *
- * transform may be null.
- */
-Bool
-i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
-				    float *x_out, float *y_out, float *w_out)
-{
-    if (transform == NULL) {
-	*x_out = x;
-	*y_out = y;
-	*w_out = 1;
-    } else {
-	float    result[3];
-
-	if (!_i830_transform_point (transform, (float) x, (float) y, result))
-	    return FALSE;
-	*x_out = result[0];
-	*y_out = result[1];
-	*w_out = result[2];
-    }
-    return TRUE;
-}
-
-/**
- * Returns whether the provided transform is affine.
- *
- * transform may be null.
- */
-Bool
-i830_transform_is_affine (PictTransformPtr t)
-{
-    if (t == NULL)
-	return TRUE;
-    return t->matrix[2][0] == 0 && t->matrix[2][1] == 0;
-}
-
-dri_bo *
-i830_get_pixmap_bo(PixmapPtr pixmap)
-{
-    ScreenPtr screen = pixmap->drawable.pScreen;
-    ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-    I830Ptr i830 = I830PTR(scrn);
-
-    if (i830->accel == ACCEL_UXA)
-	return dixLookupPrivate(&pixmap->devPrivates, &uxa_pixmap_index);
-    else
-	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->accel == ACCEL_UXA) {
-	if (bo != NULL)
-	    dri_bo_reference(bo);
-	dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, bo);
-    }
-}
-
-static void
-i830_uxa_set_pixmap_bo (PixmapPtr pixmap, dri_bo *bo)
-{
-    dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, bo);
-}
-
-static Bool
-i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access)
-{
-    dri_bo *bo = i830_get_pixmap_bo (pixmap);
-
-    if (bo) {
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	I830Ptr i830 = I830PTR(scrn);
-	
-	intel_batch_flush(scrn, FALSE);
-
-	/* No VT sema or GEM?  No GTT mapping. */
-	if (!scrn->vtSema || !i830->have_gem) {
-	    if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0)
-		return FALSE;
-	    pixmap->devPrivate.ptr = bo->virtual;
-	    return TRUE;
-	}
-
-	/* Kernel manages fences at GTT map/fault time */
-	if (i830->kernel_exec_fencing) {
-	    if (bo->size < i830->max_gtt_map_size) {
-		if (drm_intel_gem_bo_map_gtt(bo)) {
-		    xf86DrvMsg(scrn->scrnIndex, X_WARNING,
-			       "%s: bo map failed\n",
-			       __FUNCTION__);
-		    return FALSE;
-		}
-	    } else {
-		if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0) {
-		    xf86DrvMsg(scrn->scrnIndex, X_WARNING,
-			       "%s: bo map failed\n",
-			       __FUNCTION__);
-		    return FALSE;
-		}
-	    }
-	    pixmap->devPrivate.ptr = bo->virtual;
-	} else { /* or not... */
-	    if (drm_intel_bo_pin(bo, 4096) != 0)
-		return FALSE;
-	    drm_intel_gem_bo_start_gtt_access(bo, access == UXA_ACCESS_RW);
-	    pixmap->devPrivate.ptr = i830->FbBase + bo->offset;
-	}
-    }
-    return TRUE;
-}
-
-static void
-i830_uxa_finish_access (PixmapPtr pixmap)
-{
-    dri_bo *bo = i830_get_pixmap_bo (pixmap);
-
-    if (bo) {
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	I830Ptr i830 = I830PTR(scrn);
-
-	if (bo == i830->front_buffer->bo)
-	    i830->need_flush = TRUE;
-
-	if (!scrn->vtSema || !i830->have_gem) {
-	    dri_bo_unmap(bo);
-	    pixmap->devPrivate.ptr = NULL;
-	    return;
-	}
-
-	if (i830->kernel_exec_fencing)
-	    if (bo->size < i830->max_gtt_map_size)
-		drm_intel_gem_bo_unmap_gtt(bo);
-	    else
-		dri_bo_unmap(bo);
-	else
-	    drm_intel_bo_unpin(bo);
-	pixmap->devPrivate.ptr = NULL;
-    }
-}
-
-void
-i830_uxa_block_handler (ScreenPtr screen)
-{
-    ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-    I830Ptr i830 = I830PTR(scrn);
-
-    if (i830->need_flush) {
-	dri_bo_wait_rendering (i830->front_buffer->bo);
-	i830->need_flush = FALSE;
-    }
-}
-
-static Bool
-i830_uxa_pixmap_is_offscreen(PixmapPtr pixmap)
-{
-    ScreenPtr screen = pixmap->drawable.pScreen;
-
-    /* The front buffer is always in memory and pinned */
-    if (screen->GetScreenPixmap(screen) == pixmap)
-	return TRUE;
-
-    return i830_get_pixmap_bo (pixmap) != NULL;
-}
-
-static PixmapPtr
-i830_uxa_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usage)
-{
-    ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-    I830Ptr i830 = I830PTR(scrn);
-    dri_bo *bo;
-    int stride;
-    PixmapPtr pixmap;
-    
-    if (w > 32767 || h > 32767)
-	return NullPixmap;
-
-    if (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE)
-	return fbCreatePixmap (screen, w, h, depth, usage);
-
-    pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
-
-    if (w && h)
-    {
-	unsigned int size;
-	uint32_t tiling = I915_TILING_NONE;
-
-	stride = ROUND_TO((w * pixmap->drawable.bitsPerPixel + 7) / 8,
-			  i830->accel_pixmap_pitch_alignment);
-
-	if (usage == INTEL_CREATE_PIXMAP_TILING_X)
-	    tiling = I915_TILING_X;
-	else if (usage == INTEL_CREATE_PIXMAP_TILING_Y)
-	    tiling = I915_TILING_Y;
-
-	if (tiling == I915_TILING_NONE) {
-	    size = stride * h;
-	} else {
-	    stride = i830_get_fence_pitch(i830, stride, tiling);
-	    /* Round the object up to the size of the fence it will live in
-	     * if necessary.  We could potentially make the kernel allocate
-	     * a larger aperture space and just bind the subset of pages in,
-	     * but this is easier and also keeps us out of trouble (as much)
-	     * with drm_intel_bufmgr_check_aperture().
-	     */
-	    size = i830_get_fence_size(i830, stride * h);
-	}
-
-	bo = drm_intel_bo_alloc_for_render(i830->bufmgr, "pixmap", size, 0);
-	if (!bo) {
-	    fbDestroyPixmap (pixmap);
-	    return NullPixmap;
-	}
-
-	if (tiling != I915_TILING_NONE)
-	    drm_intel_bo_set_tiling(bo, &tiling, stride);
-
-	screen->ModifyPixmapHeader (pixmap, w, h, 0, 0, stride, NULL);
-    
-	i830_uxa_set_pixmap_bo (pixmap, bo);
-    }
-
-    return pixmap;
-}
-
-static Bool
-i830_uxa_destroy_pixmap (PixmapPtr pixmap)
-{
-    if (pixmap->refcnt == 1) {
-	dri_bo  *bo = i830_get_pixmap_bo (pixmap);
-    
-	if (bo)
-	    dri_bo_unreference (bo);
-    }
-    fbDestroyPixmap (pixmap);
-    return TRUE;
-}
-
-void i830_uxa_create_screen_resources(ScreenPtr pScreen)
-{
-    ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
-    I830Ptr i830 = I830PTR(scrn);
-    dri_bo *bo = i830->front_buffer->bo;
-
-    if (bo != NULL) {
-	PixmapPtr   pixmap = pScreen->GetScreenPixmap(pScreen);
-	i830_uxa_set_pixmap_bo (pixmap, bo);
-	dri_bo_reference(bo);
-    }
-}
-
-Bool
-i830_uxa_init (ScreenPtr pScreen)
-{
-    ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
-    I830Ptr i830 = I830PTR(scrn);
-
-    if (!dixRequestPrivate(&uxa_pixmap_index, 0))
-	return FALSE;
-
-    i830->uxa_driver = uxa_driver_alloc();
-    if (i830->uxa_driver == NULL) {
-	i830->accel = ACCEL_NONE;
-	return FALSE;
-    }
-    memset(i830->uxa_driver, 0, sizeof(*i830->uxa_driver));
-
-    i830->bufferOffset = 0;
-    i830->uxa_driver->uxa_major = 1;
-    i830->uxa_driver->uxa_minor = 0;
-
-    /* Solid fill */
-    i830->uxa_driver->prepare_solid = i830_uxa_prepare_solid;
-    i830->uxa_driver->solid = i830_uxa_solid;
-    i830->uxa_driver->done_solid = i830_uxa_done_solid;
-
-    /* Copy */
-    i830->uxa_driver->prepare_copy = i830_uxa_prepare_copy;
-    i830->uxa_driver->copy = i830_uxa_copy;
-    i830->uxa_driver->done_copy = i830_uxa_done_copy;
-
-    /* Composite */
-    if (!IS_I9XX(i830)) {
-    	i830->uxa_driver->check_composite = i830_check_composite;
-    	i830->uxa_driver->prepare_composite = i830_prepare_composite;
-    	i830->uxa_driver->composite = i830_composite;
-    	i830->uxa_driver->done_composite = i830_done_composite;
-    } else if (IS_I915G(i830) || IS_I915GM(i830) ||
-	       IS_I945G(i830) || IS_I945GM(i830) || IS_G33CLASS(i830))
-    {
-	i830->uxa_driver->check_composite = i915_check_composite;
-   	i830->uxa_driver->prepare_composite = i915_prepare_composite;
-	i830->uxa_driver->composite = i915_composite;
-    	i830->uxa_driver->done_composite = i830_done_composite;
-    } else {
- 	i830->uxa_driver->check_composite = i965_check_composite;
- 	i830->uxa_driver->prepare_composite = i965_prepare_composite;
- 	i830->uxa_driver->composite = i965_composite;
- 	i830->uxa_driver->done_composite = i830_done_composite;
-    }
-
-    i830->uxa_driver->prepare_access = i830_uxa_prepare_access;
-    i830->uxa_driver->finish_access = i830_uxa_finish_access;
-    i830->uxa_driver->pixmap_is_offscreen = i830_uxa_pixmap_is_offscreen;
-
-    if(!uxa_driver_init(pScreen, i830->uxa_driver)) {
-	xf86DrvMsg(scrn->scrnIndex, X_INFO,
-		   "UXA initialization failed\n");
-	xfree(i830->uxa_driver);
-	i830->accel = ACCEL_NONE;
-	return FALSE;
-    }
-
-    pScreen->CreatePixmap = i830_uxa_create_pixmap;
-    pScreen->DestroyPixmap = i830_uxa_destroy_pixmap;
-
-    uxa_set_fallback_debug(pScreen, i830->fallback_debug);
-
-    return TRUE;
-}
diff --git a/src/i830_uxa.c b/src/i830_uxa.c
new file mode 100644
index 0000000..eb35014
--- /dev/null
+++ b/src/i830_uxa.c
@@ -0,0 +1,743 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+Copyright (c) 2005 Jesse Barnes <jbarnes at virtuousgeek.org>
+  Based on code from i830_xaa.c.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xaarop.h"
+#include "i830.h"
+#include "i810_reg.h"
+#include "i915_drm.h"
+#include <string.h>
+#include <sys/mman.h>
+
+const int I830CopyROP[16] =
+{
+   ROP_0,               /* GXclear */
+   ROP_DSa,             /* GXand */
+   ROP_SDna,            /* GXandReverse */
+   ROP_S,               /* GXcopy */
+   ROP_DSna,            /* GXandInverted */
+   ROP_D,               /* GXnoop */
+   ROP_DSx,             /* GXxor */
+   ROP_DSo,             /* GXor */
+   ROP_DSon,            /* GXnor */
+   ROP_DSxn,            /* GXequiv */
+   ROP_Dn,              /* GXinvert*/
+   ROP_SDno,            /* GXorReverse */
+   ROP_Sn,              /* GXcopyInverted */
+   ROP_DSno,            /* GXorInverted */
+   ROP_DSan,            /* GXnand */
+   ROP_1                /* GXset */
+};
+
+const int I830PatternROP[16] =
+{
+    ROP_0,
+    ROP_DPa,
+    ROP_PDna,
+    ROP_P,
+    ROP_DPna,
+    ROP_D,
+    ROP_DPx,
+    ROP_DPo,
+    ROP_DPon,
+    ROP_PDxn,
+    ROP_Dn,
+    ROP_PDno,
+    ROP_Pn,
+    ROP_DPno,
+    ROP_DPan,
+    ROP_1
+};
+
+static int uxa_pixmap_index;
+
+/**
+ * Returns whether a given pixmap is tiled or not.
+ *
+ * Currently, we only have one pixmap that might be tiled, which is the front
+ * buffer.  At the point where we are tiling some pixmaps managed by the
+ * general allocator, we should move this to using pixmap privates.
+ */
+Bool
+i830_pixmap_tiled(PixmapPtr pPixmap)
+{
+    ScreenPtr pScreen = pPixmap->drawable.pScreen;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    unsigned long offset;
+    dri_bo *bo;
+
+    bo = i830_get_pixmap_bo(pPixmap);
+    if (bo != NULL) {
+	uint32_t tiling_mode, swizzle_mode;
+	int ret;
+
+	ret = drm_intel_bo_get_tiling(bo, &tiling_mode, &swizzle_mode);
+	if (ret != 0) {
+	    FatalError("Couldn't get tiling on bo %p: %s\n",
+		       bo, strerror(-ret));
+	}
+
+	return tiling_mode != I915_TILING_NONE;
+    }
+
+    offset = intel_get_pixmap_offset(pPixmap);
+    if (offset == pI830->front_buffer->offset &&
+	pI830->front_buffer->tiling != TILE_NONE)
+    {
+	return TRUE;
+    }
+
+    return FALSE;
+}
+
+Bool
+i830_get_aperture_space(ScrnInfoPtr pScrn, drm_intel_bo **bo_table, int num_bos)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (pI830->batch_bo == NULL)
+	I830FALLBACK("VT inactive\n");
+
+    bo_table[0] = pI830->batch_bo;
+    if (drm_intel_bufmgr_check_aperture_space(bo_table, num_bos) != 0) {
+	intel_batch_flush(pScrn, FALSE);
+	bo_table[0] = pI830->batch_bo;
+	if (drm_intel_bufmgr_check_aperture_space(bo_table, num_bos) != 0)
+	    I830FALLBACK("Couldn't get aperture space for BOs\n");
+    }
+    return TRUE;
+}
+
+static unsigned long
+i830_pixmap_pitch(PixmapPtr pixmap)
+{
+    return pixmap->devKind;
+}
+
+static int
+i830_pixmap_pitch_is_aligned(PixmapPtr pixmap)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pixmap->drawable.pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    return i830_pixmap_pitch(pixmap) % pI830->accel_pixmap_pitch_alignment == 0;
+}
+
+/**
+ * Sets up hardware state for a series of solid fills.
+ */
+static Bool
+i830_uxa_prepare_solid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    unsigned long pitch;
+    drm_intel_bo *bo_table[] = {
+	NULL, /* batch_bo */
+	i830_get_pixmap_bo(pPixmap),
+    };
+
+    if (!UXA_PM_IS_SOLID(&pPixmap->drawable, planemask))
+	I830FALLBACK("planemask is not solid");
+
+    if (pPixmap->drawable.bitsPerPixel == 24)
+	I830FALLBACK("solid 24bpp unsupported!\n");
+
+    if (pPixmap->drawable.bitsPerPixel < 8)
+	I830FALLBACK("under 8bpp pixmaps unsupported\n");
+
+    i830_exa_check_pitch_2d(pPixmap);
+
+    pitch = i830_pixmap_pitch(pPixmap);
+
+    if (!i830_pixmap_pitch_is_aligned(pPixmap))
+	I830FALLBACK("pixmap pitch not aligned");
+
+    if (!i830_get_aperture_space(pScrn, bo_table, ARRAY_SIZE(bo_table)))
+	return FALSE;
+
+    pI830->BR[13] = (I830PatternROP[alu] & 0xff) << 16 ;
+    switch (pPixmap->drawable.bitsPerPixel) {
+	case 8:
+	    break;
+	case 16:
+	    /* RGB565 */
+	    pI830->BR[13] |= (1 << 24);
+	    break;
+	case 32:
+	    /* RGB8888 */
+	    pI830->BR[13] |= ((1 << 24) | (1 << 25));
+	    break;
+    }
+    pI830->BR[16] = fg;
+    return TRUE;
+}
+
+static void
+i830_uxa_solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    unsigned long pitch;
+    uint32_t cmd;
+
+    pitch = i830_pixmap_pitch(pPixmap);
+
+    {
+	BEGIN_BATCH(6);
+
+	cmd = XY_COLOR_BLT_CMD;
+
+	if (pPixmap->drawable.bitsPerPixel == 32)
+	    cmd |= XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB;
+
+	if (IS_I965G(pI830) && i830_pixmap_tiled(pPixmap)) {
+	    assert((pitch % 512) == 0);
+	    pitch >>= 2;
+	    cmd |= XY_COLOR_BLT_TILED;
+	}
+
+	OUT_BATCH(cmd);
+
+	OUT_BATCH(pI830->BR[13] | pitch);
+	OUT_BATCH((y1 << 16) | (x1 & 0xffff));
+	OUT_BATCH((y2 << 16) | (x2 & 0xffff));
+	OUT_RELOC_PIXMAP(pPixmap, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
+	OUT_BATCH(pI830->BR[16]);
+	ADVANCE_BATCH();
+    }
+}
+
+static void
+i830_uxa_done_solid(PixmapPtr pPixmap)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+
+    i830_debug_sync(pScrn);
+}
+
+/**
+ * TODO:
+ *   - support planemask using FULL_BLT_CMD?
+ */
+static Bool
+i830_uxa_prepare_copy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
+		      int ydir, int alu, Pixel planemask)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    drm_intel_bo *bo_table[] = {
+	NULL, /* batch_bo */
+	i830_get_pixmap_bo(pSrcPixmap),
+	i830_get_pixmap_bo(pDstPixmap),
+    };
+
+    if (!UXA_PM_IS_SOLID(&pSrcPixmap->drawable, planemask))
+	I830FALLBACK("planemask is not solid");
+
+    if (pDstPixmap->drawable.bitsPerPixel < 8)
+	I830FALLBACK("under 8bpp pixmaps unsupported\n");
+
+    if (!i830_get_aperture_space(pScrn, bo_table, ARRAY_SIZE(bo_table)))
+	return FALSE;
+
+    i830_exa_check_pitch_2d(pSrcPixmap);
+    i830_exa_check_pitch_2d(pDstPixmap);
+
+    pI830->pSrcPixmap = pSrcPixmap;
+
+    pI830->BR[13] = I830CopyROP[alu] << 16;
+
+    switch (pSrcPixmap->drawable.bitsPerPixel) {
+    case 8:
+	break;
+    case 16:
+	pI830->BR[13] |= (1 << 24);
+	break;
+    case 32:
+	pI830->BR[13] |= ((1 << 25) | (1 << 24));
+	break;
+    }
+    return TRUE;
+}
+
+static void
+i830_uxa_copy(PixmapPtr pDstPixmap, int src_x1, int src_y1, int dst_x1,
+	      int dst_y1, int w, int h)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+    I830Ptr pI830 = I830PTR(pScrn);
+    uint32_t cmd;
+    int dst_x2, dst_y2;
+    unsigned int dst_pitch, src_pitch;
+
+    dst_x2 = dst_x1 + w;
+    dst_y2 = dst_y1 + h;
+
+    dst_pitch = i830_pixmap_pitch(pDstPixmap);
+    src_pitch = i830_pixmap_pitch(pI830->pSrcPixmap);
+
+    {
+	BEGIN_BATCH(8);
+
+	cmd = XY_SRC_COPY_BLT_CMD;
+
+	if (pDstPixmap->drawable.bitsPerPixel == 32)
+	    cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB;
+
+	if (IS_I965G(pI830)) {
+	    if (i830_pixmap_tiled(pDstPixmap)) {
+		assert((dst_pitch % 512) == 0);
+		dst_pitch >>= 2;
+		cmd |= XY_SRC_COPY_BLT_DST_TILED;
+	    }
+
+	    if (i830_pixmap_tiled(pI830->pSrcPixmap)) {
+		assert((src_pitch % 512) == 0);
+		src_pitch >>= 2;
+		cmd |= XY_SRC_COPY_BLT_SRC_TILED;
+	    }
+	}
+
+	OUT_BATCH(cmd);
+
+	OUT_BATCH(pI830->BR[13] | dst_pitch);
+	OUT_BATCH((dst_y1 << 16) | (dst_x1 & 0xffff));
+	OUT_BATCH((dst_y2 << 16) | (dst_x2 & 0xffff));
+	OUT_RELOC_PIXMAP(pDstPixmap, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
+	OUT_BATCH((src_y1 << 16) | (src_x1 & 0xffff));
+	OUT_BATCH(src_pitch);
+	OUT_RELOC_PIXMAP(pI830->pSrcPixmap, I915_GEM_DOMAIN_RENDER, 0, 0);
+
+	ADVANCE_BATCH();
+    }
+}
+
+static void
+i830_uxa_done_copy(PixmapPtr pDstPixmap)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+
+    i830_debug_sync(pScrn);
+}
+
+
+/**
+ * Do any cleanup from the Composite operation.
+ *
+ * This is shared between i830 through i965.
+ */
+void
+i830_done_composite(PixmapPtr pDst)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+
+    i830_debug_sync(pScrn);
+}
+
+#define xFixedToFloat(val) \
+	((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0))
+
+static Bool
+_i830_transform_point (PictTransformPtr transform,
+		       float		x,
+		       float		y,
+		       float		result[3])
+{
+    int		    j;
+
+    for (j = 0; j < 3; j++)
+    {
+	result[j] = (xFixedToFloat (transform->matrix[j][0]) * x +
+		     xFixedToFloat (transform->matrix[j][1]) * y +
+		     xFixedToFloat (transform->matrix[j][2]));
+    }
+    if (!result[2])
+	return FALSE;
+    return TRUE;
+}
+
+/**
+ * Returns the floating-point coordinates transformed by the given transform.
+ *
+ * transform may be null.
+ */
+Bool
+i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
+				 float *x_out, float *y_out)
+{
+    if (transform == NULL) {
+	*x_out = x;
+	*y_out = y;
+    } else {
+	float	result[3];
+
+	if (!_i830_transform_point (transform, (float) x, (float) y, result))
+	    return FALSE;
+	*x_out = result[0] / result[2];
+	*y_out = result[1] / result[2];
+    }
+    return TRUE;
+}
+
+/**
+ * Returns the un-normalized floating-point coordinates transformed by the given transform.
+ *
+ * transform may be null.
+ */
+Bool
+i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
+				    float *x_out, float *y_out, float *w_out)
+{
+    if (transform == NULL) {
+	*x_out = x;
+	*y_out = y;
+	*w_out = 1;
+    } else {
+	float    result[3];
+
+	if (!_i830_transform_point (transform, (float) x, (float) y, result))
+	    return FALSE;
+	*x_out = result[0];
+	*y_out = result[1];
+	*w_out = result[2];
+    }
+    return TRUE;
+}
+
+/**
+ * Returns whether the provided transform is affine.
+ *
+ * transform may be null.
+ */
+Bool
+i830_transform_is_affine (PictTransformPtr t)
+{
+    if (t == NULL)
+	return TRUE;
+    return t->matrix[2][0] == 0 && t->matrix[2][1] == 0;
+}
+
+dri_bo *
+i830_get_pixmap_bo(PixmapPtr pixmap)
+{
+    ScreenPtr screen = pixmap->drawable.pScreen;
+    ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+    I830Ptr i830 = I830PTR(scrn);
+
+    if (i830->accel == ACCEL_UXA)
+	return dixLookupPrivate(&pixmap->devPrivates, &uxa_pixmap_index);
+    else
+	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->accel == ACCEL_UXA) {
+	if (bo != NULL)
+	    dri_bo_reference(bo);
+	dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, bo);
+    }
+}
+
+static void
+i830_uxa_set_pixmap_bo (PixmapPtr pixmap, dri_bo *bo)
+{
+    dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, bo);
+}
+
+static Bool
+i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access)
+{
+    dri_bo *bo = i830_get_pixmap_bo (pixmap);
+
+    if (bo) {
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	I830Ptr i830 = I830PTR(scrn);
+	
+	intel_batch_flush(scrn, FALSE);
+
+	/* No VT sema or GEM?  No GTT mapping. */
+	if (!scrn->vtSema || !i830->have_gem) {
+	    if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0)
+		return FALSE;
+	    pixmap->devPrivate.ptr = bo->virtual;
+	    return TRUE;
+	}
+
+	/* Kernel manages fences at GTT map/fault time */
+	if (i830->kernel_exec_fencing) {
+	    if (bo->size < i830->max_gtt_map_size) {
+		if (drm_intel_gem_bo_map_gtt(bo)) {
+		    xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+			       "%s: bo map failed\n",
+			       __FUNCTION__);
+		    return FALSE;
+		}
+	    } else {
+		if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0) {
+		    xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+			       "%s: bo map failed\n",
+			       __FUNCTION__);
+		    return FALSE;
+		}
+	    }
+	    pixmap->devPrivate.ptr = bo->virtual;
+	} else { /* or not... */
+	    if (drm_intel_bo_pin(bo, 4096) != 0)
+		return FALSE;
+	    drm_intel_gem_bo_start_gtt_access(bo, access == UXA_ACCESS_RW);
+	    pixmap->devPrivate.ptr = i830->FbBase + bo->offset;
+	}
+    }
+    return TRUE;
+}
+
+static void
+i830_uxa_finish_access (PixmapPtr pixmap)
+{
+    dri_bo *bo = i830_get_pixmap_bo (pixmap);
+
+    if (bo) {
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	I830Ptr i830 = I830PTR(scrn);
+
+	if (bo == i830->front_buffer->bo)
+	    i830->need_flush = TRUE;
+
+	if (!scrn->vtSema || !i830->have_gem) {
+	    dri_bo_unmap(bo);
+	    pixmap->devPrivate.ptr = NULL;
+	    return;
+	}
+
+	if (i830->kernel_exec_fencing)
+	    if (bo->size < i830->max_gtt_map_size)
+		drm_intel_gem_bo_unmap_gtt(bo);
+	    else
+		dri_bo_unmap(bo);
+	else
+	    drm_intel_bo_unpin(bo);
+	pixmap->devPrivate.ptr = NULL;
+    }
+}
+
+void
+i830_uxa_block_handler (ScreenPtr screen)
+{
+    ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+    I830Ptr i830 = I830PTR(scrn);
+
+    if (i830->need_flush) {
+	dri_bo_wait_rendering (i830->front_buffer->bo);
+	i830->need_flush = FALSE;
+    }
+}
+
+static Bool
+i830_uxa_pixmap_is_offscreen(PixmapPtr pixmap)
+{
+    ScreenPtr screen = pixmap->drawable.pScreen;
+
+    /* The front buffer is always in memory and pinned */
+    if (screen->GetScreenPixmap(screen) == pixmap)
+	return TRUE;
+
+    return i830_get_pixmap_bo (pixmap) != NULL;
+}
+
+static PixmapPtr
+i830_uxa_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usage)
+{
+    ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+    I830Ptr i830 = I830PTR(scrn);
+    dri_bo *bo;
+    int stride;
+    PixmapPtr pixmap;
+    
+    if (w > 32767 || h > 32767)
+	return NullPixmap;
+
+    if (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE)
+	return fbCreatePixmap (screen, w, h, depth, usage);
+
+    pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
+
+    if (w && h)
+    {
+	unsigned int size;
+	uint32_t tiling = I915_TILING_NONE;
+
+	stride = ROUND_TO((w * pixmap->drawable.bitsPerPixel + 7) / 8,
+			  i830->accel_pixmap_pitch_alignment);
+
+	if (usage == INTEL_CREATE_PIXMAP_TILING_X)
+	    tiling = I915_TILING_X;
+	else if (usage == INTEL_CREATE_PIXMAP_TILING_Y)
+	    tiling = I915_TILING_Y;
+
+	if (tiling == I915_TILING_NONE) {
+	    size = stride * h;
+	} else {
+	    stride = i830_get_fence_pitch(i830, stride, tiling);
+	    /* Round the object up to the size of the fence it will live in
+	     * if necessary.  We could potentially make the kernel allocate
+	     * a larger aperture space and just bind the subset of pages in,
+	     * but this is easier and also keeps us out of trouble (as much)
+	     * with drm_intel_bufmgr_check_aperture().
+	     */
+	    size = i830_get_fence_size(i830, stride * h);
+	}
+
+	bo = drm_intel_bo_alloc_for_render(i830->bufmgr, "pixmap", size, 0);
+	if (!bo) {
+	    fbDestroyPixmap (pixmap);
+	    return NullPixmap;
+	}
+
+	if (tiling != I915_TILING_NONE)
+	    drm_intel_bo_set_tiling(bo, &tiling, stride);
+
+	screen->ModifyPixmapHeader (pixmap, w, h, 0, 0, stride, NULL);
+    
+	i830_uxa_set_pixmap_bo (pixmap, bo);
+    }
+
+    return pixmap;
+}
+
+static Bool
+i830_uxa_destroy_pixmap (PixmapPtr pixmap)
+{
+    if (pixmap->refcnt == 1) {
+	dri_bo  *bo = i830_get_pixmap_bo (pixmap);
+    
+	if (bo)
+	    dri_bo_unreference (bo);
+    }
+    fbDestroyPixmap (pixmap);
+    return TRUE;
+}
+
+void i830_uxa_create_screen_resources(ScreenPtr pScreen)
+{
+    ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
+    I830Ptr i830 = I830PTR(scrn);
+    dri_bo *bo = i830->front_buffer->bo;
+
+    if (bo != NULL) {
+	PixmapPtr   pixmap = pScreen->GetScreenPixmap(pScreen);
+	i830_uxa_set_pixmap_bo (pixmap, bo);
+	dri_bo_reference(bo);
+    }
+}
+
+Bool
+i830_uxa_init (ScreenPtr pScreen)
+{
+    ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
+    I830Ptr i830 = I830PTR(scrn);
+
+    if (!dixRequestPrivate(&uxa_pixmap_index, 0))
+	return FALSE;
+
+    i830->uxa_driver = uxa_driver_alloc();
+    if (i830->uxa_driver == NULL) {
+	i830->accel = ACCEL_NONE;
+	return FALSE;
+    }
+    memset(i830->uxa_driver, 0, sizeof(*i830->uxa_driver));
+
+    i830->bufferOffset = 0;
+    i830->uxa_driver->uxa_major = 1;
+    i830->uxa_driver->uxa_minor = 0;
+
+    /* Solid fill */
+    i830->uxa_driver->prepare_solid = i830_uxa_prepare_solid;
+    i830->uxa_driver->solid = i830_uxa_solid;
+    i830->uxa_driver->done_solid = i830_uxa_done_solid;
+
+    /* Copy */
+    i830->uxa_driver->prepare_copy = i830_uxa_prepare_copy;
+    i830->uxa_driver->copy = i830_uxa_copy;
+    i830->uxa_driver->done_copy = i830_uxa_done_copy;
+
+    /* Composite */
+    if (!IS_I9XX(i830)) {
+    	i830->uxa_driver->check_composite = i830_check_composite;
+    	i830->uxa_driver->prepare_composite = i830_prepare_composite;
+    	i830->uxa_driver->composite = i830_composite;
+    	i830->uxa_driver->done_composite = i830_done_composite;
+    } else if (IS_I915G(i830) || IS_I915GM(i830) ||
+	       IS_I945G(i830) || IS_I945GM(i830) || IS_G33CLASS(i830))
+    {
+	i830->uxa_driver->check_composite = i915_check_composite;
+   	i830->uxa_driver->prepare_composite = i915_prepare_composite;
+	i830->uxa_driver->composite = i915_composite;
+    	i830->uxa_driver->done_composite = i830_done_composite;
+    } else {
+ 	i830->uxa_driver->check_composite = i965_check_composite;
+ 	i830->uxa_driver->prepare_composite = i965_prepare_composite;
+ 	i830->uxa_driver->composite = i965_composite;
+ 	i830->uxa_driver->done_composite = i830_done_composite;
+    }
+
+    i830->uxa_driver->prepare_access = i830_uxa_prepare_access;
+    i830->uxa_driver->finish_access = i830_uxa_finish_access;
+    i830->uxa_driver->pixmap_is_offscreen = i830_uxa_pixmap_is_offscreen;
+
+    if(!uxa_driver_init(pScreen, i830->uxa_driver)) {
+	xf86DrvMsg(scrn->scrnIndex, X_INFO,
+		   "UXA initialization failed\n");
+	xfree(i830->uxa_driver);
+	i830->accel = ACCEL_NONE;
+	return FALSE;
+    }
+
+    pScreen->CreatePixmap = i830_uxa_create_pixmap;
+    pScreen->DestroyPixmap = i830_uxa_destroy_pixmap;
+
+    uxa_set_fallback_debug(pScreen, i830->fallback_debug);
+
+    return TRUE;
+}


More information about the xorg-commit mailing list