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