1cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/**************************************************************************
2cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
3cb3610e37c4c0a40520441b8515d044dabcc8854Adam JacksonCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4cb3610e37c4c0a40520441b8515d044dabcc8854Adam JacksonAll Rights Reserved.
5cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
6cb3610e37c4c0a40520441b8515d044dabcc8854Adam JacksonPermission is hereby granted, free of charge, to any person obtaining a
7cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksoncopy of this software and associated documentation files (the
8cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson"Software"), to deal in the Software without restriction, including
9cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonwithout limitation the rights to use, copy, modify, merge, publish,
10cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksondistribute, sub license, and/or sell copies of the Software, and to
11cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonpermit persons to whom the Software is furnished to do so, subject to
12cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonthe following conditions:
13cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
14cb3610e37c4c0a40520441b8515d044dabcc8854Adam JacksonThe above copyright notice and this permission notice (including the
15cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonnext paragraph) shall be included in all copies or substantial portions
16cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jacksonof the Software.
17cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
18cb3610e37c4c0a40520441b8515d044dabcc8854Adam JacksonTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19cb3610e37c4c0a40520441b8515d044dabcc8854Adam JacksonOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20cb3610e37c4c0a40520441b8515d044dabcc8854Adam JacksonMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21cb3610e37c4c0a40520441b8515d044dabcc8854Adam JacksonIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
22cb3610e37c4c0a40520441b8515d044dabcc8854Adam JacksonANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23cb3610e37c4c0a40520441b8515d044dabcc8854Adam JacksonTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24cb3610e37c4c0a40520441b8515d044dabcc8854Adam JacksonSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
26cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson**************************************************************************/
27cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
28cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/*
29cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Authors:
30cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson *   Kevin E. Martin <kevin@precisioninsight.com>
31cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson *   Brian Paul <brian@precisioninsight.com>
32cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson *
33cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson */
34cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
3580b280db883edc9550484dba03bd5c124b6a9bf9Jeremy Huddleston#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
36cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
376497d50924230e6b96929c8da0c2bd7287b70d8aAlan Hourihane#include <X11/Xlib.h>
3842c279a03b4d3529efc0d552c37ace2c82306822Xiang, Haihao#include <X11/extensions/Xfixes.h>
3942c279a03b4d3529efc0d552c37ace2c82306822Xiang, Haihao#include <X11/extensions/Xdamage.h>
40cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#include "glxclient.h"
41cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#include "xf86dri.h"
42a3c3c1f1437de0186d70de9017a6a8e404ecf482Adam Jackson#include "dri2.h"
43cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#include "sarea.h"
44cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#include <dlfcn.h>
45cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#include <sys/types.h>
46890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg#include <sys/mman.h>
47890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg#include "xf86drm.h"
48079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#include "dri_common.h"
49cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
50a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsbergstruct dri_display
510896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf{
520896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __GLXDRIdisplay base;
53425f9ed44e576aef27f7ab98968043f7f180d0fdKristian Høgsberg
540896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /*
55425f9ed44e576aef27f7ab98968043f7f180d0fdKristian Høgsberg    ** XFree86-DRI version information
56425f9ed44e576aef27f7ab98968043f7f180d0fdKristian Høgsberg    */
570896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int driMajor;
580896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int driMinor;
590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int driPatch;
60425f9ed44e576aef27f7ab98968043f7f180d0fdKristian Høgsberg};
61cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
62f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsbergstruct dri_screen
63f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg{
6466fc35cde9ed68a09920ad6a28de794dd1d3aa8cKristian Høgsberg   struct glx_screen base;
65f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg
6670887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   __DRIscreen *driScreen;
6770887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   __GLXDRIscreen vtable;
68f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   const __DRIlegacyExtension *legacy;
69f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   const __DRIcoreExtension *core;
70089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   const __DRIswapControlExtension *swapControl;
71089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   const __DRImediaStreamCounterExtension *msc;
72bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian Høgsberg   const __DRIconfig **driver_configs;
73a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg   const __DRIcopySubBufferExtension *driCopySubBuffer;
74089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
75f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   void *driver;
76f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   int fd;
77f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg};
78f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg
79a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsbergstruct dri_context
800896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf{
81c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian Høgsberg   struct glx_context base;
820896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __DRIcontext *driContext;
830896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   XID hwContextID;
84e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg};
85e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
86271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsbergstruct dri_drawable
87271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg{
88271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   __GLXDRIdrawable base;
89271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg
90271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   __DRIdrawable *driDrawable;
91271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg};
92271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg
93c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsbergstatic const struct glx_context_vtable dri_context_vtable;
9431819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg
95cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/*
96cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Given a display pointer and screen number, determine the name of
97e4344161bde2e24fcfba65d30d58f087bd8bf94dIan Romanick * the DRI driver for the screen (i.e., "i965", "radeon", "nouveau", etc).
98cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Return True for success, False for failure.
99cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson */
1000896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic Bool
1010896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófdriGetDriverName(Display * dpy, int scrNum, char **driverName)
102cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson{
1030896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int directCapable;
1040896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Bool b;
1050896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int event, error;
1060896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int driverMajor, driverMinor, driverPatch;
1070896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1080896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   *driverName = NULL;
1090896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1100896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (XF86DRIQueryExtension(dpy, &event, &error)) {    /* DRI1 */
1110896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) {
1120896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
1130896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         return False;
1140896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      }
1150896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (!directCapable) {
1160896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
1170896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         return False;
1180896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      }
1190896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1200896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor,
1210896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                     &driverPatch, driverName);
1220896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (!b) {
1230896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         ErrorMessageF("Cannot determine driver name for screen %d\n",
1240896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                       scrNum);
1250896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         return False;
1260896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      }
1270896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1280896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
1290896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                   driverMajor, driverMinor, driverPatch, *driverName,
1300896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                   scrNum);
1310896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1320896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return True;
1330896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
1340896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   else if (DRI2QueryExtension(dpy, &event, &error)) {  /* DRI2 */
1350896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      char *dev;
1360896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      Bool ret = DRI2Connect(dpy, RootWindow(dpy, scrNum), driverName, &dev);
1370896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1380896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (ret)
1390896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         Xfree(dev);
1400896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1410896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return ret;
1420896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
1430896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1440896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return False;
145cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}
146cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
147cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/*
148cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Exported function for querying the DRI driver for a given screen.
149cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson *
150cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * The returned char pointer points to a static array that will be
151cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * overwritten by subsequent calls.
152cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson */
15338c51a76533a90cf2c9381c99247cfac45fe70ebKristian Høgsberg_X_EXPORT const char *
1540896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófglXGetScreenDriver(Display * dpy, int scrNum)
1550896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf{
156cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson   static char ret[32];
157cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson   char *driverName;
158079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   if (driGetDriverName(dpy, scrNum, &driverName)) {
159cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      int len;
160cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      if (!driverName)
1610896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         return NULL;
1620896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      len = strlen(driverName);
163cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      if (len >= 31)
1640896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         return NULL;
1650896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      memcpy(ret, driverName, len + 1);
166cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      Xfree(driverName);
167cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      return ret;
168cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson   }
169cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson   return NULL;
170cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}
171cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
172cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/*
173cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Exported function for obtaining a driver's option list (UTF-8 encoded XML).
174cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson *
175cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * The returned char pointer points directly into the driver. Therefore
176cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * it should be treated as a constant.
177cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson *
178cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * If the driver was not found or does not support configuration NULL is
179cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * returned.
180cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson *
181cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Note: The driver remains opened after this function returns.
182cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson */
18338c51a76533a90cf2c9381c99247cfac45fe70ebKristian Høgsberg_X_EXPORT const char *
1840896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófglXGetDriverConfig(const char *driverName)
185e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
1860896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   void *handle = driOpenDriver(driverName);
1870f2723cacbaf9b27ecb8d13581f4b72ff86dd911Kristian Høgsberg   if (handle)
1880896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return dlsym(handle, "__driConfigOptions");
189cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson   else
190cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      return NULL;
191cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}
192cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
193890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg#ifdef XDAMAGE_1_1_INTERFACE
194e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
1950896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic GLboolean
1960896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófhas_damage_post(Display * dpy)
197890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg{
1980896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   static GLboolean inited = GL_FALSE;
1990896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   static GLboolean has_damage;
2000896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2010896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!inited) {
2020896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      int major, minor;
2030896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2040896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (XDamageQueryVersion(dpy, &major, &minor) &&
2050896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf          major == 1 && minor >= 1) {
2060896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         has_damage = GL_TRUE;
2070896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      }
2080896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      else {
2090896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         has_damage = GL_FALSE;
2100896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      }
2110896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      inited = GL_TRUE;
2120896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
2130896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2140896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return has_damage;
215890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg}
216890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg
2170896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
2180896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf__glXReportDamage(__DRIdrawable * driDraw,
2190896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                  int x, int y,
2200896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                  drm_clip_rect_t * rects, int num_rects,
2210896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                  GLboolean front_buffer, void *loaderPrivate)
222890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg{
2230896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   XRectangle *xrects;
2240896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   XserverRegion region;
2250896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int i;
2260896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int x_off, y_off;
2270896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __GLXDRIdrawable *glxDraw = loaderPrivate;
22866fc35cde9ed68a09920ad6a28de794dd1d3aa8cKristian Høgsberg   struct glx_screen *psc = glxDraw->psc;
2290896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Display *dpy = psc->dpy;
2300896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Drawable drawable;
2310896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2320896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!has_damage_post(dpy))
2330896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return;
2340896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2350896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (front_buffer) {
2360896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      x_off = x;
2370896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      y_off = y;
2380896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drawable = RootWindow(dpy, psc->scr);
2390896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
2400896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   else {
2410896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      x_off = 0;
2420896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      y_off = 0;
2430896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drawable = glxDraw->xDrawable;
2440896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
2450896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2460896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   xrects = malloc(sizeof(XRectangle) * num_rects);
2470896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (xrects == NULL)
2480896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return;
2490896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2500896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   for (i = 0; i < num_rects; i++) {
2510896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      xrects[i].x = rects[i].x1 + x_off;
2520896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      xrects[i].y = rects[i].y1 + y_off;
2530896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      xrects[i].width = rects[i].x2 - rects[i].x1;
2540896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      xrects[i].height = rects[i].y2 - rects[i].y1;
2550896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
2560896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   region = XFixesCreateRegion(dpy, xrects, num_rects);
2570896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   free(xrects);
2580896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   XDamageAdd(dpy, drawable, region);
2590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   XFixesDestroyRegion(dpy, region);
260890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg}
261890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg
262e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic const __DRIdamageExtension damageExtension = {
2630896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   {__DRI_DAMAGE, __DRI_DAMAGE_VERSION},
2640896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __glXReportDamage,
265e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg};
266e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
267e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg#endif
268e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
269890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsbergstatic GLboolean
2700896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf__glXDRIGetDrawableInfo(__DRIdrawable * drawable,
2710896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                        unsigned int *index, unsigned int *stamp,
2720896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                        int *X, int *Y, int *W, int *H,
2730896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                        int *numClipRects, drm_clip_rect_t ** pClipRects,
2740896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                        int *backX, int *backY,
2750896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                        int *numBackClipRects,
2760896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                        drm_clip_rect_t ** pBackClipRects,
2770896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                        void *loaderPrivate)
278890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg{
2790896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __GLXDRIdrawable *glxDraw = loaderPrivate;
28066fc35cde9ed68a09920ad6a28de794dd1d3aa8cKristian Høgsberg   struct glx_screen *psc = glxDraw->psc;
2810896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Display *dpy = psc->dpy;
2820896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2830896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return XF86DRIGetDrawableInfo(dpy, psc->scr, glxDraw->drawable,
2840896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                 index, stamp, X, Y, W, H,
2850896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                 numClipRects, pClipRects,
2860896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                 backX, backY,
2870896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                 numBackClipRects, pBackClipRects);
288890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg}
289890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg
290890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsbergstatic const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
2910896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   {__DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION},
2920896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __glXDRIGetDrawableInfo
293890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg};
294890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg
295890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsbergstatic const __DRIextension *loader_extensions[] = {
2960896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   &systemTimeExtension.base,
2970896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   &getDrawableInfoExtension.base,
298e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg#ifdef XDAMAGE_1_1_INTERFACE
2990896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   &damageExtension.base,
300e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg#endif
3010896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   NULL
302890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg};
303890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg
304890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg/**
305890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg * Perform the required libGL-side initialization and call the client-side
306890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg * driver's \c __driCreateNewScreen function.
307890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg *
308890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg * \param dpy    Display pointer.
309890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg * \param scrn   Screen number on the display.
310890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg * \param psc    DRI screen information.
311890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg * \param driDpy DRI display information.
312890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg * \param createNewScreen  Pointer to the client-side driver's
313890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg *               \c __driCreateNewScreen function.
314d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg * \returns A pointer to the \c __DRIscreen structure returned by
315890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg *          the client-side driver on success, or \c NULL on failure.
316890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg */
317890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsbergstatic void *
318f972115d33e391499e049b83a1559959f2ca9f72Kristian HøgsbergCallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc,
319a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg                    struct dri_display * driDpy)
320890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg{
3210896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   void *psp = NULL;
3220896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   drm_handle_t hSAREA;
3230896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   drmAddress pSAREA = MAP_FAILED;
3240896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   char *BusID;
3250896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __DRIversion ddx_version;
3260896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __DRIversion dri_version;
3270896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __DRIversion drm_version;
3280896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __DRIframebuffer framebuffer;
3290896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int fd = -1;
3300896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int status;
3310896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3320896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   drm_magic_t magic;
3330896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   drmVersionPtr version;
3340896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int newlyopened;
3350896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   char *driverName;
3360896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   drm_handle_t hFB;
3370896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int junk;
3380896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   const __DRIconfig **driver_configs;
33963a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   struct glx_config *visual, *configs = NULL, *visuals = NULL;
3400896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3410896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* DRI protocol version. */
3420896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   dri_version.major = driDpy->driMajor;
3430896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   dri_version.minor = driDpy->driMinor;
3440896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   dri_version.patch = driDpy->driPatch;
3450896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3460896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   framebuffer.base = MAP_FAILED;
3470896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   framebuffer.dev_priv = NULL;
34886d98fa4a2dfdae75e6ecd9a7e6e73d4183075a0Vinson Lee   framebuffer.size = 0;
3490896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3500896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
3510896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("XF86DRIOpenConnection failed\n");
3520896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
3530896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
3540896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3550896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   fd = drmOpenOnce(NULL, BusID, &newlyopened);
3560896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3570896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(BusID);                /* No longer needed */
3580896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (fd < 0) {
3600896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd));
3610896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
3620896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
3630896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3640896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (drmGetMagic(fd, &magic)) {
3650896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("drmGetMagic failed\n");
3660896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
3670896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
3680896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3690896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   version = drmGetVersion(fd);
3700896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (version) {
3710896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drm_version.major = version->version_major;
3720896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drm_version.minor = version->version_minor;
3730896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drm_version.patch = version->version_patchlevel;
3740896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drmFreeVersion(version);
3750896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
3760896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   else {
3770896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drm_version.major = -1;
3780896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drm_version.minor = -1;
3790896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drm_version.patch = -1;
3800896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
3810896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3820896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (newlyopened && !XF86DRIAuthConnection(dpy, scrn, magic)) {
3830896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("XF86DRIAuthConnection failed\n");
3840896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
3850896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
3860896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
387e4344161bde2e24fcfba65d30d58f087bd8bf94dIan Romanick   /* Get device name (like "radeon") and the ddx version numbers.
3880896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * We'll check the version in each DRI driver's "createNewScreen"
3890896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * function. */
3900896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!XF86DRIGetClientDriverName(dpy, scrn,
3910896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                   &ddx_version.major,
3920896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                   &ddx_version.minor,
3930896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                   &ddx_version.patch, &driverName)) {
3940896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("XF86DRIGetClientDriverName failed\n");
3950896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
3960896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
3970896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3980896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(driverName);           /* No longer needed. */
3990896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4000896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /*
4010896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * Get device-specific info.  pDevPriv will point to a struct
4020896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
4030896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * has information about the screen size, depth, pitch, ancilliary
4040896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * buffers, DRM mmap handles, etc.
4050896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    */
4060896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!XF86DRIGetDeviceInfo(dpy, scrn, &hFB, &junk,
4070896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                             &framebuffer.size, &framebuffer.stride,
4080896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                             &framebuffer.dev_priv_size,
4090896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                             &framebuffer.dev_priv)) {
4100896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("XF86DRIGetDeviceInfo failed");
4110896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
4120896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
4130896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4140896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   framebuffer.width = DisplayWidth(dpy, scrn);
4150896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   framebuffer.height = DisplayHeight(dpy, scrn);
4160896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4170896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* Map the framebuffer region. */
4180896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   status = drmMap(fd, hFB, framebuffer.size,
4190896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                   (drmAddressPtr) & framebuffer.base);
4200896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (status != 0) {
4210896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status));
4220896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
4230896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
4240896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4250896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* Map the SAREA region.  Further mmap regions may be setup in
4260896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * each DRI driver's "createNewScreen" function.
4270896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    */
4280896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA);
4290896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (status != 0) {
4300896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status));
4310896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
4320896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
4330896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4340896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   psp = (*psc->legacy->createNewScreen) (scrn,
4350896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                          &ddx_version,
4360896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                          &dri_version,
4370896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                          &drm_version,
4380896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                          &framebuffer,
4390896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                          pSAREA,
4400896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                          fd,
4410896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                          loader_extensions,
4420896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                          &driver_configs, psc);
4430896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4440896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (psp == NULL) {
4450896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("Calling driver entry point failed");
4460896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
4470896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
4480896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
44963a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   configs = driConvertConfigs(psc->core, psc->base.configs, driver_configs);
45063a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   visuals = driConvertConfigs(psc->core, psc->base.visuals, driver_configs);
45163a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner
45263a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   if (!configs || !visuals)
45363a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner       goto handle_error;
45463a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner
45563a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   glx_config_destroy_list(psc->base.configs);
45663a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   psc->base.configs = configs;
45763a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   glx_config_destroy_list(psc->base.visuals);
45863a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   psc->base.visuals = visuals;
4590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
460bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian Høgsberg   psc->driver_configs = driver_configs;
4610896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4620896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* Visuals with depth != screen depth are subject to automatic compositing
4630896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * in the X server, so DRI1 can't render to them properly. Mark them as
4640896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * non-conformant to prevent apps from picking them up accidentally.
4650896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    */
466f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   for (visual = psc->base.visuals; visual; visual = visual->next) {
4670896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      XVisualInfo template;
4680896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      XVisualInfo *visuals;
4690896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      int num_visuals;
4700896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      long mask;
4710896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4720896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      template.visualid = visual->visualID;
4730896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      mask = VisualIDMask;
4740896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      visuals = XGetVisualInfo(dpy, mask, &template, &num_visuals);
4750896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4760896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (visuals) {
4770896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         if (num_visuals > 0 && visuals->depth != DefaultDepth(dpy, scrn))
4780896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf            visual->visualRating = GLX_NON_CONFORMANT_CONFIG;
4790896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4800896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         XFree(visuals);
4810896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      }
4820896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
4830896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4840896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return psp;
485906e189bd362399f1ffc4d5421ae0d0abd586977George Sapountzis
486906e189bd362399f1ffc4d5421ae0d0abd586977George Sapountzis handle_error:
48763a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   if (configs)
48863a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner       glx_config_destroy_list(configs);
48963a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   if (visuals)
49063a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner       glx_config_destroy_list(visuals);
49163a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner
4920896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (pSAREA != MAP_FAILED)
4930896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drmUnmap(pSAREA, SAREA_MAX);
494906e189bd362399f1ffc4d5421ae0d0abd586977George Sapountzis
4950896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (framebuffer.base != MAP_FAILED)
4960896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drmUnmap((drmAddress) framebuffer.base, framebuffer.size);
497906e189bd362399f1ffc4d5421ae0d0abd586977George Sapountzis
4980896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (framebuffer.dev_priv != NULL)
4990896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      Xfree(framebuffer.dev_priv);
500906e189bd362399f1ffc4d5421ae0d0abd586977George Sapountzis
5010896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (fd >= 0)
5020896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drmCloseOnce(fd);
503906e189bd362399f1ffc4d5421ae0d0abd586977George Sapountzis
5040896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   XF86DRICloseConnection(dpy, scrn);
505906e189bd362399f1ffc4d5421ae0d0abd586977George Sapountzis
5060896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   ErrorMessageF("reverting to software direct rendering\n");
507906e189bd362399f1ffc4d5421ae0d0abd586977George Sapountzis
5080896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return NULL;
509890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg}
510890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg
5110896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
512c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian Høgsbergdri_destroy_context(struct glx_context * context)
513020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg{
514a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri_context *pcp = (struct dri_context *) context;
51531819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) context->psc;
516020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg
517bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin   driReleaseDrawables(&pcp->base);
518bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin
519c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg   if (context->extensions)
520c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg      XFree((char *) context->extensions);
521c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg
5220896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   (*psc->core->destroyContext) (pcp->driContext);
5230896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
524f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   XF86DRIDestroyContext(psc->base.dpy, psc->base.scr, pcp->hwContextID);
5250896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(pcp);
526020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg}
52753dc86363665b9b22f042c5d950b7de0ed02b4c8Kristian Høgsberg
528c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsbergstatic int
529c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsbergdri_bind_context(struct glx_context *context, struct glx_context *old,
530c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg		 GLXDrawable draw, GLXDrawable read)
53153dc86363665b9b22f042c5d950b7de0ed02b4c8Kristian Høgsberg{
532a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri_context *pcp = (struct dri_context *) context;
533bc34aa6128b9d509a25232d70dc826f1921fd221Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) pcp->base.psc;
534c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   struct dri_drawable *pdraw, *pread;
535c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg
536c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   pdraw = (struct dri_drawable *) driFetchDrawable(context, draw);
537c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   pread = (struct dri_drawable *) driFetchDrawable(context, read);
538020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg
539bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin   driReleaseDrawables(&pcp->base);
540bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin
541c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   if (pdraw == NULL || pread == NULL)
542c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg      return GLXBadDrawable;
543c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg
544c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   if ((*psc->core->bindContext) (pcp->driContext,
545c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg				  pdraw->driDrawable, pread->driDrawable))
546c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg      return Success;
547c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg
548c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   return GLXBadContext;
549020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg}
550020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg
5510896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
552c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsbergdri_unbind_context(struct glx_context *context, struct glx_context *new)
553020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg{
554a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri_context *pcp = (struct dri_context *) context;
555bc34aa6128b9d509a25232d70dc826f1921fd221Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) pcp->base.psc;
556020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg
557f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   (*psc->core->unbindContext) (pcp->driContext);
558020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg}
559020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg
560c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsbergstatic const struct glx_context_vtable dri_context_vtable = {
561c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg   dri_destroy_context,
562c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   dri_bind_context,
563c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   dri_unbind_context,
564c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg   NULL,
565c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg   NULL,
566c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg   DRI_glXUseXFont,
567c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg   NULL,
568c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg   NULL,
569559e4f8ebcb186b491d7d687ac43f22a62448fc1Jeremy Huddleston   NULL, /* get_proc_address */
570c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg};
571c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg
572c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian Høgsbergstatic struct glx_context *
57366fc35cde9ed68a09920ad6a28de794dd1d3aa8cKristian Høgsbergdri_create_context(struct glx_screen *base,
5746ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg		   struct glx_config *config_base,
575c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian Høgsberg		   struct glx_context *shareList, int renderType)
576020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg{
577a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri_context *pcp, *pcp_shared;
578f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) base;
5790896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   drm_context_t hwContext;
5800896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __DRIcontext *shared = NULL;
5816ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
5820896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
583f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   if (!psc->base.driScreen)
5840896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
5850896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
5860896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (shareList) {
587c4a8c54c3bb31547cba57702ffea99293afef522Ian Romanick      /* If the shareList context is not a DRI context, we cannot possibly
588c4a8c54c3bb31547cba57702ffea99293afef522Ian Romanick       * create a DRI context that shares it.
589c4a8c54c3bb31547cba57702ffea99293afef522Ian Romanick       */
590c4a8c54c3bb31547cba57702ffea99293afef522Ian Romanick      if (shareList->vtable->destroy != dri_destroy_context) {
591c4a8c54c3bb31547cba57702ffea99293afef522Ian Romanick	 return NULL;
592c4a8c54c3bb31547cba57702ffea99293afef522Ian Romanick      }
593c4a8c54c3bb31547cba57702ffea99293afef522Ian Romanick
594c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg      pcp_shared = (struct dri_context *) shareList;
5950896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      shared = pcp_shared->driContext;
5960896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
5970896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
5980896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pcp = Xmalloc(sizeof *pcp);
5990896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (pcp == NULL)
6000896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
6010896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
60231819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   memset(pcp, 0, sizeof *pcp);
6036ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   if (!glx_context_init(&pcp->base, &psc->base, &config->base)) {
60431819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg      Xfree(pcp);
60531819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg      return NULL;
60631819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   }
60731819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg
608f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   if (!XF86DRICreateContextWithConfig(psc->base.dpy, psc->base.scr,
6096ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg                                       config->base.visualID,
6100896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                       &pcp->hwContextID, &hwContext)) {
6110896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      Xfree(pcp);
6120896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
6130896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
6140896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
6150896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pcp->driContext =
61670887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg      (*psc->legacy->createNewContext) (psc->driScreen,
6170896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                        config->driConfig,
6180896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                        renderType, shared, hwContext, pcp);
6190896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (pcp->driContext == NULL) {
620f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      XF86DRIDestroyContext(psc->base.dpy, psc->base.scr, pcp->hwContextID);
6210896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      Xfree(pcp);
6220896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
6230896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
6240896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
62531819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   pcp->base.vtable = &dri_context_vtable;
6260896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
6270896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return &pcp->base;
62853dc86363665b9b22f042c5d950b7de0ed02b4c8Kristian Høgsberg}
62953dc86363665b9b22f042c5d950b7de0ed02b4c8Kristian Høgsberg
6300896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
6310896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófdriDestroyDrawable(__GLXDRIdrawable * pdraw)
6329110425c72e45f618131b559eba883fd6c5536b4Kristian Høgsberg{
633f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) pdraw->psc;
634271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
6359110425c72e45f618131b559eba883fd6c5536b4Kristian Høgsberg
636271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   (*psc->core->destroyDrawable) (pdp->driDrawable);
637f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   XF86DRIDestroyDrawable(psc->base.dpy, psc->base.scr, pdraw->drawable);
6380896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(pdraw);
6399110425c72e45f618131b559eba883fd6c5536b4Kristian Høgsberg}
64020b9230ce1b96ca246850a8088caeffc3f391a0cKristian Høgsberg
6410896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic __GLXDRIdrawable *
64266fc35cde9ed68a09920ad6a28de794dd1d3aa8cKristian HøgsbergdriCreateDrawable(struct glx_screen *base,
6430896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                  XID xDrawable,
6446ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg                  GLXDrawable drawable, struct glx_config *config_base)
64520b9230ce1b96ca246850a8088caeffc3f391a0cKristian Høgsberg{
6460896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   drm_drawable_t hwDrawable;
6470896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   void *empty_attribute_list = NULL;
6486ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
649f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) base;
650271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp;
6510896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
6520896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* Old dri can't handle GLX 1.3+ drawable constructors. */
6530896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (xDrawable != drawable)
6540896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
6550896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
656271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   pdp = Xmalloc(sizeof *pdp);
657271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   if (!pdp)
6580896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
6590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
6606393a33944ec9983426cecd5f6c9f05ac089e1aeKristian Høgsberg   memset(pdp, 0, sizeof *pdp);
661271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   pdp->base.drawable = drawable;
662271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   pdp->base.psc = &psc->base;
6630896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
664f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   if (!XF86DRICreateDrawable(psc->base.dpy, psc->base.scr,
665f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg			      drawable, &hwDrawable)) {
666271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg      Xfree(pdp);
6670896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
668e0556657526a7fe53d6e17cf70ffa6a8ee35e0a9Vinson Lee   }
6690896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
6700896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* Create a new drawable */
671271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   pdp->driDrawable =
67270887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg      (*psc->legacy->createNewDrawable) (psc->driScreen,
6730896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                         config->driConfig,
6740896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                         hwDrawable,
6750896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                         GLX_WINDOW_BIT,
676271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg                                         empty_attribute_list, pdp);
6770896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
678271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   if (!pdp->driDrawable) {
679f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      XF86DRIDestroyDrawable(psc->base.dpy, psc->base.scr, drawable);
680271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg      Xfree(pdp);
6810896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
6820896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
6830896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
684271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   pdp->base.destroyDrawable = driDestroyDrawable;
6850896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
686271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   return &pdp->base;
68720b9230ce1b96ca246850a8088caeffc3f391a0cKristian Høgsberg}
68820b9230ce1b96ca246850a8088caeffc3f391a0cKristian Høgsberg
689daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnesstatic int64_t
690daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse BarnesdriSwapBuffers(__GLXDRIdrawable * pdraw, int64_t unused1, int64_t unused2,
691daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes	       int64_t unused3)
692f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg{
693f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) pdraw->psc;
694271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
695f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg
696271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   (*psc->core->swapBuffers) (pdp->driDrawable);
697daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes   return 0;
698f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg}
699f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg
7000896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
7010896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófdriCopySubBuffer(__GLXDRIdrawable * pdraw,
7020896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                 int x, int y, int width, int height)
7034830809524b20e517e949151957512b14d7e679aKristian Høgsberg{
704271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
705a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) pdp->base.psc;
706271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg
707a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg   (*psc->driCopySubBuffer->copySubBuffer) (pdp->driDrawable,
708a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg					    x, y, width, height);
7094830809524b20e517e949151957512b14d7e679aKristian Høgsberg}
7104830809524b20e517e949151957512b14d7e679aKristian Høgsberg
7110896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
71266fc35cde9ed68a09920ad6a28de794dd1d3aa8cKristian HøgsbergdriDestroyScreen(struct glx_screen *base)
713a1ea6f6198d80f716936a308cfab235f18a014e1Kristian Høgsberg{
714f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) base;
715f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg
7160896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* Free the direct rendering per screen data */
71770887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   if (psc->driScreen)
71870887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg      (*psc->core->destroyScreen) (psc->driScreen);
719bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian Høgsberg   driDestroyConfigs(psc->driver_configs);
72070887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   psc->driScreen = NULL;
7210896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (psc->driver)
7220896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      dlclose(psc->driver);
723a1ea6f6198d80f716936a308cfab235f18a014e1Kristian Høgsberg}
724a1ea6f6198d80f716936a308cfab235f18a014e1Kristian Høgsberg
725089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg#ifdef __DRI_SWAP_BUFFER_COUNTER
726089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
727089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsbergstatic int
72866fc35cde9ed68a09920ad6a28de794dd1d3aa8cKristian HøgsbergdriDrawableGetMSC(struct glx_screen *base, __GLXDRIdrawable *pdraw,
729089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg		   int64_t *ust, int64_t *msc, int64_t *sbc)
730089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg{
731089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) base;
732271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
733089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
734271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   if (pdp && psc->sbc && psc->msc)
735089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      return ( (*psc->msc->getMSC)(psc->driScreen, msc) == 0 &&
736271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg	       (*psc->sbc->getSBC)(pdp->driDrawable, sbc) == 0 &&
737089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg	       __glXGetUST(ust) == 0 );
738089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg}
739089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
740089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsbergstatic int
741089fc37c6fa158824279e08e3b378ced94d6f803Kristian HøgsbergdriWaitForMSC(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
742089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg	       int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
743089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg{
744089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) pdraw->psc;
745271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
746089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
747271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   if (pdp != NULL && psc->msc != NULL) {
748271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg      ret = (*psc->msc->waitForMSC) (pdp->driDrawable, target_msc,
749089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg				     divisor, remainder, msc, sbc);
750089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
751089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      /* __glXGetUST returns zero on success and non-zero on failure.
752089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg       * This function returns True on success and False on failure.
753089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg       */
754089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      return ret == 0 && __glXGetUST(ust) == 0;
755089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   }
756089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg}
757089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
758089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsbergstatic int
759089fc37c6fa158824279e08e3b378ced94d6f803Kristian HøgsbergdriWaitForSBC(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
760089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg	       int64_t *msc, int64_t *sbc)
761089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg{
762271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
763271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg
764271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   if (pdp != NULL && psc->sbc != NULL) {
765089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      ret =
766271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg         (*psc->sbc->waitForSBC) (pdp->driDrawable, target_sbc, msc, sbc);
767089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
768089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      /* __glXGetUST returns zero on success and non-zero on failure.
769089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg       * This function returns True on success and False on failure.
770089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg       */
771089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      return ((ret == 0) && (__glXGetUST(ust) == 0));
772089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   }
773089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
774271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   return DRI2WaitSBC(pdp->base.psc->dpy,
775271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg		      pdp->base.xDrawable, target_sbc, ust, msc, sbc);
776089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg}
777089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
778089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg#endif
779089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
780089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsbergstatic int
781089fc37c6fa158824279e08e3b378ced94d6f803Kristian HøgsbergdriSetSwapInterval(__GLXDRIdrawable *pdraw, int interval)
782089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg{
783271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
784c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) pdraw->psc;
785089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
786c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   if (psc->swapControl != NULL && pdraw != NULL) {
787c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg      psc->swapControl->setSwapInterval(pdp->driDrawable, interval);
788c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg      return 0;
789089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   }
790089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
791089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   return GLX_BAD_CONTEXT;
792089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg}
793089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
794089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsbergstatic int
795089fc37c6fa158824279e08e3b378ced94d6f803Kristian HøgsbergdriGetSwapInterval(__GLXDRIdrawable *pdraw)
796089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg{
797271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
798c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) pdraw->psc;
799089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
800c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   if (psc->swapControl != NULL && pdraw != NULL)
801c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg      return psc->swapControl->getSwapInterval(pdp->driDrawable);
802089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
803089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   return 0;
804089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg}
805089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
806089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg/* Bind DRI1 specific extensions */
807089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsbergstatic void
808089fc37c6fa158824279e08e3b378ced94d6f803Kristian HøgsbergdriBindExtensions(struct dri_screen *psc, const __DRIextension **extensions)
809089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg{
810089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   int i;
811089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
812089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   for (i = 0; extensions[i]; i++) {
813089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      /* No DRI2 support for swap_control at the moment, since SwapBuffers
814089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg       * is done by the X server */
815089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
816089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg	 psc->swapControl = (__DRIswapControlExtension *) extensions[i];
817089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg	 __glXEnableDirectExtension(&psc->base, "GLX_SGI_swap_control");
818089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg	 __glXEnableDirectExtension(&psc->base, "GLX_MESA_swap_control");
819089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      }
820089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
821089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      if (strcmp(extensions[i]->name, __DRI_MEDIA_STREAM_COUNTER) == 0) {
822089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg         psc->msc = (__DRImediaStreamCounterExtension *) extensions[i];
823089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg         __glXEnableDirectExtension(&psc->base, "GLX_SGI_video_sync");
824089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      }
825089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
826a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg      if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
827a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg	 psc->driCopySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
828a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg	 __glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer");
829a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg      }
830a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg
831a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg      if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
832a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg	 __glXEnableDirectExtension(&psc->base, "GLX_SGI_make_current_read");
833a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg      }
834089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      /* Ignore unknown extensions */
835089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   }
836089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg}
837089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
8386ec39db726beead21d97bf64ddbe1f0b2d2d6ca1Kristian Høgsbergstatic const struct glx_screen_vtable dri_screen_vtable = {
83943409fa7b0e64f6d73c3d33bc9a39ba26dd4caebIan Romanick   dri_create_context,
84043409fa7b0e64f6d73c3d33bc9a39ba26dd4caebIan Romanick   NULL
8416ec39db726beead21d97bf64ddbe1f0b2d2d6ca1Kristian Høgsberg};
8426ec39db726beead21d97bf64ddbe1f0b2d2d6ca1Kristian Høgsberg
84366fc35cde9ed68a09920ad6a28de794dd1d3aa8cKristian Høgsbergstatic struct glx_screen *
844c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian HøgsbergdriCreateScreen(int screen, struct glx_display *priv)
845890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg{
846a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri_display *pdp;
8470896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __GLXDRIscreen *psp;
8480896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   const __DRIextension **extensions;
849f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   struct dri_screen *psc;
8500896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   char *driverName;
8510896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int i;
8520896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
853f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   psc = Xcalloc(1, sizeof *psc);
854f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   if (psc == NULL)
8550896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
8560896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
857f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   memset(psc, 0, sizeof *psc);
8580e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet   if (!glx_screen_init(&psc->base, screen, priv)) {
859f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      Xfree(psc);
8600896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
8610896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
8620896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
8630e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet   if (!driGetDriverName(priv->dpy, screen, &driverName)) {
8640e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet      goto cleanup;
8650e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet   }
8660e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet
8670896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   psc->driver = driOpenDriver(driverName);
8680e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet   if (psc->driver == NULL)
8690e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet      goto cleanup;
8700896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
8710896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
8720896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (extensions == NULL) {
8730896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
8740e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet      goto cleanup;
8750896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
8760896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
8770896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   for (i = 0; extensions[i]; i++) {
8780896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
879daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes	 psc->core = (__DRIcoreExtension *) extensions[i];
8800896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0)
881daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes	 psc->legacy = (__DRIlegacyExtension *) extensions[i];
8820896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
8830896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
8840e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet   if (psc->core == NULL || psc->legacy == NULL)
8850e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet      goto cleanup;
8860896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
887a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   pdp = (struct dri_display *) priv->driDisplay;
88870887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   psc->driScreen =
889f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      CallCreateNewScreen(psc->base.dpy, screen, psc, pdp);
8900e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet   if (psc->driScreen == NULL)
8910e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet      goto cleanup;
8920896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
89370887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   extensions = psc->core->getExtensions(psc->driScreen);
894089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   driBindExtensions(psc, extensions);
895daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes
8966ec39db726beead21d97bf64ddbe1f0b2d2d6ca1Kristian Høgsberg   psc->base.vtable = &dri_screen_vtable;
89770887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   psp = &psc->vtable;
898f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   psc->base.driScreen = psp;
899a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg   if (psc->driCopySubBuffer)
9000896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      psp->copySubBuffer = driCopySubBuffer;
9010896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
9020896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   psp->destroyScreen = driDestroyScreen;
9030896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   psp->createDrawable = driCreateDrawable;
9040896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   psp->swapBuffers = driSwapBuffers;
9050896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
906089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg#ifdef __DRI_SWAP_BUFFER_COUNTER
907089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   psp->getDrawableMSC = driDrawableGetMSC;
908089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   psp->waitForMSC = driWaitForMSC;
909089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   psp->waitForSBC = driWaitForSBC;
910089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg#endif
911089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
912089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   psp->setSwapInterval = driSetSwapInterval;
913089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   psp->getSwapInterval = driGetSwapInterval;
914089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
9155fdc42fb877644ae4c3343c9391f959bc7d71515Brian Paul   free(driverName);
9165fdc42fb877644ae4c3343c9391f959bc7d71515Brian Paul
917f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   return &psc->base;
9180e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet
9190e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeetcleanup:
9206c9af977401ff986964d678f8870eee23c504077Carl Worth   CriticalErrorMessageF("failed to load driver: %s\n", driverName);
9216c9af977401ff986964d678f8870eee23c504077Carl Worth
9225fdc42fb877644ae4c3343c9391f959bc7d71515Brian Paul   free(driverName);
9235fdc42fb877644ae4c3343c9391f959bc7d71515Brian Paul
9240e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet   if (psc->driver)
9250e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet      dlclose(psc->driver);
9260e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet   glx_screen_cleanup(&psc->base);
9270e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet   Xfree(psc);
9280e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet
9290e8e8ba29a7cbe2fe45939cb972f437ccd21bcd5Henri Verbeet   return NULL;
930890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg}
931cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
9328628b382e4ac492d829fe720219187b758add003Michel Dänzer/* Called from __glXFreeDisplayPrivate.
933cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson */
9340896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
9350896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófdriDestroyDisplay(__GLXDRIdisplay * dpy)
936cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson{
9370896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(dpy);
938cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}
939cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
940cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/*
941cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Allocate, initialize and return a __DRIdisplayPrivate object.
942cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * This is called from __glXInitialize() when we are given a new
943cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * display pointer.
944cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson */
9450896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf_X_HIDDEN __GLXDRIdisplay *
9460896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófdriCreateDisplay(Display * dpy)
947cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson{
948a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri_display *pdpyp;
9490896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int eventBase, errorBase;
9500896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int major, minor, patch;
951cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
9520896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!XF86DRIQueryExtension(dpy, &eventBase, &errorBase)) {
9530896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
9540896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
955cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
9560896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!XF86DRIQueryVersion(dpy, &major, &minor, &patch)) {
9570896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
9580896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
959cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
9600896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdpyp = Xmalloc(sizeof *pdpyp);
9610896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!pdpyp) {
9620896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
9630896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
964cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
9650896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdpyp->driMajor = major;
9660896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdpyp->driMinor = minor;
9670896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdpyp->driPatch = patch;
968cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
9690896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdpyp->base.destroyDisplay = driDestroyDisplay;
9700896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdpyp->base.createScreen = driCreateScreen;
971cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
9720896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return &pdpyp->base;
973cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}
974cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
975cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#endif /* GLX_DIRECT_RENDERING */
976