libva: update DRI2 to support swapbuffer
[profile/ivi/libva.git] / va / x11 / va_dri.c
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
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