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