1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgAll Rights Reserved.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgPermission is hereby granted, free of charge, to any person obtaining a
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcopy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org"Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgwithout limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdistribute, sub license, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpermit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgthe following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgThe above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnext paragraph) shall be included in all copies or substantial portions
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgof the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org**************************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Authors:
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   Kevin E. Martin <kevin@precisioninsight.com>
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   Brian Paul <brian@precisioninsight.com>
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <X11/Xlib.h>
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <X11/extensions/Xfixes.h>
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <X11/extensions/Xdamage.h>
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glxclient.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "xf86dri.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "dri2.h"
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "sarea.h"
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <dlfcn.h>
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <sys/types.h>
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <sys/mman.h>
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "xf86drm.h"
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "dri_common.h"
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct dri_display
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIdisplay base;
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ** XFree86-DRI version information
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int driMajor;
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int driMinor;
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int driPatch;
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct dri_screen
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glx_screen base;
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __DRIscreen *driScreen;
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIscreen vtable;
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRIlegacyExtension *legacy;
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRIcoreExtension *core;
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRIswapControlExtension *swapControl;
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRImediaStreamCounterExtension *msc;
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRIconfig **driver_configs;
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRIcopySubBufferExtension *driCopySubBuffer;
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *driver;
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int fd;
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct dri_context
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glx_context base;
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __DRIcontext *driContext;
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XID hwContextID;
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct dri_drawable
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIdrawable base;
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __DRIdrawable *driDrawable;
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glx_context_vtable dri_context_vtable;
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Given a display pointer and screen number, determine the name of
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the DRI driver for the screen (i.e., "i965", "radeon", "nouveau", etc).
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return True for success, False for failure.
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic Bool
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdriGetDriverName(Display * dpy, int scrNum, char **driverName)
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int directCapable;
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Bool b;
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int event, error;
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int driverMajor, driverMinor, driverPatch;
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *driverName = NULL;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (XF86DRIQueryExtension(dpy, &event, &error)) {    /* DRI1 */
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) {
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return False;
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!directCapable) {
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return False;
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor,
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     &driverPatch, driverName);
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!b) {
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ErrorMessageF("Cannot determine driver name for screen %d\n",
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       scrNum);
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return False;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   driverMajor, driverMinor, driverPatch, *driverName,
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   scrNum);
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return True;
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (DRI2QueryExtension(dpy, &event, &error)) {  /* DRI2 */
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      char *dev;
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Bool ret = DRI2Connect(dpy, RootWindow(dpy, scrNum), driverName, &dev);
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ret)
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         Xfree(dev);
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ret;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return False;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Exported function for querying the DRI driver for a given screen.
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The returned char pointer points to a static array that will be
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * overwritten by subsequent calls.
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_X_EXPORT const char *
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglXGetScreenDriver(Display * dpy, int scrNum)
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static char ret[32];
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   char *driverName;
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (driGetDriverName(dpy, scrNum, &driverName)) {
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int len;
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!driverName)
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return NULL;
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      len = strlen(driverName);
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (len >= 31)
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return NULL;
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      memcpy(ret, driverName, len + 1);
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Xfree(driverName);
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ret;
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Exported function for obtaining a driver's option list (UTF-8 encoded XML).
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The returned char pointer points directly into the driver. Therefore
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * it should be treated as a constant.
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If the driver was not found or does not support configuration NULL is
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * returned.
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note: The driver remains opened after this function returns.
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_X_EXPORT const char *
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglXGetDriverConfig(const char *driverName)
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *handle = driOpenDriver(driverName);
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (handle)
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return dlsym(handle, "__driConfigOptions");
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef XDAMAGE_1_1_INTERFACE
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orghas_damage_post(Display * dpy)
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static GLboolean inited = GL_FALSE;
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static GLboolean has_damage;
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!inited) {
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int major, minor;
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (XDamageQueryVersion(dpy, &major, &minor) &&
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          major == 1 && minor >= 1) {
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         has_damage = GL_TRUE;
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         has_damage = GL_FALSE;
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inited = GL_TRUE;
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return has_damage;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org__glXReportDamage(__DRIdrawable * driDraw,
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  int x, int y,
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  drm_clip_rect_t * rects, int num_rects,
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  GLboolean front_buffer, void *loaderPrivate)
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XRectangle *xrects;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XserverRegion region;
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int x_off, y_off;
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIdrawable *glxDraw = loaderPrivate;
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glx_screen *psc = glxDraw->psc;
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Display *dpy = psc->dpy;
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Drawable drawable;
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!has_damage_post(dpy))
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (front_buffer) {
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      x_off = x;
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      y_off = y;
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      drawable = RootWindow(dpy, psc->scr);
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      x_off = 0;
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      y_off = 0;
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      drawable = glxDraw->xDrawable;
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   xrects = malloc(sizeof(XRectangle) * num_rects);
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (xrects == NULL)
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < num_rects; i++) {
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      xrects[i].x = rects[i].x1 + x_off;
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      xrects[i].y = rects[i].y1 + y_off;
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      xrects[i].width = rects[i].x2 - rects[i].x1;
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      xrects[i].height = rects[i].y2 - rects[i].y1;
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   region = XFixesCreateRegion(dpy, xrects, num_rects);
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(xrects);
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XDamageAdd(dpy, drawable, region);
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XFixesDestroyRegion(dpy, region);
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const __DRIdamageExtension damageExtension = {
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {__DRI_DAMAGE, __DRI_DAMAGE_VERSION},
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __glXReportDamage,
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org__glXDRIGetDrawableInfo(__DRIdrawable * drawable,
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        unsigned int *index, unsigned int *stamp,
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        int *X, int *Y, int *W, int *H,
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        int *numClipRects, drm_clip_rect_t ** pClipRects,
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        int *backX, int *backY,
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        int *numBackClipRects,
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        drm_clip_rect_t ** pBackClipRects,
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        void *loaderPrivate)
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIdrawable *glxDraw = loaderPrivate;
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glx_screen *psc = glxDraw->psc;
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Display *dpy = psc->dpy;
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return XF86DRIGetDrawableInfo(dpy, psc->scr, glxDraw->drawable,
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 index, stamp, X, Y, W, H,
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 numClipRects, pClipRects,
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 backX, backY,
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 numBackClipRects, pBackClipRects);
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {__DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION},
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __glXDRIGetDrawableInfo
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const __DRIextension *loader_extensions[] = {
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   &systemTimeExtension.base,
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   &getDrawableInfoExtension.base,
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef XDAMAGE_1_1_INTERFACE
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   &damageExtension.base,
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   NULL
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Perform the required libGL-side initialization and call the client-side
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * driver's \c __driCreateNewScreen function.
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param dpy    Display pointer.
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param scrn   Screen number on the display.
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param psc    DRI screen information.
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param driDpy DRI display information.
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param createNewScreen  Pointer to the client-side driver's
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *               \c __driCreateNewScreen function.
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \returns A pointer to the \c __DRIscreen structure returned by
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *          the client-side driver on success, or \c NULL on failure.
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void *
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc,
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    struct dri_display * driDpy)
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *psp = NULL;
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drm_handle_t hSAREA;
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drmAddress pSAREA = MAP_FAILED;
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   char *BusID;
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __DRIversion ddx_version;
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __DRIversion dri_version;
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __DRIversion drm_version;
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __DRIframebuffer framebuffer;
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int fd = -1;
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int status;
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drm_magic_t magic;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drmVersionPtr version;
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int newlyopened;
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   char *driverName;
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drm_handle_t hFB;
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int junk;
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRIconfig **driver_configs;
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct glx_config *visual, *configs = NULL, *visuals = NULL;
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* DRI protocol version. */
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri_version.major = driDpy->driMajor;
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri_version.minor = driDpy->driMinor;
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri_version.patch = driDpy->driPatch;
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   framebuffer.base = MAP_FAILED;
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   framebuffer.dev_priv = NULL;
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   framebuffer.size = 0;
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ErrorMessageF("XF86DRIOpenConnection failed\n");
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto handle_error;
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fd = drmOpenOnce(NULL, BusID, &newlyopened);
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Xfree(BusID);                /* No longer needed */
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fd < 0) {
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd));
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto handle_error;
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (drmGetMagic(fd, &magic)) {
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ErrorMessageF("drmGetMagic failed\n");
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto handle_error;
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   version = drmGetVersion(fd);
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (version) {
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      drm_version.major = version->version_major;
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      drm_version.minor = version->version_minor;
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      drm_version.patch = version->version_patchlevel;
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      drmFreeVersion(version);
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      drm_version.major = -1;
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      drm_version.minor = -1;
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      drm_version.patch = -1;
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (newlyopened && !XF86DRIAuthConnection(dpy, scrn, magic)) {
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ErrorMessageF("XF86DRIAuthConnection failed\n");
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto handle_error;
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Get device name (like "radeon") and the ddx version numbers.
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * We'll check the version in each DRI driver's "createNewScreen"
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * function. */
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!XF86DRIGetClientDriverName(dpy, scrn,
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   &ddx_version.major,
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   &ddx_version.minor,
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   &ddx_version.patch, &driverName)) {
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ErrorMessageF("XF86DRIGetClientDriverName failed\n");
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto handle_error;
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Xfree(driverName);           /* No longer needed. */
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Get device-specific info.  pDevPriv will point to a struct
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * has information about the screen size, depth, pitch, ancilliary
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * buffers, DRM mmap handles, etc.
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!XF86DRIGetDeviceInfo(dpy, scrn, &hFB, &junk,
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             &framebuffer.size, &framebuffer.stride,
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             &framebuffer.dev_priv_size,
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             &framebuffer.dev_priv)) {
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ErrorMessageF("XF86DRIGetDeviceInfo failed");
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto handle_error;
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   framebuffer.width = DisplayWidth(dpy, scrn);
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   framebuffer.height = DisplayHeight(dpy, scrn);
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Map the framebuffer region. */
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   status = drmMap(fd, hFB, framebuffer.size,
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   (drmAddressPtr) & framebuffer.base);
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (status != 0) {
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status));
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto handle_error;
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Map the SAREA region.  Further mmap regions may be setup in
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * each DRI driver's "createNewScreen" function.
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA);
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (status != 0) {
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status));
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto handle_error;
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp = (*psc->legacy->createNewScreen) (scrn,
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          &ddx_version,
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          &dri_version,
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          &drm_version,
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          &framebuffer,
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          pSAREA,
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          fd,
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          loader_extensions,
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          &driver_configs, psc);
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psp == NULL) {
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ErrorMessageF("Calling driver entry point failed");
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto handle_error;
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   configs = driConvertConfigs(psc->core, psc->base.configs, driver_configs);
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   visuals = driConvertConfigs(psc->core, psc->base.visuals, driver_configs);
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!configs || !visuals)
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       goto handle_error;
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glx_config_destroy_list(psc->base.configs);
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->base.configs = configs;
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glx_config_destroy_list(psc->base.visuals);
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->base.visuals = visuals;
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->driver_configs = driver_configs;
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Visuals with depth != screen depth are subject to automatic compositing
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * in the X server, so DRI1 can't render to them properly. Mark them as
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * non-conformant to prevent apps from picking them up accidentally.
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (visual = psc->base.visuals; visual; visual = visual->next) {
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XVisualInfo template;
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XVisualInfo *visuals;
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int num_visuals;
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      long mask;
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      template.visualid = visual->visualID;
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mask = VisualIDMask;
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      visuals = XGetVisualInfo(dpy, mask, &template, &num_visuals);
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (visuals) {
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (num_visuals > 0 && visuals->depth != DefaultDepth(dpy, scrn))
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            visual->visualRating = GLX_NON_CONFORMANT_CONFIG;
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         XFree(visuals);
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return psp;
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org handle_error:
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (configs)
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       glx_config_destroy_list(configs);
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (visuals)
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       glx_config_destroy_list(visuals);
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pSAREA != MAP_FAILED)
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      drmUnmap(pSAREA, SAREA_MAX);
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (framebuffer.base != MAP_FAILED)
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      drmUnmap((drmAddress) framebuffer.base, framebuffer.size);
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (framebuffer.dev_priv != NULL)
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Xfree(framebuffer.dev_priv);
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fd >= 0)
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      drmCloseOnce(fd);
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XF86DRICloseConnection(dpy, scrn);
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ErrorMessageF("reverting to software direct rendering\n");
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri_destroy_context(struct glx_context * context)
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_context *pcp = (struct dri_context *) context;
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_screen *psc = (struct dri_screen *) context->psc;
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   driReleaseDrawables(&pcp->base);
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (context->extensions)
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XFree((char *) context->extensions);
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (*psc->core->destroyContext) (pcp->driContext);
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XF86DRIDestroyContext(psc->base.dpy, psc->base.scr, pcp->hwContextID);
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Xfree(pcp);
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri_bind_context(struct glx_context *context, struct glx_context *old,
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 GLXDrawable draw, GLXDrawable read)
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_context *pcp = (struct dri_context *) context;
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_screen *psc = (struct dri_screen *) pcp->base.psc;
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_drawable *pdraw, *pread;
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdraw = (struct dri_drawable *) driFetchDrawable(context, draw);
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pread = (struct dri_drawable *) driFetchDrawable(context, read);
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   driReleaseDrawables(&pcp->base);
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pdraw == NULL || pread == NULL)
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return GLXBadDrawable;
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((*psc->core->bindContext) (pcp->driContext,
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				  pdraw->driDrawable, pread->driDrawable))
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return Success;
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return GLXBadContext;
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri_unbind_context(struct glx_context *context, struct glx_context *new)
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_context *pcp = (struct dri_context *) context;
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_screen *psc = (struct dri_screen *) pcp->base.psc;
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (*psc->core->unbindContext) (pcp->driContext);
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glx_context_vtable dri_context_vtable = {
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri_destroy_context,
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri_bind_context,
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri_unbind_context,
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   NULL,
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   NULL,
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   DRI_glXUseXFont,
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   NULL,
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   NULL,
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   NULL, /* get_proc_address */
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct glx_context *
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdri_create_context(struct glx_screen *base,
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   struct glx_config *config_base,
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   struct glx_context *shareList, int renderType)
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_context *pcp, *pcp_shared;
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_screen *psc = (struct dri_screen *) base;
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drm_context_t hwContext;
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __DRIcontext *shared = NULL;
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!psc->base.driScreen)
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (shareList) {
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* If the shareList context is not a DRI context, we cannot possibly
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * create a DRI context that shares it.
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (shareList->vtable->destroy != dri_destroy_context) {
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return NULL;
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pcp_shared = (struct dri_context *) shareList;
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shared = pcp_shared->driContext;
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pcp = Xmalloc(sizeof *pcp);
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pcp == NULL)
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(pcp, 0, sizeof *pcp);
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!glx_context_init(&pcp->base, &psc->base, &config->base)) {
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Xfree(pcp);
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!XF86DRICreateContextWithConfig(psc->base.dpy, psc->base.scr,
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       config->base.visualID,
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       &pcp->hwContextID, &hwContext)) {
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Xfree(pcp);
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pcp->driContext =
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (*psc->legacy->createNewContext) (psc->driScreen,
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        config->driConfig,
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        renderType, shared, hwContext, pcp);
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pcp->driContext == NULL) {
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XF86DRIDestroyContext(psc->base.dpy, psc->base.scr, pcp->hwContextID);
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Xfree(pcp);
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pcp->base.vtable = &dri_context_vtable;
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &pcp->base;
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdriDestroyDrawable(__GLXDRIdrawable * pdraw)
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_screen *psc = (struct dri_screen *) pdraw->psc;
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (*psc->core->destroyDrawable) (pdp->driDrawable);
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XF86DRIDestroyDrawable(psc->base.dpy, psc->base.scr, pdraw->drawable);
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Xfree(pdraw);
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic __GLXDRIdrawable *
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdriCreateDrawable(struct glx_screen *base,
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  XID xDrawable,
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  GLXDrawable drawable, struct glx_config *config_base)
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   drm_drawable_t hwDrawable;
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *empty_attribute_list = NULL;
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_screen *psc = (struct dri_screen *) base;
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_drawable *pdp;
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Old dri can't handle GLX 1.3+ drawable constructors. */
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (xDrawable != drawable)
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp = Xmalloc(sizeof *pdp);
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!pdp)
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(pdp, 0, sizeof *pdp);
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp->base.drawable = drawable;
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp->base.psc = &psc->base;
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!XF86DRICreateDrawable(psc->base.dpy, psc->base.scr,
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      drawable, &hwDrawable)) {
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Xfree(pdp);
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Create a new drawable */
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp->driDrawable =
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (*psc->legacy->createNewDrawable) (psc->driScreen,
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         config->driConfig,
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         hwDrawable,
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         GLX_WINDOW_BIT,
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         empty_attribute_list, pdp);
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!pdp->driDrawable) {
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XF86DRIDestroyDrawable(psc->base.dpy, psc->base.scr, drawable);
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Xfree(pdp);
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp->base.destroyDrawable = driDestroyDrawable;
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &pdp->base;
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int64_t
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdriSwapBuffers(__GLXDRIdrawable * pdraw, int64_t unused1, int64_t unused2,
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       int64_t unused3)
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_screen *psc = (struct dri_screen *) pdraw->psc;
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (*psc->core->swapBuffers) (pdp->driDrawable);
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return 0;
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdriCopySubBuffer(__GLXDRIdrawable * pdraw,
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 int x, int y, int width, int height)
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_screen *psc = (struct dri_screen *) pdp->base.psc;
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (*psc->driCopySubBuffer->copySubBuffer) (pdp->driDrawable,
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					    x, y, width, height);
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdriDestroyScreen(struct glx_screen *base)
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_screen *psc = (struct dri_screen *) base;
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Free the direct rendering per screen data */
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->driScreen)
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (*psc->core->destroyScreen) (psc->driScreen);
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   driDestroyConfigs(psc->driver_configs);
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->driScreen = NULL;
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->driver)
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dlclose(psc->driver);
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef __DRI_SWAP_BUFFER_COUNTER
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdriDrawableGetMSC(struct glx_screen *base, __GLXDRIdrawable *pdraw,
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		   int64_t *ust, int64_t *msc, int64_t *sbc)
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_screen *psc = (struct dri_screen *) base;
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pdp && psc->sbc && psc->msc)
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ( (*psc->msc->getMSC)(psc->driScreen, msc) == 0 &&
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       (*psc->sbc->getSBC)(pdp->driDrawable, sbc) == 0 &&
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       __glXGetUST(ust) == 0 );
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdriWaitForMSC(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_screen *psc = (struct dri_screen *) pdraw->psc;
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pdp != NULL && psc->msc != NULL) {
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ret = (*psc->msc->waitForMSC) (pdp->driDrawable, target_msc,
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				     divisor, remainder, msc, sbc);
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* __glXGetUST returns zero on success and non-zero on failure.
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * This function returns True on success and False on failure.
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ret == 0 && __glXGetUST(ust) == 0;
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdriWaitForSBC(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       int64_t *msc, int64_t *sbc)
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (pdp != NULL && psc->sbc != NULL) {
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ret =
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         (*psc->sbc->waitForSBC) (pdp->driDrawable, target_sbc, msc, sbc);
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* __glXGetUST returns zero on success and non-zero on failure.
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * This function returns True on success and False on failure.
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ((ret == 0) && (__glXGetUST(ust) == 0));
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return DRI2WaitSBC(pdp->base.psc->dpy,
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      pdp->base.xDrawable, target_sbc, ust, msc, sbc);
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdriSetSwapInterval(__GLXDRIdrawable *pdraw, int interval)
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_screen *psc = (struct dri_screen *) pdraw->psc;
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->swapControl != NULL && pdraw != NULL) {
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      psc->swapControl->setSwapInterval(pdp->driDrawable, interval);
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0;
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return GLX_BAD_CONTEXT;
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdriGetSwapInterval(__GLXDRIdrawable *pdraw)
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_screen *psc = (struct dri_screen *) pdraw->psc;
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->swapControl != NULL && pdraw != NULL)
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return psc->swapControl->getSwapInterval(pdp->driDrawable);
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return 0;
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Bind DRI1 specific extensions */
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdriBindExtensions(struct dri_screen *psc, const __DRIextension **extensions)
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; extensions[i]; i++) {
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* No DRI2 support for swap_control at the moment, since SwapBuffers
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * is done by the X server */
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 psc->swapControl = (__DRIswapControlExtension *) extensions[i];
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 __glXEnableDirectExtension(&psc->base, "GLX_SGI_swap_control");
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 __glXEnableDirectExtension(&psc->base, "GLX_MESA_swap_control");
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (strcmp(extensions[i]->name, __DRI_MEDIA_STREAM_COUNTER) == 0) {
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         psc->msc = (__DRImediaStreamCounterExtension *) extensions[i];
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         __glXEnableDirectExtension(&psc->base, "GLX_SGI_video_sync");
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 psc->driCopySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 __glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer");
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 __glXEnableDirectExtension(&psc->base, "GLX_SGI_make_current_read");
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Ignore unknown extensions */
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glx_screen_vtable dri_screen_vtable = {
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dri_create_context,
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   NULL
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct glx_screen *
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdriCreateScreen(int screen, struct glx_display *priv)
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_display *pdp;
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __GLXDRIscreen *psp;
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const __DRIextension **extensions;
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_screen *psc;
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   char *driverName;
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int i;
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc = Xcalloc(1, sizeof *psc);
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc == NULL)
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(psc, 0, sizeof *psc);
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!glx_screen_init(&psc->base, screen, priv)) {
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      Xfree(psc);
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!driGetDriverName(priv->dpy, screen, &driverName)) {
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto cleanup;
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->driver = driOpenDriver(driverName);
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->driver == NULL)
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto cleanup;
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (extensions == NULL) {
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto cleanup;
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; extensions[i]; i++) {
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 psc->core = (__DRIcoreExtension *) extensions[i];
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0)
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 psc->legacy = (__DRIlegacyExtension *) extensions[i];
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->core == NULL || psc->legacy == NULL)
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto cleanup;
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdp = (struct dri_display *) priv->driDisplay;
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->driScreen =
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      CallCreateNewScreen(psc->base.dpy, screen, psc, pdp);
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->driScreen == NULL)
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto cleanup;
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   extensions = psc->core->getExtensions(psc->driScreen);
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   driBindExtensions(psc, extensions);
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->base.vtable = &dri_screen_vtable;
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp = &psc->vtable;
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psc->base.driScreen = psp;
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->driCopySubBuffer)
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      psp->copySubBuffer = driCopySubBuffer;
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp->destroyScreen = driDestroyScreen;
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp->createDrawable = driCreateDrawable;
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp->swapBuffers = driSwapBuffers;
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef __DRI_SWAP_BUFFER_COUNTER
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp->getDrawableMSC = driDrawableGetMSC;
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp->waitForMSC = driWaitForMSC;
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp->waitForSBC = driWaitForSBC;
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp->setSwapInterval = driSetSwapInterval;
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   psp->getSwapInterval = driGetSwapInterval;
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(driverName);
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &psc->base;
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcleanup:
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   CriticalErrorMessageF("failed to load driver: %s\n", driverName);
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(driverName);
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (psc->driver)
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dlclose(psc->driver);
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   glx_screen_cleanup(&psc->base);
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Xfree(psc);
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Called from __glXFreeDisplayPrivate.
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdriDestroyDisplay(__GLXDRIdisplay * dpy)
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Xfree(dpy);
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Allocate, initialize and return a __DRIdisplayPrivate object.
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is called from __glXInitialize() when we are given a new
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * display pointer.
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_X_HIDDEN __GLXDRIdisplay *
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdriCreateDisplay(Display * dpy)
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct dri_display *pdpyp;
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int eventBase, errorBase;
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int major, minor, patch;
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!XF86DRIQueryExtension(dpy, &eventBase, &errorBase)) {
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!XF86DRIQueryVersion(dpy, &major, &minor, &patch)) {
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdpyp = Xmalloc(sizeof *pdpyp);
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!pdpyp) {
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdpyp->driMajor = major;
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdpyp->driMinor = minor;
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdpyp->driPatch = patch;
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdpyp->base.destroyDisplay = driDestroyDisplay;
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pdpyp->base.createScreen = driCreateScreen;
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &pdpyp->base;
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* GLX_DIRECT_RENDERING */
976