1e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg/*
2e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * Copyright © 2008 Red Hat, Inc.
3e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg *
4e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * Permission is hereby granted, free of charge, to any person obtaining a
5e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * copy of this software and associated documentation files (the "Soft-
6e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * ware"), to deal in the Software without restriction, including without
7e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * limitation the rights to use, copy, modify, merge, publish, distribute,
8e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * and/or sell copies of the Software, and to permit persons to whom the
9e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * Software is furnished to do so, provided that the above copyright
10e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * notice(s) and this permission notice appear in all copies of the Soft-
11e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * ware and that both the above copyright notice(s) and this permission
12e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * notice appear in supporting documentation.
13e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg *
14e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
17e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
18e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
19e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
22e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * MANCE OF THIS SOFTWARE.
23e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg *
24e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * Except as contained in this notice, the name of a copyright holder shall
25e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * not be used in advertising or otherwise to promote the sale, use or
26e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * other dealings in this Software without prior written authorization of
27e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * the copyright holder.
28e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg *
29e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * Authors:
30e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg *   Kristian Høgsberg (krh@redhat.com)
31e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg */
32e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
3380b280db883edc9550484dba03bd5c124b6a9bf9Jeremy Huddleston#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
34e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
356497d50924230e6b96929c8da0c2bd7287b70d8aAlan Hourihane#include <X11/Xlib.h>
36e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg#include <X11/extensions/Xfixes.h>
37a35f6bb207efe3c959bbd16a37f2049e5aceeea9Jesse Barnes#include "glapi.h"
38e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg#include "glxclient.h"
398b0b5ace4871847f7d8608e0ce6f67b7c5731ea7Francisco Jerez#include <X11/extensions/dri2proto.h>
40e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg#include "xf86dri.h"
41e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg#include <dlfcn.h>
424830809524b20e517e949151957512b14d7e679aKristian Høgsberg#include <fcntl.h>
434830809524b20e517e949151957512b14d7e679aKristian Høgsberg#include <unistd.h>
44e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg#include <sys/types.h>
45e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg#include <sys/mman.h>
46f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák#include <sys/time.h>
47e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg#include "xf86drm.h"
48e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg#include "dri2.h"
49079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#include "dri_common.h"
5045e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes
5145e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes/* From xmlpool/options.h, user exposed so should be stable */
5245e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes#define DRI_CONF_VBLANK_NEVER 0
5345e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes#define DRI_CONF_VBLANK_DEF_INTERVAL_0 1
5445e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes#define DRI_CONF_VBLANK_DEF_INTERVAL_1 2
5545e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes#define DRI_CONF_VBLANK_ALWAYS_SYNC 3
56e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
57dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick#undef DRI2_MINOR
58dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick#define DRI2_MINOR 1
59dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick
60a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsbergstruct dri2_display
610896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf{
620896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __GLXDRIdisplay base;
63e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
640896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /*
65e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    ** XFree86-DRI version information
66e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    */
670896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int driMajor;
680896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int driMinor;
690896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int driPatch;
70a35f6bb207efe3c959bbd16a37f2049e5aceeea9Jesse Barnes   int swapAvailable;
7161d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez   int invalidateAvailable;
724258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg
733750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg   __glxHashTable *dri2Hash;
743750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg
754258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg   const __DRIextension *loader_extensions[4];
76e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg};
77e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
78f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsbergstruct dri2_screen {
7966fc35cde9ed68a09920ad6a28de794dd1d3aa8cKristian Høgsberg   struct glx_screen base;
80f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg
8170887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   __DRIscreen *driScreen;
8270887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   __GLXDRIscreen vtable;
83f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   const __DRIdri2Extension *dri2;
84f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   const __DRIcoreExtension *core;
859e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg
869e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   const __DRI2flushExtension *f;
879e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   const __DRI2configQueryExtension *config;
889e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   const __DRItexBufferExtension *texBuffer;
89511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom   const __DRI2throttleExtension *throttle;
90bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian Høgsberg   const __DRIconfig **driver_configs;
919e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg
92f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   void *driver;
93f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   int fd;
94f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák
95f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák   Bool show_fps;
96f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg};
97f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg
98a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsbergstruct dri2_context
990896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf{
100c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian Høgsberg   struct glx_context base;
1010896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __DRIcontext *driContext;
102e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg};
103e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
104a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsbergstruct dri2_drawable
1050896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf{
1060896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __GLXDRIdrawable base;
107271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   __DRIdrawable *driDrawable;
1080896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __DRIbuffer buffers[5];
1090896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int bufferCount;
1100896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int width, height;
1110896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int have_back;
1120896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int have_fake_front;
113efc82e7c703f9160cfdbe6d97e166ca6f5e75d86Jesse Barnes   int swap_interval;
114f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák
115f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák   double previous_time;
116f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák   unsigned frames;
117f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg};
118f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg
11931819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsbergstatic const struct glx_context_vtable dri2_context_vtable;
12031819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg
1210896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
122c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian Høgsbergdri2_destroy_context(struct glx_context *context)
123e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
124a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri2_context *pcp = (struct dri2_context *) context;
12531819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   struct dri2_screen *psc = (struct dri2_screen *) context->psc;
126e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
127441344ba7ed2a1d162ee33ac4bac4bf645188cebKristian Høgsberg   driReleaseDrawables(&pcp->base);
128441344ba7ed2a1d162ee33ac4bac4bf645188cebKristian Høgsberg
129c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg   if (context->extensions)
130c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg      XFree((char *) context->extensions);
131c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg
132f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   (*psc->core->destroyContext) (pcp->driContext);
133e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
1340896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(pcp);
135e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
136e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
1370896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic Bool
138c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsbergdri2_bind_context(struct glx_context *context, struct glx_context *old,
139c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg		  GLXDrawable draw, GLXDrawable read)
140e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
141a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri2_context *pcp = (struct dri2_context *) context;
14231819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   struct dri2_screen *psc = (struct dri2_screen *) pcp->base.psc;
143c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   struct dri2_drawable *pdraw, *pread;
14486a1938aa56c02d7da137b09e579d24d7da50d9eKristian Høgsberg   struct dri2_display *pdp;
145e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
146c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   pdraw = (struct dri2_drawable *) driFetchDrawable(context, draw);
147c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   pread = (struct dri2_drawable *) driFetchDrawable(context, read);
148c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg
149bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin   driReleaseDrawables(&pcp->base);
150bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin
151c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   if (pdraw == NULL || pread == NULL)
152c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg      return GLXBadDrawable;
153c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg
15486a1938aa56c02d7da137b09e579d24d7da50d9eKristian Høgsberg   if (!(*psc->core->bindContext) (pcp->driContext,
15586a1938aa56c02d7da137b09e579d24d7da50d9eKristian Høgsberg				   pdraw->driDrawable, pread->driDrawable))
15686a1938aa56c02d7da137b09e579d24d7da50d9eKristian Høgsberg      return GLXBadContext;
15786a1938aa56c02d7da137b09e579d24d7da50d9eKristian Høgsberg
15886a1938aa56c02d7da137b09e579d24d7da50d9eKristian Høgsberg   /* If the server doesn't send invalidate events, we may miss a
15986a1938aa56c02d7da137b09e579d24d7da50d9eKristian Høgsberg    * resize before the rendering starts.  Invalidate the buffers now
16086a1938aa56c02d7da137b09e579d24d7da50d9eKristian Høgsberg    * so the driver will recheck before rendering starts. */
16186a1938aa56c02d7da137b09e579d24d7da50d9eKristian Høgsberg   pdp = (struct dri2_display *) psc->base.display;
16286a1938aa56c02d7da137b09e579d24d7da50d9eKristian Høgsberg   if (!pdp->invalidateAvailable) {
16386a1938aa56c02d7da137b09e579d24d7da50d9eKristian Høgsberg      dri2InvalidateBuffers(psc->base.dpy, pdraw->base.xDrawable);
16486a1938aa56c02d7da137b09e579d24d7da50d9eKristian Høgsberg      if (pread != pdraw)
16586a1938aa56c02d7da137b09e579d24d7da50d9eKristian Høgsberg	 dri2InvalidateBuffers(psc->base.dpy, pread->base.xDrawable);
16686a1938aa56c02d7da137b09e579d24d7da50d9eKristian Høgsberg   }
167c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg
16886a1938aa56c02d7da137b09e579d24d7da50d9eKristian Høgsberg   return Success;
169e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
170e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
1710896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
172c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsbergdri2_unbind_context(struct glx_context *context, struct glx_context *new)
173e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
174a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri2_context *pcp = (struct dri2_context *) context;
17531819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   struct dri2_screen *psc = (struct dri2_screen *) pcp->base.psc;
176e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
177f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   (*psc->core->unbindContext) (pcp->driContext);
178e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
179e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
180c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian Høgsbergstatic struct glx_context *
18166fc35cde9ed68a09920ad6a28de794dd1d3aa8cKristian Høgsbergdri2_create_context(struct glx_screen *base,
1826ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg		    struct glx_config *config_base,
183c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian Høgsberg		    struct glx_context *shareList, int renderType)
184e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
185a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri2_context *pcp, *pcp_shared;
186f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   struct dri2_screen *psc = (struct dri2_screen *) base;
1876ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
1880896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __DRIcontext *shared = NULL;
1890896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1900896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (shareList) {
191c4a8c54c3bb31547cba57702ffea99293afef522Ian Romanick      /* If the shareList context is not a DRI2 context, we cannot possibly
192c4a8c54c3bb31547cba57702ffea99293afef522Ian Romanick       * create a DRI2 context that shares it.
193c4a8c54c3bb31547cba57702ffea99293afef522Ian Romanick       */
194c4a8c54c3bb31547cba57702ffea99293afef522Ian Romanick      if (shareList->vtable->destroy != dri2_destroy_context) {
195c4a8c54c3bb31547cba57702ffea99293afef522Ian Romanick	 return NULL;
196c4a8c54c3bb31547cba57702ffea99293afef522Ian Romanick      }
197c4a8c54c3bb31547cba57702ffea99293afef522Ian Romanick
198af6a2aede696ad3c45798d6c28aa04e8f5035e6eEric Anholt      pcp_shared = (struct dri2_context *) shareList;
1990896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      shared = pcp_shared->driContext;
2000896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
2010896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2020896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pcp = Xmalloc(sizeof *pcp);
2030896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (pcp == NULL)
2040896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
2050896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
20631819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   memset(pcp, 0, sizeof *pcp);
2076ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   if (!glx_context_init(&pcp->base, &psc->base, &config->base)) {
20831819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg      Xfree(pcp);
20931819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg      return NULL;
21031819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   }
21131819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg
2120896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pcp->driContext =
21370887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg      (*psc->dri2->createNewContext) (psc->driScreen,
2140896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                      config->driConfig, shared, pcp);
2150896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2160896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (pcp->driContext == NULL) {
2170896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      Xfree(pcp);
2180896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
2190896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
2200896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
22131819830b66a49f1b62e09090cc65aefc657aeb8Kristian Høgsberg   pcp->base.vtable = &dri2_context_vtable;
2220896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2230896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return &pcp->base;
224e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
225e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
22648ffc6a1553083280c217640629cc6ebed1bf982Ian Romanickstatic struct glx_context *
22748ffc6a1553083280c217640629cc6ebed1bf982Ian Romanickdri2_create_context_attribs(struct glx_screen *base,
22848ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick			    struct glx_config *config_base,
22948ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick			    struct glx_context *shareList,
23048ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick			    unsigned num_attribs,
23148ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick			    const uint32_t *attribs,
23248ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick			    unsigned *error)
23348ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick{
23448ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   struct dri2_context *pcp = NULL;
23548ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   struct dri2_context *pcp_shared = NULL;
23648ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   struct dri2_screen *psc = (struct dri2_screen *) base;
23748ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
23848ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   __DRIcontext *shared = NULL;
23948ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick
24048ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   uint32_t minor_ver = 1;
24148ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   uint32_t major_ver = 2;
24248ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   uint32_t flags = 0;
24348ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   unsigned api;
24468bccc40f55aee7f4af8eb64b15a95f0b49d6a17Kenneth Graunke   int reset = __DRI_CTX_RESET_NO_NOTIFICATION;
245a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick   uint32_t ctx_attribs[2 * 5];
24648ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   unsigned num_ctx_attribs = 0;
24748ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick
24848ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   if (psc->dri2->base.version < 3) {
24948ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick      *error = __DRI_CTX_ERROR_NO_MEMORY;
25048ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick      goto error_exit;
25148ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   }
25248ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick
25348ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   /* Remap the GLX tokens to DRI2 tokens.
25448ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick    */
25548ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   if (!dri2_convert_glx_attribs(num_attribs, attribs,
256a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick				 &major_ver, &minor_ver, &flags, &api, &reset,
257a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick                                 error))
25848ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick      goto error_exit;
25948ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick
26048ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   if (shareList) {
26148ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick      pcp_shared = (struct dri2_context *) shareList;
26248ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick      shared = pcp_shared->driContext;
26348ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   }
26448ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick
26548ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   pcp = Xmalloc(sizeof *pcp);
26648ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   if (pcp == NULL) {
26748ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick      *error = __DRI_CTX_ERROR_NO_MEMORY;
26848ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick      goto error_exit;
26948ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   }
27048ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick
27148ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   memset(pcp, 0, sizeof *pcp);
27248ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   if (!glx_context_init(&pcp->base, &psc->base, &config->base))
27348ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick      goto error_exit;
27448ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick
27548ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_MAJOR_VERSION;
27648ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   ctx_attribs[num_ctx_attribs++] = major_ver;
27748ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_MINOR_VERSION;
27848ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   ctx_attribs[num_ctx_attribs++] = minor_ver;
27948ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick
280a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick   /* Only send a value when the non-default value is requested.  By doing
281a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick    * this we don't have to check the driver's DRI2 version before sending the
282a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick    * default value.
283a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick    */
284a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick   if (reset != __DRI_CTX_RESET_NO_NOTIFICATION) {
285a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick      ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_RESET_STRATEGY;
286a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick      ctx_attribs[num_ctx_attribs++] = reset;
287a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick   }
288a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick
28948ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   if (flags != 0) {
29048ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick      ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_FLAGS;
29148ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick
29248ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick      /* The current __DRI_CTX_FLAG_* values are identical to the
29348ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick       * GLX_CONTEXT_*_BIT values.
29448ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick       */
29548ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick      ctx_attribs[num_ctx_attribs++] = flags;
29648ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   }
29748ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick
29848ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   pcp->driContext =
29948ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick      (*psc->dri2->createContextAttribs) (psc->driScreen,
30048ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick					  api,
30148ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick					  config->driConfig,
30248ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick					  shared,
30348ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick					  num_ctx_attribs / 2,
30448ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick					  ctx_attribs,
30548ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick					  error,
30648ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick					  pcp);
30748ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick
30848ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   if (pcp->driContext == NULL)
30948ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick      goto error_exit;
31048ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick
31148ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   pcp->base.vtable = &dri2_context_vtable;
31248ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick
31348ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   return &pcp->base;
31448ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick
31548ffc6a1553083280c217640629cc6ebed1bf982Ian Romanickerror_exit:
31648ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   if (pcp != NULL)
31748ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick      Xfree(pcp);
31848ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick
31948ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   return NULL;
32048ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick}
32148ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick
3220896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
323271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsbergdri2DestroyDrawable(__GLXDRIdrawable *base)
324e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
325271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri2_screen *psc = (struct dri2_screen *) base->psc;
326271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri2_drawable *pdraw = (struct dri2_drawable *) base;
327c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian Høgsberg   struct glx_display *dpyPriv = psc->base.display;
328037755122e9011c768e5caa4d4cb83aba783d3e9Kristian Høgsberg   struct dri2_display *pdp = (struct dri2_display *)dpyPriv->dri2Display;
3293750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg
330271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   __glxHashDelete(pdp->dri2Hash, pdraw->base.xDrawable);
331f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   (*psc->core->destroyDrawable) (pdraw->driDrawable);
3324ebf07a426771b62123e5fcb5a8be0de24037af1Kristian Høgsberg
3334ebf07a426771b62123e5fcb5a8be0de24037af1Kristian Høgsberg   /* If it's a GLX 1.3 drawables, we can destroy the DRI2 drawable
3344ebf07a426771b62123e5fcb5a8be0de24037af1Kristian Høgsberg    * now, as the application explicitly asked to destroy the GLX
3354ebf07a426771b62123e5fcb5a8be0de24037af1Kristian Høgsberg    * drawable.  Otherwise, for legacy drawables, we let the DRI2
3364ebf07a426771b62123e5fcb5a8be0de24037af1Kristian Høgsberg    * drawable linger on the server, since there's no good way of
3374ebf07a426771b62123e5fcb5a8be0de24037af1Kristian Høgsberg    * knowing when the application is done with it.  The server will
3384ebf07a426771b62123e5fcb5a8be0de24037af1Kristian Høgsberg    * destroy the DRI2 drawable when it destroys the X drawable or the
3394ebf07a426771b62123e5fcb5a8be0de24037af1Kristian Høgsberg    * client exits anyway. */
3404ebf07a426771b62123e5fcb5a8be0de24037af1Kristian Høgsberg   if (pdraw->base.xDrawable != pdraw->base.drawable)
3414ebf07a426771b62123e5fcb5a8be0de24037af1Kristian Høgsberg      DRI2DestroyDrawable(psc->base.dpy, pdraw->base.xDrawable);
3424ebf07a426771b62123e5fcb5a8be0de24037af1Kristian Høgsberg
3430896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(pdraw);
344e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
345e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
3460896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic __GLXDRIdrawable *
34766fc35cde9ed68a09920ad6a28de794dd1d3aa8cKristian Høgsbergdri2CreateDrawable(struct glx_screen *base, XID xDrawable,
3486ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg		   GLXDrawable drawable, struct glx_config *config_base)
349e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
350a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri2_drawable *pdraw;
351f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   struct dri2_screen *psc = (struct dri2_screen *) base;
3526ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
353c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian Høgsberg   struct glx_display *dpyPriv;
354a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri2_display *pdp;
35545e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1;
356e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
3570896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdraw = Xmalloc(sizeof(*pdraw));
3580896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!pdraw)
3590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
360e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
3616393a33944ec9983426cecd5f6c9f05ac089e1aeKristian Høgsberg   memset(pdraw, 0, sizeof *pdraw);
3620896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdraw->base.destroyDrawable = dri2DestroyDrawable;
3630896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdraw->base.xDrawable = xDrawable;
3640896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdraw->base.drawable = drawable;
365f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   pdraw->base.psc = &psc->base;
3660896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdraw->bufferCount = 0;
36745e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   pdraw->swap_interval = 1; /* default may be overridden below */
368d20fce057ee94fc3441c01a9e54cb5e19f7ddfd3Pierre Willenbrock   pdraw->have_back = 0;
36945e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes
3709e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   if (psc->config)
37170887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg      psc->config->configQueryi(psc->driScreen,
3729e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg				"vblank_mode", &vblank_mode);
37345e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes
37445e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   switch (vblank_mode) {
37545e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   case DRI_CONF_VBLANK_NEVER:
37645e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   case DRI_CONF_VBLANK_DEF_INTERVAL_0:
37745e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes      pdraw->swap_interval = 0;
37845e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes      break;
37945e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   case DRI_CONF_VBLANK_DEF_INTERVAL_1:
38045e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   case DRI_CONF_VBLANK_ALWAYS_SYNC:
38145e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   default:
38245e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes      pdraw->swap_interval = 1;
38345e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes      break;
38445e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   }
385e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
386f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   DRI2CreateDrawable(psc->base.dpy, xDrawable);
387e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
388f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   dpyPriv = __glXInitialize(psc->base.dpy);
389a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   pdp = (struct dri2_display *)dpyPriv->dri2Display;;
3900896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* Create a new drawable */
391271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   pdraw->driDrawable =
39270887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg      (*psc->dri2->createNewDrawable) (psc->driScreen,
3930896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                       config->driConfig, pdraw);
394f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg
395271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   if (!pdraw->driDrawable) {
396f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      DRI2DestroyDrawable(psc->base.dpy, xDrawable);
3970896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      Xfree(pdraw);
3980896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
3990896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
400e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
4013750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg   if (__glxHashInsert(pdp->dri2Hash, xDrawable, pdraw)) {
402271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg      (*psc->core->destroyDrawable) (pdraw->driDrawable);
403f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      DRI2DestroyDrawable(psc->base.dpy, xDrawable);
4043750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg      Xfree(pdraw);
4053750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg      return None;
4063750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg   }
4073750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg
4083750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg
409c37e275e778e8c944e3dfad159b1eb94c601af60Michel Dänzer#ifdef X_DRI2SwapInterval
410385e2896ebf54ac0b016132fe513f21a5b67ba4fJesse Barnes   /*
411385e2896ebf54ac0b016132fe513f21a5b67ba4fJesse Barnes    * Make sure server has the same swap interval we do for the new
412385e2896ebf54ac0b016132fe513f21a5b67ba4fJesse Barnes    * drawable.
413385e2896ebf54ac0b016132fe513f21a5b67ba4fJesse Barnes    */
4140a18cdb0ed2f4b747688f653d9947d174fae77ffJesse Barnes   if (pdp->swapAvailable)
415f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      DRI2SwapInterval(psc->base.dpy, xDrawable, pdraw->swap_interval);
416c37e275e778e8c944e3dfad159b1eb94c601af60Michel Dänzer#endif
4170a18cdb0ed2f4b747688f653d9947d174fae77ffJesse Barnes
4180896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return &pdraw->base;
419f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg}
420f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg
42107c6d94cd7272524ef06b2a787667e5d626137d2Michel Dänzer#ifdef X_DRI2GetMSC
42207c6d94cd7272524ef06b2a787667e5d626137d2Michel Dänzer
423daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnesstatic int
42466fc35cde9ed68a09920ad6a28de794dd1d3aa8cKristian Høgsbergdri2DrawableGetMSC(struct glx_screen *psc, __GLXDRIdrawable *pdraw,
425daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes		   int64_t *ust, int64_t *msc, int64_t *sbc)
426daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes{
4278d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   CARD64 dri2_ust, dri2_msc, dri2_sbc;
4288d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   int ret;
4298d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg
4308d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   ret = DRI2GetMSC(psc->dpy, pdraw->xDrawable,
4318d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg		    &dri2_ust, &dri2_msc, &dri2_sbc);
4328d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   *ust = dri2_ust;
4338d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   *msc = dri2_msc;
4348d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   *sbc = dri2_sbc;
4358d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg
4368d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   return ret;
437daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes}
438daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes
43907c6d94cd7272524ef06b2a787667e5d626137d2Michel Dänzer#endif
44007c6d94cd7272524ef06b2a787667e5d626137d2Michel Dänzer
44107c6d94cd7272524ef06b2a787667e5d626137d2Michel Dänzer
44207c6d94cd7272524ef06b2a787667e5d626137d2Michel Dänzer#ifdef X_DRI2WaitMSC
44307c6d94cd7272524ef06b2a787667e5d626137d2Michel Dänzer
444daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnesstatic int
445daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnesdri2WaitForMSC(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
446daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes	       int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
447daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes{
4488d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   CARD64 dri2_ust, dri2_msc, dri2_sbc;
4498d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   int ret;
4508d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg
4518d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   ret = DRI2WaitMSC(pdraw->psc->dpy, pdraw->xDrawable, target_msc, divisor,
4528d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg		     remainder, &dri2_ust, &dri2_msc, &dri2_sbc);
4538d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   *ust = dri2_ust;
4548d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   *msc = dri2_msc;
4558d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   *sbc = dri2_sbc;
4568d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg
4578d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   return ret;
458daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes}
459daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes
460daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnesstatic int
461daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnesdri2WaitForSBC(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
462daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes	       int64_t *msc, int64_t *sbc)
463daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes{
4648d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   CARD64 dri2_ust, dri2_msc, dri2_sbc;
4658d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   int ret;
4668d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg
4678d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   ret = DRI2WaitSBC(pdraw->psc->dpy, pdraw->xDrawable,
4688d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg		     target_sbc, &dri2_ust, &dri2_msc, &dri2_sbc);
4698d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   *ust = dri2_ust;
4708d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   *msc = dri2_msc;
4718d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   *sbc = dri2_sbc;
4728d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg
4738d0228912bfef173139296a96a097f1a6348c963Kristian Høgsberg   return ret;
474daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes}
475daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes
47607c6d94cd7272524ef06b2a787667e5d626137d2Michel Dänzer#endif /* X_DRI2WaitMSC */
47707c6d94cd7272524ef06b2a787667e5d626137d2Michel Dänzer
478511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom/**
479511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom * dri2Throttle - Request driver throttling
480511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom *
481511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom * This function uses the DRI2 throttle extension to give the
482511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom * driver the opportunity to throttle on flush front, copysubbuffer
483511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom * and swapbuffers.
484511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom */
485511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstromstatic void
486511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstromdri2Throttle(struct dri2_screen *psc,
487511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom	     struct dri2_drawable *draw,
488511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom	     enum __DRI2throttleReason reason)
489511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom{
490511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom   if (psc->throttle) {
491511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom      struct glx_context *gc = __glXGetCurrentContext();
492511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom      struct dri2_context *dri2Ctx = (struct dri2_context *)gc;
493511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom      __DRIcontext *ctx =
494511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom	 (dri2Ctx) ? dri2Ctx->driContext : NULL;
495511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom
496511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom      psc->throttle->throttle(ctx, draw->driDrawable, reason);
497511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom   }
498511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom}
499511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom
5000896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
501511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom__dri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y,
502511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom		    int width, int height,
503511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom		    enum __DRI2throttleReason reason)
5044830809524b20e517e949151957512b14d7e679aKristian Høgsberg{
505a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri2_drawable *priv = (struct dri2_drawable *) pdraw;
5069e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   struct dri2_screen *psc = (struct dri2_screen *) pdraw->psc;
5070896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   XRectangle xrect;
5080896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   XserverRegion region;
5094830809524b20e517e949151957512b14d7e679aKristian Høgsberg
5100896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* Check we have the right attachments */
5110896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!priv->have_back)
5120896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return;
51363b51b5cf17ddde09b72a2811296f37b9a4c5ad2Alan Hourihane
5140896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   xrect.x = x;
5150896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   xrect.y = priv->height - y - height;
5160896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   xrect.width = width;
5170896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   xrect.height = height;
5184830809524b20e517e949151957512b14d7e679aKristian Høgsberg
51965562453fba69e862d5e3b381d18db9c40d9353cAlan Hourihane#ifdef __DRI2_FLUSH
5209e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   if (psc->f)
521271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg      (*psc->f->flush) (priv->driDrawable);
52265562453fba69e862d5e3b381d18db9c40d9353cAlan Hourihane#endif
52365562453fba69e862d5e3b381d18db9c40d9353cAlan Hourihane
524511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom   dri2Throttle(psc, priv, reason);
525511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom
5269e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   region = XFixesCreateRegion(psc->base.dpy, &xrect, 1);
5279e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   DRI2CopyRegion(psc->base.dpy, pdraw->xDrawable, region,
5280896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                  DRI2BufferFrontLeft, DRI2BufferBackLeft);
5295ca800e1006555ea1c5dcbbc56c35838c9f04994Eric Anholt
5300896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* Refresh the fake front (if present) after we just damaged the real
5310896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * front.
5320896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    */
533bd3d2724f51a44b7fc814a5bc43d8ddafa8e3cbaMichel Dänzer   if (priv->have_fake_front)
534bd3d2724f51a44b7fc814a5bc43d8ddafa8e3cbaMichel Dänzer      DRI2CopyRegion(psc->base.dpy, pdraw->xDrawable, region,
535bd3d2724f51a44b7fc814a5bc43d8ddafa8e3cbaMichel Dänzer		     DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
536bd3d2724f51a44b7fc814a5bc43d8ddafa8e3cbaMichel Dänzer
5379e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   XFixesDestroyRegion(psc->base.dpy, region);
5384830809524b20e517e949151957512b14d7e679aKristian Høgsberg}
5394830809524b20e517e949151957512b14d7e679aKristian Høgsberg
5400896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
541511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstromdri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y,
542511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom		  int width, int height)
543511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom{
544511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom   __dri2CopySubBuffer(pdraw, x, y, width, height,
545511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom		       __DRI2_THROTTLE_COPYSUBBUFFER);
546511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom}
547511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom
548511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom
549511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstromstatic void
550a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsbergdri2_copy_drawable(struct dri2_drawable *priv, int dest, int src)
55163b51b5cf17ddde09b72a2811296f37b9a4c5ad2Alan Hourihane{
5520896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   XRectangle xrect;
5530896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   XserverRegion region;
5549e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   struct dri2_screen *psc = (struct dri2_screen *) priv->base.psc;
55563b51b5cf17ddde09b72a2811296f37b9a4c5ad2Alan Hourihane
5560896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   xrect.x = 0;
5570896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   xrect.y = 0;
5580896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   xrect.width = priv->width;
5590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   xrect.height = priv->height;
56063b51b5cf17ddde09b72a2811296f37b9a4c5ad2Alan Hourihane
56165562453fba69e862d5e3b381d18db9c40d9353cAlan Hourihane#ifdef __DRI2_FLUSH
562308e13ecd12a2fd894e5b509d5756bffc2035ec6Kristian Høgsberg   if (psc->f)
563271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg      (*psc->f->flush) (priv->driDrawable);
56465562453fba69e862d5e3b381d18db9c40d9353cAlan Hourihane#endif
56565562453fba69e862d5e3b381d18db9c40d9353cAlan Hourihane
5669e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   region = XFixesCreateRegion(psc->base.dpy, &xrect, 1);
5679e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   DRI2CopyRegion(psc->base.dpy, priv->base.xDrawable, region, dest, src);
5689e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   XFixesDestroyRegion(psc->base.dpy, region);
569308e13ecd12a2fd894e5b509d5756bffc2035ec6Kristian Høgsberg
57063b51b5cf17ddde09b72a2811296f37b9a4c5ad2Alan Hourihane}
57163b51b5cf17ddde09b72a2811296f37b9a4c5ad2Alan Hourihane
5720896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
573c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian Høgsbergdri2_wait_x(struct glx_context *gc)
57463b51b5cf17ddde09b72a2811296f37b9a4c5ad2Alan Hourihane{
5757b7845a076c933e096ac511b4184141ba194449aKristian Høgsberg   struct dri2_drawable *priv = (struct dri2_drawable *)
576eeaab2047cfce8a7445fd9f835e737682eb503acKristian Høgsberg      GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
57763b51b5cf17ddde09b72a2811296f37b9a4c5ad2Alan Hourihane
5787b7845a076c933e096ac511b4184141ba194449aKristian Høgsberg   if (priv == NULL || !priv->have_fake_front)
5790896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return;
58063b51b5cf17ddde09b72a2811296f37b9a4c5ad2Alan Hourihane
581308e13ecd12a2fd894e5b509d5756bffc2035ec6Kristian Høgsberg   dri2_copy_drawable(priv, DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
582308e13ecd12a2fd894e5b509d5756bffc2035ec6Kristian Høgsberg}
58363b51b5cf17ddde09b72a2811296f37b9a4c5ad2Alan Hourihane
584308e13ecd12a2fd894e5b509d5756bffc2035ec6Kristian Høgsbergstatic void
585c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian Høgsbergdri2_wait_gl(struct glx_context *gc)
586308e13ecd12a2fd894e5b509d5756bffc2035ec6Kristian Høgsberg{
5877b7845a076c933e096ac511b4184141ba194449aKristian Høgsberg   struct dri2_drawable *priv = (struct dri2_drawable *)
588eeaab2047cfce8a7445fd9f835e737682eb503acKristian Høgsberg      GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
58965562453fba69e862d5e3b381d18db9c40d9353cAlan Hourihane
5907b7845a076c933e096ac511b4184141ba194449aKristian Høgsberg   if (priv == NULL || !priv->have_fake_front)
591308e13ecd12a2fd894e5b509d5756bffc2035ec6Kristian Høgsberg      return;
592308e13ecd12a2fd894e5b509d5756bffc2035ec6Kristian Høgsberg
593308e13ecd12a2fd894e5b509d5756bffc2035ec6Kristian Høgsberg   dri2_copy_drawable(priv, DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
59463b51b5cf17ddde09b72a2811296f37b9a4c5ad2Alan Hourihane}
59563b51b5cf17ddde09b72a2811296f37b9a4c5ad2Alan Hourihane
5960896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
59761d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerezdri2FlushFrontBuffer(__DRIdrawable *driDrawable, void *loaderPrivate)
59882634ee8df7328b9235abd8352d33b0b3d953600Ian Romanick{
599e0496b63ff0d41a36812b78e9062e92590fcdd55Brian Paul   struct glx_display *priv;
600e0496b63ff0d41a36812b78e9062e92590fcdd55Brian Paul   struct dri2_display *pdp;
601e0496b63ff0d41a36812b78e9062e92590fcdd55Brian Paul   struct glx_context *gc;
602a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri2_drawable *pdraw = loaderPrivate;
603511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom   struct dri2_screen *psc;
604e0496b63ff0d41a36812b78e9062e92590fcdd55Brian Paul
6053d3ecb8520ccca0863026a94e7fda9840aff6c0aStéphane Marchesin   if (!pdraw)
6063d3ecb8520ccca0863026a94e7fda9840aff6c0aStéphane Marchesin      return;
6073d3ecb8520ccca0863026a94e7fda9840aff6c0aStéphane Marchesin
6083d3ecb8520ccca0863026a94e7fda9840aff6c0aStéphane Marchesin   if (!pdraw->base.psc)
6093d3ecb8520ccca0863026a94e7fda9840aff6c0aStéphane Marchesin      return;
6103d3ecb8520ccca0863026a94e7fda9840aff6c0aStéphane Marchesin
611511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom   psc = (struct dri2_screen *) pdraw->base.psc;
612511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom
613511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom   priv = __glXInitialize(psc->base.dpy);
614e0496b63ff0d41a36812b78e9062e92590fcdd55Brian Paul   pdp = (struct dri2_display *) priv->dri2Display;
615e0496b63ff0d41a36812b78e9062e92590fcdd55Brian Paul   gc = __glXGetCurrentContext();
6164cd259ca59128ff2712c42ff2d2340b01a3b74a8Kristian Høgsberg
617511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom   dri2Throttle(psc, pdraw, __DRI2_THROTTLE_FLUSHFRONT);
618511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom
6194cd259ca59128ff2712c42ff2d2340b01a3b74a8Kristian Høgsberg   /* Old servers don't send invalidate events */
6204cd259ca59128ff2712c42ff2d2340b01a3b74a8Kristian Høgsberg   if (!pdp->invalidateAvailable)
6219da1c9da139327132dea57b18048a4eb386b6badKristian Høgsberg       dri2InvalidateBuffers(priv->dpy, pdraw->base.xDrawable);
6224cd259ca59128ff2712c42ff2d2340b01a3b74a8Kristian Høgsberg
6239a12a3925a82475fd8f01ba53987581d30dd1128Eric Anholt   dri2_wait_gl(gc);
62482634ee8df7328b9235abd8352d33b0b3d953600Ian Romanick}
62582634ee8df7328b9235abd8352d33b0b3d953600Ian Romanick
62682634ee8df7328b9235abd8352d33b0b3d953600Ian Romanick
6270896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
62866fc35cde9ed68a09920ad6a28de794dd1d3aa8cKristian Høgsbergdri2DestroyScreen(struct glx_screen *base)
629e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
630f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   struct dri2_screen *psc = (struct dri2_screen *) base;
631f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg
6320896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* Free the direct rendering per screen data */
63370887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   (*psc->core->destroyScreen) (psc->driScreen);
634bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian Høgsberg   driDestroyConfigs(psc->driver_configs);
6350896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   close(psc->fd);
636f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   Xfree(psc);
637e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
638e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
639dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick/**
640dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick * Process list of buffer received from the server
641dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick *
642dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick * Processes the list of buffers received in a reply from the server to either
643dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick * \c DRI2GetBuffers or \c DRI2GetBuffersWithFormat.
644dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick */
645dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanickstatic void
646a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsbergprocess_buffers(struct dri2_drawable * pdraw, DRI2Buffer * buffers,
6470896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                unsigned count)
648e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
6490896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int i;
6500896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
6510896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdraw->bufferCount = count;
6520896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdraw->have_fake_front = 0;
6530896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdraw->have_back = 0;
6540896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
6550896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* This assumes the DRI2 buffer attachment tokens matches the
6560896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * __DRIbuffer tokens. */
6570896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   for (i = 0; i < count; i++) {
6580896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      pdraw->buffers[i].attachment = buffers[i].attachment;
6590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      pdraw->buffers[i].name = buffers[i].name;
6600896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      pdraw->buffers[i].pitch = buffers[i].pitch;
6610896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      pdraw->buffers[i].cpp = buffers[i].cpp;
6620896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      pdraw->buffers[i].flags = buffers[i].flags;
6630896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (pdraw->buffers[i].attachment == __DRI_BUFFER_FAKE_FRONT_LEFT)
6640896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         pdraw->have_fake_front = 1;
6650896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (pdraw->buffers[i].attachment == __DRI_BUFFER_BACK_LEFT)
6660896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         pdraw->have_back = 1;
6670896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
66877c7f90ed44748f0e54e894deff1cac63da54cd6Kristian Høgsberg
669dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick}
670dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick
671a0e510320009766faa5ff8c0ed744e87f8095df7Luca Barbieriunsigned dri2GetSwapEventType(Display* dpy, XID drawable)
672a0e510320009766faa5ff8c0ed744e87f8095df7Luca Barbieri{
673a0e510320009766faa5ff8c0ed744e87f8095df7Luca Barbieri      struct glx_display *glx_dpy = __glXInitialize(dpy);
674a0e510320009766faa5ff8c0ed744e87f8095df7Luca Barbieri      __GLXDRIdrawable *pdraw;
675a0e510320009766faa5ff8c0ed744e87f8095df7Luca Barbieri      pdraw = dri2GetGlxDrawableFromXDrawableId(dpy, drawable);
676a0e510320009766faa5ff8c0ed744e87f8095df7Luca Barbieri      if (!pdraw || !(pdraw->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK))
677a0e510320009766faa5ff8c0ed744e87f8095df7Luca Barbieri         return 0;
678a0e510320009766faa5ff8c0ed744e87f8095df7Luca Barbieri      return glx_dpy->codes->first_event + GLX_BufferSwapComplete;
679a0e510320009766faa5ff8c0ed744e87f8095df7Luca Barbieri}
680a0e510320009766faa5ff8c0ed744e87f8095df7Luca Barbieri
681f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšákstatic void show_fps(struct dri2_drawable *draw)
682f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák{
683f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák   struct timeval tv;
684f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák   double current_time;
685f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák
686f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák   gettimeofday(&tv, 0);
687f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák   current_time = (double)tv.tv_sec + (double)tv.tv_usec * 0.000001;
688f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák
689f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák   draw->frames++;
690f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák
691f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák   if (draw->previous_time + 1 < current_time) {
692f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák      if (draw->previous_time) {
693f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák         fprintf(stderr, "libGL: FPS = %.1f\n",
694f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák                 draw->frames / (current_time - draw->previous_time));
695f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák      }
696f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák      draw->frames = 0;
697f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák      draw->previous_time = current_time;
698f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák   }
699f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák}
700f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák
701daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnesstatic int64_t
702daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnesdri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
703daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes		int64_t remainder)
704a35f6bb207efe3c959bbd16a37f2049e5aceeea9Jesse Barnes{
705a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg    struct dri2_drawable *priv = (struct dri2_drawable *) pdraw;
706c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian Høgsberg    struct glx_display *dpyPriv = __glXInitialize(priv->base.psc->dpy);
7079e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg    struct dri2_screen *psc = (struct dri2_screen *) priv->base.psc;
708a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg    struct dri2_display *pdp =
709a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg	(struct dri2_display *)dpyPriv->dri2Display;
710db011c8141d7b01b67f2ded4e634657b92ed707aCarl Worth    CARD64 ret = 0;
711a35f6bb207efe3c959bbd16a37f2049e5aceeea9Jesse Barnes
712d8c443ddde5e9734d60b63b3ec3b5a5ba756d022Michel Dänzer    /* Check we have the right attachments */
713d8c443ddde5e9734d60b63b3ec3b5a5ba756d022Michel Dänzer    if (!priv->have_back)
714d8c443ddde5e9734d60b63b3ec3b5a5ba756d022Michel Dänzer	return ret;
715d8c443ddde5e9734d60b63b3ec3b5a5ba756d022Michel Dänzer
7164a7667b96b7bd7cdffbe929182c15935b74facd2Kristian Høgsberg    /* Old servers can't handle swapbuffers */
7174a7667b96b7bd7cdffbe929182c15935b74facd2Kristian Høgsberg    if (!pdp->swapAvailable) {
718511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom       __dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height,
719511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom			   __DRI2_THROTTLE_SWAPBUFFER);
7204a7667b96b7bd7cdffbe929182c15935b74facd2Kristian Høgsberg    } else {
7214a7667b96b7bd7cdffbe929182c15935b74facd2Kristian Høgsberg#ifdef X_DRI2SwapBuffers
722a35f6bb207efe3c959bbd16a37f2049e5aceeea9Jesse Barnes#ifdef __DRI2_FLUSH
72374cde6505c233f388e902d1daa0e9f186dd012a9Eric Anholt    if (psc->f) {
72474cde6505c233f388e902d1daa0e9f186dd012a9Eric Anholt       struct glx_context *gc = __glXGetCurrentContext();
72574cde6505c233f388e902d1daa0e9f186dd012a9Eric Anholt
72674cde6505c233f388e902d1daa0e9f186dd012a9Eric Anholt       if (gc) {
72774cde6505c233f388e902d1daa0e9f186dd012a9Eric Anholt	  (*psc->f->flush)(priv->driDrawable);
72874cde6505c233f388e902d1daa0e9f186dd012a9Eric Anholt       }
72974cde6505c233f388e902d1daa0e9f186dd012a9Eric Anholt    }
730a35f6bb207efe3c959bbd16a37f2049e5aceeea9Jesse Barnes#endif
731a35f6bb207efe3c959bbd16a37f2049e5aceeea9Jesse Barnes
732511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom       dri2Throttle(psc, priv, __DRI2_THROTTLE_SWAPBUFFER);
733511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom
7344a7667b96b7bd7cdffbe929182c15935b74facd2Kristian Høgsberg       DRI2SwapBuffers(psc->base.dpy, pdraw->xDrawable,
7354a7667b96b7bd7cdffbe929182c15935b74facd2Kristian Høgsberg		       target_msc, divisor, remainder, &ret);
7364a7667b96b7bd7cdffbe929182c15935b74facd2Kristian Høgsberg#endif
7374a7667b96b7bd7cdffbe929182c15935b74facd2Kristian Høgsberg    }
7384a7667b96b7bd7cdffbe929182c15935b74facd2Kristian Høgsberg
739f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák    if (psc->show_fps) {
740f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák       show_fps(priv);
741f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák    }
742f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák
7434cd259ca59128ff2712c42ff2d2340b01a3b74a8Kristian Høgsberg    /* Old servers don't send invalidate events */
7444cd259ca59128ff2712c42ff2d2340b01a3b74a8Kristian Høgsberg    if (!pdp->invalidateAvailable)
7459da1c9da139327132dea57b18048a4eb386b6badKristian Høgsberg       dri2InvalidateBuffers(dpyPriv->dpy, pdraw->xDrawable);
7464cd259ca59128ff2712c42ff2d2340b01a3b74a8Kristian Høgsberg
747daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes    return ret;
748a35f6bb207efe3c959bbd16a37f2049e5aceeea9Jesse Barnes}
749a35f6bb207efe3c959bbd16a37f2049e5aceeea9Jesse Barnes
750dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanickstatic __DRIbuffer *
7510896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófdri2GetBuffers(__DRIdrawable * driDrawable,
7520896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf               int *width, int *height,
7530896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf               unsigned int *attachments, int count,
7540896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf               int *out_count, void *loaderPrivate)
755dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick{
756a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri2_drawable *pdraw = loaderPrivate;
7570896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   DRI2Buffer *buffers;
758dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick
7590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
7600896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                            width, height, attachments, count, out_count);
7610896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (buffers == NULL)
7620896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
763dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick
7640896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdraw->width = *width;
7650896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdraw->height = *height;
7660896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   process_buffers(pdraw, buffers, *out_count);
767dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick
7680896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(buffers);
769dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick
7700896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return pdraw->buffers;
771dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick}
772dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick
773dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanickstatic __DRIbuffer *
7740896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófdri2GetBuffersWithFormat(__DRIdrawable * driDrawable,
7750896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                         int *width, int *height,
7760896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                         unsigned int *attachments, int count,
7770896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                         int *out_count, void *loaderPrivate)
778dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick{
779a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri2_drawable *pdraw = loaderPrivate;
7800896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   DRI2Buffer *buffers;
781dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick
7820896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   buffers = DRI2GetBuffersWithFormat(pdraw->base.psc->dpy,
7830896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                      pdraw->base.xDrawable,
7840896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                      width, height, attachments,
7850896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                                      count, out_count);
7860896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (buffers == NULL)
7870896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
788dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick
7890896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdraw->width = *width;
7900896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdraw->height = *height;
7910896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   process_buffers(pdraw, buffers, *out_count);
792dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick
7930896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(buffers);
79477c7f90ed44748f0e54e894deff1cac63da54cd6Kristian Høgsberg
7950896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return pdraw->buffers;
796e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
797e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
79807c6d94cd7272524ef06b2a787667e5d626137d2Michel Dänzer#ifdef X_DRI2SwapInterval
79907c6d94cd7272524ef06b2a787667e5d626137d2Michel Dänzer
800089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsbergstatic int
801efc82e7c703f9160cfdbe6d97e166ca6f5e75d86Jesse Barnesdri2SetSwapInterval(__GLXDRIdrawable *pdraw, int interval)
802efc82e7c703f9160cfdbe6d97e166ca6f5e75d86Jesse Barnes{
803a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri2_drawable *priv =  (struct dri2_drawable *) pdraw;
80445e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1;
8059e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   struct dri2_screen *psc = (struct dri2_screen *) priv->base.psc;
80645e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes
80745e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   if (psc->config)
80870887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg      psc->config->configQueryi(psc->driScreen,
8099e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg				"vblank_mode", &vblank_mode);
81045e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes
81145e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   switch (vblank_mode) {
81245e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   case DRI_CONF_VBLANK_NEVER:
813089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg      return GLX_BAD_VALUE;
81445e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   case DRI_CONF_VBLANK_ALWAYS_SYNC:
81545e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes      if (interval <= 0)
816089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg	 return GLX_BAD_VALUE;
81745e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes      break;
81845e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   default:
81945e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes      break;
82045e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   }
821efc82e7c703f9160cfdbe6d97e166ca6f5e75d86Jesse Barnes
8229e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   DRI2SwapInterval(priv->base.psc->dpy, priv->base.xDrawable, interval);
823efc82e7c703f9160cfdbe6d97e166ca6f5e75d86Jesse Barnes   priv->swap_interval = interval;
824089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg
825089fc37c6fa158824279e08e3b378ced94d6f803Kristian Høgsberg   return 0;
826efc82e7c703f9160cfdbe6d97e166ca6f5e75d86Jesse Barnes}
827efc82e7c703f9160cfdbe6d97e166ca6f5e75d86Jesse Barnes
8288d0228912bfef173139296a96a097f1a6348c963Kristian Høgsbergstatic int
829efc82e7c703f9160cfdbe6d97e166ca6f5e75d86Jesse Barnesdri2GetSwapInterval(__GLXDRIdrawable *pdraw)
830efc82e7c703f9160cfdbe6d97e166ca6f5e75d86Jesse Barnes{
831a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri2_drawable *priv =  (struct dri2_drawable *) pdraw;
832efc82e7c703f9160cfdbe6d97e166ca6f5e75d86Jesse Barnes
833efc82e7c703f9160cfdbe6d97e166ca6f5e75d86Jesse Barnes  return priv->swap_interval;
834efc82e7c703f9160cfdbe6d97e166ca6f5e75d86Jesse Barnes}
835efc82e7c703f9160cfdbe6d97e166ca6f5e75d86Jesse Barnes
83607c6d94cd7272524ef06b2a787667e5d626137d2Michel Dänzer#endif /* X_DRI2SwapInterval */
83707c6d94cd7272524ef06b2a787667e5d626137d2Michel Dänzer
838f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsbergstatic const __DRIdri2LoaderExtension dri2LoaderExtension = {
8390896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   {__DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION},
8400896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   dri2GetBuffers,
8410896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   dri2FlushFrontBuffer,
8420896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   dri2GetBuffersWithFormat,
843dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick};
844dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick
845dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanickstatic const __DRIdri2LoaderExtension dri2LoaderExtension_old = {
8460896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   {__DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION},
8470896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   dri2GetBuffers,
8480896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   dri2FlushFrontBuffer,
8490896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   NULL,
850e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg};
851e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
8524258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg#ifdef __DRI_USE_INVALIDATE
8534258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsbergstatic const __DRIuseInvalidateExtension dri2UseInvalidate = {
8544258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg   { __DRI_USE_INVALIDATE, __DRI_USE_INVALIDATE_VERSION }
855dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick};
8564258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg#endif
857dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick
85861d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez_X_HIDDEN void
85961d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerezdri2InvalidateBuffers(Display *dpy, XID drawable)
86061d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez{
8613750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg   __GLXDRIdrawable *pdraw =
8623750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg      dri2GetGlxDrawableFromXDrawableId(dpy, drawable);
863164108e3db5ba09d8e0605f88aa17dab83b68742Eric Anholt   struct dri2_screen *psc;
864271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri2_drawable *pdp = (struct dri2_drawable *) pdraw;
86561d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez
866164108e3db5ba09d8e0605f88aa17dab83b68742Eric Anholt   if (!pdraw)
867164108e3db5ba09d8e0605f88aa17dab83b68742Eric Anholt      return;
868164108e3db5ba09d8e0605f88aa17dab83b68742Eric Anholt
869164108e3db5ba09d8e0605f88aa17dab83b68742Eric Anholt   psc = (struct dri2_screen *) pdraw->psc;
870164108e3db5ba09d8e0605f88aa17dab83b68742Eric Anholt
87161d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez#if __DRI2_FLUSH_VERSION >= 3
872a3e2c8f31f0c5d8d5c1c76e33a572c7be8938573nobled   if (pdraw && psc->f && psc->f->base.version >= 3 && psc->f->invalidate)
873271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg       psc->f->invalidate(pdp->driDrawable);
87461d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez#endif
87561d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez}
87661d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez
877643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsbergstatic void
878643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsbergdri2_bind_tex_image(Display * dpy,
879643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg		    GLXDrawable drawable,
880643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg		    int buffer, const int *attrib_list)
881643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg{
882c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian Høgsberg   struct glx_context *gc = __glXGetCurrentContext();
883566373967a6a63b6a9c85a2392bc827ac7ef679fEric Anholt   struct dri2_context *pcp = (struct dri2_context *) gc;
884eeaab2047cfce8a7445fd9f835e737682eb503acKristian Høgsberg   __GLXDRIdrawable *base = GetGLXDRIDrawable(dpy, drawable);
885c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian Høgsberg   struct glx_display *dpyPriv = __glXInitialize(dpy);
886271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri2_drawable *pdraw = (struct dri2_drawable *) base;
887271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg   struct dri2_display *pdp =
888271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg      (struct dri2_display *) dpyPriv->dri2Display;
8892542d8e0c2ec3eb4de266c0b2ad93dba918cb89cKristian Høgsberg   struct dri2_screen *psc;
890643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg
891643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg   if (pdraw != NULL) {
8922542d8e0c2ec3eb4de266c0b2ad93dba918cb89cKristian Høgsberg      psc = (struct dri2_screen *) base->psc;
893ab780bccb737e0dc25a55b5e54faad9c4a790ac0Kristian Høgsberg
894ab780bccb737e0dc25a55b5e54faad9c4a790ac0Kristian Høgsberg#if __DRI2_FLUSH_VERSION >= 3
895a3e2c8f31f0c5d8d5c1c76e33a572c7be8938573nobled      if (!pdp->invalidateAvailable && psc->f &&
896a3e2c8f31f0c5d8d5c1c76e33a572c7be8938573nobled           psc->f->base.version >= 3 && psc->f->invalidate)
8979e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg	 psc->f->invalidate(pdraw->driDrawable);
898ab780bccb737e0dc25a55b5e54faad9c4a790ac0Kristian Høgsberg#endif
899ab780bccb737e0dc25a55b5e54faad9c4a790ac0Kristian Høgsberg
9009e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg      if (psc->texBuffer->base.version >= 2 &&
9019e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg	  psc->texBuffer->setTexBuffer2 != NULL) {
902f679640868ae6ef700d8672702c31ba2515220a7Kristian Høgsberg	 (*psc->texBuffer->setTexBuffer2) (pcp->driContext,
903271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg					   pdraw->base.textureTarget,
904271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg					   pdraw->base.textureFormat,
9059e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg					   pdraw->driDrawable);
906643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg      }
907643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg      else {
908f679640868ae6ef700d8672702c31ba2515220a7Kristian Høgsberg	 (*psc->texBuffer->setTexBuffer) (pcp->driContext,
909271c3c3a90ccfd01da9d7ac7fa451518f4e6a27cKristian Høgsberg					  pdraw->base.textureTarget,
9109e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg					  pdraw->driDrawable);
911643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg      }
912643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg   }
913643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg}
914643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg
915643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsbergstatic void
916643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsbergdri2_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
917643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg{
918e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao#if __DRI_TEX_BUFFER_VERSION >= 3
919e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao   struct glx_context *gc = __glXGetCurrentContext();
920e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao   struct dri2_context *pcp = (struct dri2_context *) gc;
921e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao   __GLXDRIdrawable *base = GetGLXDRIDrawable(dpy, drawable);
922e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao   struct glx_display *dpyPriv = __glXInitialize(dpy);
923e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao   struct dri2_drawable *pdraw = (struct dri2_drawable *) base;
924e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao   struct dri2_display *pdp =
925e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao      (struct dri2_display *) dpyPriv->dri2Display;
926e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao   struct dri2_screen *psc;
927e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao
928e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao   if (pdraw != NULL) {
929e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao      psc = (struct dri2_screen *) base->psc;
930e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao
931e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao      if (psc->texBuffer->base.version >= 3 &&
932e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao          psc->texBuffer->releaseTexBuffer != NULL) {
933e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao         (*psc->texBuffer->releaseTexBuffer) (pcp->driContext,
934e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao                                           pdraw->base.textureTarget,
935e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao                                           pdraw->driDrawable);
936e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao      }
937e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao   }
938e59fa4c46c8857f2e04447777dd197464c95b2cbJuan Zhao#endif
939643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg}
940643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg
941643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsbergstatic const struct glx_context_vtable dri2_context_vtable = {
942c796bb0cc3fde409545bff320540ddf5c029e513Kristian Høgsberg   dri2_destroy_context,
943c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   dri2_bind_context,
944c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   dri2_unbind_context,
9457b7845a076c933e096ac511b4184141ba194449aKristian Høgsberg   dri2_wait_gl,
9467b7845a076c933e096ac511b4184141ba194449aKristian Høgsberg   dri2_wait_x,
9477b7845a076c933e096ac511b4184141ba194449aKristian Høgsberg   DRI_glXUseXFont,
948643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg   dri2_bind_tex_image,
949643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg   dri2_release_tex_image,
950559e4f8ebcb186b491d7d687ac43f22a62448fc1Jeremy Huddleston   NULL, /* get_proc_address */
951643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg};
952643b2af0203764cb9f0a5b9e082937ab3f243523Kristian Høgsberg
9539e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsbergstatic void
954f84fe6aa2eac6984b77ca6da0c7e5a571b425827Zack Rusindri2BindExtensions(struct dri2_screen *psc, const __DRIextension **extensions,
955f84fe6aa2eac6984b77ca6da0c7e5a571b425827Zack Rusin                   const char *driverName)
9569e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg{
9579e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   int i;
9589e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg
9599e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   __glXEnableDirectExtension(&psc->base, "GLX_SGI_video_sync");
9609e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   __glXEnableDirectExtension(&psc->base, "GLX_SGI_swap_control");
9619e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   __glXEnableDirectExtension(&psc->base, "GLX_MESA_swap_control");
962a7292f2920a28a190ca39ce530454a852ec36d59Kristian Høgsberg   __glXEnableDirectExtension(&psc->base, "GLX_SGI_make_current_read");
9639e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg
964f84fe6aa2eac6984b77ca6da0c7e5a571b425827Zack Rusin   /*
965f84fe6aa2eac6984b77ca6da0c7e5a571b425827Zack Rusin    * GLX_INTEL_swap_event is broken on the server side, where it's
966f84fe6aa2eac6984b77ca6da0c7e5a571b425827Zack Rusin    * currently unconditionally enabled. This completely breaks
967f84fe6aa2eac6984b77ca6da0c7e5a571b425827Zack Rusin    * systems running on drivers which don't support that extension.
968f84fe6aa2eac6984b77ca6da0c7e5a571b425827Zack Rusin    * There's no way to test for its presence on this side, so instead
969f84fe6aa2eac6984b77ca6da0c7e5a571b425827Zack Rusin    * of disabling it uncondtionally, just disable it for drivers
970f84fe6aa2eac6984b77ca6da0c7e5a571b425827Zack Rusin    * which are known to not support it.
971f84fe6aa2eac6984b77ca6da0c7e5a571b425827Zack Rusin    */
972f84fe6aa2eac6984b77ca6da0c7e5a571b425827Zack Rusin   if (strcmp(driverName, "vmwgfx") != 0) {
97363f858943084b5cbeb20cce96ccae3c25e633663Zack Rusin      __glXEnableDirectExtension(&psc->base, "GLX_INTEL_swap_event");
97463f858943084b5cbeb20cce96ccae3c25e633663Zack Rusin   }
9759e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg
97648ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   if (psc->dri2->base.version >= 3) {
977e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick      const unsigned mask = psc->dri2->getAPIMask(psc->driScreen);
978e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick
97948ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick      __glXEnableDirectExtension(&psc->base, "GLX_ARB_create_context");
98048ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick      __glXEnableDirectExtension(&psc->base, "GLX_ARB_create_context_profile");
981e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick
982e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick      if ((mask & (1 << __DRI_API_GLES2)) != 0)
983e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick	 __glXEnableDirectExtension(&psc->base,
984e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick				    "GLX_EXT_create_context_es2_profile");
98548ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   }
98648ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick
9879e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   for (i = 0; extensions[i]; i++) {
9889e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg      if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) {
9899e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg	 psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
9909e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg	 __glXEnableDirectExtension(&psc->base, "GLX_EXT_texture_from_pixmap");
9919e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg      }
9929e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg
9939e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg      if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0)) {
9949e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg	 psc->f = (__DRI2flushExtension *) extensions[i];
9959e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg	 /* internal driver extension, no GL extension exposed */
9969e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg      }
9979e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg
9989e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg      if ((strcmp(extensions[i]->name, __DRI2_CONFIG_QUERY) == 0))
9999e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg	 psc->config = (__DRI2configQueryExtension *) extensions[i];
1000511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom
1001511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom      if (((strcmp(extensions[i]->name, __DRI2_THROTTLE) == 0)))
1002511dc295f82c61acefe026d0f4de43d4a31dbf90Thomas Hellstrom	 psc->throttle = (__DRI2throttleExtension *) extensions[i];
1003a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick
1004a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick      /* DRI2 version 3 is also required because
1005a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick       * GLX_ARB_create_context_robustness requires GLX_ARB_create_context.
1006a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick       */
1007a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick      if (psc->dri2->base.version >= 3
1008a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick          && strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0)
1009a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick         __glXEnableDirectExtension(&psc->base,
1010a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick                                    "GLX_ARB_create_context_robustness");
10119e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg   }
10129e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg}
10139e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg
10146ec39db726beead21d97bf64ddbe1f0b2d2d6ca1Kristian Høgsbergstatic const struct glx_screen_vtable dri2_screen_vtable = {
101543409fa7b0e64f6d73c3d33bc9a39ba26dd4caebIan Romanick   dri2_create_context,
101648ffc6a1553083280c217640629cc6ebed1bf982Ian Romanick   dri2_create_context_attribs
10176ec39db726beead21d97bf64ddbe1f0b2d2d6ca1Kristian Høgsberg};
10189e546ecfd446abf1236cdb0b9469157de5d084ceKristian Høgsberg
101966fc35cde9ed68a09920ad6a28de794dd1d3aa8cKristian Høgsbergstatic struct glx_screen *
1020c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian Høgsbergdri2CreateScreen(int screen, struct glx_display * priv)
1021e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
10220896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   const __DRIconfig **driver_configs;
10230896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   const __DRIextension **extensions;
1024a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   const struct dri2_display *const pdp = (struct dri2_display *)
1025dbf87f23126cc869637575e9ea2cb58774efe888Ian Romanick      priv->dri2Display;
1026f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   struct dri2_screen *psc;
10270896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __GLXDRIscreen *psp;
102863a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   struct glx_config *configs = NULL, *visuals = NULL;
1029f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák   char *driverName, *deviceName, *tmp;
10300896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   drm_magic_t magic;
10310896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int i;
10320896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1033f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   psc = Xmalloc(sizeof *psc);
1034f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   if (psc == NULL)
10350896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
10360896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1037f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   memset(psc, 0, sizeof *psc);
10387d9e0ea7393c14cbf2d58364726951b14e0d4fc7Henri Verbeet   psc->fd = -1;
10397d9e0ea7393c14cbf2d58364726951b14e0d4fc7Henri Verbeet
1040bfc889517ad0d490cce1817eecac146d66bcd923Henri Verbeet   if (!glx_screen_init(&psc->base, screen, priv)) {
1041bfc889517ad0d490cce1817eecac146d66bcd923Henri Verbeet      Xfree(psc);
1042bfc889517ad0d490cce1817eecac146d66bcd923Henri Verbeet      return NULL;
1043bfc889517ad0d490cce1817eecac146d66bcd923Henri Verbeet   }
1044f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg
1045f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   if (!DRI2Connect(priv->dpy, RootWindow(priv->dpy, screen),
104681cca6d4538bdde1661ce868af2a5de47cd251abRodolfo Ribeiro Gomes		    &driverName, &deviceName)) {
1047bfc889517ad0d490cce1817eecac146d66bcd923Henri Verbeet      glx_screen_cleanup(&psc->base);
1048f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      XFree(psc);
104945e0a7a51d88c397a27317d22b325ec31b3e2e99Andrew Deason      InfoMessageF("screen %d does not appear to be DRI2 capable\n", screen);
10500896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
105181cca6d4538bdde1661ce868af2a5de47cd251abRodolfo Ribeiro Gomes   }
10520896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
10530896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   psc->driver = driOpenDriver(driverName);
10540896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (psc->driver == NULL) {
10550896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("driver pointer missing\n");
10560896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
10570896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
10580896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
10590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
10600896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (extensions == NULL) {
10610896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
10620896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
10630896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
10640896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
10650896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   for (i = 0; extensions[i]; i++) {
10660896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
1067daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes	 psc->core = (__DRIcoreExtension *) extensions[i];
10680896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (strcmp(extensions[i]->name, __DRI_DRI2) == 0)
1069daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes	 psc->dri2 = (__DRIdri2Extension *) extensions[i];
10700896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
10710896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
10720896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (psc->core == NULL || psc->dri2 == NULL) {
10730896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("core dri or dri2 extension not found\n");
10740896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      goto handle_error;
10750896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
10760896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1077b60120608f6ddf4098bc324363197c979ee04cb7David Fries#ifdef O_CLOEXEC
1078b60120608f6ddf4098bc324363197c979ee04cb7David Fries   psc->fd = open(deviceName, O_RDWR | O_CLOEXEC);
1079b60120608f6ddf4098bc324363197c979ee04cb7David Fries   if (psc->fd == -1 && errno == EINVAL)
1080b60120608f6ddf4098bc324363197c979ee04cb7David Fries#endif
1081b60120608f6ddf4098bc324363197c979ee04cb7David Fries   {
1082b60120608f6ddf4098bc324363197c979ee04cb7David Fries      psc->fd = open(deviceName, O_RDWR);
1083b60120608f6ddf4098bc324363197c979ee04cb7David Fries      if (psc->fd != -1)
1084b60120608f6ddf4098bc324363197c979ee04cb7David Fries         fcntl(psc->fd, F_SETFD, fcntl(psc->fd, F_GETFD) | FD_CLOEXEC);
1085b60120608f6ddf4098bc324363197c979ee04cb7David Fries   }
10860896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (psc->fd < 0) {
10870896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("failed to open drm device: %s\n", strerror(errno));
108881cca6d4538bdde1661ce868af2a5de47cd251abRodolfo Ribeiro Gomes      goto handle_error;
10890896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
10900896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
10910896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (drmGetMagic(psc->fd, &magic)) {
10920896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("failed to get magic\n");
109381cca6d4538bdde1661ce868af2a5de47cd251abRodolfo Ribeiro Gomes      goto handle_error;
10940896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
10950896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1096f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   if (!DRI2Authenticate(priv->dpy, RootWindow(priv->dpy, screen), magic)) {
10970896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("failed to authenticate magic %d\n", magic);
109881cca6d4538bdde1661ce868af2a5de47cd251abRodolfo Ribeiro Gomes      goto handle_error;
10990896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
11000896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
11014258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg
11020896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* If the server does not support the protocol for
11030896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * DRI2GetBuffersWithFormat, don't supply that interface to the driver.
11040896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    */
110570887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   psc->driScreen =
11064258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg      psc->dri2->createNewScreen(screen, psc->fd,
11074258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg				 (const __DRIextension **)
11084258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg				 &pdp->loader_extensions[0],
1109daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barnes				 &driver_configs, psc);
11100896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
111170887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   if (psc->driScreen == NULL) {
11120896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      ErrorMessageF("failed to create dri screen\n");
111381cca6d4538bdde1661ce868af2a5de47cd251abRodolfo Ribeiro Gomes      goto handle_error;
11140896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
11150896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
111670887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   extensions = psc->core->getExtensions(psc->driScreen);
1117f84fe6aa2eac6984b77ca6da0c7e5a571b425827Zack Rusin   dri2BindExtensions(psc, extensions, driverName);
11180896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
111963a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   configs = driConvertConfigs(psc->core, psc->base.configs, driver_configs);
112063a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   visuals = driConvertConfigs(psc->core, psc->base.visuals, driver_configs);
112163a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner
112263a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   if (!configs || !visuals)
112363a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner       goto handle_error;
112463a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner
112563a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   glx_config_destroy_list(psc->base.configs);
112663a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   psc->base.configs = configs;
112763a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   glx_config_destroy_list(psc->base.visuals);
112863a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   psc->base.visuals = visuals;
11290896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1130bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian Høgsberg   psc->driver_configs = driver_configs;
11310896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
11326ec39db726beead21d97bf64ddbe1f0b2d2d6ca1Kristian Høgsberg   psc->base.vtable = &dri2_screen_vtable;
113370887d517290060a80c7f5dd8c0ea0c834c4d91eKristian Høgsberg   psp = &psc->vtable;
1134f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   psc->base.driScreen = psp;
11350896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   psp->destroyScreen = dri2DestroyScreen;
11360896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   psp->createDrawable = dri2CreateDrawable;
11370896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   psp->swapBuffers = dri2SwapBuffers;
113801923fb72d755b319dde521c3c81a20caa95b540Keith Whitwell   psp->getDrawableMSC = NULL;
113901923fb72d755b319dde521c3c81a20caa95b540Keith Whitwell   psp->waitForMSC = NULL;
114001923fb72d755b319dde521c3c81a20caa95b540Keith Whitwell   psp->waitForSBC = NULL;
114101923fb72d755b319dde521c3c81a20caa95b540Keith Whitwell   psp->setSwapInterval = NULL;
114201923fb72d755b319dde521c3c81a20caa95b540Keith Whitwell   psp->getSwapInterval = NULL;
114301923fb72d755b319dde521c3c81a20caa95b540Keith Whitwell
11441cfd769c2ec0b605cacd75c0e9c89346e1f9518dJesse Barnes   if (pdp->driMinor >= 2) {
114501923fb72d755b319dde521c3c81a20caa95b540Keith Whitwell#ifdef X_DRI2GetMSC
11461cfd769c2ec0b605cacd75c0e9c89346e1f9518dJesse Barnes      psp->getDrawableMSC = dri2DrawableGetMSC;
114701923fb72d755b319dde521c3c81a20caa95b540Keith Whitwell#endif
114801923fb72d755b319dde521c3c81a20caa95b540Keith Whitwell#ifdef X_DRI2WaitMSC
11491cfd769c2ec0b605cacd75c0e9c89346e1f9518dJesse Barnes      psp->waitForMSC = dri2WaitForMSC;
11501cfd769c2ec0b605cacd75c0e9c89346e1f9518dJesse Barnes      psp->waitForSBC = dri2WaitForSBC;
115101923fb72d755b319dde521c3c81a20caa95b540Keith Whitwell#endif
115201923fb72d755b319dde521c3c81a20caa95b540Keith Whitwell#ifdef X_DRI2SwapInterval
11531cfd769c2ec0b605cacd75c0e9c89346e1f9518dJesse Barnes      psp->setSwapInterval = dri2SetSwapInterval;
11541cfd769c2ec0b605cacd75c0e9c89346e1f9518dJesse Barnes      psp->getSwapInterval = dri2GetSwapInterval;
115501923fb72d755b319dde521c3c81a20caa95b540Keith Whitwell#endif
11561ca968363dd55e919bd91c8fc31c34d207af3958Jesse Barnes#if defined(X_DRI2GetMSC) && defined(X_DRI2WaitMSC) && defined(X_DRI2SwapInterval)
1157f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg      __glXEnableDirectExtension(&psc->base, "GLX_OML_sync_control");
11581ca968363dd55e919bd91c8fc31c34d207af3958Jesse Barnes#endif
11591cfd769c2ec0b605cacd75c0e9c89346e1f9518dJesse Barnes   }
11600896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
11610896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   /* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always
11620896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf    * available.*/
11630896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   psp->copySubBuffer = dri2CopySubBuffer;
1164f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   __glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer");
11650896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
11660896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(driverName);
11670896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(deviceName);
11680896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
1169f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák   tmp = getenv("LIBGL_SHOW_FPS");
1170f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák   psc->show_fps = tmp && strcmp(tmp, "1") == 0;
1171f82d40d4b1aa60364c03c32578ecd675d4d86dcfMarek Olšák
1172f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   return &psc->base;
1173e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
1174daf7fe69f7bd0caa955d30b43fc35b7ce0069b6bJesse Barneshandle_error:
11756c9af977401ff986964d678f8870eee23c504077Carl Worth   CriticalErrorMessageF("failed to load driver: %s\n", driverName);
11766c9af977401ff986964d678f8870eee23c504077Carl Worth
117763a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   if (configs)
117863a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner       glx_config_destroy_list(configs);
117963a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   if (visuals)
118063a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner       glx_config_destroy_list(visuals);
118163a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   if (psc->driScreen)
118263a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner       psc->core->destroyScreen(psc->driScreen);
118363a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner   psc->driScreen = NULL;
11847d9e0ea7393c14cbf2d58364726951b14e0d4fc7Henri Verbeet   if (psc->fd >= 0)
1185bfc889517ad0d490cce1817eecac146d66bcd923Henri Verbeet      close(psc->fd);
1186bfc889517ad0d490cce1817eecac146d66bcd923Henri Verbeet   if (psc->driver)
1187bfc889517ad0d490cce1817eecac146d66bcd923Henri Verbeet      dlclose(psc->driver);
118863a6fd6603574c1c01324fbeb0863e39d3864c16Aaron Plattner
11890896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(driverName);
11900896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(deviceName);
1191bfc889517ad0d490cce1817eecac146d66bcd923Henri Verbeet   glx_screen_cleanup(&psc->base);
1192f972115d33e391499e049b83a1559959f2ca9f72Kristian Høgsberg   XFree(psc);
1193e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
11940896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return NULL;
1195e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
1196e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
1197e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg/* Called from __glXFreeDisplayPrivate.
1198e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg */
11990896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic void
12000896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófdri2DestroyDisplay(__GLXDRIdisplay * dpy)
1201e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
1202a75de67c51e9124a7c3846b4110552ea28c60349Henri Verbeet   struct dri2_display *pdp = (struct dri2_display *) dpy;
1203a75de67c51e9124a7c3846b4110552ea28c60349Henri Verbeet
1204a75de67c51e9124a7c3846b4110552ea28c60349Henri Verbeet   __glxHashDestroy(pdp->dri2Hash);
12050896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   Xfree(dpy);
1206e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
1207e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
12083750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg_X_HIDDEN __GLXDRIdrawable *
12093750ebd540510324ef5ada769537ae05309adadbKristian Høgsbergdri2GetGlxDrawableFromXDrawableId(Display *dpy, XID id)
12103750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg{
1211c356f5867f2c1fad7155df538b9affa8dbdcf869Kristian Høgsberg   struct glx_display *d = __glXInitialize(dpy);
1212a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri2_display *pdp = (struct dri2_display *) d->dri2Display;
12133750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg   __GLXDRIdrawable *pdraw;
12143750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg
12153750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg   if (__glxHashLookup(pdp->dri2Hash, id, (void *) &pdraw) == 0)
12163750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg      return pdraw;
12173750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg
12183750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg   return NULL;
12193750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg}
12203750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg
1221e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg/*
1222e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * Allocate, initialize and return a __DRIdisplayPrivate object.
1223e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * This is called from __glXInitialize() when we are given a new
1224e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * display pointer.
1225e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg */
12260896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf_X_HIDDEN __GLXDRIdisplay *
12270896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófdri2CreateDisplay(Display * dpy)
1228e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
1229a296d96de45d38a6ed0b3c817334d443facc169bKristian Høgsberg   struct dri2_display *pdp;
12304258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg   int eventBase, errorBase, i;
1231e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
12320896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!DRI2QueryExtension(dpy, &eventBase, &errorBase))
12330896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
1234e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
12350896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdp = Xmalloc(sizeof *pdp);
12360896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (pdp == NULL)
12370896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
1238e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
12390896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (!DRI2QueryVersion(dpy, &pdp->driMajor, &pdp->driMinor)) {
12400896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      Xfree(pdp);
12410896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
12420896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
1243e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
12440896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdp->driPatch = 0;
124561d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez   pdp->swapAvailable = (pdp->driMinor >= 2);
124661d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez   pdp->invalidateAvailable = (pdp->driMinor >= 3);
1247e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
12480896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdp->base.destroyDisplay = dri2DestroyDisplay;
12490896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   pdp->base.createScreen = dri2CreateScreen;
1250e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
12514258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg   i = 0;
12524258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg   if (pdp->driMinor < 1)
12534258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg      pdp->loader_extensions[i++] = &dri2LoaderExtension_old.base;
12544258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg   else
12554258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg      pdp->loader_extensions[i++] = &dri2LoaderExtension.base;
12564258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg
12574258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg   pdp->loader_extensions[i++] = &systemTimeExtension.base;
12584258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg
12594258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg#ifdef __DRI_USE_INVALIDATE
12604cd259ca59128ff2712c42ff2d2340b01a3b74a8Kristian Høgsberg   pdp->loader_extensions[i++] = &dri2UseInvalidate.base;
12614258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg#endif
1262c8f407bcec7619eb2030ea9fe52501ad33075699Kristian Høgsberg   pdp->loader_extensions[i++] = NULL;
12634258e3a2e1c3278694ed10f7fc544d2154d91a96Kristian Høgsberg
12643750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg   pdp->dri2Hash = __glxHashCreate();
12653750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg   if (pdp->dri2Hash == NULL) {
12663750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg      Xfree(pdp);
12673750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg      return NULL;
12683750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg   }
12693750ebd540510324ef5ada769537ae05309adadbKristian Høgsberg
12700896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return &pdp->base;
1271e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
1272e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
1273e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg#endif /* GLX_DIRECT_RENDERING */
1274