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