mesa_dri2.c revision 549c0c5b
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
36549c0c5bSmrg#ifdef HAVE_CONFIG_H
37549c0c5bSmrg#include "config.h"
38549c0c5bSmrg#endif
39a4f78defSmrg
40a4f78defSmrg#define NEED_REPLIES
41a4f78defSmrg#include <X11/Xlibint.h>
42a4f78defSmrg#include <X11/extensions/Xext.h>
43a4f78defSmrg#include <X11/extensions/extutil.h>
44a4f78defSmrg#include <X11/extensions/dri2proto.h>
45a4f78defSmrg#include "mesa_dri2.h"
46a4f78defSmrg#include "util.h"
47a4f78defSmrg
48a4f78defSmrgstatic char dri2ExtensionName[] = DRI2_NAME;
49a4f78defSmrgstatic XExtensionInfo *dri2Info;
50a4f78defSmrg
51a4f78defSmrgstatic /* const */ XExtensionHooks dri2ExtensionHooks = {
52a4f78defSmrg  NULL,                   /* create_gc */
53a4f78defSmrg  NULL,                   /* copy_gc */
54a4f78defSmrg  NULL,                   /* flush_gc */
55a4f78defSmrg  NULL,                   /* free_gc */
56a4f78defSmrg  NULL,                   /* create_font */
57a4f78defSmrg  NULL,                   /* free_font */
58a4f78defSmrg  NULL,                   /* close_display */
59a4f78defSmrg  NULL,                   /* wire_to_event */
60a4f78defSmrg  NULL,                   /* event_to_wire */
61a4f78defSmrg  NULL,                   /* error */
62a4f78defSmrg  NULL,                   /* error_string */
63a4f78defSmrg};
64a4f78defSmrg
65a4f78defSmrgstatic XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay,
66a4f78defSmrg                                   dri2Info,
67a4f78defSmrg                                   dri2ExtensionName,
68a4f78defSmrg                                   &dri2ExtensionHooks,
69a4f78defSmrg                                   0, NULL)
70a4f78defSmrg
71a4f78defSmrgBool
72a4f78defSmrg_vdp_DRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase)
73a4f78defSmrg{
74a4f78defSmrg   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
75a4f78defSmrg
76a4f78defSmrg   if (XextHasExtension(info)) {
77a4f78defSmrg      *eventBase = info->codes->first_event;
78a4f78defSmrg      *errorBase = info->codes->first_error;
79a4f78defSmrg      return True;
80a4f78defSmrg   }
81a4f78defSmrg
82a4f78defSmrg   if (dri2Info) {
83a4f78defSmrg      if (info) {
84a4f78defSmrg         XextRemoveDisplay(dri2Info, dpy);
85a4f78defSmrg      }
86a4f78defSmrg      XextDestroyExtension(dri2Info);
87a4f78defSmrg      dri2Info = NULL;
88a4f78defSmrg   }
89a4f78defSmrg
90a4f78defSmrg   return False;
91a4f78defSmrg}
92a4f78defSmrg
93a4f78defSmrgBool
94a4f78defSmrg_vdp_DRI2QueryVersion(Display * dpy, int *major, int *minor)
95a4f78defSmrg{
96a4f78defSmrg   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
97a4f78defSmrg   xDRI2QueryVersionReply rep;
98a4f78defSmrg   xDRI2QueryVersionReq *req;
99a4f78defSmrg
100a4f78defSmrg   XextCheckExtension(dpy, info, dri2ExtensionName, False);
101a4f78defSmrg
102a4f78defSmrg   LockDisplay(dpy);
103a4f78defSmrg   GetReq(DRI2QueryVersion, req);
104a4f78defSmrg   req->reqType = info->codes->major_opcode;
105a4f78defSmrg   req->dri2ReqType = X_DRI2QueryVersion;
106a4f78defSmrg   req->majorVersion = DRI2_MAJOR;
107a4f78defSmrg   req->minorVersion = DRI2_MINOR;
108a4f78defSmrg   if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
109a4f78defSmrg      UnlockDisplay(dpy);
110a4f78defSmrg      SyncHandle();
111a4f78defSmrg      return False;
112a4f78defSmrg   }
113a4f78defSmrg   *major = rep.majorVersion;
114a4f78defSmrg   *minor = rep.minorVersion;
115a4f78defSmrg   UnlockDisplay(dpy);
116a4f78defSmrg   SyncHandle();
117a4f78defSmrg
118a4f78defSmrg   return True;
119a4f78defSmrg}
120a4f78defSmrg
121a4f78defSmrgBool
122a4f78defSmrg_vdp_DRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName)
123a4f78defSmrg{
124a4f78defSmrg   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
125a4f78defSmrg   xDRI2ConnectReply rep;
126a4f78defSmrg   xDRI2ConnectReq *req;
127a4f78defSmrg
128a4f78defSmrg   XextCheckExtension(dpy, info, dri2ExtensionName, False);
129a4f78defSmrg
130a4f78defSmrg   LockDisplay(dpy);
131a4f78defSmrg   GetReq(DRI2Connect, req);
132a4f78defSmrg   req->reqType = info->codes->major_opcode;
133a4f78defSmrg   req->dri2ReqType = X_DRI2Connect;
134a4f78defSmrg   req->window = window;
135a4f78defSmrg   req->driverType = DRI2DriverVDPAU;
136a4f78defSmrg#ifdef DRI2DriverPrimeShift
137a4f78defSmrg   {
138a551a712Smrg      char *prime = getenv_wrapper("DRI_PRIME");
139a4f78defSmrg      if (prime) {
140a4f78defSmrg         unsigned int primeid;
141a4f78defSmrg         errno = 0;
142a4f78defSmrg         primeid = strtoul(prime, NULL, 0);
143a4f78defSmrg         if (errno == 0)
144a4f78defSmrg            req->driverType |=
145a4f78defSmrg               ((primeid & DRI2DriverPrimeMask) << DRI2DriverPrimeShift);
146a4f78defSmrg      }
147a4f78defSmrg   }
148a4f78defSmrg#endif
149a4f78defSmrg
150a4f78defSmrg   if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
151a4f78defSmrg      UnlockDisplay(dpy);
152a4f78defSmrg      SyncHandle();
153a4f78defSmrg      return False;
154a4f78defSmrg   }
155a4f78defSmrg
156a4f78defSmrg   if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) {
157a4f78defSmrg      UnlockDisplay(dpy);
158a4f78defSmrg      SyncHandle();
159a4f78defSmrg      return False;
160a4f78defSmrg   }
161a4f78defSmrg
162a4f78defSmrg   *driverName = Xmalloc(rep.driverNameLength + 1);
163a4f78defSmrg   if (*driverName == NULL) {
164a4f78defSmrg      _XEatData(dpy,
165a4f78defSmrg                ((rep.driverNameLength + 3) & ~3) +
166a4f78defSmrg                ((rep.deviceNameLength + 3) & ~3));
167a4f78defSmrg      UnlockDisplay(dpy);
168a4f78defSmrg      SyncHandle();
169a4f78defSmrg      return False;
170a4f78defSmrg   }
171a4f78defSmrg   _XReadPad(dpy, *driverName, rep.driverNameLength);
172a4f78defSmrg   (*driverName)[rep.driverNameLength] = '\0';
173a4f78defSmrg
174a4f78defSmrg   *deviceName = Xmalloc(rep.deviceNameLength + 1);
175a4f78defSmrg   if (*deviceName == NULL) {
176a4f78defSmrg      Xfree(*driverName);
177a4f78defSmrg      _XEatData(dpy, ((rep.deviceNameLength + 3) & ~3));
178a4f78defSmrg      UnlockDisplay(dpy);
179a4f78defSmrg      SyncHandle();
180a4f78defSmrg      return False;
181a4f78defSmrg   }
182a4f78defSmrg   _XReadPad(dpy, *deviceName, rep.deviceNameLength);
183a4f78defSmrg   (*deviceName)[rep.deviceNameLength] = '\0';
184a4f78defSmrg
185a4f78defSmrg   UnlockDisplay(dpy);
186a4f78defSmrg   SyncHandle();
187a4f78defSmrg
188a4f78defSmrg   return True;
189a4f78defSmrg}
190a4f78defSmrg
191a4f78defSmrgvoid
192a4f78defSmrg_vdp_DRI2RemoveExtension(Display * dpy)
193a4f78defSmrg{
194a4f78defSmrg   XextRemoveDisplay(dri2Info, dpy);
195a4f78defSmrg   XextDestroyExtension(dri2Info);
196a4f78defSmrg   dri2Info = NULL;
197a4f78defSmrg}
198