mesa_dri2.c revision a551a712
1a4f78defSmrg/*
2a4f78defSmrg * Copyright © 2008 Red Hat, Inc.
3a4f78defSmrg * Copyright © 2010-2015 NVIDIA Corporation
4a4f78defSmrg *
5a4f78defSmrg * Permission is hereby granted, free of charge, to any person obtaining a
6a4f78defSmrg * copy of this software and associated documentation files (the "Soft-
7a4f78defSmrg * ware"), to deal in the Software without restriction, including without
8a4f78defSmrg * limitation the rights to use, copy, modify, merge, publish, distribute,
9a4f78defSmrg * and/or sell copies of the Software, and to permit persons to whom the
10a4f78defSmrg * Software is furnished to do so, provided that the above copyright
11a4f78defSmrg * notice(s) and this permission notice appear in all copies of the Soft-
12a4f78defSmrg * ware and that both the above copyright notice(s) and this permission
13a4f78defSmrg * notice appear in supporting documentation.
14a4f78defSmrg *
15a4f78defSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16a4f78defSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
17a4f78defSmrg * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
18a4f78defSmrg * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
19a4f78defSmrg * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
20a4f78defSmrg * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21a4f78defSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22a4f78defSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
23a4f78defSmrg * MANCE OF THIS SOFTWARE.
24a4f78defSmrg *
25a4f78defSmrg * Except as contained in this notice, the name of a copyright holder shall
26a4f78defSmrg * not be used in advertising or otherwise to promote the sale, use or
27a4f78defSmrg * other dealings in this Software without prior written authorization of
28a4f78defSmrg * the copyright holder.
29a4f78defSmrg *
30a4f78defSmrg * Authors:
31a4f78defSmrg *   Kristian Høgsberg (krh@redhat.com)
32a4f78defSmrg *   Modified for VDPAU by Aaron Plattner (aplattner@nvidia.com)
33a4f78defSmrg *   and José Hiram Soltren (jsoltren@nvidia.com)
34a4f78defSmrg */
35a4f78defSmrg
36a4f78defSmrg
37a4f78defSmrg#define NEED_REPLIES
38a4f78defSmrg#include <X11/Xlibint.h>
39a4f78defSmrg#include <X11/extensions/Xext.h>
40a4f78defSmrg#include <X11/extensions/extutil.h>
41a4f78defSmrg#include <X11/extensions/dri2proto.h>
42a4f78defSmrg#include "mesa_dri2.h"
43a4f78defSmrg#include "util.h"
44a4f78defSmrg
45a4f78defSmrgstatic char dri2ExtensionName[] = DRI2_NAME;
46a4f78defSmrgstatic XExtensionInfo *dri2Info;
47a4f78defSmrg
48a4f78defSmrgstatic /* const */ XExtensionHooks dri2ExtensionHooks = {
49a4f78defSmrg  NULL,                   /* create_gc */
50a4f78defSmrg  NULL,                   /* copy_gc */
51a4f78defSmrg  NULL,                   /* flush_gc */
52a4f78defSmrg  NULL,                   /* free_gc */
53a4f78defSmrg  NULL,                   /* create_font */
54a4f78defSmrg  NULL,                   /* free_font */
55a4f78defSmrg  NULL,                   /* close_display */
56a4f78defSmrg  NULL,                   /* wire_to_event */
57a4f78defSmrg  NULL,                   /* event_to_wire */
58a4f78defSmrg  NULL,                   /* error */
59a4f78defSmrg  NULL,                   /* error_string */
60a4f78defSmrg};
61a4f78defSmrg
62a4f78defSmrgstatic XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay,
63a4f78defSmrg                                   dri2Info,
64a4f78defSmrg                                   dri2ExtensionName,
65a4f78defSmrg                                   &dri2ExtensionHooks,
66a4f78defSmrg                                   0, NULL)
67a4f78defSmrg
68a4f78defSmrgBool
69a4f78defSmrg_vdp_DRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase)
70a4f78defSmrg{
71a4f78defSmrg   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
72a4f78defSmrg
73a4f78defSmrg   if (XextHasExtension(info)) {
74a4f78defSmrg      *eventBase = info->codes->first_event;
75a4f78defSmrg      *errorBase = info->codes->first_error;
76a4f78defSmrg      return True;
77a4f78defSmrg   }
78a4f78defSmrg
79a4f78defSmrg   if (dri2Info) {
80a4f78defSmrg      if (info) {
81a4f78defSmrg         XextRemoveDisplay(dri2Info, dpy);
82a4f78defSmrg      }
83a4f78defSmrg      XextDestroyExtension(dri2Info);
84a4f78defSmrg      dri2Info = NULL;
85a4f78defSmrg   }
86a4f78defSmrg
87a4f78defSmrg   return False;
88a4f78defSmrg}
89a4f78defSmrg
90a4f78defSmrgBool
91a4f78defSmrg_vdp_DRI2QueryVersion(Display * dpy, int *major, int *minor)
92a4f78defSmrg{
93a4f78defSmrg   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
94a4f78defSmrg   xDRI2QueryVersionReply rep;
95a4f78defSmrg   xDRI2QueryVersionReq *req;
96a4f78defSmrg
97a4f78defSmrg   XextCheckExtension(dpy, info, dri2ExtensionName, False);
98a4f78defSmrg
99a4f78defSmrg   LockDisplay(dpy);
100a4f78defSmrg   GetReq(DRI2QueryVersion, req);
101a4f78defSmrg   req->reqType = info->codes->major_opcode;
102a4f78defSmrg   req->dri2ReqType = X_DRI2QueryVersion;
103a4f78defSmrg   req->majorVersion = DRI2_MAJOR;
104a4f78defSmrg   req->minorVersion = DRI2_MINOR;
105a4f78defSmrg   if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
106a4f78defSmrg      UnlockDisplay(dpy);
107a4f78defSmrg      SyncHandle();
108a4f78defSmrg      return False;
109a4f78defSmrg   }
110a4f78defSmrg   *major = rep.majorVersion;
111a4f78defSmrg   *minor = rep.minorVersion;
112a4f78defSmrg   UnlockDisplay(dpy);
113a4f78defSmrg   SyncHandle();
114a4f78defSmrg
115a4f78defSmrg   return True;
116a4f78defSmrg}
117a4f78defSmrg
118a4f78defSmrgBool
119a4f78defSmrg_vdp_DRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName)
120a4f78defSmrg{
121a4f78defSmrg   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
122a4f78defSmrg   xDRI2ConnectReply rep;
123a4f78defSmrg   xDRI2ConnectReq *req;
124a4f78defSmrg
125a4f78defSmrg   XextCheckExtension(dpy, info, dri2ExtensionName, False);
126a4f78defSmrg
127a4f78defSmrg   LockDisplay(dpy);
128a4f78defSmrg   GetReq(DRI2Connect, req);
129a4f78defSmrg   req->reqType = info->codes->major_opcode;
130a4f78defSmrg   req->dri2ReqType = X_DRI2Connect;
131a4f78defSmrg   req->window = window;
132a4f78defSmrg   req->driverType = DRI2DriverVDPAU;
133a4f78defSmrg#ifdef DRI2DriverPrimeShift
134a4f78defSmrg   {
135a551a712Smrg      char *prime = getenv_wrapper("DRI_PRIME");
136a4f78defSmrg      if (prime) {
137a4f78defSmrg         unsigned int primeid;
138a4f78defSmrg         errno = 0;
139a4f78defSmrg         primeid = strtoul(prime, NULL, 0);
140a4f78defSmrg         if (errno == 0)
141a4f78defSmrg            req->driverType |=
142a4f78defSmrg               ((primeid & DRI2DriverPrimeMask) << DRI2DriverPrimeShift);
143a4f78defSmrg      }
144a4f78defSmrg   }
145a4f78defSmrg#endif
146a4f78defSmrg
147a4f78defSmrg   if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
148a4f78defSmrg      UnlockDisplay(dpy);
149a4f78defSmrg      SyncHandle();
150a4f78defSmrg      return False;
151a4f78defSmrg   }
152a4f78defSmrg
153a4f78defSmrg   if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) {
154a4f78defSmrg      UnlockDisplay(dpy);
155a4f78defSmrg      SyncHandle();
156a4f78defSmrg      return False;
157a4f78defSmrg   }
158a4f78defSmrg
159a4f78defSmrg   *driverName = Xmalloc(rep.driverNameLength + 1);
160a4f78defSmrg   if (*driverName == NULL) {
161a4f78defSmrg      _XEatData(dpy,
162a4f78defSmrg                ((rep.driverNameLength + 3) & ~3) +
163a4f78defSmrg                ((rep.deviceNameLength + 3) & ~3));
164a4f78defSmrg      UnlockDisplay(dpy);
165a4f78defSmrg      SyncHandle();
166a4f78defSmrg      return False;
167a4f78defSmrg   }
168a4f78defSmrg   _XReadPad(dpy, *driverName, rep.driverNameLength);
169a4f78defSmrg   (*driverName)[rep.driverNameLength] = '\0';
170a4f78defSmrg
171a4f78defSmrg   *deviceName = Xmalloc(rep.deviceNameLength + 1);
172a4f78defSmrg   if (*deviceName == NULL) {
173a4f78defSmrg      Xfree(*driverName);
174a4f78defSmrg      _XEatData(dpy, ((rep.deviceNameLength + 3) & ~3));
175a4f78defSmrg      UnlockDisplay(dpy);
176a4f78defSmrg      SyncHandle();
177a4f78defSmrg      return False;
178a4f78defSmrg   }
179a4f78defSmrg   _XReadPad(dpy, *deviceName, rep.deviceNameLength);
180a4f78defSmrg   (*deviceName)[rep.deviceNameLength] = '\0';
181a4f78defSmrg
182a4f78defSmrg   UnlockDisplay(dpy);
183a4f78defSmrg   SyncHandle();
184a4f78defSmrg
185a4f78defSmrg   return True;
186a4f78defSmrg}
187a4f78defSmrg
188a4f78defSmrgvoid
189a4f78defSmrg_vdp_DRI2RemoveExtension(Display * dpy)
190a4f78defSmrg{
191a4f78defSmrg   XextRemoveDisplay(dri2Info, dpy);
192a4f78defSmrg   XextDestroyExtension(dri2Info);
193a4f78defSmrg   dri2Info = NULL;
194a4f78defSmrg}
195