dri_glx.c revision 6ddf66e9230ee862ac341c4767cf6b3b2dd2552b
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{
64f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   __GLXscreenConfigs 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{
8131819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   __GLXcontext base;
8231819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   __GLXDRIcontext dri_vtable;
830896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __DRIcontext *driContext;
840896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   XID hwContextID;
85e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg};
86e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
87271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsbergstruct dri_drawable
88271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg{
89271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   __GLXDRIdrawable base;
90271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg
91271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   __DRIdrawable *driDrawable;
92271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg};
93271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg
94c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsbergstatic const struct glx_context_vtable dri_context_vtable;
9531819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg
96cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/*
97cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Given a display pointer and screen number, determine the name of
98cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
99cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Return True for success, False for failure.
100cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson */
1010896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic Bool
1020896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófdriGetDriverName(Display * dpy, int scrNum, char **driverName)
103cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson{
1040896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int directCapable;
1050896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Bool b;
1060896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int event, error;
1070896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int driverMajor, driverMinor, driverPatch;
1080896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1090896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   *driverName = NULL;
1100896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1110896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (XF86DRIQueryExtension(dpy, &event, &error)) {    /* DRI1 */
1120896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) {
1130896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
1140896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         return False;
1150896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      }
1160896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (!directCapable) {
1170896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
1180896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         return False;
1190896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      }
1200896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1210896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor,
1220896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                     &driverPatch, driverName);
1230896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (!b) {
1240896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         ErrorMessageF("Cannot determine driver name for screen %d\n",
1250896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                       scrNum);
1260896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         return False;
1270896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      }
1280896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1290896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
1300896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                   driverMajor, driverMinor, driverPatch, *driverName,
1310896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                   scrNum);
1320896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1330896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return True;
1340896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
1350896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   else if (DRI2QueryExtension(dpy, &event, &error)) {  /* DRI2 */
1360896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      char *dev;
1370896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      Bool ret = DRI2Connect(dpy, RootWindow(dpy, scrNum), driverName, &dev);
1380896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1390896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (ret)
1400896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         Xfree(dev);
1410896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1420896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return ret;
1430896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
1440896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1450896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return False;
146cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}
147cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
148cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/*
149cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Exported function for querying the DRI driver for a given screen.
150cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson *
151cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * The returned char pointer points to a static array that will be
152cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * overwritten by subsequent calls.
153cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson */
1540896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófPUBLIC const char *
1550896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófglXGetScreenDriver(Display * dpy, int scrNum)
1560896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf{
157cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson   static char ret[32];
158cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson   char *driverName;
159079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   if (driGetDriverName(dpy, scrNum, &driverName)) {
160cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      int len;
161cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      if (!driverName)
1620896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         return NULL;
1630896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      len = strlen(driverName);
164cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      if (len >= 31)
1650896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         return NULL;
1660896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      memcpy(ret, driverName, len + 1);
167cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      Xfree(driverName);
168cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      return ret;
169cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson   }
170cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson   return NULL;
171cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}
172cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
173cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/*
174cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Exported function for obtaining a driver's option list (UTF-8 encoded XML).
175cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson *
176cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * The returned char pointer points directly into the driver. Therefore
177cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * it should be treated as a constant.
178cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson *
179cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * If the driver was not found or does not support configuration NULL is
180cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * returned.
181cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson *
182cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Note: The driver remains opened after this function returns.
183cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson */
1840896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófPUBLIC const char *
1850896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófglXGetDriverConfig(const char *driverName)
186e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
1870896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   void *handle = driOpenDriver(driverName);
1880f2723cacbaf9b27ecb8d13581f4b72ff86dd911Kristian Høgsberg   if (handle)
1890896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return dlsym(handle, "__driConfigOptions");
190cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson   else
191cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson      return NULL;
192cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}
193cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
194890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg#ifdef XDAMAGE_1_1_INTERFACE
195e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
1960896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic GLboolean
1970896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófhas_damage_post(Display * dpy)
198890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg{
1990896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   static GLboolean inited = GL_FALSE;
2000896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   static GLboolean has_damage;
2010896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2020896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!inited) {
2030896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      int major, minor;
2040896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2050896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (XDamageQueryVersion(dpy, &major, &minor) &&
2060896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf          major == 1 && minor >= 1) {
2070896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         has_damage = GL_TRUE;
2080896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      }
2090896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      else {
2100896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         has_damage = GL_FALSE;
2110896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      }
2120896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      inited = GL_TRUE;
2130896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
2140896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2150896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return has_damage;
216890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg}
217890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg
2180896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
2190896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf__glXReportDamage(__DRIdrawable * driDraw,
2200896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                  int x, int y,
2210896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                  drm_clip_rect_t * rects, int num_rects,
2220896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                  GLboolean front_buffer, void *loaderPrivate)
223890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg{
2240896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   XRectangle *xrects;
2250896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   XserverRegion region;
2260896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int i;
2270896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int x_off, y_off;
2280896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __GLXDRIdrawable *glxDraw = loaderPrivate;
2290896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __GLXscreenConfigs *psc = glxDraw->psc;
2300896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Display *dpy = psc->dpy;
2310896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Drawable drawable;
2320896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2330896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!has_damage_post(dpy))
2340896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return;
2350896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2360896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (front_buffer) {
2370896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      x_off = x;
2380896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      y_off = y;
2390896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drawable = RootWindow(dpy, psc->scr);
2400896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
2410896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   else {
2420896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      x_off = 0;
2430896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      y_off = 0;
2440896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drawable = glxDraw->xDrawable;
2450896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
2460896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2470896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   xrects = malloc(sizeof(XRectangle) * num_rects);
2480896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (xrects == NULL)
2490896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return;
2500896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2510896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   for (i = 0; i < num_rects; i++) {
2520896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      xrects[i].x = rects[i].x1 + x_off;
2530896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      xrects[i].y = rects[i].y1 + y_off;
2540896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      xrects[i].width = rects[i].x2 - rects[i].x1;
2550896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      xrects[i].height = rects[i].y2 - rects[i].y1;
2560896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
2570896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   region = XFixesCreateRegion(dpy, xrects, num_rects);
2580896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   free(xrects);
2590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   XDamageAdd(dpy, drawable, region);
2600896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   XFixesDestroyRegion(dpy, region);
261890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg}
262890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg
263e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic const __DRIdamageExtension damageExtension = {
2640896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   {__DRI_DAMAGE, __DRI_DAMAGE_VERSION},
2650896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __glXReportDamage,
266e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg};
267e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
268e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg#endif
269e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
270890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsbergstatic GLboolean
2710896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf__glXDRIGetDrawableInfo(__DRIdrawable * drawable,
2720896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                        unsigned int *index, unsigned int *stamp,
2730896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                        int *X, int *Y, int *W, int *H,
2740896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                        int *numClipRects, drm_clip_rect_t ** pClipRects,
2750896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                        int *backX, int *backY,
2760896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                        int *numBackClipRects,
2770896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                        drm_clip_rect_t ** pBackClipRects,
2780896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                        void *loaderPrivate)
279890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg{
2800896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __GLXDRIdrawable *glxDraw = loaderPrivate;
2810896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __GLXscreenConfigs *psc = glxDraw->psc;
2820896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Display *dpy = psc->dpy;
2830896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2840896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return XF86DRIGetDrawableInfo(dpy, psc->scr, glxDraw->drawable,
2850896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                 index, stamp, X, Y, W, H,
2860896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                 numClipRects, pClipRects,
2870896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                 backX, backY,
2880896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                 numBackClipRects, pBackClipRects);
289890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg}
290890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg
291890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsbergstatic const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
2920896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   {__DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION},
2930896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __glXDRIGetDrawableInfo
294890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg};
295890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg
296890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsbergstatic const __DRIextension *loader_extensions[] = {
2970896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   &systemTimeExtension.base,
2980896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   &getDrawableInfoExtension.base,
299e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg#ifdef XDAMAGE_1_1_INTERFACE
3000896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   &damageExtension.base,
301e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg#endif
3020896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   NULL
303890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg};
304890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg
305890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg/**
306890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg * Perform the required libGL-side initialization and call the client-side
307890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg * driver's \c __driCreateNewScreen function.
308890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg *
309890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg * \param dpy    Display pointer.
310890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg * \param scrn   Screen number on the display.
311890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg * \param psc    DRI screen information.
312890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg * \param driDpy DRI display information.
313890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg * \param createNewScreen  Pointer to the client-side driver's
314890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg *               \c __driCreateNewScreen function.
315d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg * \returns A pointer to the \c __DRIscreen structure returned by
316890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg *          the client-side driver on success, or \c NULL on failure.
317890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg */
318890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsbergstatic void *
319f972115d33e391499e049b83a1559959f2ca9f72Kristian HøgsbergCallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc,
320a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg                    struct dri_display * driDpy)
321890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg{
3220896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   void *psp = NULL;
3230896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   drm_handle_t hSAREA;
3240896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   drmAddress pSAREA = MAP_FAILED;
3250896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   char *BusID;
3260896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __DRIversion ddx_version;
3270896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __DRIversion dri_version;
3280896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __DRIversion drm_version;
3290896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __DRIframebuffer framebuffer;
3300896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int fd = -1;
3310896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int status;
3320896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3330896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   drm_magic_t magic;
3340896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   drmVersionPtr version;
3350896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int newlyopened;
3360896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   char *driverName;
3370896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   drm_handle_t hFB;
3380896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int junk;
3390896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   const __DRIconfig **driver_configs;
3406ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   struct glx_config *visual;
3410896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3420896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* DRI protocol version. */
3430896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   dri_version.major = driDpy->driMajor;
3440896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   dri_version.minor = driDpy->driMinor;
3450896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   dri_version.patch = driDpy->driPatch;
3460896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3470896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   framebuffer.base = MAP_FAILED;
3480896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   framebuffer.dev_priv = NULL;
34986d98fa4a2dfdae75e6ecd9a7e6e73d4183075a0Vinson Lee   framebuffer.size = 0;
3500896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3510896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
3520896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("XF86DRIOpenConnection failed\n");
3530896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
3540896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
3550896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3560896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   fd = drmOpenOnce(NULL, BusID, &newlyopened);
3570896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3580896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(BusID);                /* No longer needed */
3590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3600896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (fd < 0) {
3610896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd));
3620896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
3630896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
3640896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3650896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (drmGetMagic(fd, &magic)) {
3660896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("drmGetMagic failed\n");
3670896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
3680896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
3690896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3700896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   version = drmGetVersion(fd);
3710896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (version) {
3720896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drm_version.major = version->version_major;
3730896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drm_version.minor = version->version_minor;
3740896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drm_version.patch = version->version_patchlevel;
3750896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drmFreeVersion(version);
3760896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
3770896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   else {
3780896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drm_version.major = -1;
3790896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drm_version.minor = -1;
3800896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drm_version.patch = -1;
3810896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
3820896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3830896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (newlyopened && !XF86DRIAuthConnection(dpy, scrn, magic)) {
3840896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("XF86DRIAuthConnection failed\n");
3850896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
3860896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
3870896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3880896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* Get device name (like "tdfx") and the ddx version numbers.
3890896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * We'll check the version in each DRI driver's "createNewScreen"
3900896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * function. */
3910896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!XF86DRIGetClientDriverName(dpy, scrn,
3920896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                   &ddx_version.major,
3930896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                   &ddx_version.minor,
3940896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                   &ddx_version.patch, &driverName)) {
3950896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("XF86DRIGetClientDriverName failed\n");
3960896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
3970896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
3980896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3990896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(driverName);           /* No longer needed. */
4000896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4010896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /*
4020896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * Get device-specific info.  pDevPriv will point to a struct
4030896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
4040896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * has information about the screen size, depth, pitch, ancilliary
4050896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * buffers, DRM mmap handles, etc.
4060896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    */
4070896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!XF86DRIGetDeviceInfo(dpy, scrn, &hFB, &junk,
4080896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                             &framebuffer.size, &framebuffer.stride,
4090896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                             &framebuffer.dev_priv_size,
4100896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                             &framebuffer.dev_priv)) {
4110896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("XF86DRIGetDeviceInfo failed");
4120896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
4130896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
4140896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4150896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   framebuffer.width = DisplayWidth(dpy, scrn);
4160896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   framebuffer.height = DisplayHeight(dpy, scrn);
4170896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4180896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* Map the framebuffer region. */
4190896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   status = drmMap(fd, hFB, framebuffer.size,
4200896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                   (drmAddressPtr) & framebuffer.base);
4210896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (status != 0) {
4220896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status));
4230896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
4240896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
4250896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4260896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* Map the SAREA region.  Further mmap regions may be setup in
4270896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * each DRI driver's "createNewScreen" function.
4280896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    */
4290896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA);
4300896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (status != 0) {
4310896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status));
4320896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
4330896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
4340896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4350896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   psp = (*psc->legacy->createNewScreen) (scrn,
4360896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                          &ddx_version,
4370896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                          &dri_version,
4380896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                          &drm_version,
4390896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                          &framebuffer,
4400896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                          pSAREA,
4410896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                          fd,
4420896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                          loader_extensions,
4430896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                          &driver_configs, psc);
4440896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4450896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (psp == NULL) {
4460896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("Calling driver entry point failed");
4470896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
4480896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
4490896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
450f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   psc->base.configs =
451f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      driConvertConfigs(psc->core, psc->base.configs, driver_configs);
452f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   psc->base.visuals =
453f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      driConvertConfigs(psc->core, psc->base.visuals, driver_configs);
4540896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
455bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian Høgsberg   psc->driver_configs = driver_configs;
4560896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4570896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* Visuals with depth != screen depth are subject to automatic compositing
4580896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * in the X server, so DRI1 can't render to them properly. Mark them as
4590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * non-conformant to prevent apps from picking them up accidentally.
4600896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    */
461f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   for (visual = psc->base.visuals; visual; visual = visual->next) {
4620896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      XVisualInfo template;
4630896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      XVisualInfo *visuals;
4640896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      int num_visuals;
4650896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      long mask;
4660896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4670896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      template.visualid = visual->visualID;
4680896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      mask = VisualIDMask;
4690896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      visuals = XGetVisualInfo(dpy, mask, &template, &num_visuals);
4700896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4710896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (visuals) {
4720896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         if (num_visuals > 0 && visuals->depth != DefaultDepth(dpy, scrn))
4730896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf            visual->visualRating = GLX_NON_CONFORMANT_CONFIG;
4740896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4750896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         XFree(visuals);
4760896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      }
4770896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
4780896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
4790896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return psp;
480906e189bd362399f1ffc4d5421ae0d0abd586977George Sapountzis
481906e189bd362399f1ffc4d5421ae0d0abd586977George Sapountzis handle_error:
4820896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (pSAREA != MAP_FAILED)
4830896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drmUnmap(pSAREA, SAREA_MAX);
484906e189bd362399f1ffc4d5421ae0d0abd586977George Sapountzis
4850896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (framebuffer.base != MAP_FAILED)
4860896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drmUnmap((drmAddress) framebuffer.base, framebuffer.size);
487906e189bd362399f1ffc4d5421ae0d0abd586977George Sapountzis
4880896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (framebuffer.dev_priv != NULL)
4890896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      Xfree(framebuffer.dev_priv);
490906e189bd362399f1ffc4d5421ae0d0abd586977George Sapountzis
4910896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (fd >= 0)
4920896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      drmCloseOnce(fd);
493906e189bd362399f1ffc4d5421ae0d0abd586977George Sapountzis
4940896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   XF86DRICloseConnection(dpy, scrn);
495906e189bd362399f1ffc4d5421ae0d0abd586977George Sapountzis
4960896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   ErrorMessageF("reverting to software direct rendering\n");
497906e189bd362399f1ffc4d5421ae0d0abd586977George Sapountzis
4980896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return NULL;
499890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg}
500890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg
5010896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
502c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsbergdri_destroy_context(__GLXcontext * context)
503020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg{
504a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri_context *pcp = (struct dri_context *) context;
50531819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) context->psc;
506020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg
507d77bb8e059ecfed9b714301fc31b093c6026c7bcKristian Høgsberg   if (context->xid)
508d77bb8e059ecfed9b714301fc31b093c6026c7bcKristian Høgsberg      glx_send_destroy_context(psc->base.dpy, context->xid);
509c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg
510c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg   if (context->extensions)
511c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg      XFree((char *) context->extensions);
512c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg
513c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg   GarbageCollectDRIDrawables(context->psc);
514c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg
5150896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   (*psc->core->destroyContext) (pcp->driContext);
5160896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
517f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   XF86DRIDestroyContext(psc->base.dpy, psc->base.scr, pcp->hwContextID);
5180896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(pcp);
519020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg}
52053dc86363665b9b22f042c5d950b7de0ed02b4c8Kristian Høgsberg
5210896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic Bool
52231819830b66a49f1b62e09090cc65aefc657aeb8Kristian HøgsbergdriBindContext(__GLXcontext *context,
523f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg	       __GLXDRIdrawable *draw, __GLXDRIdrawable *read)
52453dc86363665b9b22f042c5d950b7de0ed02b4c8Kristian Høgsberg{
525a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri_context *pcp = (struct dri_context *) context;
526bc34aa6128b9d509a25232d70dc826f1921fd221Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) pcp->base.psc;
527271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdr = (struct dri_drawable *) draw;
528271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *prd = (struct dri_drawable *) read;
529020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg
530f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   return (*psc->core->bindContext) (pcp->driContext,
531271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg				     pdr->driDrawable, prd->driDrawable);
532020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg}
533020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg
5340896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
53531819830b66a49f1b62e09090cc65aefc657aeb8Kristian HøgsbergdriUnbindContext(__GLXcontext * context)
536020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg{
537a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri_context *pcp = (struct dri_context *) context;
538bc34aa6128b9d509a25232d70dc826f1921fd221Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) pcp->base.psc;
539020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg
540f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   (*psc->core->unbindContext) (pcp->driContext);
541020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg}
542020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg
543c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsbergstatic const struct glx_context_vtable dri_context_vtable = {
544c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg   dri_destroy_context,
545c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg   NULL,
546c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg   NULL,
547c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg   DRI_glXUseXFont,
548c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg   NULL,
549c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg   NULL,
550c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg};
551c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg
55231819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsbergstatic __GLXcontext *
5536ec39db726beead21d97bf64ddbe1f0b2d2d6ca1Kristian Høgsbergdri_create_context(__GLXscreenConfigs *base,
5546ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg		   struct glx_config *config_base,
5556ec39db726beead21d97bf64ddbe1f0b2d2d6ca1Kristian Høgsberg		   GLXContext shareList, int renderType)
556020c64b2cf2973b5cb41e233d2bfbd85f1b699f7Kristian Høgsberg{
557a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri_context *pcp, *pcp_shared;
558f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) base;
5590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   drm_context_t hwContext;
5600896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __DRIcontext *shared = NULL;
5616ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
5620896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
563f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   if (!psc->base.driScreen)
5640896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
5650896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
5660896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (shareList) {
567a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg      pcp_shared = (struct dri_context *) shareList->driContext;
5680896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      shared = pcp_shared->driContext;
5690896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
5700896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
5710896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pcp = Xmalloc(sizeof *pcp);
5720896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (pcp == NULL)
5730896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
5740896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
57531819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   memset(pcp, 0, sizeof *pcp);
5766ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   if (!glx_context_init(&pcp->base, &psc->base, &config->base)) {
57731819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg      Xfree(pcp);
57831819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg      return NULL;
57931819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   }
58031819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg
581f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   if (!XF86DRICreateContextWithConfig(psc->base.dpy, psc->base.scr,
5826ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg                                       config->base.visualID,
5830896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                       &pcp->hwContextID, &hwContext)) {
5840896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      Xfree(pcp);
5850896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
5860896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
5870896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
5880896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pcp->driContext =
58970887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg      (*psc->legacy->createNewContext) (psc->driScreen,
5900896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                        config->driConfig,
5910896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                        renderType, shared, hwContext, pcp);
5920896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (pcp->driContext == NULL) {
593f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      XF86DRIDestroyContext(psc->base.dpy, psc->base.scr, pcp->hwContextID);
5940896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      Xfree(pcp);
5950896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
5960896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
5970896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
59831819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   pcp->base.vtable = &dri_context_vtable;
59931819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   pcp->base.driContext = &pcp->dri_vtable;
60031819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   pcp->dri_vtable.bindContext = driBindContext;
60131819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   pcp->dri_vtable.unbindContext = driUnbindContext;
6020896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
6030896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return &pcp->base;
60453dc86363665b9b22f042c5d950b7de0ed02b4c8Kristian Høgsberg}
60553dc86363665b9b22f042c5d950b7de0ed02b4c8Kristian Høgsberg
6060896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
6070896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófdriDestroyDrawable(__GLXDRIdrawable * pdraw)
6089110425c72e45f618131b559eba883fd6c5536b4Kristian Høgsberg{
609f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) pdraw->psc;
610271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
6119110425c72e45f618131b559eba883fd6c5536b4Kristian Høgsberg
612271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   (*psc->core->destroyDrawable) (pdp->driDrawable);
613f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   XF86DRIDestroyDrawable(psc->base.dpy, psc->base.scr, pdraw->drawable);
6140896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(pdraw);
6159110425c72e45f618131b559eba883fd6c5536b4Kristian Høgsberg}
61620b9230ce1b96ca246850a8088caeffc3f391a0cKristian Høgsberg
6170896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic __GLXDRIdrawable *
618f972115d33e391499e049b83a1559959f2ca9f72Kristian HøgsbergdriCreateDrawable(__GLXscreenConfigs *base,
6190896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                  XID xDrawable,
6206ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg                  GLXDrawable drawable, struct glx_config *config_base)
62120b9230ce1b96ca246850a8088caeffc3f391a0cKristian Høgsberg{
6220896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   drm_drawable_t hwDrawable;
6230896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   void *empty_attribute_list = NULL;
6246ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
625f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) base;
626271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp;
6270896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
6280896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* Old dri can't handle GLX 1.3+ drawable constructors. */
6290896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (xDrawable != drawable)
6300896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
6310896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
632271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   pdp = Xmalloc(sizeof *pdp);
633271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   if (!pdp)
6340896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
6350896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
6366393a33944ec9983426cecd5f6c9f05ac089e1aeKristian Høgsberg   memset(pdp, 0, sizeof *pdp);
637271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   pdp->base.drawable = drawable;
638271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   pdp->base.psc = &psc->base;
6390896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
640f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   if (!XF86DRICreateDrawable(psc->base.dpy, psc->base.scr,
641f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg			      drawable, &hwDrawable)) {
642271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg      Xfree(pdp);
6430896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
644e0556657526a7fe53d6e17cf70ffa6a8ee35e0a9Vinson Lee   }
6450896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
6460896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* Create a new drawable */
647271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   pdp->driDrawable =
64870887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg      (*psc->legacy->createNewDrawable) (psc->driScreen,
6490896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                         config->driConfig,
6500896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                         hwDrawable,
6510896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                         GLX_WINDOW_BIT,
652271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg                                         empty_attribute_list, pdp);
6530896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
654271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   if (!pdp->driDrawable) {
655f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      XF86DRIDestroyDrawable(psc->base.dpy, psc->base.scr, drawable);
656271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg      Xfree(pdp);
6570896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
6580896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
6590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
660271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   pdp->base.destroyDrawable = driDestroyDrawable;
6610896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
662271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   return &pdp->base;
66320b9230ce1b96ca246850a8088caeffc3f391a0cKristian Høgsberg}
66420b9230ce1b96ca246850a8088caeffc3f391a0cKristian Høgsberg
665daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnesstatic int64_t
666daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse BarnesdriSwapBuffers(__GLXDRIdrawable * pdraw, int64_t unused1, int64_t unused2,
667daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes	       int64_t unused3)
668f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg{
669f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) pdraw->psc;
670271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
671f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg
672271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   (*psc->core->swapBuffers) (pdp->driDrawable);
673daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes   return 0;
674f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg}
675f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg
6760896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
6770896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófdriCopySubBuffer(__GLXDRIdrawable * pdraw,
6780896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                 int x, int y, int width, int height)
6794830809524b20e517e949151957512b14d7e679aKristian Høgsberg{
680271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
681a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) pdp->base.psc;
682271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg
683a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg   (*psc->driCopySubBuffer->copySubBuffer) (pdp->driDrawable,
684a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg					    x, y, width, height);
6854830809524b20e517e949151957512b14d7e679aKristian Høgsberg}
6864830809524b20e517e949151957512b14d7e679aKristian Høgsberg
6870896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
688f972115d33e391499e049b83a1559959f2ca9f72Kristian HøgsbergdriDestroyScreen(__GLXscreenConfigs *base)
689a1ea6f6198d80f716936a308cfab235f18a014e1Kristian Høgsberg{
690f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) base;
691f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg
6920896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* Free the direct rendering per screen data */
69370887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   if (psc->driScreen)
69470887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg      (*psc->core->destroyScreen) (psc->driScreen);
695bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian Høgsberg   driDestroyConfigs(psc->driver_configs);
69670887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   psc->driScreen = NULL;
6970896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (psc->driver)
6980896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      dlclose(psc->driver);
699a1ea6f6198d80f716936a308cfab235f18a014e1Kristian Høgsberg}
700a1ea6f6198d80f716936a308cfab235f18a014e1Kristian Høgsberg
701089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg#ifdef __DRI_SWAP_BUFFER_COUNTER
702089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
703089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsbergstatic int
704089fc37c6fa158824279e08e3b378ced94d6f803Kristian HøgsbergdriDrawableGetMSC(__GLXscreenConfigs *base, __GLXDRIdrawable *pdraw,
705089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg		   int64_t *ust, int64_t *msc, int64_t *sbc)
706089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg{
707089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) base;
708271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
709089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
710271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   if (pdp && psc->sbc && psc->msc)
711089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      return ( (*psc->msc->getMSC)(psc->driScreen, msc) == 0 &&
712271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg	       (*psc->sbc->getSBC)(pdp->driDrawable, sbc) == 0 &&
713089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg	       __glXGetUST(ust) == 0 );
714089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg}
715089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
716089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsbergstatic int
717089fc37c6fa158824279e08e3b378ced94d6f803Kristian HøgsbergdriWaitForMSC(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
718089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg	       int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
719089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg{
720089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   struct dri_screen *psc = (struct dri_screen *) pdraw->psc;
721271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
722089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
723271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   if (pdp != NULL && psc->msc != NULL) {
724271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg      ret = (*psc->msc->waitForMSC) (pdp->driDrawable, target_msc,
725089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg				     divisor, remainder, msc, sbc);
726089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
727089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      /* __glXGetUST returns zero on success and non-zero on failure.
728089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg       * This function returns True on success and False on failure.
729089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg       */
730089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      return ret == 0 && __glXGetUST(ust) == 0;
731089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   }
732089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg}
733089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
734089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsbergstatic int
735089fc37c6fa158824279e08e3b378ced94d6f803Kristian HøgsbergdriWaitForSBC(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
736089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg	       int64_t *msc, int64_t *sbc)
737089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg{
738271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
739271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg
740271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   if (pdp != NULL && psc->sbc != NULL) {
741089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      ret =
742271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg         (*psc->sbc->waitForSBC) (pdp->driDrawable, target_sbc, msc, sbc);
743089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
744089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      /* __glXGetUST returns zero on success and non-zero on failure.
745089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg       * This function returns True on success and False on failure.
746089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg       */
747089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      return ((ret == 0) && (__glXGetUST(ust) == 0));
748089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   }
749089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
750271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   return DRI2WaitSBC(pdp->base.psc->dpy,
751271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg		      pdp->base.xDrawable, target_sbc, ust, msc, sbc);
752089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg}
753089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
754089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg#endif
755089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
756089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsbergstatic int
757089fc37c6fa158824279e08e3b378ced94d6f803Kristian HøgsbergdriSetSwapInterval(__GLXDRIdrawable *pdraw, int interval)
758089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg{
759089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   GLXContext gc = __glXGetCurrentContext();
760271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
761089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   struct dri_screen *psc;
762089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
763089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   if (gc->driContext) {
764089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      psc = (struct dri_screen *) pdraw->psc;
765089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
766089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      if (psc->swapControl != NULL && pdraw != NULL) {
767271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg	 psc->swapControl->setSwapInterval(pdp->driDrawable, interval);
768089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg	 return 0;
769089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      }
770089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   }
771089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
772089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   return GLX_BAD_CONTEXT;
773089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg}
774089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
775089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsbergstatic int
776089fc37c6fa158824279e08e3b378ced94d6f803Kristian HøgsbergdriGetSwapInterval(__GLXDRIdrawable *pdraw)
777089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg{
778089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   GLXContext gc = __glXGetCurrentContext();
779271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
780089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   struct dri_screen *psc;
781089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
782089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   if (gc != NULL && gc->driContext) {
783089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      psc = (struct dri_screen *) pdraw->psc;
784089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
785089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      if (psc->swapControl != NULL && pdraw != NULL) {
786271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg	 return psc->swapControl->getSwapInterval(pdp->driDrawable);
787089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      }
788089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   }
789089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
790089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   return 0;
791089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg}
792089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
793089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg/* Bind DRI1 specific extensions */
794089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsbergstatic void
795089fc37c6fa158824279e08e3b378ced94d6f803Kristian HøgsbergdriBindExtensions(struct dri_screen *psc, const __DRIextension **extensions)
796089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg{
797089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   int i;
798089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
799089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   for (i = 0; extensions[i]; i++) {
800089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      /* No DRI2 support for swap_control at the moment, since SwapBuffers
801089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg       * is done by the X server */
802089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
803089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg	 psc->swapControl = (__DRIswapControlExtension *) extensions[i];
804089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg	 __glXEnableDirectExtension(&psc->base, "GLX_SGI_swap_control");
805089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg	 __glXEnableDirectExtension(&psc->base, "GLX_MESA_swap_control");
806089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      }
807089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
808089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      if (strcmp(extensions[i]->name, __DRI_MEDIA_STREAM_COUNTER) == 0) {
809089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg         psc->msc = (__DRImediaStreamCounterExtension *) extensions[i];
810089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg         __glXEnableDirectExtension(&psc->base, "GLX_SGI_video_sync");
811089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      }
812089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
813a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg      if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
814a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg	 psc->driCopySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
815a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg	 __glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer");
816a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg      }
817a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg
818a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg      if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
819a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg	 __glXEnableDirectExtension(&psc->base, "GLX_SGI_make_current_read");
820a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg      }
821089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      /* Ignore unknown extensions */
822089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   }
823089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg}
824089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
8256ec39db726beead21d97bf64ddbe1f0b2d2d6ca1Kristian Høgsbergstatic const struct glx_screen_vtable dri_screen_vtable = {
8266ec39db726beead21d97bf64ddbe1f0b2d2d6ca1Kristian Høgsberg   dri_create_context
8276ec39db726beead21d97bf64ddbe1f0b2d2d6ca1Kristian Høgsberg};
8286ec39db726beead21d97bf64ddbe1f0b2d2d6ca1Kristian Høgsberg
829f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsbergstatic __GLXscreenConfigs *
830f972115d33e391499e049b83a1559959f2ca9f72Kristian HøgsbergdriCreateScreen(int screen, __GLXdisplayPrivate *priv)
831890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg{
832a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri_display *pdp;
8330896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __GLXDRIscreen *psp;
8340896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   const __DRIextension **extensions;
835f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   struct dri_screen *psc;
8360896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   char *driverName;
8370896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int i;
8380896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
839f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   psc = Xcalloc(1, sizeof *psc);
840f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   if (psc == NULL)
8410896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
8420896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
843f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   memset(psc, 0, sizeof *psc);
844f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   if (!glx_screen_init(&psc->base, screen, priv))
845f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg       return NULL;
846f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg
8470896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!driGetDriverName(priv->dpy, screen, &driverName)) {
848f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      Xfree(psc);
8490896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
8500896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
8510896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
8520896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   psc->driver = driOpenDriver(driverName);
8530896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(driverName);
8540896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (psc->driver == NULL) {
855f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      Xfree(psc);
8560896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
8570896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
8580896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
8590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
8600896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (extensions == NULL) {
8610896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
862f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      Xfree(psc);
8630896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
8640896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
8650896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
8660896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   for (i = 0; extensions[i]; i++) {
8670896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
868daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes	 psc->core = (__DRIcoreExtension *) extensions[i];
8690896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0)
870daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes	 psc->legacy = (__DRIlegacyExtension *) extensions[i];
8710896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
8720896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
8730896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (psc->core == NULL || psc->legacy == NULL) {
874f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      Xfree(psc);
8750896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
8760896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
8770896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
878a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   pdp = (struct dri_display *) priv->driDisplay;
87970887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   psc->driScreen =
880f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      CallCreateNewScreen(psc->base.dpy, screen, psc, pdp);
88170887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   if (psc->driScreen == NULL) {
8820896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      dlclose(psc->driver);
883f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      Xfree(psc);
8840896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
8850896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
8860896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
88770887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   extensions = psc->core->getExtensions(psc->driScreen);
888089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   driBindExtensions(psc, extensions);
889daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes
8906ec39db726beead21d97bf64ddbe1f0b2d2d6ca1Kristian Høgsberg   psc->base.vtable = &dri_screen_vtable;
89170887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   psp = &psc->vtable;
892f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   psc->base.driScreen = psp;
893a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg   if (psc->driCopySubBuffer)
8940896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      psp->copySubBuffer = driCopySubBuffer;
8950896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
8960896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   psp->destroyScreen = driDestroyScreen;
8970896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   psp->createDrawable = driCreateDrawable;
8980896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   psp->swapBuffers = driSwapBuffers;
8990896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
900089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg#ifdef __DRI_SWAP_BUFFER_COUNTER
901089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   psp->getDrawableMSC = driDrawableGetMSC;
902089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   psp->waitForMSC = driWaitForMSC;
903089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   psp->waitForSBC = driWaitForSBC;
904089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg#endif
905089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
906089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   psp->setSwapInterval = driSetSwapInterval;
907089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   psp->getSwapInterval = driGetSwapInterval;
908089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
909f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   return &psc->base;
910890d44e54f2c800f066f59eb074ad09e14d54483Kristian Høgsberg}
911cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
9128628b382e4ac492d829fe720219187b758add003Michel Dänzer/* Called from __glXFreeDisplayPrivate.
913cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson */
9140896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
9150896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófdriDestroyDisplay(__GLXDRIdisplay * dpy)
916cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson{
9170896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(dpy);
918cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}
919cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
920cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson/*
921cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * Allocate, initialize and return a __DRIdisplayPrivate object.
922cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * This is called from __glXInitialize() when we are given a new
923cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson * display pointer.
924cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson */
9250896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf_X_HIDDEN __GLXDRIdisplay *
9260896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófdriCreateDisplay(Display * dpy)
927cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson{
928a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri_display *pdpyp;
9290896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int eventBase, errorBase;
9300896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int major, minor, patch;
931cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
9320896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!XF86DRIQueryExtension(dpy, &eventBase, &errorBase)) {
9330896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
9340896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
935cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
9360896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!XF86DRIQueryVersion(dpy, &major, &minor, &patch)) {
9370896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
9380896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
939cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
9400896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdpyp = Xmalloc(sizeof *pdpyp);
9410896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!pdpyp) {
9420896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
9430896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
944cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
9450896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdpyp->driMajor = major;
9460896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdpyp->driMinor = minor;
9470896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdpyp->driPatch = patch;
948cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
9490896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdpyp->base.destroyDisplay = driDestroyDisplay;
9500896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdpyp->base.createScreen = driCreateScreen;
951cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
9520896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return &pdpyp->base;
953cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson}
954cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson
955cb3610e37c4c0a40520441b8515d044dabcc8854Adam Jackson#endif /* GLX_DIRECT_RENDERING */
956