1 /* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */ 2 /************************************************************************** 3 4 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 5 Copyright 2000 VA Linux Systems, Inc. 6 Copyright 2007 Intel Corporation 7 All Rights Reserved. 8 9 Permission is hereby granted, free of charge, to any person obtaining a 10 copy of this software and associated documentation files (the 11 "Software"), to deal in the Software without restriction, including 12 without limitation the rights to use, copy, modify, merge, publish, 13 distribute, sub license, and/or sell copies of the Software, and to 14 permit persons to whom the Software is furnished to do so, subject to 15 the following conditions: 16 17 The above copyright notice and this permission notice (including the 18 next paragraph) shall be included in all copies or substantial portions 19 of the Software. 20 21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 29 **************************************************************************/ 30 31 /* 32 * Authors: 33 * Kevin E. Martin <martin (at) valinux.com> 34 * Jens Owen <jens (at) tungstengraphics.com> 35 * Rickard E. (Rik) Faith <faith (at) valinux.com> 36 * 37 */ 38 39 /* THIS IS NOT AN X CONSORTIUM STANDARD */ 40 41 #define NEED_REPLIES 42 #include <X11/Xlibint.h> 43 #include <X11/extensions/Xext.h> 44 #include <X11/extensions/extutil.h> 45 #include "va_dristr.h" 46 47 #define PUBLIC 48 49 static XExtensionInfo _va_dri_info_data; 50 static XExtensionInfo *va_dri_info = &_va_dri_info_data; 51 static char va_dri_extension_name[] = VA_DRINAME; 52 53 #define VA_DRICheckExtension(dpy,i,val) \ 54 XextCheckExtension (dpy, i, va_dri_extension_name, val) 55 56 /***************************************************************************** 57 * * 58 * private utility routines * 59 * * 60 *****************************************************************************/ 61 62 static int close_display(Display *dpy, XExtCodes *extCodes); 63 static /* const */ XExtensionHooks va_dri_extension_hooks = { 64 NULL, /* create_gc */ 65 NULL, /* copy_gc */ 66 NULL, /* flush_gc */ 67 NULL, /* free_gc */ 68 NULL, /* create_font */ 69 NULL, /* free_font */ 70 close_display, /* close_display */ 71 NULL, /* wire_to_event */ 72 NULL, /* event_to_wire */ 73 NULL, /* error */ 74 NULL, /* error_string */ 75 }; 76 77 static XEXT_GENERATE_FIND_DISPLAY (find_display, va_dri_info, 78 va_dri_extension_name, 79 &va_dri_extension_hooks, 80 0, NULL) 81 82 static XEXT_GENERATE_CLOSE_DISPLAY (close_display, va_dri_info) 83 84 85 /***************************************************************************** 86 * * 87 * public XFree86-DRI Extension routines * 88 * * 89 *****************************************************************************/ 90 91 #if 0 92 #include <stdio.h> 93 #define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg); 94 #else 95 #define TRACE(msg) 96 #endif 97 98 99 PUBLIC Bool VA_DRIQueryExtension (dpy, event_basep, error_basep) 100 Display *dpy; 101 int *event_basep, *error_basep; 102 { 103 XExtDisplayInfo *info = find_display (dpy); 104 105 TRACE("QueryExtension..."); 106 if (XextHasExtension(info)) { 107 *event_basep = info->codes->first_event; 108 *error_basep = info->codes->first_error; 109 TRACE("QueryExtension... return True"); 110 return True; 111 } else { 112 TRACE("QueryExtension... return False"); 113 return False; 114 } 115 } 116 117 PUBLIC Bool VA_DRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion) 118 Display* dpy; 119 int* majorVersion; 120 int* minorVersion; 121 int* patchVersion; 122 { 123 XExtDisplayInfo *info = find_display (dpy); 124 xVA_DRIQueryVersionReply rep; 125 xVA_DRIQueryVersionReq *req; 126 127 TRACE("QueryVersion..."); 128 VA_DRICheckExtension (dpy, info, False); 129 130 LockDisplay(dpy); 131 GetReq(VA_DRIQueryVersion, req); 132 req->reqType = info->codes->major_opcode; 133 req->driReqType = X_VA_DRIQueryVersion; 134 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 135 UnlockDisplay(dpy); 136 SyncHandle(); 137 TRACE("QueryVersion... return False"); 138 return False; 139 } 140 *majorVersion = rep.majorVersion; 141 *minorVersion = rep.minorVersion; 142 *patchVersion = rep.patchVersion; 143 UnlockDisplay(dpy); 144 SyncHandle(); 145 TRACE("QueryVersion... return True"); 146 return True; 147 } 148 149 PUBLIC Bool VA_DRIQueryDirectRenderingCapable(dpy, screen, isCapable) 150 Display* dpy; 151 int screen; 152 Bool* isCapable; 153 { 154 XExtDisplayInfo *info = find_display (dpy); 155 xVA_DRIQueryDirectRenderingCapableReply rep; 156 xVA_DRIQueryDirectRenderingCapableReq *req; 157 158 TRACE("QueryDirectRenderingCapable..."); 159 VA_DRICheckExtension (dpy, info, False); 160 161 LockDisplay(dpy); 162 GetReq(VA_DRIQueryDirectRenderingCapable, req); 163 req->reqType = info->codes->major_opcode; 164 req->driReqType = X_VA_DRIQueryDirectRenderingCapable; 165 req->screen = screen; 166 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 167 UnlockDisplay(dpy); 168 SyncHandle(); 169 TRACE("QueryDirectRenderingCapable... return False"); 170 return False; 171 } 172 *isCapable = rep.isCapable; 173 UnlockDisplay(dpy); 174 SyncHandle(); 175 TRACE("QueryDirectRenderingCapable... return True"); 176 return True; 177 } 178 179 PUBLIC Bool VA_DRIOpenConnection(dpy, screen, hSAREA, busIdString) 180 Display* dpy; 181 int screen; 182 drm_handle_t * hSAREA; 183 char **busIdString; 184 { 185 XExtDisplayInfo *info = find_display (dpy); 186 xVA_DRIOpenConnectionReply rep; 187 xVA_DRIOpenConnectionReq *req; 188 189 TRACE("OpenConnection..."); 190 VA_DRICheckExtension (dpy, info, False); 191 192 LockDisplay(dpy); 193 GetReq(VA_DRIOpenConnection, req); 194 req->reqType = info->codes->major_opcode; 195 req->driReqType = X_VA_DRIOpenConnection; 196 req->screen = screen; 197 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 198 UnlockDisplay(dpy); 199 SyncHandle(); 200 TRACE("OpenConnection... return False"); 201 return False; 202 } 203 204 *hSAREA = rep.hSAREALow; 205 if (sizeof(drm_handle_t) == 8) { 206 int shift = 32; /* var to prevent warning on next line */ 207 *hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift; 208 } 209 210 if (rep.length) { 211 if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) { 212 _XEatData(dpy, ((rep.busIdStringLength+3) & ~3)); 213 UnlockDisplay(dpy); 214 SyncHandle(); 215 TRACE("OpenConnection... return False"); 216 return False; 217 } 218 _XReadPad(dpy, *busIdString, rep.busIdStringLength); 219 } else { 220 *busIdString = NULL; 221 } 222 UnlockDisplay(dpy); 223 SyncHandle(); 224 TRACE("OpenConnection... return True"); 225 return True; 226 } 227 228 PUBLIC Bool VA_DRIAuthConnection(dpy, screen, magic) 229 Display* dpy; 230 int screen; 231 drm_magic_t magic; 232 { 233 XExtDisplayInfo *info = find_display (dpy); 234 xVA_DRIAuthConnectionReq *req; 235 xVA_DRIAuthConnectionReply rep; 236 237 TRACE("AuthConnection..."); 238 VA_DRICheckExtension (dpy, info, False); 239 240 LockDisplay(dpy); 241 GetReq(VA_DRIAuthConnection, req); 242 req->reqType = info->codes->major_opcode; 243 req->driReqType = X_VA_DRIAuthConnection; 244 req->screen = screen; 245 req->magic = magic; 246 rep.authenticated = 0; 247 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.authenticated) { 248 UnlockDisplay(dpy); 249 SyncHandle(); 250 TRACE("AuthConnection... return False"); 251 return False; 252 } 253 UnlockDisplay(dpy); 254 SyncHandle(); 255 TRACE("AuthConnection... return True"); 256 return True; 257 } 258 259 PUBLIC Bool VA_DRICloseConnection(dpy, screen) 260 Display* dpy; 261 int screen; 262 { 263 XExtDisplayInfo *info = find_display (dpy); 264 xVA_DRICloseConnectionReq *req; 265 266 TRACE("CloseConnection..."); 267 268 VA_DRICheckExtension (dpy, info, False); 269 270 LockDisplay(dpy); 271 GetReq(VA_DRICloseConnection, req); 272 req->reqType = info->codes->major_opcode; 273 req->driReqType = X_VA_DRICloseConnection; 274 req->screen = screen; 275 UnlockDisplay(dpy); 276 SyncHandle(); 277 TRACE("CloseConnection... return True"); 278 return True; 279 } 280 281 PUBLIC Bool VA_DRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion, 282 ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName) 283 Display* dpy; 284 int screen; 285 int* ddxDriverMajorVersion; 286 int* ddxDriverMinorVersion; 287 int* ddxDriverPatchVersion; 288 char** clientDriverName; 289 { 290 XExtDisplayInfo *info = find_display (dpy); 291 xVA_DRIGetClientDriverNameReply rep; 292 xVA_DRIGetClientDriverNameReq *req; 293 294 TRACE("GetClientDriverName..."); 295 VA_DRICheckExtension (dpy, info, False); 296 297 LockDisplay(dpy); 298 GetReq(VA_DRIGetClientDriverName, req); 299 req->reqType = info->codes->major_opcode; 300 req->driReqType = X_VA_DRIGetClientDriverName; 301 req->screen = screen; 302 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 303 UnlockDisplay(dpy); 304 SyncHandle(); 305 TRACE("GetClientDriverName... return False"); 306 return False; 307 } 308 309 *ddxDriverMajorVersion = rep.ddxDriverMajorVersion; 310 *ddxDriverMinorVersion = rep.ddxDriverMinorVersion; 311 *ddxDriverPatchVersion = rep.ddxDriverPatchVersion; 312 313 if (rep.length) { 314 if (!(*clientDriverName = (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) { 315 _XEatData(dpy, ((rep.clientDriverNameLength+3) & ~3)); 316 UnlockDisplay(dpy); 317 SyncHandle(); 318 TRACE("GetClientDriverName... return False"); 319 return False; 320 } 321 _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength); 322 } else { 323 *clientDriverName = NULL; 324 } 325 UnlockDisplay(dpy); 326 SyncHandle(); 327 TRACE("GetClientDriverName... return True"); 328 return True; 329 } 330 331 PUBLIC Bool VA_DRICreateContextWithConfig(dpy, screen, configID, context, 332 hHWContext) 333 Display* dpy; 334 int screen; 335 int configID; 336 XID* context; 337 drm_context_t * hHWContext; 338 { 339 XExtDisplayInfo *info = find_display (dpy); 340 xVA_DRICreateContextReply rep; 341 xVA_DRICreateContextReq *req; 342 343 TRACE("CreateContext..."); 344 VA_DRICheckExtension (dpy, info, False); 345 346 LockDisplay(dpy); 347 GetReq(VA_DRICreateContext, req); 348 req->reqType = info->codes->major_opcode; 349 req->driReqType = X_VA_DRICreateContext; 350 req->visual = configID; 351 req->screen = screen; 352 *context = XAllocID(dpy); 353 req->context = *context; 354 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 355 UnlockDisplay(dpy); 356 SyncHandle(); 357 TRACE("CreateContext... return False"); 358 return False; 359 } 360 *hHWContext = rep.hHWContext; 361 UnlockDisplay(dpy); 362 SyncHandle(); 363 TRACE("CreateContext... return True"); 364 return True; 365 } 366 367 PUBLIC Bool VA_DRICreateContext(dpy, screen, visual, context, hHWContext) 368 Display* dpy; 369 int screen; 370 Visual* visual; 371 XID* context; 372 drm_context_t * hHWContext; 373 { 374 return VA_DRICreateContextWithConfig( dpy, screen, visual->visualid, 375 context, hHWContext ); 376 } 377 378 PUBLIC Bool VA_DRIDestroyContext( __DRInativeDisplay * ndpy, int screen, 379 __DRIid context ) 380 { 381 Display * const dpy = (Display *) ndpy; 382 XExtDisplayInfo *info = find_display (dpy); 383 xVA_DRIDestroyContextReq *req; 384 385 TRACE("DestroyContext..."); 386 VA_DRICheckExtension (dpy, info, False); 387 388 LockDisplay(dpy); 389 GetReq(VA_DRIDestroyContext, req); 390 req->reqType = info->codes->major_opcode; 391 req->driReqType = X_VA_DRIDestroyContext; 392 req->screen = screen; 393 req->context = context; 394 UnlockDisplay(dpy); 395 SyncHandle(); 396 TRACE("DestroyContext... return True"); 397 return True; 398 } 399 400 PUBLIC Bool VA_DRICreateDrawable( __DRInativeDisplay * ndpy, int screen, 401 __DRIid drawable, drm_drawable_t * hHWDrawable ) 402 { 403 Display * const dpy = (Display *) ndpy; 404 XExtDisplayInfo *info = find_display (dpy); 405 xVA_DRICreateDrawableReply rep; 406 xVA_DRICreateDrawableReq *req; 407 408 TRACE("CreateDrawable..."); 409 VA_DRICheckExtension (dpy, info, False); 410 411 LockDisplay(dpy); 412 GetReq(VA_DRICreateDrawable, req); 413 req->reqType = info->codes->major_opcode; 414 req->driReqType = X_VA_DRICreateDrawable; 415 req->screen = screen; 416 req->drawable = drawable; 417 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 418 UnlockDisplay(dpy); 419 SyncHandle(); 420 TRACE("CreateDrawable... return False"); 421 return False; 422 } 423 *hHWDrawable = rep.hHWDrawable; 424 UnlockDisplay(dpy); 425 SyncHandle(); 426 TRACE("CreateDrawable... return True"); 427 return True; 428 } 429 430 PUBLIC Bool VA_DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen, 431 __DRIid drawable ) 432 { 433 Display * const dpy = (Display *) ndpy; 434 XExtDisplayInfo *info = find_display (dpy); 435 xVA_DRIDestroyDrawableReq *req; 436 437 TRACE("DestroyDrawable..."); 438 VA_DRICheckExtension (dpy, info, False); 439 440 LockDisplay(dpy); 441 GetReq(VA_DRIDestroyDrawable, req); 442 req->reqType = info->codes->major_opcode; 443 req->driReqType = X_VA_DRIDestroyDrawable; 444 req->screen = screen; 445 req->drawable = drawable; 446 UnlockDisplay(dpy); 447 SyncHandle(); 448 TRACE("DestroyDrawable... return True"); 449 return True; 450 } 451 452 PUBLIC Bool VA_DRIGetDrawableInfo(Display* dpy, int screen, Drawable drawable, 453 unsigned int* index, unsigned int* stamp, 454 int* X, int* Y, int* W, int* H, 455 int* numClipRects, drm_clip_rect_t ** pClipRects, 456 int* backX, int* backY, 457 int* numBackClipRects, drm_clip_rect_t ** pBackClipRects ) 458 { 459 XExtDisplayInfo *info = find_display (dpy); 460 xVA_DRIGetDrawableInfoReply rep; 461 xVA_DRIGetDrawableInfoReq *req; 462 int total_rects; 463 464 TRACE("GetDrawableInfo..."); 465 VA_DRICheckExtension (dpy, info, False); 466 467 LockDisplay(dpy); 468 GetReq(VA_DRIGetDrawableInfo, req); 469 req->reqType = info->codes->major_opcode; 470 req->driReqType = X_VA_DRIGetDrawableInfo; 471 req->screen = screen; 472 req->drawable = drawable; 473 474 if (!_XReply(dpy, (xReply *)&rep, 1, xFalse)) 475 { 476 UnlockDisplay(dpy); 477 SyncHandle(); 478 TRACE("GetDrawableInfo... return False"); 479 return False; 480 } 481 *index = rep.drawableTableIndex; 482 *stamp = rep.drawableTableStamp; 483 *X = (int)rep.drawableX; 484 *Y = (int)rep.drawableY; 485 *W = (int)rep.drawableWidth; 486 *H = (int)rep.drawableHeight; 487 *numClipRects = rep.numClipRects; 488 total_rects = *numClipRects; 489 490 *backX = rep.backX; 491 *backY = rep.backY; 492 *numBackClipRects = rep.numBackClipRects; 493 total_rects += *numBackClipRects; 494 495 #if 0 496 /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks 497 * backwards compatibility (Because of the >> 2 shift) but the fix 498 * enables multi-threaded apps to work. 499 */ 500 if (rep.length != ((((SIZEOF(xVA_DRIGetDrawableInfoReply) - 501 SIZEOF(xGenericReply) + 502 total_rects * sizeof(drm_clip_rect_t)) + 3) & ~3) >> 2)) { 503 _XEatData(dpy, rep.length); 504 UnlockDisplay(dpy); 505 SyncHandle(); 506 TRACE("GetDrawableInfo... return False"); 507 return False; 508 } 509 #endif 510 511 if (*numClipRects) { 512 int len = sizeof(drm_clip_rect_t) * (*numClipRects); 513 514 *pClipRects = (drm_clip_rect_t *)Xcalloc(len, 1); 515 if (*pClipRects) 516 _XRead(dpy, (char*)*pClipRects, len); 517 } else { 518 *pClipRects = NULL; 519 } 520 521 if (*numBackClipRects) { 522 int len = sizeof(drm_clip_rect_t) * (*numBackClipRects); 523 524 *pBackClipRects = (drm_clip_rect_t *)Xcalloc(len, 1); 525 if (*pBackClipRects) 526 _XRead(dpy, (char*)*pBackClipRects, len); 527 } else { 528 *pBackClipRects = NULL; 529 } 530 531 UnlockDisplay(dpy); 532 SyncHandle(); 533 TRACE("GetDrawableInfo... return True"); 534 return True; 535 } 536 537 PUBLIC Bool VA_DRIGetDeviceInfo(dpy, screen, hFrameBuffer, 538 fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate) 539 Display* dpy; 540 int screen; 541 drm_handle_t * hFrameBuffer; 542 int* fbOrigin; 543 int* fbSize; 544 int* fbStride; 545 int* devPrivateSize; 546 void** pDevPrivate; 547 { 548 XExtDisplayInfo *info = find_display (dpy); 549 xVA_DRIGetDeviceInfoReply rep; 550 xVA_DRIGetDeviceInfoReq *req; 551 552 TRACE("GetDeviceInfo..."); 553 VA_DRICheckExtension (dpy, info, False); 554 555 LockDisplay(dpy); 556 GetReq(VA_DRIGetDeviceInfo, req); 557 req->reqType = info->codes->major_opcode; 558 req->driReqType = X_VA_DRIGetDeviceInfo; 559 req->screen = screen; 560 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 561 UnlockDisplay(dpy); 562 SyncHandle(); 563 TRACE("GetDeviceInfo... return False"); 564 return False; 565 } 566 567 *hFrameBuffer = rep.hFrameBufferLow; 568 if (sizeof(drm_handle_t) == 8) { 569 int shift = 32; /* var to prevent warning on next line */ 570 *hFrameBuffer |= ((drm_handle_t) rep.hFrameBufferHigh) << shift; 571 } 572 573 *fbOrigin = rep.framebufferOrigin; 574 *fbSize = rep.framebufferSize; 575 *fbStride = rep.framebufferStride; 576 *devPrivateSize = rep.devPrivateSize; 577 578 if (rep.length) { 579 if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) { 580 _XEatData(dpy, ((rep.devPrivateSize+3) & ~3)); 581 UnlockDisplay(dpy); 582 SyncHandle(); 583 TRACE("GetDeviceInfo... return False"); 584 return False; 585 } 586 _XRead(dpy, (char*)*pDevPrivate, rep.devPrivateSize); 587 } else { 588 *pDevPrivate = NULL; 589 } 590 591 UnlockDisplay(dpy); 592 SyncHandle(); 593 TRACE("GetDeviceInfo... return True"); 594 return True; 595 } 596 597 PUBLIC Bool VA_DRIOpenFullScreen(dpy, screen, drawable) 598 Display* dpy; 599 int screen; 600 Drawable drawable; 601 { 602 /* This function and the underlying X protocol are deprecated. 603 */ 604 (void) dpy; 605 (void) screen; 606 (void) drawable; 607 return False; 608 } 609 610 PUBLIC Bool VA_DRICloseFullScreen(dpy, screen, drawable) 611 Display* dpy; 612 int screen; 613 Drawable drawable; 614 { 615 /* This function and the underlying X protocol are deprecated. 616 */ 617 (void) dpy; 618 (void) screen; 619 (void) drawable; 620 return True; 621 } 622 623 #undef TRACE 624 625