Home | History | Annotate | Line # | Download | only in src
      1 /**************************************************************************
      2 
      3 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
      4 All Rights Reserved.
      5 Copyright (c) 2005 Jesse Barnes <jbarnes (at) virtuousgeek.org>
      6   Based on code from i830_xaa.c.
      7 
      8 Permission is hereby granted, free of charge, to any person obtaining a
      9 copy of this software and associated documentation files (the
     10 "Software"), to deal in the Software without restriction, including
     11 without limitation the rights to use, copy, modify, merge, publish,
     12 distribute, sub license, and/or sell copies of the Software, and to
     13 permit persons to whom the Software is furnished to do so, subject to
     14 the following conditions:
     15 
     16 The above copyright notice and this permission notice (including the
     17 next paragraph) shall be included in all copies or substantial portions
     18 of the Software.
     19 
     20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     21 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     23 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
     24 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     25 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     26 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     27 
     28 **************************************************************************/
     29 
     30 #ifdef HAVE_CONFIG_H
     31 #include "config.h"
     32 #endif
     33 
     34 #include "xf86.h"
     35 #include "xaarop.h"
     36 #include "i830.h"
     37 #include "i810_reg.h"
     38 #include "i915_drm.h"
     39 #include <string.h>
     40 #include <sys/mman.h>
     41 
     42 const int I830CopyROP[16] =
     43 {
     44    ROP_0,               /* GXclear */
     45    ROP_DSa,             /* GXand */
     46    ROP_SDna,            /* GXandReverse */
     47    ROP_S,               /* GXcopy */
     48    ROP_DSna,            /* GXandInverted */
     49    ROP_D,               /* GXnoop */
     50    ROP_DSx,             /* GXxor */
     51    ROP_DSo,             /* GXor */
     52    ROP_DSon,            /* GXnor */
     53    ROP_DSxn,            /* GXequiv */
     54    ROP_Dn,              /* GXinvert*/
     55    ROP_SDno,            /* GXorReverse */
     56    ROP_Sn,              /* GXcopyInverted */
     57    ROP_DSno,            /* GXorInverted */
     58    ROP_DSan,            /* GXnand */
     59    ROP_1                /* GXset */
     60 };
     61 
     62 const int I830PatternROP[16] =
     63 {
     64     ROP_0,
     65     ROP_DPa,
     66     ROP_PDna,
     67     ROP_P,
     68     ROP_DPna,
     69     ROP_D,
     70     ROP_DPx,
     71     ROP_DPo,
     72     ROP_DPon,
     73     ROP_PDxn,
     74     ROP_Dn,
     75     ROP_PDno,
     76     ROP_Pn,
     77     ROP_DPno,
     78     ROP_DPan,
     79     ROP_1
     80 };
     81 
     82 static DevPrivateKeyRec uxa_pixmap_index;
     83 
     84 /**
     85  * Returns whether a given pixmap is tiled or not.
     86  *
     87  * Currently, we only have one pixmap that might be tiled, which is the front
     88  * buffer.  At the point where we are tiling some pixmaps managed by the
     89  * general allocator, we should move this to using pixmap privates.
     90  */
     91 Bool
     92 i830_pixmap_tiled(PixmapPtr pPixmap)
     93 {
     94     ScreenPtr pScreen = pPixmap->drawable.pScreen;
     95     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     96     I830Ptr pI830 = I830PTR(pScrn);
     97     unsigned long offset;
     98     dri_bo *bo;
     99 
    100     bo = i830_get_pixmap_bo(pPixmap);
    101     if (bo != NULL) {
    102 	uint32_t tiling_mode, swizzle_mode;
    103 	int ret;
    104 
    105 	ret = drm_intel_bo_get_tiling(bo, &tiling_mode, &swizzle_mode);
    106 	if (ret != 0) {
    107 	    FatalError("Couldn't get tiling on bo %p: %s\n",
    108 		       bo, strerror(-ret));
    109 	}
    110 
    111 	return tiling_mode != I915_TILING_NONE;
    112     }
    113 
    114     offset = intel_get_pixmap_offset(pPixmap);
    115     if (offset == pI830->front_buffer->offset &&
    116 	pI830->front_buffer->tiling != TILE_NONE)
    117     {
    118 	return TRUE;
    119     }
    120 
    121     return FALSE;
    122 }
    123 
    124 Bool
    125 i830_get_aperture_space(ScrnInfoPtr pScrn, drm_intel_bo **bo_table, int num_bos)
    126 {
    127     I830Ptr pI830 = I830PTR(pScrn);
    128 
    129     if (pI830->batch_bo == NULL)
    130 	I830FALLBACK("VT inactive\n");
    131 
    132     bo_table[0] = pI830->batch_bo;
    133     if (drm_intel_bufmgr_check_aperture_space(bo_table, num_bos) != 0) {
    134 	intel_batch_flush(pScrn, FALSE);
    135 	bo_table[0] = pI830->batch_bo;
    136 	if (drm_intel_bufmgr_check_aperture_space(bo_table, num_bos) != 0)
    137 	    I830FALLBACK("Couldn't get aperture space for BOs\n");
    138     }
    139     return TRUE;
    140 }
    141 
    142 static unsigned long
    143 i830_pixmap_pitch(PixmapPtr pixmap)
    144 {
    145     return pixmap->devKind;
    146 }
    147 
    148 static int
    149 i830_pixmap_pitch_is_aligned(PixmapPtr pixmap)
    150 {
    151     ScrnInfoPtr pScrn = xf86Screens[pixmap->drawable.pScreen->myNum];
    152     I830Ptr pI830 = I830PTR(pScrn);
    153 
    154     return i830_pixmap_pitch(pixmap) % pI830->accel_pixmap_pitch_alignment == 0;
    155 }
    156 
    157 /**
    158  * Sets up hardware state for a series of solid fills.
    159  */
    160 static Bool
    161 i830_uxa_prepare_solid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
    162 {
    163     ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
    164     I830Ptr pI830 = I830PTR(pScrn);
    165     unsigned long pitch;
    166     drm_intel_bo *bo_table[] = {
    167 	NULL, /* batch_bo */
    168 	i830_get_pixmap_bo(pPixmap),
    169     };
    170 
    171     if (!UXA_PM_IS_SOLID(&pPixmap->drawable, planemask))
    172 	I830FALLBACK("planemask is not solid");
    173 
    174     if (pPixmap->drawable.bitsPerPixel == 24)
    175 	I830FALLBACK("solid 24bpp unsupported!\n");
    176 
    177     if (pPixmap->drawable.bitsPerPixel < 8)
    178 	I830FALLBACK("under 8bpp pixmaps unsupported\n");
    179 
    180     i830_exa_check_pitch_2d(pPixmap);
    181 
    182     pitch = i830_pixmap_pitch(pPixmap);
    183 
    184     if (!i830_pixmap_pitch_is_aligned(pPixmap))
    185 	I830FALLBACK("pixmap pitch not aligned");
    186 
    187     if (!i830_get_aperture_space(pScrn, bo_table, ARRAY_SIZE(bo_table)))
    188 	return FALSE;
    189 
    190     pI830->BR[13] = (I830PatternROP[alu] & 0xff) << 16 ;
    191     switch (pPixmap->drawable.bitsPerPixel) {
    192 	case 8:
    193 	    break;
    194 	case 16:
    195 	    /* RGB565 */
    196 	    pI830->BR[13] |= (1 << 24);
    197 	    break;
    198 	case 32:
    199 	    /* RGB8888 */
    200 	    pI830->BR[13] |= ((1 << 24) | (1 << 25));
    201 	    break;
    202     }
    203     pI830->BR[16] = fg;
    204     return TRUE;
    205 }
    206 
    207 static void
    208 i830_uxa_solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
    209 {
    210     ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
    211     I830Ptr pI830 = I830PTR(pScrn);
    212     unsigned long pitch;
    213     uint32_t cmd;
    214 
    215     pitch = i830_pixmap_pitch(pPixmap);
    216 
    217     {
    218 	BEGIN_BATCH(6);
    219 
    220 	cmd = XY_COLOR_BLT_CMD;
    221 
    222 	if (pPixmap->drawable.bitsPerPixel == 32)
    223 	    cmd |= XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB;
    224 
    225 	if (IS_I965G(pI830) && i830_pixmap_tiled(pPixmap)) {
    226 	    assert((pitch % 512) == 0);
    227 	    pitch >>= 2;
    228 	    cmd |= XY_COLOR_BLT_TILED;
    229 	}
    230 
    231 	OUT_BATCH(cmd);
    232 
    233 	OUT_BATCH(pI830->BR[13] | pitch);
    234 	OUT_BATCH((y1 << 16) | (x1 & 0xffff));
    235 	OUT_BATCH((y2 << 16) | (x2 & 0xffff));
    236 	OUT_RELOC_PIXMAP(pPixmap, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
    237 	OUT_BATCH(pI830->BR[16]);
    238 	ADVANCE_BATCH();
    239     }
    240 }
    241 
    242 static void
    243 i830_uxa_done_solid(PixmapPtr pPixmap)
    244 {
    245     ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
    246 
    247     i830_debug_sync(pScrn);
    248 }
    249 
    250 /**
    251  * TODO:
    252  *   - support planemask using FULL_BLT_CMD?
    253  */
    254 static Bool
    255 i830_uxa_prepare_copy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
    256 		      int ydir, int alu, Pixel planemask)
    257 {
    258     ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
    259     I830Ptr pI830 = I830PTR(pScrn);
    260     drm_intel_bo *bo_table[] = {
    261 	NULL, /* batch_bo */
    262 	i830_get_pixmap_bo(pSrcPixmap),
    263 	i830_get_pixmap_bo(pDstPixmap),
    264     };
    265 
    266     if (!UXA_PM_IS_SOLID(&pSrcPixmap->drawable, planemask))
    267 	I830FALLBACK("planemask is not solid");
    268 
    269     if (pDstPixmap->drawable.bitsPerPixel < 8)
    270 	I830FALLBACK("under 8bpp pixmaps unsupported\n");
    271 
    272     if (!i830_get_aperture_space(pScrn, bo_table, ARRAY_SIZE(bo_table)))
    273 	return FALSE;
    274 
    275     i830_exa_check_pitch_2d(pSrcPixmap);
    276     i830_exa_check_pitch_2d(pDstPixmap);
    277 
    278     pI830->pSrcPixmap = pSrcPixmap;
    279 
    280     pI830->BR[13] = I830CopyROP[alu] << 16;
    281 
    282     switch (pSrcPixmap->drawable.bitsPerPixel) {
    283     case 8:
    284 	break;
    285     case 16:
    286 	pI830->BR[13] |= (1 << 24);
    287 	break;
    288     case 32:
    289 	pI830->BR[13] |= ((1 << 25) | (1 << 24));
    290 	break;
    291     }
    292     return TRUE;
    293 }
    294 
    295 static void
    296 i830_uxa_copy(PixmapPtr pDstPixmap, int src_x1, int src_y1, int dst_x1,
    297 	      int dst_y1, int w, int h)
    298 {
    299     ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
    300     I830Ptr pI830 = I830PTR(pScrn);
    301     uint32_t cmd;
    302     int dst_x2, dst_y2;
    303     unsigned int dst_pitch, src_pitch;
    304 
    305     dst_x2 = dst_x1 + w;
    306     dst_y2 = dst_y1 + h;
    307 
    308     dst_pitch = i830_pixmap_pitch(pDstPixmap);
    309     src_pitch = i830_pixmap_pitch(pI830->pSrcPixmap);
    310 
    311     {
    312 	BEGIN_BATCH(8);
    313 
    314 	cmd = XY_SRC_COPY_BLT_CMD;
    315 
    316 	if (pDstPixmap->drawable.bitsPerPixel == 32)
    317 	    cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB;
    318 
    319 	if (IS_I965G(pI830)) {
    320 	    if (i830_pixmap_tiled(pDstPixmap)) {
    321 		assert((dst_pitch % 512) == 0);
    322 		dst_pitch >>= 2;
    323 		cmd |= XY_SRC_COPY_BLT_DST_TILED;
    324 	    }
    325 
    326 	    if (i830_pixmap_tiled(pI830->pSrcPixmap)) {
    327 		assert((src_pitch % 512) == 0);
    328 		src_pitch >>= 2;
    329 		cmd |= XY_SRC_COPY_BLT_SRC_TILED;
    330 	    }
    331 	}
    332 
    333 	OUT_BATCH(cmd);
    334 
    335 	OUT_BATCH(pI830->BR[13] | dst_pitch);
    336 	OUT_BATCH((dst_y1 << 16) | (dst_x1 & 0xffff));
    337 	OUT_BATCH((dst_y2 << 16) | (dst_x2 & 0xffff));
    338 	OUT_RELOC_PIXMAP(pDstPixmap, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
    339 	OUT_BATCH((src_y1 << 16) | (src_x1 & 0xffff));
    340 	OUT_BATCH(src_pitch);
    341 	OUT_RELOC_PIXMAP(pI830->pSrcPixmap, I915_GEM_DOMAIN_RENDER, 0, 0);
    342 
    343 	ADVANCE_BATCH();
    344     }
    345 }
    346 
    347 static void
    348 i830_uxa_done_copy(PixmapPtr pDstPixmap)
    349 {
    350     ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
    351 
    352     i830_debug_sync(pScrn);
    353 }
    354 
    355 
    356 /**
    357  * Do any cleanup from the Composite operation.
    358  *
    359  * This is shared between i830 through i965.
    360  */
    361 void
    362 i830_done_composite(PixmapPtr pDst)
    363 {
    364     ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
    365 
    366     i830_debug_sync(pScrn);
    367 }
    368 
    369 #define xFixedToFloat(val) \
    370 	((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0))
    371 
    372 static Bool
    373 _i830_transform_point (PictTransformPtr transform,
    374 		       float		x,
    375 		       float		y,
    376 		       float		result[3])
    377 {
    378     int		    j;
    379 
    380     for (j = 0; j < 3; j++)
    381     {
    382 	result[j] = (xFixedToFloat (transform->matrix[j][0]) * x +
    383 		     xFixedToFloat (transform->matrix[j][1]) * y +
    384 		     xFixedToFloat (transform->matrix[j][2]));
    385     }
    386     if (!result[2])
    387 	return FALSE;
    388     return TRUE;
    389 }
    390 
    391 /**
    392  * Returns the floating-point coordinates transformed by the given transform.
    393  *
    394  * transform may be null.
    395  */
    396 Bool
    397 i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
    398 				 float *x_out, float *y_out)
    399 {
    400     if (transform == NULL) {
    401 	*x_out = x;
    402 	*y_out = y;
    403     } else {
    404 	float	result[3];
    405 
    406 	if (!_i830_transform_point (transform, (float) x, (float) y, result))
    407 	    return FALSE;
    408 	*x_out = result[0] / result[2];
    409 	*y_out = result[1] / result[2];
    410     }
    411     return TRUE;
    412 }
    413 
    414 /**
    415  * Returns the un-normalized floating-point coordinates transformed by the given transform.
    416  *
    417  * transform may be null.
    418  */
    419 Bool
    420 i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
    421 				    float *x_out, float *y_out, float *w_out)
    422 {
    423     if (transform == NULL) {
    424 	*x_out = x;
    425 	*y_out = y;
    426 	*w_out = 1;
    427     } else {
    428 	float    result[3];
    429 
    430 	if (!_i830_transform_point (transform, (float) x, (float) y, result))
    431 	    return FALSE;
    432 	*x_out = result[0];
    433 	*y_out = result[1];
    434 	*w_out = result[2];
    435     }
    436     return TRUE;
    437 }
    438 
    439 /**
    440  * Returns whether the provided transform is affine.
    441  *
    442  * transform may be null.
    443  */
    444 Bool
    445 i830_transform_is_affine (PictTransformPtr t)
    446 {
    447     if (t == NULL)
    448 	return TRUE;
    449     return t->matrix[2][0] == 0 && t->matrix[2][1] == 0;
    450 }
    451 
    452 dri_bo *
    453 i830_get_pixmap_bo(PixmapPtr pixmap)
    454 {
    455 #if HAS_DEVPRIVATEKEYREC
    456     return dixGetPrivate(&pixmap->devPrivates, &uxa_pixmap_index);
    457 #else
    458     return dixLookupPrivate(&pixmap->devPrivates, &uxa_pixmap_index);
    459 #endif
    460 }
    461 
    462 void
    463 i830_set_pixmap_bo(PixmapPtr pixmap, dri_bo *bo)
    464 {
    465     dri_bo  *old_bo = i830_get_pixmap_bo (pixmap);
    466 
    467     if (old_bo)
    468 	dri_bo_unreference (old_bo);
    469     if (bo != NULL)
    470 	dri_bo_reference(bo);
    471     dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, bo);
    472 }
    473 
    474 static void
    475 i830_uxa_set_pixmap_bo (PixmapPtr pixmap, dri_bo *bo)
    476 {
    477     dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, bo);
    478 }
    479 
    480 static Bool
    481 i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access)
    482 {
    483     dri_bo *bo = i830_get_pixmap_bo (pixmap);
    484     ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
    485 
    486     intel_batch_flush(scrn, FALSE);
    487 
    488     if (bo) {
    489 	I830Ptr i830 = I830PTR(scrn);
    490 
    491 	/* No VT sema or GEM?  No GTT mapping. */
    492 	if (!scrn->vtSema || !i830->have_gem) {
    493 	    if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0)
    494 		return FALSE;
    495 	    pixmap->devPrivate.ptr = bo->virtual;
    496 	    return TRUE;
    497 	}
    498 
    499 	/* Kernel manages fences at GTT map/fault time */
    500 	if (i830->kernel_exec_fencing) {
    501 	    if (bo->size < i830->max_gtt_map_size) {
    502 		if (drm_intel_gem_bo_map_gtt(bo)) {
    503 		    xf86DrvMsg(scrn->scrnIndex, X_WARNING,
    504 			       "%s: bo map failed\n",
    505 			       __FUNCTION__);
    506 		    return FALSE;
    507 		}
    508 	    } else {
    509 		if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0) {
    510 		    xf86DrvMsg(scrn->scrnIndex, X_WARNING,
    511 			       "%s: bo map failed\n",
    512 			       __FUNCTION__);
    513 		    return FALSE;
    514 		}
    515 	    }
    516 	    pixmap->devPrivate.ptr = bo->virtual;
    517 	} else { /* or not... */
    518 	    if (drm_intel_bo_pin(bo, 4096) != 0)
    519 		return FALSE;
    520 	    drm_intel_gem_bo_start_gtt_access(bo, access == UXA_ACCESS_RW);
    521 	    pixmap->devPrivate.ptr = i830->FbBase + bo->offset;
    522 	}
    523     } else
    524 	i830_wait_ring_idle(scrn);
    525 
    526     return TRUE;
    527 }
    528 
    529 static void
    530 i830_uxa_finish_access (PixmapPtr pixmap)
    531 {
    532     dri_bo *bo = i830_get_pixmap_bo (pixmap);
    533 
    534     if (bo) {
    535 	ScreenPtr screen = pixmap->drawable.pScreen;
    536 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
    537 	I830Ptr i830 = I830PTR(scrn);
    538 
    539 	if (bo == i830->front_buffer->bo)
    540 	    i830->need_flush = TRUE;
    541 
    542 	if (!scrn->vtSema || !i830->have_gem) {
    543 	    dri_bo_unmap(bo);
    544 	    pixmap->devPrivate.ptr = NULL;
    545 	    return;
    546 	}
    547 
    548 	if (i830->kernel_exec_fencing)
    549 	    if (bo->size < i830->max_gtt_map_size)
    550 		drm_intel_gem_bo_unmap_gtt(bo);
    551 	    else
    552 		dri_bo_unmap(bo);
    553 	else
    554 	    drm_intel_bo_unpin(bo);
    555 	pixmap->devPrivate.ptr = NULL;
    556     }
    557 }
    558 
    559 void
    560 i830_uxa_block_handler (ScreenPtr screen)
    561 {
    562     ScrnInfoPtr scrn = xf86Screens[screen->myNum];
    563     I830Ptr i830 = I830PTR(scrn);
    564 
    565     if (i830->need_flush) {
    566 	dri_bo_wait_rendering (i830->front_buffer->bo);
    567 	i830->need_flush = FALSE;
    568     }
    569 }
    570 
    571 static Bool
    572 i830_uxa_pixmap_is_offscreen(PixmapPtr pixmap)
    573 {
    574     ScreenPtr screen = pixmap->drawable.pScreen;
    575 
    576     /* The front buffer is always in memory and pinned */
    577     if (screen->GetScreenPixmap(screen) == pixmap)
    578 	return TRUE;
    579 
    580     return i830_get_pixmap_bo (pixmap) != NULL;
    581 }
    582 
    583 static PixmapPtr
    584 i830_uxa_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usage)
    585 {
    586     ScrnInfoPtr scrn = xf86Screens[screen->myNum];
    587     I830Ptr i830 = I830PTR(scrn);
    588     dri_bo *bo;
    589     int stride;
    590     PixmapPtr pixmap;
    591 
    592     if (w > 32767 || h > 32767)
    593 	return NullPixmap;
    594 
    595     if (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE)
    596 	return fbCreatePixmap (screen, w, h, depth, usage);
    597 
    598     pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
    599 
    600     if (w && h)
    601     {
    602 	unsigned int size;
    603 	uint32_t tiling = I915_TILING_NONE;
    604 	int pitch_align;
    605 
    606 	if (usage == INTEL_CREATE_PIXMAP_TILING_X) {
    607 	    tiling = I915_TILING_X;
    608 	    pitch_align = 512;
    609 	} else if (usage == INTEL_CREATE_PIXMAP_TILING_Y) {
    610 	    tiling = I915_TILING_Y;
    611 	    pitch_align = 512;
    612 	} else {
    613 	    pitch_align = i830->accel_pixmap_pitch_alignment;
    614 	}
    615 
    616 	stride = ROUND_TO((w * pixmap->drawable.bitsPerPixel + 7) / 8,
    617 			  pitch_align);
    618 
    619 	if (tiling == I915_TILING_NONE) {
    620 	    /* Round the height up so that the GPU's access to a 2x2 aligned
    621 	     * subspan doesn't address an invalid page offset beyond the
    622 	     * end of the GTT.
    623 	     */
    624 	    size = stride * ALIGN(h, 2);
    625 	} else {
    626 	    int aligned_h = h;
    627 	    if (tiling == I915_TILING_X)
    628 		aligned_h = ALIGN(h, 8);
    629 	    else
    630 		aligned_h = ALIGN(h, 32);
    631 
    632 	    stride = i830_get_fence_pitch(i830, stride, tiling);
    633 	    /* Round the object up to the size of the fence it will live in
    634 	     * if necessary.  We could potentially make the kernel allocate
    635 	     * a larger aperture space and just bind the subset of pages in,
    636 	     * but this is easier and also keeps us out of trouble (as much)
    637 	     * with drm_intel_bufmgr_check_aperture().
    638 	     */
    639 	    size = i830_get_fence_size(i830, stride * aligned_h);
    640 	    assert(size >= stride * aligned_h);
    641 	}
    642 
    643 	/* Fail very large allocations on 32-bit systems.  Large BOs will
    644 	 * tend to hit SW fallbacks frequently, and also will tend to fail
    645 	 * to successfully map when doing SW fallbacks because we overcommit
    646 	 * address space for BO access.
    647 	 *
    648 	 * Note that size should fit in 32 bits.  We throw out >32767x32767x4,
    649 	 * and pitch alignment could get us up to 32768x32767x4.
    650 	 */
    651 	if (sizeof(unsigned long) == 4 &&
    652 	    size > (unsigned int)(1024 * 1024 * 1024))
    653 	{
    654 	    fbDestroyPixmap (pixmap);
    655 	    return NullPixmap;
    656 	}
    657 
    658 	if (usage == UXA_CREATE_PIXMAP_FOR_MAP)
    659 	    bo = drm_intel_bo_alloc(i830->bufmgr, "pixmap", size, 0);
    660 	else
    661 	    bo = drm_intel_bo_alloc_for_render(i830->bufmgr, "pixmap", size, 0);
    662 	if (!bo) {
    663 	    fbDestroyPixmap (pixmap);
    664 	    return NullPixmap;
    665 	}
    666 
    667 	if (tiling != I915_TILING_NONE)
    668 	    drm_intel_bo_set_tiling(bo, &tiling, stride);
    669 
    670 	screen->ModifyPixmapHeader (pixmap, w, h, 0, 0, stride, NULL);
    671 
    672 	i830_uxa_set_pixmap_bo (pixmap, bo);
    673     }
    674 
    675     return pixmap;
    676 }
    677 
    678 static Bool
    679 i830_uxa_destroy_pixmap (PixmapPtr pixmap)
    680 {
    681     if (pixmap->refcnt == 1) {
    682 	dri_bo  *bo = i830_get_pixmap_bo (pixmap);
    683 
    684 	if (bo)
    685 	    dri_bo_unreference (bo);
    686     }
    687     fbDestroyPixmap (pixmap);
    688     return TRUE;
    689 }
    690 
    691 void i830_uxa_create_screen_resources(ScreenPtr pScreen)
    692 {
    693     ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
    694     I830Ptr i830 = I830PTR(scrn);
    695     dri_bo *bo = i830->front_buffer->bo;
    696 
    697     if (bo != NULL) {
    698 	PixmapPtr   pixmap = pScreen->GetScreenPixmap(pScreen);
    699 	i830_uxa_set_pixmap_bo (pixmap, bo);
    700 	dri_bo_reference(bo);
    701     }
    702 }
    703 
    704 Bool
    705 i830_uxa_init (ScreenPtr pScreen)
    706 {
    707     ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
    708     I830Ptr i830 = I830PTR(scrn);
    709 
    710 #if HAS_DIXREGISTERPRIVATEKEY
    711     if (!dixRegisterPrivateKey(&uxa_pixmap_index, PRIVATE_PIXMAP, 0))
    712 #else
    713     if (!dixRequestPrivate(&uxa_pixmap_index, 0))
    714 #endif
    715 	return FALSE;
    716 
    717     i830->uxa_driver = uxa_driver_alloc();
    718     if (i830->uxa_driver == NULL)
    719 	return FALSE;
    720 
    721     memset(i830->uxa_driver, 0, sizeof(*i830->uxa_driver));
    722 
    723     i830->bufferOffset = 0;
    724     i830->uxa_driver->uxa_major = 1;
    725     i830->uxa_driver->uxa_minor = 0;
    726 
    727     /* Solid fill */
    728     i830->uxa_driver->prepare_solid = i830_uxa_prepare_solid;
    729     i830->uxa_driver->solid = i830_uxa_solid;
    730     i830->uxa_driver->done_solid = i830_uxa_done_solid;
    731 
    732     /* Copy */
    733     i830->uxa_driver->prepare_copy = i830_uxa_prepare_copy;
    734     i830->uxa_driver->copy = i830_uxa_copy;
    735     i830->uxa_driver->done_copy = i830_uxa_done_copy;
    736 
    737     /* Composite */
    738     if (!IS_I9XX(i830)) {
    739     	i830->uxa_driver->check_composite = i830_check_composite;
    740     	i830->uxa_driver->prepare_composite = i830_prepare_composite;
    741     	i830->uxa_driver->composite = i830_composite;
    742     	i830->uxa_driver->done_composite = i830_done_composite;
    743     } else if (IS_I915G(i830) || IS_I915GM(i830) ||
    744 	       IS_I945G(i830) || IS_I945GM(i830) || IS_G33CLASS(i830))
    745     {
    746 	i830->uxa_driver->check_composite = i915_check_composite;
    747    	i830->uxa_driver->prepare_composite = i915_prepare_composite;
    748 	i830->uxa_driver->composite = i915_composite;
    749     	i830->uxa_driver->done_composite = i830_done_composite;
    750     } else {
    751  	i830->uxa_driver->check_composite = i965_check_composite;
    752  	i830->uxa_driver->prepare_composite = i965_prepare_composite;
    753  	i830->uxa_driver->composite = i965_composite;
    754  	i830->uxa_driver->done_composite = i830_done_composite;
    755     }
    756 
    757     i830->uxa_driver->prepare_access = i830_uxa_prepare_access;
    758     i830->uxa_driver->finish_access = i830_uxa_finish_access;
    759     i830->uxa_driver->pixmap_is_offscreen = i830_uxa_pixmap_is_offscreen;
    760 
    761     if(!uxa_driver_init(pScreen, i830->uxa_driver)) {
    762 	xf86DrvMsg(scrn->scrnIndex, X_ERROR,
    763 		   "UXA initialization failed\n");
    764 	xfree(i830->uxa_driver);
    765 	return FALSE;
    766     }
    767 
    768     pScreen->CreatePixmap = i830_uxa_create_pixmap;
    769     pScreen->DestroyPixmap = i830_uxa_destroy_pixmap;
    770 
    771     uxa_set_fallback_debug(pScreen, i830->fallback_debug);
    772 
    773     return TRUE;
    774 }
    775