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