xorg_exa.c revision b97547027e0f049d1ceef7863815d53e471fb18c
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 442 debug_printf("ExaPrepareComposite\n"); 443 444#if DISABLE_ACCEL 445 (void) exa; 446 return FALSE; 447#else 448 return xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture, 449 pDstPicture, 450 exaGetPixmapDriverPrivate(pSrc), 451 exaGetPixmapDriverPrivate(pMask), 452 exaGetPixmapDriverPrivate(pDst)); 453#endif 454} 455 456static void 457ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 458 int dstX, int dstY, int width, int height) 459{ 460 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 461 modesettingPtr ms = modesettingPTR(pScrn); 462 struct exa_context *exa = ms->exa; 463 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDst); 464 465 debug_printf("\tExaComposite\n"); 466 467 xorg_composite(exa, priv, srcX, srcY, maskX, maskY, 468 dstX, dstY, width, height); 469} 470 471static Bool 472ExaCheckComposite(int op, 473 PicturePtr pSrcPicture, PicturePtr pMaskPicture, 474 PicturePtr pDstPicture) 475{ 476 boolean accelerated = xorg_composite_accelerated(op, 477 pSrcPicture, 478 pMaskPicture, 479 pDstPicture); 480 debug_printf("ExaCheckComposite(%d, %p, %p, %p) = %d\n", 481 op, pSrcPicture, pMaskPicture, pDstPicture, accelerated); 482 return accelerated; 483} 484 485static void * 486ExaCreatePixmap(ScreenPtr pScreen, int size, int align) 487{ 488 struct exa_pixmap_priv *priv; 489 490 priv = xcalloc(1, sizeof(struct exa_pixmap_priv)); 491 if (!priv) 492 return NULL; 493 494 return priv; 495} 496 497static void 498ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv) 499{ 500 struct exa_pixmap_priv *priv = (struct exa_pixmap_priv *)dPriv; 501 502 if (!priv) 503 return; 504 505 pipe_texture_reference(&priv->tex, NULL); 506 507 xfree(priv); 508} 509 510static Bool 511ExaPixmapIsOffscreen(PixmapPtr pPixmap) 512{ 513 struct exa_pixmap_priv *priv; 514 515 priv = exaGetPixmapDriverPrivate(pPixmap); 516 517 if (!priv) 518 return FALSE; 519 520 if (priv->tex) 521 return TRUE; 522 523 return FALSE; 524} 525 526int 527xorg_exa_set_displayed_usage(PixmapPtr pPixmap) 528{ 529 struct exa_pixmap_priv *priv; 530 priv = exaGetPixmapDriverPrivate(pPixmap); 531 532 if (!priv) { 533 FatalError("NO PIXMAP PRIVATE\n"); 534 return 0; 535 } 536 537 priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY; 538 539 return 0; 540} 541 542int 543xorg_exa_set_shared_usage(PixmapPtr pPixmap) 544{ 545 struct exa_pixmap_priv *priv; 546 priv = exaGetPixmapDriverPrivate(pPixmap); 547 548 if (!priv) { 549 FatalError("NO PIXMAP PRIVATE\n"); 550 return 0; 551 } 552 553 priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; 554 555 return 0; 556} 557 558unsigned 559xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out) 560{ 561 ScreenPtr pScreen = pPixmap->drawable.pScreen; 562 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 563 modesettingPtr ms = modesettingPTR(pScrn); 564 struct exa_pixmap_priv *priv; 565 unsigned handle; 566 unsigned stride; 567 568 if (!ms->exa) { 569 FatalError("NO MS->EXA\n"); 570 return 0; 571 } 572 573 priv = exaGetPixmapDriverPrivate(pPixmap); 574 575 if (!priv) { 576 FatalError("NO PIXMAP PRIVATE\n"); 577 return 0; 578 } 579 580 ms->api->local_handle_from_texture(ms->api, ms->screen, priv->tex, &stride, &handle); 581 if (stride_out) 582 *stride_out = stride; 583 584 return handle; 585} 586 587static Bool 588ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, 589 int depth, int bitsPerPixel, int devKind, 590 pointer pPixData) 591{ 592 ScreenPtr pScreen = pPixmap->drawable.pScreen; 593 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 594 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); 595 modesettingPtr ms = modesettingPTR(pScrn); 596 struct exa_context *exa = ms->exa; 597 598 if (!priv || pPixData) 599 return FALSE; 600 601 if (depth <= 0) 602 depth = pPixmap->drawable.depth; 603 604 if (bitsPerPixel <= 0) 605 bitsPerPixel = pPixmap->drawable.bitsPerPixel; 606 607 if (width <= 0) 608 width = pPixmap->drawable.width; 609 610 if (height <= 0) 611 height = pPixmap->drawable.height; 612 613 if (width <= 0 || height <= 0 || depth <= 0) 614 return FALSE; 615 616 miModifyPixmapHeader(pPixmap, width, height, depth, 617 bitsPerPixel, devKind, NULL); 618 619 /* Deal with screen resize */ 620 if (!priv->tex || 621 (priv->tex->width[0] != width || 622 priv->tex->height[0] != height || 623 priv->tex_flags != priv->flags)) { 624 struct pipe_texture *texture = NULL; 625 626#ifdef DRM_MODE_FEATURE_DIRTYFB 627 if (priv->flags) 628#endif 629 { 630 struct pipe_texture template; 631 632 memset(&template, 0, sizeof(template)); 633 template.target = PIPE_TEXTURE_2D; 634 exa_get_pipe_format(depth, &template.format, &bitsPerPixel); 635 pf_get_block(template.format, &template.block); 636 template.width[0] = width; 637 template.height[0] = height; 638 template.depth[0] = 1; 639 template.last_level = 0; 640 template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags; 641 priv->tex_flags = priv->flags; 642 texture = exa->scrn->texture_create(exa->scrn, &template); 643 644 if (priv->tex) { 645 struct pipe_surface *dst_surf; 646 struct pipe_surface *src_surf; 647 648 dst_surf = exa->scrn->get_tex_surface( 649 exa->scrn, texture, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); 650 src_surf = exa_gpu_surface(exa, priv); 651 exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf, 652 0, 0, min(width, texture->width[0]), 653 min(height, texture->height[0])); 654 exa->scrn->tex_surface_destroy(dst_surf); 655 exa->scrn->tex_surface_destroy(src_surf); 656 } else if (pPixmap->devPrivate.ptr) { 657 struct pipe_transfer *transfer; 658 659 if (priv->map_count != 0) 660 FatalError("doing ExaModifyPixmapHeader on mapped buffer\n"); 661 662 transfer = 663 exa->scrn->get_tex_transfer(exa->scrn, texture, 0, 0, 0, 664 PIPE_TRANSFER_WRITE, 665 0, 0, width, height); 666 util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer), 667 &texture->block, transfer->stride, 0, 0, 668 width, height, pPixmap->devPrivate.ptr, 669 pPixmap->devKind, 0, 0); 670 exa->scrn->transfer_unmap(exa->scrn, transfer); 671 exa->scrn->tex_transfer_destroy(transfer); 672 673 xfree(pPixmap->devPrivate.ptr); 674 pPixmap->devPrivate.ptr = NULL; 675 } 676 } 677#ifdef DRM_MODE_FEATURE_DIRTYFB 678 else { 679 xfree(pPixmap->devPrivate.ptr); 680 pPixmap->devPrivate.ptr = xalloc(pPixmap->drawable.height * 681 pPixmap->devKind); 682 } 683#endif 684 685 pipe_texture_reference(&priv->tex, texture); 686 /* the texture we create has one reference */ 687 pipe_texture_reference(&texture, NULL); 688 } 689 690 return TRUE; 691} 692 693struct pipe_texture * 694xorg_exa_get_texture(PixmapPtr pPixmap) 695{ 696 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); 697 struct pipe_texture *tex = NULL; 698 pipe_texture_reference(&tex, priv->tex); 699 return tex; 700} 701 702void 703xorg_exa_close(ScrnInfoPtr pScrn) 704{ 705 modesettingPtr ms = modesettingPTR(pScrn); 706 struct exa_context *exa = ms->exa; 707 struct pipe_constant_buffer *vsbuf = &exa->vs_const_buffer; 708 struct pipe_constant_buffer *fsbuf = &exa->fs_const_buffer; 709 710 if (exa->shaders) { 711 xorg_shaders_destroy(exa->shaders); 712 } 713 714 if (vsbuf && vsbuf->buffer) 715 pipe_buffer_reference(&vsbuf->buffer, NULL); 716 717 if (fsbuf && fsbuf->buffer) 718 pipe_buffer_reference(&fsbuf->buffer, NULL); 719 720 if (exa->cso) { 721 cso_release_all(exa->cso); 722 cso_destroy_context(exa->cso); 723 } 724 725 if (exa->pipe) 726 exa->pipe->destroy(exa->pipe); 727 728 exaDriverFini(pScrn->pScreen); 729 xfree(exa); 730 ms->exa = NULL; 731} 732 733void * 734xorg_exa_init(ScrnInfoPtr pScrn) 735{ 736 modesettingPtr ms = modesettingPTR(pScrn); 737 struct exa_context *exa; 738 ExaDriverPtr pExa; 739 740 exa = xcalloc(1, sizeof(struct exa_context)); 741 if (!exa) 742 return NULL; 743 744 pExa = exaDriverAlloc(); 745 if (!pExa) { 746 goto out_err; 747 } 748 749 memset(pExa, 0, sizeof(*pExa)); 750 751 pExa->exa_major = 2; 752 pExa->exa_minor = 2; 753 pExa->memoryBase = 0; 754 pExa->memorySize = 0; 755 pExa->offScreenBase = 0; 756 pExa->pixmapOffsetAlign = 0; 757 pExa->pixmapPitchAlign = 1; 758 pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS; 759#ifdef EXA_SUPPORTS_PREPARE_AUX 760 pExa->flags |= EXA_SUPPORTS_PREPARE_AUX; 761#endif 762#ifdef EXA_MIXED_PIXMAPS 763 pExa->flags |= EXA_MIXED_PIXMAPS; 764#endif 765 pExa->maxX = 8191; /* FIXME */ 766 pExa->maxY = 8191; /* FIXME */ 767 768 pExa->WaitMarker = ExaWaitMarker; 769 pExa->MarkSync = ExaMarkSync; 770 pExa->PrepareSolid = ExaPrepareSolid; 771 pExa->Solid = ExaSolid; 772 pExa->DoneSolid = ExaDone; 773 pExa->PrepareCopy = ExaPrepareCopy; 774 pExa->Copy = ExaCopy; 775 pExa->DoneCopy = ExaDone; 776 pExa->CheckComposite = ExaCheckComposite; 777 pExa->PrepareComposite = ExaPrepareComposite; 778 pExa->Composite = ExaComposite; 779 pExa->DoneComposite = ExaDoneComposite; 780 pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen; 781 pExa->DownloadFromScreen = ExaDownloadFromScreen; 782 pExa->UploadToScreen = ExaUploadToScreen; 783 pExa->PrepareAccess = ExaPrepareAccess; 784 pExa->FinishAccess = ExaFinishAccess; 785 pExa->CreatePixmap = ExaCreatePixmap; 786 pExa->DestroyPixmap = ExaDestroyPixmap; 787 pExa->ModifyPixmapHeader = ExaModifyPixmapHeader; 788 789 if (!exaDriverInit(pScrn->pScreen, pExa)) { 790 goto out_err; 791 } 792 793 exa->scrn = ms->screen; 794 exa->pipe = ms->api->create_context(ms->api, exa->scrn); 795 /* Share context with DRI */ 796 ms->ctx = exa->pipe; 797 798 exa->cso = cso_create_context(exa->pipe); 799 exa->shaders = xorg_shaders_create(exa); 800 801 xorg_exa_init_state(exa); 802 803 return (void *)exa; 804 805out_err: 806 xorg_exa_close(pScrn); 807 808 return NULL; 809} 810 811struct pipe_surface * 812exa_gpu_surface(struct exa_context *exa, struct exa_pixmap_priv *priv) 813{ 814 return exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0, 815 PIPE_BUFFER_USAGE_GPU_READ | 816 PIPE_BUFFER_USAGE_GPU_WRITE); 817 818} 819 820void xorg_exa_flush(struct exa_context *exa, uint pipeFlushFlags, 821 struct pipe_fence_handle **fence) 822{ 823 exa->pipe->flush(exa->pipe, pipeFlushFlags, fence); 824} 825 826void xorg_exa_finish(struct exa_context *exa) 827{ 828 struct pipe_fence_handle *fence = NULL; 829 830 xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, &fence); 831 832 exa->pipe->screen->fence_finish(exa->pipe->screen, fence, 0); 833 exa->pipe->screen->fence_reference(exa->pipe->screen, &fence, NULL); 834} 835 836