xorg_exa.c revision 552efdae06eae578da6d0c6d6bad4b662bce9735
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_A8_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#ifdef EXA_MIXED_PIXMAPS 214 PIPE_TRANSFER_MAP_DIRECTLY | 215#endif 216 PIPE_TRANSFER_READ_WRITE, 217 0, 0, priv->tex->width[0], priv->tex->height[0]); 218 if (!priv->map_transfer) 219 return FALSE; 220 221 pPix->devPrivate.ptr = 222 exa->scrn->transfer_map(exa->scrn, priv->map_transfer); 223 pPix->devKind = priv->map_transfer->stride; 224 } 225 226 priv->map_count++; 227 228 return TRUE; 229} 230 231static void 232ExaFinishAccess(PixmapPtr pPix, int index) 233{ 234 ScreenPtr pScreen = pPix->drawable.pScreen; 235 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 236 modesettingPtr ms = modesettingPTR(pScrn); 237 struct exa_context *exa = ms->exa; 238 struct exa_pixmap_priv *priv; 239 priv = exaGetPixmapDriverPrivate(pPix); 240 241 if (!priv) 242 return; 243 244 if (!priv->map_transfer) 245 return; 246 247 if (--priv->map_count == 0) { 248 assert(priv->map_transfer); 249 exa->scrn->transfer_unmap(exa->scrn, priv->map_transfer); 250 exa->scrn->tex_transfer_destroy(priv->map_transfer); 251 priv->map_transfer = NULL; 252 pPix->devPrivate.ptr = NULL; 253 } 254} 255 256static void 257ExaDone(PixmapPtr pPixmap) 258{ 259 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 260 modesettingPtr ms = modesettingPTR(pScrn); 261 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); 262 struct exa_context *exa = ms->exa; 263 264 if (!priv) 265 return; 266 267#if 1 268 xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL); 269#else 270 xorg_exa_finish(exa); 271#endif 272 xorg_exa_common_done(exa); 273} 274 275static void 276ExaDoneComposite(PixmapPtr pPixmap) 277{ 278 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 279 modesettingPtr ms = modesettingPTR(pScrn); 280 struct exa_context *exa = ms->exa; 281 282 xorg_exa_common_done(exa); 283} 284 285static Bool 286ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) 287{ 288 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 289 modesettingPtr ms = modesettingPTR(pScrn); 290 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); 291 struct exa_context *exa = ms->exa; 292 293#if DEBUG_PRINT 294 debug_printf("ExaPrepareSolid(0x%x)\n", fg); 295#endif 296 if (!exa->pipe) 297 XORG_FALLBACK("solid accle not enabled"); 298 299 if (!priv || !priv->tex) 300 XORG_FALLBACK("solid !priv || !priv->tex"); 301 302 if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask)) 303 XORG_FALLBACK("solid planeMask is not solid"); 304 305 if (alu != GXcopy) 306 XORG_FALLBACK("solid not GXcopy"); 307 308 if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, 309 priv->tex->target, 310 PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { 311 XORG_FALLBACK("solid bad format %s", pf_name(priv->tex->format)); 312 } 313 314#if DEBUG_SOLID 315 fg = 0xffff0000; 316#endif 317 318#if DISABLE_ACCEL 319 return FALSE; 320#else 321 return xorg_solid_bind_state(exa, priv, fg); 322#endif 323} 324 325static void 326ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1) 327{ 328 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 329 modesettingPtr ms = modesettingPTR(pScrn); 330 struct exa_context *exa = ms->exa; 331 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); 332 333#if DEBUG_PRINT 334 debug_printf("\tExaSolid(%d, %d, %d, %d)\n", x0, y0, x1, y1); 335#endif 336 337#if 0 338 if (x0 == 0 && y0 == 0 && 339 x1 == priv->tex->width[0] && 340 y1 == priv->tex->height[0]) { 341 exa->ctx->clear(exa->pipe, PIPE_CLEAR_COLOR, 342 exa->solid_color, 1., 0); 343 } else 344#endif 345 346#if DEBUG_SOLID 347 exa->solid_color[0] = 0.f; 348 exa->solid_color[1] = 1.f; 349 exa->solid_color[2] = 0.f; 350 exa->solid_color[3] = 1.f; 351 xorg_solid(exa, priv, 0, 0, 1024, 768); 352 exa->solid_color[0] = 1.f; 353 exa->solid_color[1] = 0.f; 354 exa->solid_color[2] = 0.f; 355 exa->solid_color[3] = 1.f; 356 xorg_solid(exa, priv, 0, 0, 300, 300); 357 xorg_solid(exa, priv, 300, 300, 350, 350); 358 xorg_solid(exa, priv, 350, 350, 500, 500); 359 360 xorg_solid(exa, priv, 361 priv->tex->width[0] - 10, 362 priv->tex->height[0] - 10, 363 priv->tex->width[0], 364 priv->tex->height[0]); 365 366 exa->solid_color[0] = 0.f; 367 exa->solid_color[1] = 0.f; 368 exa->solid_color[2] = 1.f; 369 exa->solid_color[3] = 1.f; 370 371 exa->has_solid_color = FALSE; 372 ExaPrepareCopy(pPixmap, pPixmap, 0, 0, GXcopy, 0xffffffff); 373 ExaCopy(pPixmap, 0, 0, 50, 50, 500, 500); 374#else 375 xorg_solid(exa, priv, x0, y0, x1, y1) ; 376#endif 377} 378 379static Bool 380ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, 381 int ydir, int alu, Pixel planeMask) 382{ 383 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 384 modesettingPtr ms = modesettingPTR(pScrn); 385 struct exa_context *exa = ms->exa; 386 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap); 387 struct exa_pixmap_priv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap); 388 389#if DEBUG_PRINT 390 debug_printf("ExaPrepareCopy\n"); 391#endif 392 if (!exa->pipe) 393 XORG_FALLBACK("copy accle not enabled"); 394 395 if (!priv || !src_priv) 396 XORG_FALLBACK("copy !priv || !src_priv"); 397 398 if (!priv->tex || !src_priv->tex) 399 XORG_FALLBACK("copy !priv->tex || !src_priv->tex"); 400 401 if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planeMask)) 402 XORG_FALLBACK("copy planeMask is not solid"); 403 404 if (alu != GXcopy) 405 XORG_FALLBACK("copy alu not GXcopy"); 406 407 if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, 408 priv->tex->target, 409 PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) 410 XORG_FALLBACK("copy pDst format %s", pf_name(priv->tex->format)); 411 412 if (!exa->scrn->is_format_supported(exa->scrn, src_priv->tex->format, 413 src_priv->tex->target, 414 PIPE_TEXTURE_USAGE_SAMPLER, 0)) 415 XORG_FALLBACK("copy pSrc format %s", pf_name(src_priv->tex->format)); 416 417 exa->copy.src = src_priv; 418 exa->copy.dst = priv; 419 420#if DISABLE_ACCEL 421 return FALSE; 422#else 423 return TRUE; 424#endif 425} 426 427static void 428ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, 429 int width, int height) 430{ 431 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 432 modesettingPtr ms = modesettingPTR(pScrn); 433 struct exa_context *exa = ms->exa; 434 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap); 435 436#if DEBUG_PRINT 437 debug_printf("\tExaCopy(srcx=%d, srcy=%d, dstX=%d, dstY=%d, w=%d, h=%d)\n", 438 srcX, srcY, dstX, dstY, width, height); 439#endif 440 441 debug_assert(priv == exa->copy.dst); 442 443 xorg_copy_pixmap(exa, exa->copy.dst, dstX, dstY, 444 exa->copy.src, srcX, srcY, 445 width, height); 446} 447 448static Bool 449ExaPrepareComposite(int op, PicturePtr pSrcPicture, 450 PicturePtr pMaskPicture, PicturePtr pDstPicture, 451 PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) 452{ 453 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 454 modesettingPtr ms = modesettingPTR(pScrn); 455 struct exa_context *exa = ms->exa; 456 struct exa_pixmap_priv *priv; 457 458#if DEBUG_PRINT 459 debug_printf("ExaPrepareComposite\n"); 460#endif 461 if (!exa->pipe) 462 XORG_FALLBACK("comp accle not enabled"); 463 464 priv = exaGetPixmapDriverPrivate(pDst); 465 if (!priv || !priv->tex) 466 XORG_FALLBACK("comp pDst %s", !priv ? "!priv" : "!priv->tex"); 467 468 if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, 469 priv->tex->target, 470 PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) 471 XORG_FALLBACK("copy pDst format: %s", pf_name(priv->tex->format)); 472 473 if (pSrc) { 474 priv = exaGetPixmapDriverPrivate(pSrc); 475 if (!priv || !priv->tex) 476 XORG_FALLBACK("comp pSrc %s", !priv ? "!priv" : "!priv->tex"); 477 478 if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, 479 priv->tex->target, 480 PIPE_TEXTURE_USAGE_SAMPLER, 0)) 481 XORG_FALLBACK("copy pSrc format: %s", pf_name(priv->tex->format)); 482 } 483 484 if (pMask) { 485 priv = exaGetPixmapDriverPrivate(pMask); 486 if (!priv || !priv->tex) 487 XORG_FALLBACK("comp pMask %s", !priv ? "!priv" : "!priv->tex"); 488 489 if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, 490 priv->tex->target, 491 PIPE_TEXTURE_USAGE_SAMPLER, 0)) 492 XORG_FALLBACK("copy pMask format: %s", pf_name(priv->tex->format)); 493 } 494 495#if DISABLE_ACCEL 496 (void) exa; 497 return FALSE; 498#else 499 return xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture, 500 pDstPicture, 501 pSrc ? exaGetPixmapDriverPrivate(pSrc) : NULL, 502 pMask ? exaGetPixmapDriverPrivate(pMask) : NULL, 503 exaGetPixmapDriverPrivate(pDst)); 504#endif 505} 506 507static void 508ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 509 int dstX, int dstY, int width, int height) 510{ 511 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 512 modesettingPtr ms = modesettingPTR(pScrn); 513 struct exa_context *exa = ms->exa; 514 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDst); 515 516#if DEBUG_PRINT 517 debug_printf("\tExaComposite\n"); 518#endif 519 520 xorg_composite(exa, priv, srcX, srcY, maskX, maskY, 521 dstX, dstY, width, height); 522} 523 524static Bool 525ExaCheckComposite(int op, 526 PicturePtr pSrcPicture, PicturePtr pMaskPicture, 527 PicturePtr pDstPicture) 528{ 529 boolean accelerated = xorg_composite_accelerated(op, 530 pSrcPicture, 531 pMaskPicture, 532 pDstPicture); 533#if DEBUG_PRINT 534 debug_printf("ExaCheckComposite(%d, %p, %p, %p) = %d\n", 535 op, pSrcPicture, pMaskPicture, pDstPicture, accelerated); 536#endif 537 return accelerated; 538} 539 540static void * 541ExaCreatePixmap(ScreenPtr pScreen, int size, int align) 542{ 543 struct exa_pixmap_priv *priv; 544 545 priv = xcalloc(1, sizeof(struct exa_pixmap_priv)); 546 if (!priv) 547 return NULL; 548 549 return priv; 550} 551 552static void 553ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv) 554{ 555 struct exa_pixmap_priv *priv = (struct exa_pixmap_priv *)dPriv; 556 557 if (!priv) 558 return; 559 560 pipe_texture_reference(&priv->tex, NULL); 561 562 xfree(priv); 563} 564 565static Bool 566ExaPixmapIsOffscreen(PixmapPtr pPixmap) 567{ 568 struct exa_pixmap_priv *priv; 569 570 priv = exaGetPixmapDriverPrivate(pPixmap); 571 572 if (!priv) 573 return FALSE; 574 575 if (priv->tex) 576 return TRUE; 577 578 return FALSE; 579} 580 581int 582xorg_exa_set_displayed_usage(PixmapPtr pPixmap) 583{ 584 struct exa_pixmap_priv *priv; 585 priv = exaGetPixmapDriverPrivate(pPixmap); 586 587 if (!priv) { 588 FatalError("NO PIXMAP PRIVATE\n"); 589 return 0; 590 } 591 592 priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY; 593 594 return 0; 595} 596 597int 598xorg_exa_set_shared_usage(PixmapPtr pPixmap) 599{ 600 struct exa_pixmap_priv *priv; 601 priv = exaGetPixmapDriverPrivate(pPixmap); 602 603 if (!priv) { 604 FatalError("NO PIXMAP PRIVATE\n"); 605 return 0; 606 } 607 608 priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; 609 610 return 0; 611} 612 613unsigned 614xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out) 615{ 616 ScreenPtr pScreen = pPixmap->drawable.pScreen; 617 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 618 modesettingPtr ms = modesettingPTR(pScrn); 619 struct exa_pixmap_priv *priv; 620 unsigned handle; 621 unsigned stride; 622 623 if (!ms->exa) { 624 FatalError("NO MS->EXA\n"); 625 return 0; 626 } 627 628 priv = exaGetPixmapDriverPrivate(pPixmap); 629 630 if (!priv) { 631 FatalError("NO PIXMAP PRIVATE\n"); 632 return 0; 633 } 634 635 ms->api->local_handle_from_texture(ms->api, ms->screen, priv->tex, &stride, &handle); 636 if (stride_out) 637 *stride_out = stride; 638 639 return handle; 640} 641 642static Bool 643ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, 644 int depth, int bitsPerPixel, int devKind, 645 pointer pPixData) 646{ 647 ScreenPtr pScreen = pPixmap->drawable.pScreen; 648 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 649 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); 650 modesettingPtr ms = modesettingPTR(pScrn); 651 struct exa_context *exa = ms->exa; 652 653 if (!priv || pPixData) 654 return FALSE; 655 656 if (depth <= 0) 657 depth = pPixmap->drawable.depth; 658 659 if (bitsPerPixel <= 0) 660 bitsPerPixel = pPixmap->drawable.bitsPerPixel; 661 662 if (width <= 0) 663 width = pPixmap->drawable.width; 664 665 if (height <= 0) 666 height = pPixmap->drawable.height; 667 668 if (width <= 0 || height <= 0 || depth <= 0) 669 return FALSE; 670 671 miModifyPixmapHeader(pPixmap, width, height, depth, 672 bitsPerPixel, devKind, NULL); 673 674 /* Deal with screen resize */ 675 if (!priv->tex || 676 (priv->tex->width[0] != width || 677 priv->tex->height[0] != height || 678 priv->tex_flags != priv->flags)) { 679 struct pipe_texture *texture = NULL; 680 struct pipe_texture template; 681 682 memset(&template, 0, sizeof(template)); 683 template.target = PIPE_TEXTURE_2D; 684 exa_get_pipe_format(depth, &template.format, &bitsPerPixel); 685 pf_get_block(template.format, &template.block); 686 template.width[0] = width; 687 template.height[0] = height; 688 template.depth[0] = 1; 689 template.last_level = 0; 690 template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags; 691 priv->tex_flags = priv->flags; 692 texture = exa->scrn->texture_create(exa->scrn, &template); 693 694 if (priv->tex) { 695 struct pipe_surface *dst_surf; 696 struct pipe_surface *src_surf; 697 698 dst_surf = exa->scrn->get_tex_surface( 699 exa->scrn, texture, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); 700 src_surf = exa_gpu_surface(exa, priv); 701 exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf, 702 0, 0, min(width, texture->width[0]), 703 min(height, texture->height[0])); 704 exa->scrn->tex_surface_destroy(dst_surf); 705 exa->scrn->tex_surface_destroy(src_surf); 706 } 707 708 pipe_texture_reference(&priv->tex, texture); 709 /* the texture we create has one reference */ 710 pipe_texture_reference(&texture, NULL); 711 } 712 713 return TRUE; 714} 715 716struct pipe_texture * 717xorg_exa_get_texture(PixmapPtr pPixmap) 718{ 719 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); 720 struct pipe_texture *tex = NULL; 721 pipe_texture_reference(&tex, priv->tex); 722 return tex; 723} 724 725void 726xorg_exa_close(ScrnInfoPtr pScrn) 727{ 728 modesettingPtr ms = modesettingPTR(pScrn); 729 struct exa_context *exa = ms->exa; 730 struct pipe_constant_buffer *vsbuf = &exa->vs_const_buffer; 731 struct pipe_constant_buffer *fsbuf = &exa->fs_const_buffer; 732 733 if (exa->shaders) { 734 xorg_shaders_destroy(exa->shaders); 735 } 736 737 if (vsbuf && vsbuf->buffer) 738 pipe_buffer_reference(&vsbuf->buffer, NULL); 739 740 if (fsbuf && fsbuf->buffer) 741 pipe_buffer_reference(&fsbuf->buffer, NULL); 742 743 if (exa->cso) { 744 cso_release_all(exa->cso); 745 cso_destroy_context(exa->cso); 746 } 747 748 if (exa->pipe) 749 exa->pipe->destroy(exa->pipe); 750 751 exaDriverFini(pScrn->pScreen); 752 xfree(exa); 753 ms->exa = NULL; 754} 755 756void * 757xorg_exa_init(ScrnInfoPtr pScrn) 758{ 759 modesettingPtr ms = modesettingPTR(pScrn); 760 struct exa_context *exa; 761 ExaDriverPtr pExa; 762 763 exa = xcalloc(1, sizeof(struct exa_context)); 764 if (!exa) 765 return NULL; 766 767 pExa = exaDriverAlloc(); 768 if (!pExa) { 769 goto out_err; 770 } 771 772 memset(pExa, 0, sizeof(*pExa)); 773 774 pExa->exa_major = 2; 775 pExa->exa_minor = 2; 776 pExa->memoryBase = 0; 777 pExa->memorySize = 0; 778 pExa->offScreenBase = 0; 779 pExa->pixmapOffsetAlign = 0; 780 pExa->pixmapPitchAlign = 1; 781 pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS; 782#ifdef EXA_SUPPORTS_PREPARE_AUX 783 pExa->flags |= EXA_SUPPORTS_PREPARE_AUX; 784#endif 785#ifdef EXA_MIXED_PIXMAPS 786 pExa->flags |= EXA_MIXED_PIXMAPS; 787#endif 788 pExa->maxX = 8191; /* FIXME */ 789 pExa->maxY = 8191; /* FIXME */ 790 791 pExa->WaitMarker = ExaWaitMarker; 792 pExa->MarkSync = ExaMarkSync; 793 pExa->PrepareSolid = ExaPrepareSolid; 794 pExa->Solid = ExaSolid; 795 pExa->DoneSolid = ExaDone; 796 pExa->PrepareCopy = ExaPrepareCopy; 797 pExa->Copy = ExaCopy; 798 pExa->DoneCopy = ExaDone; 799 pExa->CheckComposite = ExaCheckComposite; 800 pExa->PrepareComposite = ExaPrepareComposite; 801 pExa->Composite = ExaComposite; 802 pExa->DoneComposite = ExaDoneComposite; 803 pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen; 804 pExa->DownloadFromScreen = ExaDownloadFromScreen; 805 pExa->UploadToScreen = ExaUploadToScreen; 806 pExa->PrepareAccess = ExaPrepareAccess; 807 pExa->FinishAccess = ExaFinishAccess; 808 pExa->CreatePixmap = ExaCreatePixmap; 809 pExa->DestroyPixmap = ExaDestroyPixmap; 810 pExa->ModifyPixmapHeader = ExaModifyPixmapHeader; 811 812 if (!exaDriverInit(pScrn->pScreen, pExa)) { 813 goto out_err; 814 } 815 816 exa->scrn = ms->screen; 817 exa->pipe = ms->api->create_context(ms->api, exa->scrn); 818 /* Share context with DRI */ 819 ms->ctx = exa->pipe; 820 821 exa->cso = cso_create_context(exa->pipe); 822 exa->shaders = xorg_shaders_create(exa); 823 824 xorg_exa_init_state(exa); 825 826 return (void *)exa; 827 828out_err: 829 xorg_exa_close(pScrn); 830 831 return NULL; 832} 833 834struct pipe_surface * 835exa_gpu_surface(struct exa_context *exa, struct exa_pixmap_priv *priv) 836{ 837 return exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0, 838 PIPE_BUFFER_USAGE_GPU_READ | 839 PIPE_BUFFER_USAGE_GPU_WRITE); 840 841} 842 843void xorg_exa_flush(struct exa_context *exa, uint pipeFlushFlags, 844 struct pipe_fence_handle **fence) 845{ 846 exa->pipe->flush(exa->pipe, pipeFlushFlags, fence); 847} 848 849void xorg_exa_finish(struct exa_context *exa) 850{ 851 struct pipe_fence_handle *fence = NULL; 852 853 xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, &fence); 854 855 exa->pipe->screen->fence_finish(exa->pipe->screen, fence, 0); 856 exa->pipe->screen->fence_reference(exa->pipe->screen, &fence, NULL); 857} 858 859