xorg_exa.c revision b611f81477b196fed9d249b1e0f37ef186dd1426
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/* FIXME ! */ 32#define DRI_DRIVER_PATH "/ISO/X.Org/modular/i386/lib/dri" 33 34#include "xf86.h" 35//#include "xf86_OSproc.h" 36#include "xorg_tracker.h" 37 38//#include "pipe/p_winsys.h" 39#include "pipe/p_format.h" 40#include "pipe/p_context.h" 41#include "pipe/p_state.h" 42#include "pipe/p_inlines.h" 43 44struct exa_entity 45{ 46 ExaDriverPtr pExa; 47 struct pipe_context *ctx; 48 struct pipe_screen *scrn; 49}; 50 51struct PixmapPriv 52{ 53 int flags; 54 struct pipe_texture *tex; 55 unsigned int color; 56 struct pipe_surface *src_surf; /* for copies */ 57 58 struct pipe_transfer *map_transfer; 59 unsigned map_count; 60}; 61 62/* 63 * Helper functions 64 */ 65 66static void 67exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp) 68{ 69 switch (depth) { 70 case 32: 71 *format = PIPE_FORMAT_A8R8G8B8_UNORM; 72 assert(*bbp == 32); 73 break; 74 case 24: 75 *format = PIPE_FORMAT_X8R8G8B8_UNORM; 76 assert(*bbp == 32); 77 break; 78 case 16: 79 *format = PIPE_FORMAT_R5G6B5_UNORM; 80 assert(*bbp == 16); 81 break; 82 case 15: 83 *format = PIPE_FORMAT_A1R5G5B5_UNORM; 84 assert(*bbp == 16); 85 break; 86 case 8: 87 case 4: 88 case 1: 89 *format = PIPE_FORMAT_A8R8G8B8_UNORM; /* bad bad bad */ 90 break; 91 default: 92 assert(0); 93 break; 94 } 95} 96 97/* 98 * Static exported EXA functions 99 */ 100 101static void 102ExaWaitMarker(ScreenPtr pScreen, int marker) 103{ 104} 105 106static int 107ExaMarkSync(ScreenPtr pScreen) 108{ 109 return 1; 110} 111 112static Bool 113ExaPrepareAccess(PixmapPtr pPix, int index) 114{ 115 ScreenPtr pScreen = pPix->drawable.pScreen; 116 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 117 modesettingPtr ms = modesettingPTR(pScrn); 118 //PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); 119 struct exa_entity *exa = ms->exa; 120 struct PixmapPriv *priv; 121 //int ret; 122 123 priv = exaGetPixmapDriverPrivate(pPix); 124 125 if (!priv) 126 return FALSE; 127 128 if (!priv->tex) 129 return FALSE; 130 131 if (priv->map_count++ == 0) 132 { 133 priv->map_transfer = 134 exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0, 135 PIPE_TRANSFER_READ_WRITE, 136 0, 0, priv->tex->width[0], priv->tex->height[0]); 137 138 pPix->devPrivate.ptr = 139 exa->scrn->transfer_map(exa->scrn, priv->map_transfer); 140 pPix->devKind = priv->map_transfer->stride; 141 } 142 143 return TRUE; 144} 145 146static void 147ExaFinishAccess(PixmapPtr pPix, int index) 148{ 149 ScreenPtr pScreen = pPix->drawable.pScreen; 150 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 151 modesettingPtr ms = modesettingPTR(pScrn); 152 struct exa_entity *exa = ms->exa; 153 struct PixmapPriv *priv; 154 priv = exaGetPixmapDriverPrivate(pPix); 155 156 if (!priv) 157 return; 158 159 if (!priv->map_transfer) 160 return; 161 162 if (--priv->map_count == 0) { 163 assert(priv->map_transfer); 164 exa->scrn->transfer_unmap(exa->scrn, priv->map_transfer); 165 exa->scrn->tex_transfer_destroy(priv->map_transfer); 166 priv->map_transfer = NULL; 167 } 168} 169 170static void 171ExaDone(PixmapPtr pPixmap) 172{ 173 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 174 modesettingPtr ms = modesettingPTR(pScrn); 175 struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap); 176 struct exa_entity *exa = ms->exa; 177 178 if (!priv) 179 return; 180 181 if (priv->src_surf) 182 exa->scrn->tex_surface_destroy(priv->src_surf); 183 priv->src_surf = NULL; 184} 185 186static void 187ExaDoneComposite(PixmapPtr pPixmap) 188{ 189 190} 191 192static Bool 193ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) 194{ 195 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 196 modesettingPtr ms = modesettingPTR(pScrn); 197 struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap); 198 struct exa_entity *exa = ms->exa; 199 200 if (1) 201 return FALSE; 202 203 if (pPixmap->drawable.depth < 15) 204 return FALSE; 205 206 if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask)) 207 return FALSE; 208 209 if (!priv || !priv->tex) 210 return FALSE; 211 212 if (alu != GXcopy) 213 return FALSE; 214 215 if (!exa->ctx || !exa->ctx->surface_fill) 216 return FALSE; 217 218 priv->color = fg; 219 220 return TRUE; 221} 222 223static void 224ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1) 225{ 226 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 227 modesettingPtr ms = modesettingPTR(pScrn); 228 struct exa_entity *exa = ms->exa; 229 struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap); 230 struct pipe_surface *surf = 231 exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0, 232 PIPE_BUFFER_USAGE_GPU_READ | 233 PIPE_BUFFER_USAGE_GPU_WRITE); 234 235 exa->ctx->surface_fill(exa->ctx, surf, x0, y0, x1 - x0, y1 - y0, 236 priv->color); 237 238 exa->scrn->tex_surface_destroy(surf); 239} 240 241static Bool 242ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, 243 int ydir, int alu, Pixel planeMask) 244{ 245 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 246 modesettingPtr ms = modesettingPTR(pScrn); 247 struct exa_entity *exa = ms->exa; 248 struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pDstPixmap); 249 struct PixmapPriv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap); 250 251 if (1) 252 return FALSE; 253 254 if (alu != GXcopy) 255 return FALSE; 256 257 if (pSrcPixmap->drawable.depth < 15 || pDstPixmap->drawable.depth < 15) 258 return FALSE; 259 260 if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planeMask)) 261 return FALSE; 262 263 if (!priv || !src_priv) 264 return FALSE; 265 266 if (!priv->tex || !src_priv->tex) 267 return FALSE; 268 269 if (!exa->ctx || !exa->ctx->surface_copy) 270 return FALSE; 271 272 priv->src_surf = 273 exa->scrn->get_tex_surface(exa->scrn, src_priv->tex, 0, 0, 0, 274 PIPE_BUFFER_USAGE_GPU_READ | 275 PIPE_BUFFER_USAGE_GPU_WRITE); 276 277 return TRUE; 278} 279 280static void 281ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, 282 int width, int height) 283{ 284 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 285 modesettingPtr ms = modesettingPTR(pScrn); 286 struct exa_entity *exa = ms->exa; 287 struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pDstPixmap); 288 struct pipe_surface *surf = 289 exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0, 290 PIPE_BUFFER_USAGE_GPU_READ | 291 PIPE_BUFFER_USAGE_GPU_WRITE); 292 293 exa->ctx->surface_copy(exa->ctx, 0, surf, dstX, dstY, priv->src_surf, 294 srcX, srcY, width, height); 295 exa->scrn->tex_surface_destroy(surf); 296} 297 298static Bool 299ExaPrepareComposite(int op, PicturePtr pSrcPicture, 300 PicturePtr pMaskPicture, PicturePtr pDstPicture, 301 PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) 302{ 303 return FALSE; 304} 305 306#if 0 307static Bool 308ExaUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, 309 int src_pitch) 310{ 311 ErrorF("UPLOAD\n"); 312 313 return FALSE; 314} 315#endif 316 317static void 318ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 319 int dstX, int dstY, int width, int height) 320{ 321} 322 323static Bool 324ExaCheckComposite(int op, 325 PicturePtr pSrcPicture, PicturePtr pMaskPicture, 326 PicturePtr pDstPicture) 327{ 328 return FALSE; 329} 330 331static void * 332ExaCreatePixmap(ScreenPtr pScreen, int size, int align) 333{ 334 struct PixmapPriv *priv; 335 336 priv = xcalloc(1, sizeof(struct PixmapPriv)); 337 if (!priv) 338 return NULL; 339 340 return priv; 341} 342 343static void 344ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv) 345{ 346 struct PixmapPriv *priv = (struct PixmapPriv *)dPriv; 347 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 348 modesettingPtr ms = modesettingPTR(pScrn); 349 struct exa_entity *exa = ms->exa; 350 351 if (!priv) 352 return; 353 354 if (priv->tex) 355 ms->screen->texture_destroy(priv->tex); 356 357 xfree(priv); 358} 359 360static Bool 361ExaPixmapIsOffscreen(PixmapPtr pPixmap) 362{ 363 struct PixmapPriv *priv; 364 365 priv = exaGetPixmapDriverPrivate(pPixmap); 366 367 if (!priv) 368 return FALSE; 369 370 if (priv->tex) 371 return TRUE; 372 373 return FALSE; 374} 375 376unsigned 377xorg_exa_get_pixmap_handle(PixmapPtr pPixmap) 378{ 379 ScreenPtr pScreen = pPixmap->drawable.pScreen; 380 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 381 modesettingPtr ms = modesettingPTR(pScrn); 382 struct PixmapPriv *priv; 383 struct pipe_buffer *buffer = NULL; 384 unsigned handle; 385 unsigned stride; 386 387 if (!ms->exa) { 388 FatalError("NO MS->EXA\n"); 389 return 0; 390 } 391 392 priv = exaGetPixmapDriverPrivate(pPixmap); 393 394 if (!priv) { 395 FatalError("NO PIXMAP PRIVATE\n"); 396 return 0; 397 } 398 399 drm_api_hooks.buffer_from_texture(priv->tex, &buffer, &stride); 400 drm_api_hooks.handle_from_buffer(ms->screen, buffer, &handle); 401 pipe_buffer_reference(&buffer, NULL); 402 return handle; 403} 404 405static Bool 406ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, 407 int depth, int bitsPerPixel, int devKind, 408 pointer pPixData) 409{ 410 ScreenPtr pScreen = pPixmap->drawable.pScreen; 411 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 412 struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap); 413 modesettingPtr ms = modesettingPTR(pScrn); 414 //PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); 415 struct exa_entity *exa = ms->exa; 416 417 if (!priv) 418 return FALSE; 419 420 if (depth <= 0) 421 depth = pPixmap->drawable.depth; 422 423 if (bitsPerPixel <= 0) 424 bitsPerPixel = pPixmap->drawable.bitsPerPixel; 425 426 if (width <= 0) 427 width = pPixmap->drawable.width; 428 429 if (height <= 0) 430 height = pPixmap->drawable.height; 431 432 if (width <= 0 || height <= 0 || depth <= 0) 433 return FALSE; 434 435 miModifyPixmapHeader(pPixmap, width, height, depth, 436 bitsPerPixel, devKind, NULL); 437 438 /* Deal with screen resize */ 439 if (priv->tex && (priv->tex->width[0] != width || priv->tex->height[0] != height)) { 440 pipe_texture_reference(&priv->tex, NULL); 441 } 442 443 if (!priv->tex) { 444 struct pipe_texture template; 445 446 memset(&template, 0, sizeof(template)); 447 template.target = PIPE_TEXTURE_2D; 448 template.compressed = 0; 449 exa_get_pipe_format(depth, &template.format, &bitsPerPixel); 450 pf_get_block(template.format, &template.block); 451 template.width[0] = width; 452 template.height[0] = height; 453 template.depth[0] = 1; 454 template.last_level = 0; 455 template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; 456 priv->tex = exa->scrn->texture_create(exa->scrn, &template); 457 } 458 459 return TRUE; 460} 461 462struct pipe_texture * 463xorg_exa_get_texture(PixmapPtr pPixmap) 464{ 465 struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap); 466 struct pipe_texture *tex = NULL; 467 pipe_texture_reference(&tex, priv->tex); 468 return tex; 469} 470 471void 472xorg_exa_close(ScrnInfoPtr pScrn) 473{ 474 modesettingPtr ms = modesettingPTR(pScrn); 475 struct exa_entity *exa = ms->exa; 476 477 if (exa->ctx) 478 exa->ctx->destroy(exa->ctx); 479 480 exaDriverFini(pScrn->pScreen); 481 xfree(exa); 482 ms->exa = NULL; 483} 484 485void * 486xorg_exa_init(ScrnInfoPtr pScrn) 487{ 488 modesettingPtr ms = modesettingPTR(pScrn); 489 struct exa_entity *exa; 490 ExaDriverPtr pExa; 491 492 exa = xcalloc(1, sizeof(struct exa_entity)); 493 if (!exa) 494 return NULL; 495 496 pExa = exaDriverAlloc(); 497 if (!pExa) { 498 goto out_err; 499 } 500 501 memset(pExa, 0, sizeof(*pExa)); 502 pExa->exa_major = 2; 503 pExa->exa_minor = 2; 504 pExa->memoryBase = 0; 505 pExa->memorySize = 0; 506 pExa->offScreenBase = 0; 507 pExa->pixmapOffsetAlign = 0; 508 pExa->pixmapPitchAlign = 1; 509 pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS; 510 pExa->maxX = 8191; /* FIXME */ 511 pExa->maxY = 8191; /* FIXME */ 512 pExa->WaitMarker = ExaWaitMarker; 513 pExa->MarkSync = ExaMarkSync; 514 pExa->PrepareSolid = ExaPrepareSolid; 515 pExa->Solid = ExaSolid; 516 pExa->DoneSolid = ExaDone; 517 pExa->PrepareCopy = ExaPrepareCopy; 518 pExa->Copy = ExaCopy; 519 pExa->DoneCopy = ExaDone; 520 pExa->CheckComposite = ExaCheckComposite; 521 pExa->PrepareComposite = ExaPrepareComposite; 522 pExa->Composite = ExaComposite; 523 pExa->DoneComposite = ExaDoneComposite; 524 pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen; 525 pExa->PrepareAccess = ExaPrepareAccess; 526 pExa->FinishAccess = ExaFinishAccess; 527 //pExa->UploadToScreen = ExaUploadToScreen; 528 pExa->UploadToScreen = NULL; 529 pExa->CreatePixmap = ExaCreatePixmap; 530 pExa->DestroyPixmap = ExaDestroyPixmap; 531 pExa->ModifyPixmapHeader = ExaModifyPixmapHeader; 532 533 if (!exaDriverInit(pScrn->pScreen, pExa)) { 534 goto out_err; 535 } 536 537 exa->scrn = ms->screen; 538 exa->ctx = drm_api_hooks.create_context(exa->scrn); 539 /* Share context with DRI */ 540 ms->ctx = exa->ctx; 541 542 return (void *)exa; 543 544 out_err: 545 xorg_exa_close(pScrn); 546 547 return NULL; 548} 549 550/* vim: set sw=4 ts=8 sts=4: */ 551