1/************************************************************************** 2 3Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 4All Rights Reserved. 5Copyright (c) 2005 Jesse Barnes <jbarnes@virtuousgeek.org> 6 Based on code from i830_xaa.c. 7 8Permission is hereby granted, free of charge, to any person obtaining a 9copy of this software and associated documentation files (the 10"Software"), to deal in the Software without restriction, including 11without limitation the rights to use, copy, modify, merge, publish, 12distribute, sub license, and/or sell copies of the Software, and to 13permit persons to whom the Software is furnished to do so, subject to 14the following conditions: 15 16The above copyright notice and this permission notice (including the 17next paragraph) shall be included in all copies or substantial portions 18of the Software. 19 20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 23IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 24ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 25TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 26SOFTWARE 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 "xorg-server.h" 35#include <xf86.h> 36#include <xf86drm.h> 37#include <xaarop.h> 38#include <string.h> 39#include <errno.h> 40#include <unistd.h> 41 42#include "intel.h" 43#include "intel_uxa.h" 44 45#include "i830_reg.h" 46#include "i915_drm.h" 47#include "brw_defines.h" 48 49static const int I830CopyROP[16] = { 50 ROP_0, /* GXclear */ 51 ROP_DSa, /* GXand */ 52 ROP_SDna, /* GXandReverse */ 53 ROP_S, /* GXcopy */ 54 ROP_DSna, /* GXandInverted */ 55 ROP_D, /* GXnoop */ 56 ROP_DSx, /* GXxor */ 57 ROP_DSo, /* GXor */ 58 ROP_DSon, /* GXnor */ 59 ROP_DSxn, /* GXequiv */ 60 ROP_Dn, /* GXinvert */ 61 ROP_SDno, /* GXorReverse */ 62 ROP_Sn, /* GXcopyInverted */ 63 ROP_DSno, /* GXorInverted */ 64 ROP_DSan, /* GXnand */ 65 ROP_1 /* GXset */ 66}; 67 68static const int I830PatternROP[16] = { 69 ROP_0, 70 ROP_DPa, 71 ROP_PDna, 72 ROP_P, 73 ROP_DPna, 74 ROP_D, 75 ROP_DPx, 76 ROP_DPo, 77 ROP_DPon, 78 ROP_PDxn, 79 ROP_Dn, 80 ROP_PDno, 81 ROP_Pn, 82 ROP_DPno, 83 ROP_DPan, 84 ROP_1 85}; 86 87#if HAS_DEVPRIVATEKEYREC 88DevPrivateKeyRec uxa_pixmap_index; 89#else 90int uxa_pixmap_index; 91#endif 92 93static void 94gen6_context_switch(intel_screen_private *intel, 95 int new_mode) 96{ 97 intel_batch_submit(intel->scrn); 98} 99 100static void 101gen5_context_switch(intel_screen_private *intel, 102 int new_mode) 103{ 104 /* Ironlake has a limitation that a 3D or Media command can't 105 * be the first command after a BLT, unless it's 106 * non-pipelined. Instead of trying to track it and emit a 107 * command at the right time, we just emit a dummy 108 * non-pipelined 3D instruction after each blit. 109 */ 110 111 if (new_mode == I915_EXEC_BLT) { 112 OUT_BATCH(MI_FLUSH | 113 MI_STATE_INSTRUCTION_CACHE_FLUSH | 114 MI_INHIBIT_RENDER_CACHE_FLUSH); 115 } else { 116 OUT_BATCH(CMD_POLY_STIPPLE_OFFSET << 16); 117 OUT_BATCH(0); 118 } 119} 120 121static void 122gen4_context_switch(intel_screen_private *intel, 123 int new_mode) 124{ 125 if (new_mode == I915_EXEC_BLT) { 126 OUT_BATCH(MI_FLUSH | 127 MI_STATE_INSTRUCTION_CACHE_FLUSH | 128 MI_INHIBIT_RENDER_CACHE_FLUSH); 129 } 130} 131 132Bool 133intel_uxa_get_aperture_space(ScrnInfoPtr scrn, drm_intel_bo ** bo_table, 134 int num_bos) 135{ 136 intel_screen_private *intel = intel_get_screen_private(scrn); 137 138 if (intel->batch_bo == NULL) { 139 intel_uxa_debug_fallback(scrn, "VT inactive\n"); 140 return FALSE; 141 } 142 143 bo_table[0] = intel->batch_bo; 144 if (drm_intel_bufmgr_check_aperture_space(bo_table, num_bos) != 0) { 145 intel_batch_submit(scrn); 146 bo_table[0] = intel->batch_bo; 147 if (drm_intel_bufmgr_check_aperture_space(bo_table, num_bos) != 148 0) { 149 intel_uxa_debug_fallback(scrn, "Couldn't get aperture " 150 "space for BOs\n"); 151 return FALSE; 152 } 153 } 154 return TRUE; 155} 156 157static Bool 158intel_uxa_check_solid(DrawablePtr drawable, int alu, Pixel planemask) 159{ 160 ScrnInfoPtr scrn = xf86ScreenToScrn(drawable->pScreen); 161 162 if (!UXA_PM_IS_SOLID(drawable, planemask)) { 163 intel_uxa_debug_fallback(scrn, "planemask is not solid\n"); 164 return FALSE; 165 } 166 167 switch (drawable->bitsPerPixel) { 168 case 8: 169 case 16: 170 case 32: 171 break; 172 default: 173 return FALSE; 174 } 175 176 return TRUE; 177} 178 179/** 180 * Sets up hardware state for a series of solid fills. 181 */ 182static Bool 183intel_uxa_prepare_solid(PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg) 184{ 185 ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); 186 intel_screen_private *intel = intel_get_screen_private(scrn); 187 drm_intel_bo *bo_table[] = { 188 NULL, /* batch_bo */ 189 intel_uxa_get_pixmap_bo(pixmap), 190 }; 191 192 if (!intel_uxa_check_pitch_2d(pixmap)) 193 return FALSE; 194 195 if (!intel_uxa_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table))) 196 return FALSE; 197 198 intel->BR[13] = (I830PatternROP[alu] & 0xff) << 16; 199 switch (pixmap->drawable.bitsPerPixel) { 200 case 8: 201 break; 202 case 16: 203 /* RGB565 */ 204 intel->BR[13] |= (1 << 24); 205 break; 206 case 32: 207 /* RGB8888 */ 208 intel->BR[13] |= ((1 << 24) | (1 << 25)); 209 break; 210 } 211 intel->BR[16] = fg; 212 213 return TRUE; 214} 215 216static void intel_uxa_solid(PixmapPtr pixmap, int x1, int y1, int x2, int y2) 217{ 218 ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); 219 intel_screen_private *intel = intel_get_screen_private(scrn); 220 unsigned long pitch; 221 uint32_t cmd; 222 223 if (x1 < 0) 224 x1 = 0; 225 if (y1 < 0) 226 y1 = 0; 227 if (x2 > pixmap->drawable.width) 228 x2 = pixmap->drawable.width; 229 if (y2 > pixmap->drawable.height) 230 y2 = pixmap->drawable.height; 231 232 if (x2 <= x1 || y2 <= y1) 233 return; 234 235 pitch = intel_pixmap_pitch(pixmap); 236 237 { 238 int len = INTEL_INFO(intel)->gen >= 0100 ? 7 : 6; 239 BEGIN_BATCH_BLT(len); 240 241 cmd = XY_COLOR_BLT_CMD | (len - 2); 242 243 if (pixmap->drawable.bitsPerPixel == 32) 244 cmd |= 245 XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB; 246 247 if (INTEL_INFO(intel)->gen >= 040 && intel_uxa_pixmap_tiled(pixmap)) { 248 assert((pitch % 512) == 0); 249 pitch >>= 2; 250 cmd |= XY_COLOR_BLT_TILED; 251 } 252 253 OUT_BATCH(cmd); 254 255 OUT_BATCH(intel->BR[13] | pitch); 256 OUT_BATCH((y1 << 16) | (x1 & 0xffff)); 257 OUT_BATCH((y2 << 16) | (x2 & 0xffff)); 258 OUT_RELOC_PIXMAP_FENCED(pixmap, I915_GEM_DOMAIN_RENDER, 259 I915_GEM_DOMAIN_RENDER, 0); 260 OUT_BATCH(intel->BR[16]); 261 ADVANCE_BATCH(); 262 } 263} 264 265/** 266 * TODO: 267 * - support planemask using FULL_BLT_CMD? 268 */ 269static Bool 270intel_uxa_check_copy(PixmapPtr source, PixmapPtr dest, 271 int alu, Pixel planemask) 272{ 273 ScrnInfoPtr scrn = xf86ScreenToScrn(dest->drawable.pScreen); 274 275 if (!UXA_PM_IS_SOLID(&source->drawable, planemask)) { 276 intel_uxa_debug_fallback(scrn, "planemask is not solid"); 277 return FALSE; 278 } 279 280 if (source->drawable.bitsPerPixel != dest->drawable.bitsPerPixel) { 281 intel_uxa_debug_fallback(scrn, "mixed bpp copies unsupported\n"); 282 return FALSE; 283 } 284 switch (source->drawable.bitsPerPixel) { 285 case 8: 286 case 16: 287 case 32: 288 break; 289 default: 290 return FALSE; 291 } 292 293 if (!intel_uxa_check_pitch_2d(source)) 294 return FALSE; 295 if (!intel_uxa_check_pitch_2d(dest)) 296 return FALSE; 297 298 return TRUE; 299} 300 301static Bool 302intel_uxa_prepare_copy(PixmapPtr source, PixmapPtr dest, int xdir, 303 int ydir, int alu, Pixel planemask) 304{ 305 ScrnInfoPtr scrn = xf86ScreenToScrn(dest->drawable.pScreen); 306 intel_screen_private *intel = intel_get_screen_private(scrn); 307 drm_intel_bo *bo_table[] = { 308 NULL, /* batch_bo */ 309 intel_uxa_get_pixmap_bo(source), 310 intel_uxa_get_pixmap_bo(dest), 311 }; 312 313 if (!intel_uxa_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table))) 314 return FALSE; 315 316 intel->render_source = source; 317 318 intel->BR[13] = I830CopyROP[alu] << 16; 319 switch (source->drawable.bitsPerPixel) { 320 case 8: 321 break; 322 case 16: 323 intel->BR[13] |= (1 << 24); 324 break; 325 case 32: 326 intel->BR[13] |= ((1 << 25) | (1 << 24)); 327 break; 328 } 329 330 return TRUE; 331} 332 333static void 334intel_uxa_copy(PixmapPtr dest, int src_x1, int src_y1, int dst_x1, 335 int dst_y1, int w, int h) 336{ 337 ScrnInfoPtr scrn = xf86ScreenToScrn(dest->drawable.pScreen); 338 intel_screen_private *intel = intel_get_screen_private(scrn); 339 uint32_t cmd; 340 int dst_x2, dst_y2, src_x2, src_y2; 341 unsigned int dst_pitch, src_pitch; 342 343 dst_x2 = dst_x1 + w; 344 dst_y2 = dst_y1 + h; 345 346 /* XXX Fixup extents as a lamentable workaround for missing 347 * source clipping in the upper layers. 348 */ 349 if (dst_x1 < 0) 350 src_x1 -= dst_x1, dst_x1 = 0; 351 if (dst_y1 < 0) 352 src_y1 -= dst_y1, dst_y1 = 0; 353 if (dst_x2 > dest->drawable.width) 354 dst_x2 = dest->drawable.width; 355 if (dst_y2 > dest->drawable.height) 356 dst_y2 = dest->drawable.height; 357 358 src_x2 = src_x1 + (dst_x2 - dst_x1); 359 src_y2 = src_y1 + (dst_y2 - dst_y1); 360 361 if (src_x1 < 0) 362 dst_x1 -= src_x1, src_x1 = 0; 363 if (src_y1 < 0) 364 dst_y1 -= src_y1, src_y1 = 0; 365 if (src_x2 > intel->render_source->drawable.width) 366 dst_x2 -= src_x2 - intel->render_source->drawable.width; 367 if (src_y2 > intel->render_source->drawable.height) 368 dst_y2 -= src_y2 - intel->render_source->drawable.height; 369 370 if (dst_x2 <= dst_x1 || dst_y2 <= dst_y1) 371 return; 372 373 dst_pitch = intel_pixmap_pitch(dest); 374 src_pitch = intel_pixmap_pitch(intel->render_source); 375 376 { 377 int len = INTEL_INFO(intel)->gen >= 0100 ? 10 : 8; 378 BEGIN_BATCH_BLT(len); 379 380 cmd = XY_SRC_COPY_BLT_CMD | (len - 2); 381 382 if (dest->drawable.bitsPerPixel == 32) 383 cmd |= 384 XY_SRC_COPY_BLT_WRITE_ALPHA | 385 XY_SRC_COPY_BLT_WRITE_RGB; 386 387 if (INTEL_INFO(intel)->gen >= 040) { 388 if (intel_uxa_pixmap_tiled(dest)) { 389 assert((dst_pitch % 512) == 0); 390 dst_pitch >>= 2; 391 cmd |= XY_SRC_COPY_BLT_DST_TILED; 392 } 393 394 if (intel_uxa_pixmap_tiled(intel->render_source)) { 395 assert((src_pitch % 512) == 0); 396 src_pitch >>= 2; 397 cmd |= XY_SRC_COPY_BLT_SRC_TILED; 398 } 399 } 400 401 OUT_BATCH(cmd); 402 403 OUT_BATCH(intel->BR[13] | dst_pitch); 404 OUT_BATCH((dst_y1 << 16) | (dst_x1 & 0xffff)); 405 OUT_BATCH((dst_y2 << 16) | (dst_x2 & 0xffff)); 406 OUT_RELOC_PIXMAP_FENCED(dest, 407 I915_GEM_DOMAIN_RENDER, 408 I915_GEM_DOMAIN_RENDER, 409 0); 410 OUT_BATCH((src_y1 << 16) | (src_x1 & 0xffff)); 411 OUT_BATCH(src_pitch); 412 OUT_RELOC_PIXMAP_FENCED(intel->render_source, 413 I915_GEM_DOMAIN_RENDER, 0, 414 0); 415 416 ADVANCE_BATCH(); 417 } 418} 419 420static void intel_uxa_done(PixmapPtr pixmap) 421{ 422 ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); 423 intel_screen_private *intel = intel_get_screen_private(scrn); 424 425 if (INTEL_INFO(intel)->gen >= 060) { 426 /* workaround a random BLT hang */ 427 BEGIN_BATCH_BLT(3); 428 OUT_BATCH(XY_SETUP_CLIP_BLT_CMD | (3 - 2)); 429 OUT_BATCH(0); 430 OUT_BATCH(0); 431 ADVANCE_BATCH(); 432 } 433 434 intel_uxa_debug_flush(scrn); 435} 436 437/** 438 * Do any cleanup from the Composite operation. 439 * 440 * This is shared between i830 through i965. 441 */ 442static void i830_done_composite(PixmapPtr dest) 443{ 444 ScrnInfoPtr scrn = xf86ScreenToScrn(dest->drawable.pScreen); 445 intel_screen_private *intel = intel_get_screen_private(scrn); 446 447 if (intel->vertex_flush) 448 intel->vertex_flush(intel); 449 450 intel_uxa_debug_flush(scrn); 451} 452 453#define xFixedToFloat(val) \ 454 ((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0)) 455 456static Bool 457_intel_transform_point(PictTransformPtr transform, 458 float x, float y, float result[3]) 459{ 460 int j; 461 462 for (j = 0; j < 3; j++) { 463 result[j] = (xFixedToFloat(transform->matrix[j][0]) * x + 464 xFixedToFloat(transform->matrix[j][1]) * y + 465 xFixedToFloat(transform->matrix[j][2])); 466 } 467 if (!result[2]) 468 return FALSE; 469 return TRUE; 470} 471 472/** 473 * Returns the floating-point coordinates transformed by the given transform. 474 * 475 * transform may be null. 476 */ 477Bool 478intel_uxa_get_transformed_coordinates(int x, int y, PictTransformPtr transform, 479 float *x_out, float *y_out) 480{ 481 if (transform == NULL) { 482 *x_out = x; 483 *y_out = y; 484 } else { 485 float result[3]; 486 487 if (!_intel_transform_point(transform, 488 x, y, 489 result)) 490 return FALSE; 491 *x_out = result[0] / result[2]; 492 *y_out = result[1] / result[2]; 493 } 494 return TRUE; 495} 496 497/** 498 * Returns the un-normalized floating-point coordinates transformed by the given transform. 499 * 500 * transform may be null. 501 */ 502Bool 503intel_uxa_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform, 504 float *x_out, float *y_out, float *w_out) 505{ 506 if (transform == NULL) { 507 *x_out = x; 508 *y_out = y; 509 *w_out = 1; 510 } else { 511 float result[3]; 512 513 if (!_intel_transform_point(transform, 514 x, y, 515 result)) 516 return FALSE; 517 *x_out = result[0]; 518 *y_out = result[1]; 519 *w_out = result[2]; 520 } 521 return TRUE; 522} 523 524/** 525 * Returns whether the provided transform is affine. 526 * 527 * transform may be null. 528 */ 529Bool intel_uxa_transform_is_affine(PictTransformPtr t) 530{ 531 if (t == NULL) 532 return TRUE; 533 return t->matrix[2][0] == 0 && t->matrix[2][1] == 0; 534} 535 536dri_bo *intel_uxa_get_pixmap_bo(PixmapPtr pixmap) 537{ 538 struct intel_uxa_pixmap *intel; 539 540 intel = intel_uxa_get_pixmap_private(pixmap); 541 if (intel == NULL) 542 return NULL; 543 544 return intel->bo; 545} 546 547static unsigned intel_get_tile_width(intel_screen_private *intel, int tiling, int pitch) 548{ 549 unsigned long tile_width; 550 551 if (tiling == I915_TILING_NONE) 552 return 4; 553 554 tile_width = (tiling == I915_TILING_Y) ? 128 : 512; 555 if (INTEL_INFO(intel)->gen >= 040) 556 return tile_width; 557 558 while (tile_width < pitch) 559 tile_width <<= 1; 560 561 return tile_width; 562} 563 564void intel_uxa_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo) 565{ 566 ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); 567 intel_screen_private *intel = intel_get_screen_private(scrn); 568 struct intel_uxa_pixmap *priv; 569 570 priv = intel_uxa_get_pixmap_private(pixmap); 571 if (priv == NULL && bo == NULL) 572 return; 573 574 if (priv != NULL) { 575 if (priv->bo == bo) 576 return; 577 578free_priv: 579 dri_bo_unreference(priv->bo); 580 list_del(&priv->batch); 581 582 free(priv); 583 priv = NULL; 584 } 585 586 if (bo != NULL) { 587 uint32_t tiling, swizzle_mode; 588 unsigned tile_width; 589 int size, stride; 590 591 priv = calloc(1, sizeof (struct intel_uxa_pixmap)); 592 if (priv == NULL) 593 goto BAIL; 594 595 list_init(&priv->batch); 596 597 dri_bo_reference(bo); 598 priv->bo = bo; 599 600 if (drm_intel_bo_get_tiling(bo, &tiling, &swizzle_mode)) { 601 bo = NULL; 602 goto free_priv; 603 } 604 605 priv->tiling = tiling; 606 priv->busy = -1; 607 priv->offscreen = 1; 608 609 stride = (pixmap->drawable.width * pixmap->drawable.bitsPerPixel + 7) / 8; 610 tile_width = intel_get_tile_width(intel, tiling, stride); 611 stride = ALIGN(stride, tile_width); 612 613 if (intel_pixmap_pitch(pixmap) < stride || 614 intel_pixmap_pitch(pixmap) & (tile_width - 1) || 615 intel_pixmap_pitch(pixmap) >= KB(32)) { 616 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 617 "%s: stride on buffer object does not match constraints: stride=%d, must be greater than %d, but less than %d, and have alignment at least %d\n", 618 __FUNCTION__, intel_pixmap_pitch(pixmap), stride, KB(32), tile_width); 619 bo = NULL; 620 goto free_priv; 621 } 622 623 if (tiling != I915_TILING_NONE) { 624 int height; 625 626 if (IS_GEN2(intel)) 627 height = 16; 628 else if (tiling == I915_TILING_X) 629 height = 8; 630 else 631 height = 32; 632 633 height = ALIGN(pixmap->drawable.height, height); 634 size = intel_get_fence_size(intel, intel_pixmap_pitch(pixmap) * height); 635 } else 636 size = intel_pixmap_pitch(pixmap) * pixmap->drawable.height; 637 638 if (bo->size < size || bo->size > intel->max_bo_size) { 639 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 640 "%s: size of buffer object does not match constraints: size=%ld, must be greater than %d, but less than %d\n", 641 __FUNCTION__, (long)bo->size, size, intel->max_bo_size); 642 bo = NULL; 643 goto free_priv; 644 } 645 } 646 647 BAIL: 648 intel_uxa_set_pixmap_private(pixmap, priv); 649} 650 651static Bool intel_uxa_prepare_access(PixmapPtr pixmap, uxa_access_t access) 652{ 653 ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); 654 intel_screen_private *intel = intel_get_screen_private(scrn); 655 struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap); 656 dri_bo *bo = priv->bo; 657 int ret; 658 659 /* When falling back to swrast, flush all pending operations */ 660 if (access == UXA_ACCESS_RW || priv->dirty) 661 intel_batch_submit(scrn); 662 663 assert(bo->size <= intel->max_gtt_map_size); 664 ret = drm_intel_gem_bo_map_gtt(bo); 665 if (ret) { 666 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 667 "%s: bo map (use gtt? %d, access %d) failed: %s\n", 668 __FUNCTION__, 669 priv->tiling || bo->size <= intel->max_gtt_map_size, 670 access, 671 strerror(-ret)); 672 return FALSE; 673 } 674 675 pixmap->devPrivate.ptr = bo->virtual; 676 priv->busy = 0; 677 678 return TRUE; 679} 680 681static void intel_uxa_finish_access(PixmapPtr pixmap, uxa_access_t access) 682{ 683 struct intel_uxa_pixmap *priv; 684 685 priv = intel_uxa_get_pixmap_private(pixmap); 686 if (priv == NULL) 687 return; 688 689 drm_intel_gem_bo_unmap_gtt(priv->bo); 690 pixmap->devPrivate.ptr = NULL; 691} 692 693static Bool intel_uxa_pixmap_put_image(PixmapPtr pixmap, 694 char *src, int src_pitch, 695 int x, int y, int w, int h) 696{ 697 struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap); 698 int stride = intel_pixmap_pitch(pixmap); 699 int cpp = pixmap->drawable.bitsPerPixel/8; 700 int ret = FALSE; 701 702 if (priv == NULL || priv->bo == NULL) 703 return FALSE; 704 705 if (priv->tiling == I915_TILING_NONE && 706 (h == 1 || (src_pitch == stride && w == pixmap->drawable.width))) { 707 return drm_intel_bo_subdata(priv->bo, y*stride + x*cpp, stride*(h-1) + w*cpp, src) == 0; 708 } else if (drm_intel_gem_bo_map_gtt(priv->bo) == 0) { 709 char *dst = priv->bo->virtual; 710 int row_length = w * cpp; 711 int num_rows = h; 712 if (row_length == src_pitch && src_pitch == stride) 713 num_rows = 1, row_length *= h; 714 dst += y * stride + x * cpp; 715 do { 716 memcpy (dst, src, row_length); 717 src += src_pitch; 718 dst += stride; 719 } while (--num_rows); 720 drm_intel_gem_bo_unmap_gtt(priv->bo); 721 ret = TRUE; 722 } 723 724 return ret; 725} 726 727static Bool intel_uxa_put_image(PixmapPtr pixmap, 728 int x, int y, 729 int w, int h, 730 char *src, int src_pitch) 731{ 732 struct intel_uxa_pixmap *priv; 733 734 priv = intel_uxa_get_pixmap_private(pixmap); 735 if (!intel_uxa_pixmap_is_busy(priv)) { 736 /* bo is not busy so can be replaced without a stall, upload in-place. */ 737 return intel_uxa_pixmap_put_image(pixmap, src, src_pitch, x, y, w, h); 738 } else { 739 ScreenPtr screen = pixmap->drawable.pScreen; 740 741 if (!priv->pinned && 742 x == 0 && y == 0 && 743 w == pixmap->drawable.width && 744 h == pixmap->drawable.height) 745 { 746 intel_screen_private *intel = intel_get_screen_private(xf86ScreenToScrn(screen)); 747 uint32_t tiling = priv->tiling; 748 int size, stride; 749 dri_bo *bo; 750 751 /* Replace busy bo. */ 752 size = intel_compute_size(intel, 753 w, h, 754 pixmap->drawable.bitsPerPixel, pixmap->usage_hint, 755 &tiling, &stride); 756 if (size > intel->max_gtt_map_size) 757 return FALSE; 758 759 bo = drm_intel_bo_alloc(intel->bufmgr, "pixmap", size, 0); 760 if (bo == NULL) 761 return FALSE; 762 763 if (tiling != I915_TILING_NONE) 764 drm_intel_bo_set_tiling(bo, &tiling, stride); 765 priv->tiling = tiling; 766 767 screen->ModifyPixmapHeader(pixmap, 768 w, h, 769 0, 0, 770 stride, NULL); 771 intel_uxa_set_pixmap_bo(pixmap, bo); 772 dri_bo_unreference(bo); 773 774 return intel_uxa_pixmap_put_image(pixmap, src, src_pitch, 0, 0, w, h); 775 } 776 else 777 { 778 PixmapPtr scratch; 779 Bool ret; 780 781 /* Upload to a linear buffer and queue a blit. */ 782 scratch = (*screen->CreatePixmap)(screen, w, h, 783 pixmap->drawable.depth, 784 UXA_CREATE_PIXMAP_FOR_MAP); 785 if (!scratch) 786 return FALSE; 787 788 if (!intel_uxa_pixmap_is_offscreen(scratch)) { 789 screen->DestroyPixmap(scratch); 790 return FALSE; 791 } 792 793 ret = intel_uxa_pixmap_put_image(scratch, src, src_pitch, 0, 0, w, h); 794 if (ret) { 795 GCPtr gc = GetScratchGC(pixmap->drawable.depth, screen); 796 if (gc) { 797 ValidateGC(&pixmap->drawable, gc); 798 799 (*gc->ops->CopyArea)(&scratch->drawable, 800 &pixmap->drawable, 801 gc, 0, 0, w, h, x, y); 802 803 FreeScratchGC(gc); 804 } else 805 ret = FALSE; 806 } 807 808 (*screen->DestroyPixmap)(scratch); 809 return ret; 810 } 811 } 812} 813 814static Bool intel_uxa_pixmap_get_image(PixmapPtr pixmap, 815 int x, int y, int w, int h, 816 char *dst, int dst_pitch) 817{ 818 struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap); 819 int stride = intel_pixmap_pitch(pixmap); 820 int cpp = pixmap->drawable.bitsPerPixel/8; 821 822 /* assert(priv->tiling == I915_TILING_NONE); */ 823 if (h == 1 || (dst_pitch == stride && w == pixmap->drawable.width)) { 824 return drm_intel_bo_get_subdata(priv->bo, y*stride + x*cpp, (h-1)*stride + w*cpp, dst) == 0; 825 } else { 826 char *src; 827 828 if (drm_intel_gem_bo_map_gtt(priv->bo)) 829 return FALSE; 830 831 src = (char *) priv->bo->virtual + y * stride + x * cpp; 832 w *= cpp; 833 do { 834 memcpy(dst, src, w); 835 src += stride; 836 dst += dst_pitch; 837 } while (--h); 838 839 drm_intel_gem_bo_unmap_gtt(priv->bo); 840 841 return TRUE; 842 } 843} 844 845static Bool intel_uxa_get_image(PixmapPtr pixmap, 846 int x, int y, 847 int w, int h, 848 char *dst, int dst_pitch) 849{ 850 struct intel_uxa_pixmap *priv; 851 PixmapPtr scratch = NULL; 852 Bool ret; 853 854 /* The presumption is that we wish to keep the target hot, so 855 * copy to a new bo and move that to the CPU in preference to 856 * causing ping-pong of the original. 857 * 858 * Also the gpu is much faster at detiling. 859 */ 860 861 priv = intel_uxa_get_pixmap_private(pixmap); 862 if (intel_uxa_pixmap_is_busy(priv) || priv->tiling != I915_TILING_NONE) { 863 ScreenPtr screen = pixmap->drawable.pScreen; 864 GCPtr gc; 865 866 /* Copy to a linear buffer and pull. */ 867 scratch = screen->CreatePixmap(screen, w, h, 868 pixmap->drawable.depth, 869 INTEL_CREATE_PIXMAP_TILING_NONE); 870 if (!scratch) 871 return FALSE; 872 873 if (!intel_uxa_pixmap_is_offscreen(scratch)) { 874 screen->DestroyPixmap(scratch); 875 return FALSE; 876 } 877 878 gc = GetScratchGC(pixmap->drawable.depth, screen); 879 if (!gc) { 880 screen->DestroyPixmap(scratch); 881 return FALSE; 882 } 883 884 ValidateGC(&pixmap->drawable, gc); 885 886 gc->ops->CopyArea(&pixmap->drawable, 887 &scratch->drawable, 888 gc, x, y, w, h, 0, 0); 889 890 FreeScratchGC(gc); 891 892 intel_batch_submit(xf86ScreenToScrn(screen)); 893 894 x = y = 0; 895 pixmap = scratch; 896 } 897 898 ret = intel_uxa_pixmap_get_image(pixmap, x, y, w, h, dst, dst_pitch); 899 900 if (scratch) 901 scratch->drawable.pScreen->DestroyPixmap(scratch); 902 903 return ret; 904} 905 906static CARD32 intel_cache_expire(OsTimerPtr timer, CARD32 now, pointer data) 907{ 908 intel_screen_private *intel = data; 909 910 /* We just want to create and destroy a bo as this causes libdrm 911 * to reap its caches. However, since we can't remove that buffer 912 * from the cache due to its own activity, we want to use something 913 * that we know we will reuse later. The most frequently reused buffer 914 * we have is the batchbuffer, and the best way to trigger its 915 * reallocation is to submit a flush. 916 */ 917 intel_batch_emit_flush(intel->scrn); 918 intel_batch_submit(intel->scrn); 919 920 return 0; 921} 922 923static void intel_flush_rendering(intel_screen_private *intel) 924{ 925 if (intel->needs_flush == 0) 926 return; 927 928 if (intel->has_kernel_flush) { 929 intel_batch_submit(intel->scrn); 930 drm_intel_bo_busy(intel->front_buffer); 931 } else { 932 intel_batch_emit_flush(intel->scrn); 933 intel_batch_submit(intel->scrn); 934 } 935 936 intel->cache_expire = TimerSet(intel->cache_expire, 0, 3000, 937 intel_cache_expire, intel); 938 939 intel->needs_flush = 0; 940} 941 942static void intel_throttle(intel_screen_private *intel) 943{ 944 drmCommandNone(intel->drmSubFD, DRM_I915_GEM_THROTTLE); 945} 946 947void intel_uxa_block_handler(intel_screen_private *intel) 948{ 949 /* Emit a flush of the rendering cache, or on the 965 950 * and beyond rendering results may not hit the 951 * framebuffer until significantly later. 952 */ 953 intel_flush_rendering(intel); 954 intel_throttle(intel); 955} 956 957static PixmapPtr 958intel_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth, 959 unsigned usage) 960{ 961 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 962 intel_screen_private *intel = intel_get_screen_private(scrn); 963 struct intel_uxa_pixmap *priv; 964 PixmapPtr pixmap, new_pixmap = NULL; 965 966 if (w > 32767 || h > 32767) 967 return NullPixmap; 968 969 if (depth == 1 || intel->force_fallback) 970 return fbCreatePixmap(screen, w, h, depth, usage); 971 972 if (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 32 && h <= 32) 973 return fbCreatePixmap(screen, w, h, depth, usage); 974 975 pixmap = fbCreatePixmap(screen, 0, 0, depth, usage); 976 if (pixmap == NullPixmap) 977 return pixmap; 978 979 if (w && h) { 980 unsigned int size, tiling; 981 int stride; 982 983 /* Always attempt to tile, compute_size() will remove the 984 * tiling for pixmaps that are either too large or too small 985 * to be effectively tiled. 986 */ 987 tiling = I915_TILING_X; 988 if (usage & INTEL_CREATE_PIXMAP_TILING_Y) 989 tiling = I915_TILING_Y; 990 if (usage == UXA_CREATE_PIXMAP_FOR_MAP || usage & INTEL_CREATE_PIXMAP_TILING_NONE) 991 tiling = I915_TILING_NONE; 992 993#ifdef CREATE_PIXMAP_USAGE_SHARED 994 if (usage == CREATE_PIXMAP_USAGE_SHARED) 995 tiling = I915_TILING_NONE; 996#endif 997 /* if tiling is off force to none */ 998 if (!intel->tiling) 999 tiling = I915_TILING_NONE; 1000 1001 if (tiling != I915_TILING_NONE && !(usage & INTEL_CREATE_PIXMAP_DRI2)) { 1002 if (h <= 4) 1003 tiling = I915_TILING_NONE; 1004 if (h <= 16 && tiling == I915_TILING_Y) 1005 tiling = I915_TILING_X; 1006 } 1007 size = intel_compute_size(intel, 1008 w, h, pixmap->drawable.bitsPerPixel, usage, 1009 &tiling, &stride); 1010 1011 /* Fail very large allocations. Large BOs will tend to hit SW fallbacks 1012 * frequently, and also will tend to fail to successfully map when doing 1013 * SW fallbacks because we overcommit address space for BO access. 1014 */ 1015 if (size > intel->max_bo_size || stride >= KB(32)) 1016 goto fallback_pixmap; 1017 1018 priv = calloc(1, sizeof (struct intel_uxa_pixmap)); 1019 if (priv == NULL) 1020 goto fallback_pixmap; 1021 1022 if (usage == UXA_CREATE_PIXMAP_FOR_MAP) { 1023 priv->busy = 0; 1024 priv->bo = drm_intel_bo_alloc(intel->bufmgr, 1025 "pixmap", size, 0); 1026 } else { 1027 priv->busy = -1; 1028 priv->bo = drm_intel_bo_alloc_for_render(intel->bufmgr, 1029 "pixmap", 1030 size, 0); 1031 } 1032 if (!priv->bo) 1033 goto fallback_priv; 1034 1035 if (tiling != I915_TILING_NONE) 1036 drm_intel_bo_set_tiling(priv->bo, &tiling, stride); 1037 priv->tiling = tiling; 1038 priv->offscreen = 1; 1039 1040 list_init(&priv->batch); 1041 intel_uxa_set_pixmap_private(pixmap, priv); 1042 1043 screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, NULL); 1044 } 1045 1046 return pixmap; 1047 1048fallback_priv: 1049 free(priv); 1050fallback_pixmap: 1051 fbDestroyPixmap(pixmap); 1052 if (new_pixmap) 1053 return new_pixmap; 1054 else 1055 return fbCreatePixmap(screen, w, h, depth, usage); 1056} 1057 1058static Bool intel_uxa_destroy_pixmap(PixmapPtr pixmap) 1059{ 1060 if (pixmap->refcnt == 1) 1061 intel_uxa_set_pixmap_bo(pixmap, NULL); 1062 fbDestroyPixmap(pixmap); 1063 return TRUE; 1064} 1065 1066Bool intel_uxa_create_screen_resources(ScreenPtr screen) 1067{ 1068 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 1069 PixmapPtr pixmap; 1070 intel_screen_private *intel = intel_get_screen_private(scrn); 1071 dri_bo *bo = intel->front_buffer; 1072 int old_width, old_height, old_pitch; 1073 1074 if (!uxa_resources_init(screen)) 1075 return FALSE; 1076 1077 if (drm_intel_gem_bo_map_gtt(bo)) 1078 return FALSE; 1079 1080 pixmap = screen->GetScreenPixmap(screen); 1081 old_width = pixmap->drawable.width; 1082 old_height = pixmap->drawable.height; 1083 old_pitch = pixmap->devKind; 1084 1085 if (!screen->ModifyPixmapHeader(pixmap, 1086 scrn->virtualX, 1087 scrn->virtualY, 1088 -1, -1, 1089 intel->front_pitch, 1090 NULL)) 1091 return FALSE; 1092 1093 intel_uxa_set_pixmap_bo(pixmap, bo); 1094 if (intel_uxa_get_pixmap_private(pixmap) == NULL) 1095 goto err; 1096 1097 intel_uxa_get_pixmap_private(pixmap)->pinned |= PIN_SCANOUT; 1098 scrn->displayWidth = intel->front_pitch / intel->cpp; 1099 1100 return TRUE; 1101 1102err: 1103 screen->ModifyPixmapHeader(pixmap, 1104 old_width, old_height, -1, -1, old_pitch, NULL); 1105 return FALSE; 1106} 1107 1108#ifdef CREATE_PIXMAP_USAGE_SHARED 1109static Bool 1110intel_uxa_share_pixmap_backing(PixmapPtr ppix, ScreenPtr slave, void **fd_handle) 1111{ 1112 ScrnInfoPtr scrn = xf86ScreenToScrn(ppix->drawable.pScreen); 1113 intel_screen_private *intel = intel_get_screen_private(scrn); 1114 struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(ppix); 1115 unsigned int size, tiling, swizzle; 1116 dri_bo *bo = intel_uxa_get_pixmap_bo(ppix), *newbo; 1117 int stride; 1118 int handle; 1119 1120 if (drm_intel_bo_references(intel->batch_bo, bo)) 1121 intel_batch_submit(intel->scrn); 1122 1123 drm_intel_bo_get_tiling(bo, &tiling, &swizzle); 1124 1125 if (tiling == I915_TILING_X) { 1126 if (priv->pinned) 1127 return FALSE; 1128 1129 tiling = I915_TILING_NONE; 1130 1131 size = intel_compute_size(intel, 1132 ppix->drawable.width, ppix->drawable.height, 1133 ppix->drawable.bitsPerPixel, INTEL_CREATE_PIXMAP_DRI2, 1134 &tiling, &stride); 1135 1136 newbo = drm_intel_bo_alloc_for_render(intel->bufmgr, 1137 "pixmap", 1138 size, 0); 1139 1140 if (tiling != I915_TILING_NONE) 1141 drm_intel_bo_set_tiling(newbo, &tiling, stride); 1142 priv->tiling = tiling; 1143 intel_uxa_set_pixmap_bo(ppix, newbo); 1144 1145 ppix->drawable.pScreen->ModifyPixmapHeader(ppix, ppix->drawable.width, 1146 ppix->drawable.height, 0, 0, 1147 stride, NULL); 1148 bo = newbo; 1149 } 1150 drm_intel_bo_get_tiling(bo, &tiling, &swizzle); 1151 drm_intel_bo_gem_export_to_prime(bo, &handle); 1152 priv->pinned |= PIN_PRIME; 1153 1154 *fd_handle = (void *)(long)handle; 1155 return TRUE; 1156} 1157 1158static Bool 1159intel_uxa_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle) 1160{ 1161 ScrnInfoPtr scrn = xf86ScreenToScrn(ppix->drawable.pScreen); 1162 intel_screen_private *intel = intel_get_screen_private(scrn); 1163 dri_bo *bo; 1164 int ihandle = (int)(long)fd_handle; 1165 1166 /* force untiled for now */ 1167 bo = drm_intel_bo_gem_create_from_prime(intel->bufmgr, ihandle, 0); 1168 if (!bo) 1169 return FALSE; 1170 1171 intel_uxa_set_pixmap_bo(ppix, bo); 1172 close(ihandle); 1173 return TRUE; 1174} 1175#endif 1176 1177static void 1178intel_limits_init(intel_screen_private *intel) 1179{ 1180 /* Limits are described in the BLT engine chapter under Graphics Data Size 1181 * Limitations, and the descriptions of SURFACE_STATE, 3DSTATE_BUFFER_INFO, 1182 * 3DSTATE_DRAWING_RECTANGLE, 3DSTATE_MAP_INFO, and 3DSTATE_MAP_INFO. 1183 * 1184 * i845 through i965 limits 2D rendering to 65536 lines and pitch of 32768. 1185 * 1186 * i965 limits 3D surface to (2*element size)-aligned offset if un-tiled. 1187 * i965 limits 3D surface to 4kB-aligned offset if tiled. 1188 * i965 limits 3D surfaces to w,h of ?,8192. 1189 * i965 limits 3D surface to pitch of 1B - 128kB. 1190 * i965 limits 3D surface pitch alignment to 1 or 2 times the element size. 1191 * i965 limits 3D surface pitch alignment to 512B if tiled. 1192 * i965 limits 3D destination drawing rect to w,h of 8192,8192. 1193 * 1194 * i915 limits 3D textures to 4B-aligned offset if un-tiled. 1195 * i915 limits 3D textures to ~4kB-aligned offset if tiled. 1196 * i915 limits 3D textures to width,height of 2048,2048. 1197 * i915 limits 3D textures to pitch of 16B - 8kB, in dwords. 1198 * i915 limits 3D destination to ~4kB-aligned offset if tiled. 1199 * i915 limits 3D destination to pitch of 16B - 8kB, in dwords, if un-tiled. 1200 * i915 limits 3D destination to pitch 64B-aligned if used with depth. 1201 * i915 limits 3D destination to pitch of 512B - 8kB, in tiles, if tiled. 1202 * i915 limits 3D destination to POT aligned pitch if tiled. 1203 * i915 limits 3D destination drawing rect to w,h of 2048,2048. 1204 * 1205 * i845 limits 3D textures to 4B-aligned offset if un-tiled. 1206 * i845 limits 3D textures to ~4kB-aligned offset if tiled. 1207 * i845 limits 3D textures to width,height of 2048,2048. 1208 * i845 limits 3D textures to pitch of 4B - 8kB, in dwords. 1209 * i845 limits 3D destination to 4B-aligned offset if un-tiled. 1210 * i845 limits 3D destination to ~4kB-aligned offset if tiled. 1211 * i845 limits 3D destination to pitch of 8B - 8kB, in dwords. 1212 * i845 limits 3D destination drawing rect to w,h of 2048,2048. 1213 * 1214 * For the tiled issues, the only tiled buffer we draw to should be 1215 * the front, which will have an appropriate pitch/offset already set up, 1216 * so UXA doesn't need to worry. 1217 */ 1218 if (INTEL_INFO(intel)->gen >= 040) { 1219 intel->accel_pixmap_offset_alignment = 4 * 2; 1220 intel->accel_max_x = 8192; 1221 intel->accel_max_y = 8192; 1222 } else { 1223 intel->accel_pixmap_offset_alignment = 4; 1224 intel->accel_max_x = 2048; 1225 intel->accel_max_y = 2048; 1226 } 1227} 1228 1229static Bool intel_option_accel_none(intel_screen_private *intel) 1230{ 1231 const char *s; 1232 1233 s = xf86GetOptValString(intel->Options, OPTION_ACCEL_METHOD); 1234 if (s == NULL) 1235 return IS_DEFAULT_ACCEL_METHOD(NOACCEL); 1236 1237 return strcasecmp(s, "none") == 0; 1238} 1239 1240static Bool intel_option_accel_blt(intel_screen_private *intel) 1241{ 1242 const char *s; 1243 1244 s = xf86GetOptValString(intel->Options, OPTION_ACCEL_METHOD); 1245 if (s == NULL) 1246 return FALSE; 1247 1248 return strcasecmp(s, "blt") == 0; 1249} 1250 1251/** 1252 * Intialiazes the hardware for the 3D pipeline use in the 2D driver. 1253 * 1254 * Some state caching is performed to avoid redundant state emits. This 1255 * function is also responsible for marking the state as clobbered for DRI 1256 * clients. 1257 */ 1258void IntelEmitInvarientState(ScrnInfoPtr scrn) 1259{ 1260 intel_screen_private *intel = intel_get_screen_private(scrn); 1261 1262 /* If we've emitted our state since the last clobber by another client, 1263 * skip it. 1264 */ 1265 if (intel->last_3d != LAST_3D_OTHER) 1266 return; 1267 1268 if (IS_GEN2(intel)) 1269 I830EmitInvarientState(scrn); 1270 else if IS_GEN3(intel) 1271 I915EmitInvarientState(scrn); 1272} 1273 1274Bool intel_uxa_init(ScreenPtr screen) 1275{ 1276 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 1277 intel_screen_private *intel = intel_get_screen_private(scrn); 1278 1279 intel_batch_init(scrn); 1280 1281 if (INTEL_INFO(intel)->gen >= 040 && INTEL_INFO(intel)->gen < 0100) 1282 gen4_render_state_init(scrn); 1283 1284#if HAS_DIXREGISTERPRIVATEKEY 1285 if (!dixRegisterPrivateKey(&uxa_pixmap_index, PRIVATE_PIXMAP, 0)) 1286#else 1287 if (!dixRequestPrivate(&uxa_pixmap_index, 0)) 1288#endif 1289 return FALSE; 1290 1291 intel_limits_init(intel); 1292 1293 intel->uxa_driver = uxa_driver_alloc(); 1294 if (intel->uxa_driver == NULL) 1295 return FALSE; 1296 1297 memset(intel->uxa_driver, 0, sizeof(*intel->uxa_driver)); 1298 1299 intel->uxa_driver->uxa_major = 1; 1300 intel->uxa_driver->uxa_minor = 0; 1301 1302 intel->prim_offset = 0; 1303 intel->vertex_count = 0; 1304 intel->vertex_offset = 0; 1305 intel->vertex_used = 0; 1306 intel->floats_per_vertex = 0; 1307 intel->last_floats_per_vertex = 0; 1308 intel->vertex_bo = NULL; 1309 intel->surface_used = 0; 1310 intel->surface_reloc = 0; 1311 1312 /* Solid fill */ 1313 intel->uxa_driver->check_solid = intel_uxa_check_solid; 1314 intel->uxa_driver->prepare_solid = intel_uxa_prepare_solid; 1315 intel->uxa_driver->solid = intel_uxa_solid; 1316 intel->uxa_driver->done_solid = intel_uxa_done; 1317 1318 /* Copy */ 1319 intel->uxa_driver->check_copy = intel_uxa_check_copy; 1320 intel->uxa_driver->prepare_copy = intel_uxa_prepare_copy; 1321 intel->uxa_driver->copy = intel_uxa_copy; 1322 intel->uxa_driver->done_copy = intel_uxa_done; 1323 1324 /* Composite */ 1325 if (intel_option_accel_blt(intel)) { 1326 } else if (INTEL_INFO(intel)->gen < 030) { 1327 intel->uxa_driver->check_composite = i830_check_composite; 1328 intel->uxa_driver->check_composite_target = i830_check_composite_target; 1329 intel->uxa_driver->check_composite_texture = i830_check_composite_texture; 1330 intel->uxa_driver->prepare_composite = i830_prepare_composite; 1331 intel->uxa_driver->composite = i830_composite; 1332 intel->uxa_driver->done_composite = i830_done_composite; 1333 1334 intel->vertex_flush = i830_vertex_flush; 1335 intel->batch_commit_notify = i830_batch_commit_notify; 1336 } else if (INTEL_INFO(intel)->gen < 040) { 1337 intel->uxa_driver->check_composite = i915_check_composite; 1338 intel->uxa_driver->check_composite_target = i915_check_composite_target; 1339 intel->uxa_driver->check_composite_texture = i915_check_composite_texture; 1340 intel->uxa_driver->prepare_composite = i915_prepare_composite; 1341 intel->uxa_driver->composite = i915_composite; 1342 intel->uxa_driver->done_composite = i830_done_composite; 1343 1344 intel->vertex_flush = i915_vertex_flush; 1345 intel->batch_commit_notify = i915_batch_commit_notify; 1346 } else if (INTEL_INFO(intel)->gen < 0100) { 1347 intel->uxa_driver->check_composite = i965_check_composite; 1348 intel->uxa_driver->check_composite_texture = i965_check_composite_texture; 1349 intel->uxa_driver->prepare_composite = i965_prepare_composite; 1350 intel->uxa_driver->composite = i965_composite; 1351 intel->uxa_driver->done_composite = i830_done_composite; 1352 1353 intel->vertex_flush = i965_vertex_flush; 1354 intel->batch_flush = i965_batch_flush; 1355 intel->batch_commit_notify = i965_batch_commit_notify; 1356 1357 if (INTEL_INFO(intel)->gen < 050) { 1358 intel->context_switch = gen4_context_switch; 1359 } else if (INTEL_INFO(intel)->gen < 060) { 1360 intel->context_switch = gen5_context_switch; 1361 } else { 1362 intel->context_switch = gen6_context_switch; 1363 } 1364 } 1365 1366 /* PutImage */ 1367 intel->uxa_driver->put_image = intel_uxa_put_image; 1368 intel->uxa_driver->get_image = intel_uxa_get_image; 1369 1370 intel->uxa_driver->prepare_access = intel_uxa_prepare_access; 1371 intel->uxa_driver->finish_access = intel_uxa_finish_access; 1372 intel->uxa_driver->pixmap_is_offscreen = intel_uxa_pixmap_is_offscreen; 1373 1374 screen->CreatePixmap = intel_uxa_create_pixmap; 1375 screen->DestroyPixmap = intel_uxa_destroy_pixmap; 1376 1377#ifdef CREATE_PIXMAP_USAGE_SHARED 1378 screen->SharePixmapBacking = intel_uxa_share_pixmap_backing; 1379 screen->SetSharedPixmapBacking = intel_uxa_set_shared_pixmap_backing; 1380#endif 1381 1382 if (!uxa_driver_init(screen, intel->uxa_driver)) { 1383 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 1384 "UXA initialization failed\n"); 1385 free(intel->uxa_driver); 1386 return FALSE; 1387 } 1388 1389 if (intel_option_accel_none(intel)) 1390 intel->force_fallback = 1; 1391 1392 uxa_set_fallback_debug(screen, intel->fallback_debug); 1393 uxa_set_force_fallback(screen, intel->force_fallback); 1394 1395 intel->flush_rendering = intel_flush_rendering; 1396 return TRUE; 1397} 1398