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@valinux.com>
34 * Jens Owen <jens@tungstengraphics.com>
35 * Rickard E. (Rik) Faith <faith@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
VA_DRIQueryVersion(dpy,majorVersion,minorVersion,patchVersion)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
VA_DRIQueryDirectRenderingCapable(dpy,screen,isCapable)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
VA_DRIOpenConnection(dpy,screen,hSAREA,busIdString)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
VA_DRIAuthConnection(dpy,screen,magic)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
VA_DRICloseConnection(dpy,screen)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
VA_DRIGetClientDriverName(dpy,screen,ddxDriverMajorVersion,ddxDriverMinorVersion,ddxDriverPatchVersion,clientDriverName)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
VA_DRICreateContextWithConfig(dpy,screen,configID,context,hHWContext)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
VA_DRICreateContext(dpy,screen,visual,context,hHWContext)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
VA_DRIDestroyContext(__DRInativeDisplay * ndpy,int screen,__DRIid context)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
VA_DRICreateDrawable(__DRInativeDisplay * ndpy,int screen,__DRIid drawable,drm_drawable_t * hHWDrawable)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
VA_DRIDestroyDrawable(__DRInativeDisplay * ndpy,int screen,__DRIid drawable)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
VA_DRIGetDrawableInfo(Display * dpy,int screen,Drawable drawable,unsigned int * index,unsigned int * stamp,int * X,int * Y,int * W,int * H,int * numClipRects,drm_clip_rect_t ** pClipRects,int * backX,int * backY,int * numBackClipRects,drm_clip_rect_t ** pBackClipRects)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
VA_DRIGetDeviceInfo(dpy,screen,hFrameBuffer,fbOrigin,fbSize,fbStride,devPrivateSize,pDevPrivate)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
VA_DRIOpenFullScreen(dpy,screen,drawable)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
VA_DRICloseFullScreen(dpy,screen,drawable)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