xorg_exa.c revision 3a8d525373c50c6cdc9ae5dd00e7298ab58df8c6
1/* 2 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * 26 * Author: Alan Hourihane <alanh@tungstengraphics.com> 27 * Author: Jakob Bornecrantz <wallbraker@gmail.com> 28 * 29 */ 30 31#include "xorg_exa.h" 32#include "xorg_tracker.h" 33#include "xorg_composite.h" 34#include "xorg_exa_tgsi.h" 35 36#include <xorg-server.h> 37#include <xf86.h> 38#include <picturestr.h> 39#include <picture.h> 40 41#include "pipe/p_format.h" 42#include "pipe/p_context.h" 43#include "pipe/p_state.h" 44#include "pipe/p_inlines.h" 45 46#include "cso_cache/cso_context.h" 47 48#include "util/u_rect.h" 49 50#define DEBUG_PRINT 0 51#define DEBUG_SOLID 0 52#define DISABLE_ACCEL 0 53 54/* 55 * Helper functions 56 */ 57 58static void 59exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp) 60{ 61 switch (depth) { 62 case 32: 63 *format = PIPE_FORMAT_A8R8G8B8_UNORM; 64 assert(*bbp == 32); 65 break; 66 case 24: 67 *format = PIPE_FORMAT_X8R8G8B8_UNORM; 68 assert(*bbp == 32); 69 break; 70 case 16: 71 *format = PIPE_FORMAT_R5G6B5_UNORM; 72 assert(*bbp == 16); 73 break; 74 case 15: 75 *format = PIPE_FORMAT_A1R5G5B5_UNORM; 76 assert(*bbp == 16); 77 break; 78 case 8: 79 *format = PIPE_FORMAT_I8_UNORM; 80 assert(*bbp == 8); 81 break; 82 case 4: 83 case 1: 84 *format = PIPE_FORMAT_A8R8G8B8_UNORM; /* bad bad bad */ 85 break; 86 default: 87 assert(0); 88 break; 89 } 90} 91 92static void 93xorg_exa_init_state(struct exa_context *exa) 94{ 95 struct pipe_depth_stencil_alpha_state dsa; 96 97 /* set common initial clip state */ 98 memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state)); 99 cso_set_depth_stencil_alpha(exa->cso, &dsa); 100} 101 102static void 103xorg_exa_common_done(struct exa_context *exa) 104{ 105 exa->copy.src = NULL; 106 exa->copy.dst = NULL; 107 exa->has_solid_color = FALSE; 108 exa->num_bound_samplers = 0; 109} 110 111/* 112 * Static exported EXA functions 113 */ 114 115static void 116ExaWaitMarker(ScreenPtr pScreen, int marker) 117{ 118} 119 120static int 121ExaMarkSync(ScreenPtr pScreen) 122{ 123 return 1; 124} 125 126static Bool 127ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst, 128 int dst_pitch) 129{ 130 ScreenPtr pScreen = pPix->drawable.pScreen; 131 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 132 modesettingPtr ms = modesettingPTR(pScrn); 133 struct exa_context *exa = ms->exa; 134 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix); 135 struct pipe_transfer *transfer; 136 137 if (!priv || !priv->tex) 138 return FALSE; 139 140 if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) & 141 PIPE_REFERENCED_FOR_WRITE) 142 exa->pipe->flush(exa->pipe, 0, NULL); 143 144 transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0, 145 PIPE_TRANSFER_READ, x, y, w, h); 146 if (!transfer) 147 return FALSE; 148 149 util_copy_rect((unsigned char*)dst, &priv->tex->block, dst_pitch, 0, 0, 150 w, h, exa->scrn->transfer_map(exa->scrn, transfer), 151 transfer->stride, 0, 0); 152 153 exa->scrn->transfer_unmap(exa->scrn, transfer); 154 exa->scrn->tex_transfer_destroy(transfer); 155 156 return TRUE; 157} 158 159static Bool 160ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src, 161 int src_pitch) 162{ 163 ScreenPtr pScreen = pPix->drawable.pScreen; 164 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 165 modesettingPtr ms = modesettingPTR(pScrn); 166 struct exa_context *exa = ms->exa; 167 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix); 168 struct pipe_transfer *transfer; 169 170 if (!priv || !priv->tex) 171 return FALSE; 172 173 transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0, 174 PIPE_TRANSFER_WRITE, x, y, w, h); 175 if (!transfer) 176 return FALSE; 177 178 util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer), 179 &priv->tex->block, transfer->stride, 0, 0, w, h, 180 (unsigned char*)src, src_pitch, 0, 0); 181 182 exa->scrn->transfer_unmap(exa->scrn, transfer); 183 exa->scrn->tex_transfer_destroy(transfer); 184 185 return TRUE; 186} 187 188static Bool 189ExaPrepareAccess(PixmapPtr pPix, int index) 190{ 191 ScreenPtr pScreen = pPix->drawable.pScreen; 192 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 193 modesettingPtr ms = modesettingPTR(pScrn); 194 struct exa_context *exa = ms->exa; 195 struct exa_pixmap_priv *priv; 196 197 priv = exaGetPixmapDriverPrivate(pPix); 198 199 if (!priv) 200 return FALSE; 201 202 if (!priv->tex) 203 return FALSE; 204 205 if (priv->map_count++ == 0) 206 { 207 if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) & 208 PIPE_REFERENCED_FOR_WRITE) 209 exa->pipe->flush(exa->pipe, 0, NULL); 210 211 priv->map_transfer = 212 exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0, 213 PIPE_TRANSFER_READ_WRITE, 214 0, 0, priv->tex->width[0], priv->tex->height[0]); 215 216 pPix->devPrivate.ptr = 217 exa->scrn->transfer_map(exa->scrn, priv->map_transfer); 218 pPix->devKind = priv->map_transfer->stride; 219 } 220 221 return TRUE; 222} 223 224static void 225ExaFinishAccess(PixmapPtr pPix, int index) 226{ 227 ScreenPtr pScreen = pPix->drawable.pScreen; 228 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 229 modesettingPtr ms = modesettingPTR(pScrn); 230 struct exa_context *exa = ms->exa; 231 struct exa_pixmap_priv *priv; 232 priv = exaGetPixmapDriverPrivate(pPix); 233 234 if (!priv) 235 return; 236 237 if (!priv->map_transfer) 238 return; 239 240 if (--priv->map_count == 0) { 241 assert(priv->map_transfer); 242 exa->scrn->transfer_unmap(exa->scrn, priv->map_transfer); 243 exa->scrn->tex_transfer_destroy(priv->map_transfer); 244 priv->map_transfer = NULL; 245 pPix->devPrivate.ptr = NULL; 246 } 247} 248 249static void 250ExaDone(PixmapPtr pPixmap) 251{ 252 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 253 modesettingPtr ms = modesettingPTR(pScrn); 254 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); 255 struct exa_context *exa = ms->exa; 256 257 if (!priv) 258 return; 259 260#if 1 261 xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL); 262#else 263 xorg_exa_finish(exa); 264#endif 265 xorg_exa_common_done(exa); 266} 267 268static void 269ExaDoneComposite(PixmapPtr pPixmap) 270{ 271 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 272 modesettingPtr ms = modesettingPTR(pScrn); 273 struct exa_context *exa = ms->exa; 274 275 xorg_exa_common_done(exa); 276} 277 278static Bool 279ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) 280{ 281 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 282 modesettingPtr ms = modesettingPTR(pScrn); 283 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); 284 struct exa_context *exa = ms->exa; 285 286#if DEBUG_PRINT 287 debug_printf("ExaPrepareSolid(0x%x)\n", fg); 288#endif 289 if (!exa->pipe) 290 XORG_FALLBACK("solid accle not enabled"); 291 292 if (!priv || !priv->tex) 293 XORG_FALLBACK("solid !priv || !priv->tex"); 294 295 if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask)) 296 XORG_FALLBACK("solid planeMask is not solid"); 297 298 if (alu != GXcopy) 299 XORG_FALLBACK("solid not GXcopy"); 300 301 if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, 302 priv->tex->target, 303 PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { 304 XORG_FALLBACK("solid bad format %s", pf_name(priv->tex->format)); 305 } 306 307#if DEBUG_SOLID 308 fg = 0xffff0000; 309#endif 310 311#if DISABLE_ACCEL 312 return FALSE; 313#else 314 return xorg_solid_bind_state(exa, priv, fg); 315#endif 316} 317 318static void 319ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1) 320{ 321 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 322 modesettingPtr ms = modesettingPTR(pScrn); 323 struct exa_context *exa = ms->exa; 324 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); 325 326#if DEBUG_PRINT 327 debug_printf("\tExaSolid(%d, %d, %d, %d)\n", x0, y0, x1, y1); 328#endif 329 330#if 0 331 if (x0 == 0 && y0 == 0 && 332 x1 == priv->tex->width[0] && 333 y1 == priv->tex->height[0]) { 334 exa->ctx->clear(exa->pipe, PIPE_CLEAR_COLOR, 335 exa->solid_color, 1., 0); 336 } else 337#endif 338 339#if DEBUG_SOLID 340 exa->solid_color[0] = 0.f; 341 exa->solid_color[1] = 1.f; 342 exa->solid_color[2] = 0.f; 343 exa->solid_color[3] = 1.f; 344 xorg_solid(exa, priv, 0, 0, 1024, 768); 345 exa->solid_color[0] = 1.f; 346 exa->solid_color[1] = 0.f; 347 exa->solid_color[2] = 0.f; 348 exa->solid_color[3] = 1.f; 349 xorg_solid(exa, priv, 0, 0, 300, 300); 350 xorg_solid(exa, priv, 300, 300, 350, 350); 351 xorg_solid(exa, priv, 350, 350, 500, 500); 352 353 xorg_solid(exa, priv, 354 priv->tex->width[0] - 10, 355 priv->tex->height[0] - 10, 356 priv->tex->width[0], 357 priv->tex->height[0]); 358 359 exa->solid_color[0] = 0.f; 360 exa->solid_color[1] = 0.f; 361 exa->solid_color[2] = 1.f; 362 exa->solid_color[3] = 1.f; 363 364 exa->has_solid_color = FALSE; 365 ExaPrepareCopy(pPixmap, pPixmap, 0, 0, GXcopy, 0xffffffff); 366 ExaCopy(pPixmap, 0, 0, 50, 50, 500, 500); 367#else 368 xorg_solid(exa, priv, x0, y0, x1, y1) ; 369#endif 370} 371 372static Bool 373ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, 374 int ydir, int alu, Pixel planeMask) 375{ 376 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 377 modesettingPtr ms = modesettingPTR(pScrn); 378 struct exa_context *exa = ms->exa; 379 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap); 380 struct exa_pixmap_priv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap); 381 382#if DEBUG_PRINT 383 debug_printf("ExaPrepareCopy\n"); 384#endif 385 if (!exa->pipe) 386 XORG_FALLBACK("copy accle not enabled"); 387 388 if (!priv || !src_priv) 389 XORG_FALLBACK("copy !priv || !src_priv"); 390 391 if (!priv->tex || !src_priv->tex) 392 XORG_FALLBACK("copy !priv->tex || !src_priv->tex"); 393 394 if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planeMask)) 395 XORG_FALLBACK("copy planeMask is not solid"); 396 397 if (alu != GXcopy) 398 XORG_FALLBACK("copy alu not GXcopy"); 399 400 if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, 401 priv->tex->target, 402 PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) 403 XORG_FALLBACK("copy pDst format %s", pf_name(priv->tex->format)); 404 405 if (!exa->scrn->is_format_supported(exa->scrn, src_priv->tex->format, 406 src_priv->tex->target, 407 PIPE_TEXTURE_USAGE_SAMPLER, 0)) 408 XORG_FALLBACK("copy pSrc format %s", pf_name(src_priv->tex->format)); 409 410 exa->copy.src = src_priv; 411 exa->copy.dst = priv; 412 413#if DISABLE_ACCEL 414 return FALSE; 415#else 416 return TRUE; 417#endif 418} 419 420static void 421ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, 422 int width, int height) 423{ 424 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 425 modesettingPtr ms = modesettingPTR(pScrn); 426 struct exa_context *exa = ms->exa; 427 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap); 428 429#if DEBUG_PRINT 430 debug_printf("\tExaCopy(srcx=%d, srcy=%d, dstX=%d, dstY=%d, w=%d, h=%d)\n", 431 srcX, srcY, dstX, dstY, width, height); 432#endif 433 434 debug_assert(priv == exa->copy.dst); 435 436 xorg_copy_pixmap(exa, exa->copy.dst, dstX, dstY, 437 exa->copy.src, srcX, srcY, 438 width, height); 439} 440 441static Bool 442ExaPrepareComposite(int op, PicturePtr pSrcPicture, 443 PicturePtr pMaskPicture, PicturePtr pDstPicture, 444 PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) 445{ 446 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 447 modesettingPtr ms = modesettingPTR(pScrn); 448 struct exa_context *exa = ms->exa; 449 struct exa_pixmap_priv *priv; 450 451#if DEBUG_PRINT 452 debug_printf("ExaPrepareComposite\n"); 453#endif 454 if (!exa->pipe) 455 XORG_FALLBACK("comp accle not enabled"); 456 457 priv = exaGetPixmapDriverPrivate(pDst); 458 if (!priv || !priv->tex) 459 XORG_FALLBACK("comp pDst %s", !priv ? "!priv" : "!priv->tex"); 460 461 if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, 462 priv->tex->target, 463 PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) 464 XORG_FALLBACK("copy pDst format: %s", pf_name(priv->tex->format)); 465 466 if (pSrc) { 467 priv = exaGetPixmapDriverPrivate(pSrc); 468 if (!priv || !priv->tex) 469 XORG_FALLBACK("comp pSrc %s", !priv ? "!priv" : "!priv->tex"); 470 471 if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, 472 priv->tex->target, 473 PIPE_TEXTURE_USAGE_SAMPLER, 0)) 474 XORG_FALLBACK("copy pSrc format: %s", pf_name(priv->tex->format)); 475 } 476 477 if (pMask) { 478 priv = exaGetPixmapDriverPrivate(pMask); 479 if (!priv || !priv->tex) 480 XORG_FALLBACK("comp pMask %s", !priv ? "!priv" : "!priv->tex"); 481 482 if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, 483 priv->tex->target, 484 PIPE_TEXTURE_USAGE_SAMPLER, 0)) 485 XORG_FALLBACK("copy pMask format: %s", pf_name(priv->tex->format)); 486 } 487 488#if DISABLE_ACCEL 489 (void) exa; 490 return FALSE; 491#else 492 return xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture, 493 pDstPicture, 494 pSrc ? exaGetPixmapDriverPrivate(pSrc) : NULL, 495 pMask ? exaGetPixmapDriverPrivate(pMask) : NULL, 496 exaGetPixmapDriverPrivate(pDst)); 497#endif 498} 499 500static void 501ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 502 int dstX, int dstY, int width, int height) 503{ 504 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 505 modesettingPtr ms = modesettingPTR(pScrn); 506 struct exa_context *exa = ms->exa; 507 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDst); 508 509#if DEBUG_PRINT 510 debug_printf("\tExaComposite\n"); 511#endif 512 513 xorg_composite(exa, priv, srcX, srcY, maskX, maskY, 514 dstX, dstY, width, height); 515} 516 517static Bool 518ExaCheckComposite(int op, 519 PicturePtr pSrcPicture, PicturePtr pMaskPicture, 520 PicturePtr pDstPicture) 521{ 522 boolean accelerated = xorg_composite_accelerated(op, 523 pSrcPicture, 524 pMaskPicture, 525 pDstPicture); 526#if DEBUG_PRINT 527 debug_printf("ExaCheckComposite(%d, %p, %p, %p) = %d\n", 528 op, pSrcPicture, pMaskPicture, pDstPicture, accelerated); 529#endif 530 return accelerated; 531} 532 533static void * 534ExaCreatePixmap(ScreenPtr pScreen, int size, int align) 535{ 536 struct exa_pixmap_priv *priv; 537 538 priv = xcalloc(1, sizeof(struct exa_pixmap_priv)); 539 if (!priv) 540 return NULL; 541 542 return priv; 543} 544 545static void 546ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv) 547{ 548 struct exa_pixmap_priv *priv = (struct exa_pixmap_priv *)dPriv; 549 550 if (!priv) 551 return; 552 553 pipe_texture_reference(&priv->tex, NULL); 554 555 xfree(priv); 556} 557 558static Bool 559ExaPixmapIsOffscreen(PixmapPtr pPixmap) 560{ 561 struct exa_pixmap_priv *priv; 562 563 priv = exaGetPixmapDriverPrivate(pPixmap); 564 565 if (!priv) 566 return FALSE; 567 568 if (priv->tex) 569 return TRUE; 570 571 return FALSE; 572} 573 574int 575xorg_exa_set_displayed_usage(PixmapPtr pPixmap) 576{ 577 struct exa_pixmap_priv *priv; 578 priv = exaGetPixmapDriverPrivate(pPixmap); 579 580 if (!priv) { 581 FatalError("NO PIXMAP PRIVATE\n"); 582 return 0; 583 } 584 585 priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY; 586 587 return 0; 588} 589 590int 591xorg_exa_set_shared_usage(PixmapPtr pPixmap) 592{ 593 struct exa_pixmap_priv *priv; 594 priv = exaGetPixmapDriverPrivate(pPixmap); 595 596 if (!priv) { 597 FatalError("NO PIXMAP PRIVATE\n"); 598 return 0; 599 } 600 601 priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; 602 603 return 0; 604} 605 606unsigned 607xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out) 608{ 609 ScreenPtr pScreen = pPixmap->drawable.pScreen; 610 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 611 modesettingPtr ms = modesettingPTR(pScrn); 612 struct exa_pixmap_priv *priv; 613 unsigned handle; 614 unsigned stride; 615 616 if (!ms->exa) { 617 FatalError("NO MS->EXA\n"); 618 return 0; 619 } 620 621 priv = exaGetPixmapDriverPrivate(pPixmap); 622 623 if (!priv) { 624 FatalError("NO PIXMAP PRIVATE\n"); 625 return 0; 626 } 627 628 ms->api->local_handle_from_texture(ms->api, ms->screen, priv->tex, &stride, &handle); 629 if (stride_out) 630 *stride_out = stride; 631 632 return handle; 633} 634 635static Bool 636ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, 637 int depth, int bitsPerPixel, int devKind, 638 pointer pPixData) 639{ 640 ScreenPtr pScreen = pPixmap->drawable.pScreen; 641 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 642 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); 643 modesettingPtr ms = modesettingPTR(pScrn); 644 struct exa_context *exa = ms->exa; 645 646 if (!priv || pPixData) 647 return FALSE; 648 649 if (depth <= 0) 650 depth = pPixmap->drawable.depth; 651 652 if (bitsPerPixel <= 0) 653 bitsPerPixel = pPixmap->drawable.bitsPerPixel; 654 655 if (width <= 0) 656 width = pPixmap->drawable.width; 657 658 if (height <= 0) 659 height = pPixmap->drawable.height; 660 661 if (width <= 0 || height <= 0 || depth <= 0) 662 return FALSE; 663 664 miModifyPixmapHeader(pPixmap, width, height, depth, 665 bitsPerPixel, devKind, NULL); 666 667 /* Deal with screen resize */ 668 if (!priv->tex || 669 (priv->tex->width[0] != width || 670 priv->tex->height[0] != height || 671 priv->tex_flags != priv->flags)) { 672 struct pipe_texture *texture = NULL; 673 674#ifdef DRM_MODE_FEATURE_DIRTYFB 675 if (priv->flags) 676#endif 677 { 678 struct pipe_texture template; 679 680 memset(&template, 0, sizeof(template)); 681 template.target = PIPE_TEXTURE_2D; 682 exa_get_pipe_format(depth, &template.format, &bitsPerPixel); 683 pf_get_block(template.format, &template.block); 684 template.width[0] = width; 685 template.height[0] = height; 686 template.depth[0] = 1; 687 template.last_level = 0; 688 template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags; 689 priv->tex_flags = priv->flags; 690 texture = exa->scrn->texture_create(exa->scrn, &template); 691 692 if (priv->tex) { 693 struct pipe_surface *dst_surf; 694 struct pipe_surface *src_surf; 695 696 dst_surf = exa->scrn->get_tex_surface( 697 exa->scrn, texture, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); 698 src_surf = exa_gpu_surface(exa, priv); 699 exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf, 700 0, 0, min(width, texture->width[0]), 701 min(height, texture->height[0])); 702 exa->scrn->tex_surface_destroy(dst_surf); 703 exa->scrn->tex_surface_destroy(src_surf); 704 } else if (pPixmap->devPrivate.ptr) { 705 struct pipe_transfer *transfer; 706 707 if (priv->map_count != 0) 708 FatalError("doing ExaModifyPixmapHeader on mapped buffer\n"); 709 710 transfer = 711 exa->scrn->get_tex_transfer(exa->scrn, texture, 0, 0, 0, 712 PIPE_TRANSFER_WRITE, 713 0, 0, width, height); 714 util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer), 715 &texture->block, transfer->stride, 0, 0, 716 width, height, pPixmap->devPrivate.ptr, 717 pPixmap->devKind, 0, 0); 718 exa->scrn->transfer_unmap(exa->scrn, transfer); 719 exa->scrn->tex_transfer_destroy(transfer); 720 721 xfree(pPixmap->devPrivate.ptr); 722 pPixmap->devPrivate.ptr = NULL; 723 } 724 } 725#ifdef DRM_MODE_FEATURE_DIRTYFB 726 else { 727 xfree(pPixmap->devPrivate.ptr); 728 pPixmap->devPrivate.ptr = xalloc(pPixmap->drawable.height * 729 pPixmap->devKind); 730 } 731#endif 732 733 pipe_texture_reference(&priv->tex, texture); 734 /* the texture we create has one reference */ 735 pipe_texture_reference(&texture, NULL); 736 } 737 738 return TRUE; 739} 740 741struct pipe_texture * 742xorg_exa_get_texture(PixmapPtr pPixmap) 743{ 744 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); 745 struct pipe_texture *tex = NULL; 746 pipe_texture_reference(&tex, priv->tex); 747 return tex; 748} 749 750void 751xorg_exa_close(ScrnInfoPtr pScrn) 752{ 753 modesettingPtr ms = modesettingPTR(pScrn); 754 struct exa_context *exa = ms->exa; 755 struct pipe_constant_buffer *vsbuf = &exa->vs_const_buffer; 756 struct pipe_constant_buffer *fsbuf = &exa->fs_const_buffer; 757 758 if (exa->shaders) { 759 xorg_shaders_destroy(exa->shaders); 760 } 761 762 if (vsbuf && vsbuf->buffer) 763 pipe_buffer_reference(&vsbuf->buffer, NULL); 764 765 if (fsbuf && fsbuf->buffer) 766 pipe_buffer_reference(&fsbuf->buffer, NULL); 767 768 if (exa->cso) { 769 cso_release_all(exa->cso); 770 cso_destroy_context(exa->cso); 771 } 772 773 if (exa->pipe) 774 exa->pipe->destroy(exa->pipe); 775 776 exaDriverFini(pScrn->pScreen); 777 xfree(exa); 778 ms->exa = NULL; 779} 780 781void * 782xorg_exa_init(ScrnInfoPtr pScrn) 783{ 784 modesettingPtr ms = modesettingPTR(pScrn); 785 struct exa_context *exa; 786 ExaDriverPtr pExa; 787 788 exa = xcalloc(1, sizeof(struct exa_context)); 789 if (!exa) 790 return NULL; 791 792 pExa = exaDriverAlloc(); 793 if (!pExa) { 794 goto out_err; 795 } 796 797 memset(pExa, 0, sizeof(*pExa)); 798 799 pExa->exa_major = 2; 800 pExa->exa_minor = 2; 801 pExa->memoryBase = 0; 802 pExa->memorySize = 0; 803 pExa->offScreenBase = 0; 804 pExa->pixmapOffsetAlign = 0; 805 pExa->pixmapPitchAlign = 1; 806 pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS; 807#ifdef EXA_SUPPORTS_PREPARE_AUX 808 pExa->flags |= EXA_SUPPORTS_PREPARE_AUX; 809#endif 810#ifdef EXA_MIXED_PIXMAPS 811 pExa->flags |= EXA_MIXED_PIXMAPS; 812#endif 813 pExa->maxX = 8191; /* FIXME */ 814 pExa->maxY = 8191; /* FIXME */ 815 816 pExa->WaitMarker = ExaWaitMarker; 817 pExa->MarkSync = ExaMarkSync; 818 pExa->PrepareSolid = ExaPrepareSolid; 819 pExa->Solid = ExaSolid; 820 pExa->DoneSolid = ExaDone; 821 pExa->PrepareCopy = ExaPrepareCopy; 822 pExa->Copy = ExaCopy; 823 pExa->DoneCopy = ExaDone; 824 pExa->CheckComposite = ExaCheckComposite; 825 pExa->PrepareComposite = ExaPrepareComposite; 826 pExa->Composite = ExaComposite; 827 pExa->DoneComposite = ExaDoneComposite; 828 pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen; 829 pExa->DownloadFromScreen = ExaDownloadFromScreen; 830 pExa->UploadToScreen = ExaUploadToScreen; 831 pExa->PrepareAccess = ExaPrepareAccess; 832 pExa->FinishAccess = ExaFinishAccess; 833 pExa->CreatePixmap = ExaCreatePixmap; 834 pExa->DestroyPixmap = ExaDestroyPixmap; 835 pExa->ModifyPixmapHeader = ExaModifyPixmapHeader; 836 837 if (!exaDriverInit(pScrn->pScreen, pExa)) { 838 goto out_err; 839 } 840 841 exa->scrn = ms->screen; 842 exa->pipe = ms->api->create_context(ms->api, exa->scrn); 843 /* Share context with DRI */ 844 ms->ctx = exa->pipe; 845 846 exa->cso = cso_create_context(exa->pipe); 847 exa->shaders = xorg_shaders_create(exa); 848 849 xorg_exa_init_state(exa); 850 851 return (void *)exa; 852 853out_err: 854 xorg_exa_close(pScrn); 855 856 return NULL; 857} 858 859struct pipe_surface * 860exa_gpu_surface(struct exa_context *exa, struct exa_pixmap_priv *priv) 861{ 862 return exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0, 863 PIPE_BUFFER_USAGE_GPU_READ | 864 PIPE_BUFFER_USAGE_GPU_WRITE); 865 866} 867 868void xorg_exa_flush(struct exa_context *exa, uint pipeFlushFlags, 869 struct pipe_fence_handle **fence) 870{ 871 exa->pipe->flush(exa->pipe, pipeFlushFlags, fence); 872} 873 874void xorg_exa_finish(struct exa_context *exa) 875{ 876 struct pipe_fence_handle *fence = NULL; 877 878 xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, &fence); 879 880 exa->pipe->screen->fence_finish(exa->pipe->screen, fence, 0); 881 exa->pipe->screen->fence_reference(exa->pipe->screen, &fence, NULL); 882} 883 884