1079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis/*
2079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
3079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * Copyright © 2008 Red Hat, Inc.
4079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis *
5079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * Permission is hereby granted, free of charge, to any person obtaining a
6079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * copy of this software and associated documentation files (the "Soft-
7079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * ware"), to deal in the Software without restriction, including without
8079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * limitation the rights to use, copy, modify, merge, publish, distribute,
9079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * and/or sell copies of the Software, and to permit persons to whom the
10079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * Software is furnished to do so, provided that the above copyright
11079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * notice(s) and this permission notice appear in all copies of the Soft-
12079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * ware and that both the above copyright notice(s) and this permission
13079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * notice appear in supporting documentation.
14079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis *
15079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
17079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
18079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
19079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
20079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
23079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * MANCE OF THIS SOFTWARE.
24079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis *
25079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * Except as contained in this notice, the name of a copyright holder shall
26079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * not be used in advertising or otherwise to promote the sale, use or
27079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * other dealings in this Software without prior written authorization of
28079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * the copyright holder.
29079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis *
30079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * Authors:
31079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis *   Kevin E. Martin <kevin@precisioninsight.com>
32079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis *   Brian Paul <brian@precisioninsight.com>
33079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis *   Kristian Høgsberg (krh@redhat.com)
34079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis */
35079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
3680b280db883edc9550484dba03bd5c124b6a9bf9Jeremy Huddleston#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
37079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
38079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#include <unistd.h>
39079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#include <dlfcn.h>
40a25e1aa0aab6bd278eefa7c0748b491c9c6ae62cBrian Paul#include <stdarg.h>
41079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#include "glxclient.h"
42079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#include "dri_common.h"
43079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
44079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#ifndef RTLD_NOW
45079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#define RTLD_NOW 0
46079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#endif
47079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#ifndef RTLD_GLOBAL
48079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#define RTLD_GLOBAL 0
49079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#endif
50079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
51c09504c343d904dc8c135c9b7241e8315c134d0fCarl Worth/**
52c09504c343d904dc8c135c9b7241e8315c134d0fCarl Worth * Print informational message to stderr if LIBGL_DEBUG is set to
53c09504c343d904dc8c135c9b7241e8315c134d0fCarl Worth * "verbose".
54c09504c343d904dc8c135c9b7241e8315c134d0fCarl Worth */
550896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf_X_HIDDEN void
560896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófInfoMessageF(const char *f, ...)
57079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis{
580896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   va_list args;
590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   const char *env;
600896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
610896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if ((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) {
620896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      fprintf(stderr, "libGL: ");
630896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      va_start(args, f);
640896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      vfprintf(stderr, f, args);
650896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      va_end(args);
660896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
67079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis}
68079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
69079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis/**
70c09504c343d904dc8c135c9b7241e8315c134d0fCarl Worth * Print error message to stderr if LIBGL_DEBUG is set to anything but
71c09504c343d904dc8c135c9b7241e8315c134d0fCarl Worth * "quiet", (do nothing if LIBGL_DEBUG is unset).
72079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis */
730896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf_X_HIDDEN void
740896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófErrorMessageF(const char *f, ...)
75079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis{
760896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   va_list args;
770896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   const char *env;
780896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
790896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if ((env = getenv("LIBGL_DEBUG")) && !strstr(env, "quiet")) {
800896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      fprintf(stderr, "libGL error: ");
810896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      va_start(args, f);
820896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      vfprintf(stderr, f, args);
830896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      va_end(args);
840896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
85079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis}
86079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
8792bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth/**
8892bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth * Print error message unless LIBGL_DEBUG is set to "quiet".
8992bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth *
9092bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth * The distinction between CriticalErrorMessageF and ErrorMessageF is
9192bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth * that critcial errors will be printed by default, (even when
9292bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth * LIBGL_DEBUG is unset).
9392bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth */
9492bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth_X_HIDDEN void
9592bef0bfa121e0e58112ffae352c8ad9e5da6307Carl WorthCriticalErrorMessageF(const char *f, ...)
9692bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth{
9792bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth   va_list args;
9892bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth   const char *env;
9992bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth
10092bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth   if (!(env = getenv("LIBGL_DEBUG")) || !strstr(env, "quiet")) {
10192bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth      fprintf(stderr, "libGL error: ");
10292bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth      va_start(args, f);
10392bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth      vfprintf(stderr, f, args);
10492bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth      va_end(args);
10592bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth
10692bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth      if (!env || !strstr(env, "verbose"))
10792bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth         fprintf(stderr, "libGL error: Try again with LIBGL_DEBUG=verbose for more details.\n");
10892bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth   }
10992bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth}
11092bef0bfa121e0e58112ffae352c8ad9e5da6307Carl Worth
111079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#ifndef DEFAULT_DRIVER_DIR
112079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis/* this is normally defined in Mesa/configs/default with DRI_DRIVER_SEARCH_PATH */
113079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#define DEFAULT_DRIVER_DIR "/usr/local/lib/dri"
114079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#endif
115079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
116079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis/**
117079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * Try to \c dlopen the named driver.
118079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis *
119079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * This function adds the "_dri.so" suffix to the driver name and searches the
120079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * directories specified by the \c LIBGL_DRIVERS_PATH environment variable in
121079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * order to find the driver.
122079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis *
123e4344161bde2e24fcfba65d30d58f087bd8bf94dIan Romanick * \param driverName - a name like "i965", "radeon", "nouveau", etc.
124079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis *
125079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * \returns
126079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis * A handle from \c dlopen, or \c NULL if driver file not found.
127079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis */
1280896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf_X_HIDDEN void *
1290896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófdriOpenDriver(const char *driverName)
130079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis{
131079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   void *glhandle, *handle;
132079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   const char *libPaths, *p, *next;
133079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   char realDriverName[200];
134079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   int len;
135079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
136079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   /* Attempt to make sure libGL symbols will be visible to the driver */
137079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   glhandle = dlopen("libGL.so.1", RTLD_NOW | RTLD_GLOBAL);
138079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
139079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   libPaths = NULL;
140079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   if (geteuid() == getuid()) {
141079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis      /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
142079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis      libPaths = getenv("LIBGL_DRIVERS_PATH");
143079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis      if (!libPaths)
1440896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         libPaths = getenv("LIBGL_DRIVERS_DIR");        /* deprecated */
145079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   }
146079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   if (libPaths == NULL)
1470896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      libPaths = DEFAULT_DRIVER_DIR;
148079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
149079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   handle = NULL;
150079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   for (p = libPaths; *p; p = next) {
1510896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      next = strchr(p, ':');
1520896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (next == NULL) {
1530896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         len = strlen(p);
1540896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         next = p + len;
1550896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      }
1560896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      else {
1570896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         len = next - p;
1580896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         next++;
1590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      }
160079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
161079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#ifdef GLX_USE_TLS
162079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis      snprintf(realDriverName, sizeof realDriverName,
1630896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf               "%.*s/tls/%s_dri.so", len, p, driverName);
164079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis      InfoMessageF("OpenDriver: trying %s\n", realDriverName);
165079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis      handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
166079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#endif
167079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
1680896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (handle == NULL) {
1690896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         snprintf(realDriverName, sizeof realDriverName,
1700896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                  "%.*s/%s_dri.so", len, p, driverName);
1710896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         InfoMessageF("OpenDriver: trying %s\n", realDriverName);
1720896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
173079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis      }
174079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
1750896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (handle != NULL)
1760896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         break;
177079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis      else
1780896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         ErrorMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror());
179079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   }
180079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
181079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   if (!handle)
182079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis      ErrorMessageF("unable to load driver: %s_dri.so\n", driverName);
183079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
184079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   if (glhandle)
185079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis      dlclose(glhandle);
186079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
187079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis   return handle;
188079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis}
189079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
1907a66e549583a3168f05acc7df1e872d218fd670dKristian Høgsbergstatic GLboolean
1917a66e549583a3168f05acc7df1e872d218fd670dKristian Høgsberg__driGetMSCRate(__DRIdrawable *draw,
1927a66e549583a3168f05acc7df1e872d218fd670dKristian Høgsberg		int32_t * numerator, int32_t * denominator,
1937a66e549583a3168f05acc7df1e872d218fd670dKristian Høgsberg		void *loaderPrivate)
1947a66e549583a3168f05acc7df1e872d218fd670dKristian Høgsberg{
1957a66e549583a3168f05acc7df1e872d218fd670dKristian Høgsberg   __GLXDRIdrawable *glxDraw = loaderPrivate;
1967a66e549583a3168f05acc7df1e872d218fd670dKristian Høgsberg
1977a66e549583a3168f05acc7df1e872d218fd670dKristian Høgsberg   return __glxGetMscRate(glxDraw, numerator, denominator);
1987a66e549583a3168f05acc7df1e872d218fd670dKristian Høgsberg}
1997a66e549583a3168f05acc7df1e872d218fd670dKristian Høgsberg
200079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis_X_HIDDEN const __DRIsystemTimeExtension systemTimeExtension = {
2010896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   {__DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION},
2020896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __glXGetUST,
2037a66e549583a3168f05acc7df1e872d218fd670dKristian Høgsberg   __driGetMSCRate
204079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis};
205079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
206079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#define __ATTRIB(attrib, field) \
2076ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg    { attrib, offsetof(struct glx_config, field) }
208079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
2090896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristófstatic const struct
2100896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf{
2110896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   unsigned int attrib, offset;
2120896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf} attribMap[] = {
2130896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
2140896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_LEVEL, level),
2150896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits),
2160896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits),
2170896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits),
2180896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits),
2190896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits),
2200896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits),
2210896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits),
2220896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits),
2230896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits),
2240896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits),
2250896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers),
2260896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_SAMPLES, samples),
2270896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode),
2280896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode),
2290896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers),
230079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#if 0
2310896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel),
2320896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentIndex),
2330896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed),
2340896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen),
2350896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue),
2360896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha),
2370896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask),
2380896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask),
2390896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask),
2400896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask),
241079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#endif
2420896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth),
2430896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight),
2440896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
2450896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
2460896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
247079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#if 0
2480896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
249079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#endif
2500896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf__ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
2510896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
2520896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE,
2530896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf                     bindToMipmapTexture),
2546538b5824e298eaebede2d9686c7607c44ab446aDave Airlie      __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
2556538b5824e298eaebede2d9686c7607c44ab446aDave Airlie      __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable)
2566538b5824e298eaebede2d9686c7607c44ab446aDave Airlie};
257079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
258079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzisstatic int
2596ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian HøgsbergscalarEqual(struct glx_config *mode, unsigned int attrib, unsigned int value)
260079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis{
2610896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   unsigned int glxValue;
2620896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int i;
263079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
2640896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   for (i = 0; i < ARRAY_SIZE(attribMap); i++)
2650896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (attribMap[i].attrib == attrib) {
2660896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         glxValue = *(unsigned int *) ((char *) mode + attribMap[i].offset);
2670896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         return glxValue == GLX_DONT_CARE || glxValue == value;
2680896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      }
269079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
2700896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return GL_TRUE;              /* Is a non-existing attribute equal to value? */
271079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis}
272079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
273079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzisstatic int
2746ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian HøgsbergdriConfigEqual(const __DRIcoreExtension *core,
2756ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg               struct glx_config *config, const __DRIconfig *driConfig)
276079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis{
2770896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   unsigned int attrib, value, glxValue;
2780896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int i;
2790896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2800896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   i = 0;
2810896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   while (core->indexConfigAttrib(driConfig, i++, &attrib, &value)) {
2820896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      switch (attrib) {
2830896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      case __DRI_ATTRIB_RENDER_TYPE:
2840896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         glxValue = 0;
2850896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         if (value & __DRI_ATTRIB_RGBA_BIT) {
2860896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf            glxValue |= GLX_RGBA_BIT;
2870896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         }
2880896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         else if (value & __DRI_ATTRIB_COLOR_INDEX_BIT) {
2890896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf            glxValue |= GLX_COLOR_INDEX_BIT;
2900896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         }
2916ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg         if (glxValue != config->renderType)
2920896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf            return GL_FALSE;
2930896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         break;
2940896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
2950896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      case __DRI_ATTRIB_CONFIG_CAVEAT:
2960896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
2970896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf            glxValue = GLX_NON_CONFORMANT_CONFIG;
2980896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         else if (value & __DRI_ATTRIB_SLOW_BIT)
2990896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf            glxValue = GLX_SLOW_CONFIG;
3000896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         else
3010896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf            glxValue = GLX_NONE;
3026ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg         if (glxValue != config->visualRating)
3030896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf            return GL_FALSE;
3040896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         break;
3050896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3060896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS:
3070896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         glxValue = 0;
3080896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         if (value & __DRI_ATTRIB_TEXTURE_1D_BIT)
3090896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf            glxValue |= GLX_TEXTURE_1D_BIT_EXT;
3100896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         if (value & __DRI_ATTRIB_TEXTURE_2D_BIT)
3110896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf            glxValue |= GLX_TEXTURE_2D_BIT_EXT;
3120896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         if (value & __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT)
3130896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf            glxValue |= GLX_TEXTURE_RECTANGLE_BIT_EXT;
3146ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg         if (config->bindToTextureTargets != GLX_DONT_CARE &&
3156ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg             glxValue != config->bindToTextureTargets)
3160896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf            return GL_FALSE;
3170896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         break;
3180896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3190896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      default:
3206ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg         if (!scalarEqual(config, attrib, value))
3210896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf            return GL_FALSE;
3220896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      }
3230896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
3240896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3250896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return GL_TRUE;
326079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis}
327079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
3286ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsbergstatic struct glx_config *
3290896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófcreateDriMode(const __DRIcoreExtension * core,
3306ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg	      struct glx_config *config, const __DRIconfig **driConfigs)
331079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis{
3326ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   __GLXDRIconfigPrivate *driConfig;
3330896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   int i;
334079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
3350896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   for (i = 0; driConfigs[i]; i++) {
3366ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg      if (driConfigEqual(core, config, driConfigs[i]))
3370896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         break;
3380896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
339079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
3400896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   if (driConfigs[i] == NULL)
3410896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
342079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
3436ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   driConfig = Xmalloc(sizeof *driConfig);
3446ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   if (driConfig == NULL)
3450896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      return NULL;
346079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
3476ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   driConfig->base = *config;
3486ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   driConfig->driConfig = driConfigs[i];
349079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
3506ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   return &driConfig->base;
351079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis}
352079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
3536ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg_X_HIDDEN struct glx_config *
3540896268b97674d009d609476acfa1eed5dfea350RALOVICH, KristófdriConvertConfigs(const __DRIcoreExtension * core,
3556ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg                  struct glx_config *configs, const __DRIconfig **driConfigs)
356079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis{
3576ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   struct glx_config head, *tail, *m;
3580896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf
3590896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   tail = &head;
3600896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   head.next = NULL;
3616ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg   for (m = configs; m; m = m->next) {
3626ddf66e9230ee862ac341c4767cf6b3b2dd2552bKristian Høgsberg      tail->next = createDriMode(core, m, driConfigs);
3630896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      if (tail->next == NULL) {
3640896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         /* no matching dri config for m */
3650896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf         continue;
3660896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      }
367079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
368079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
3690896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf      tail = tail->next;
3700896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   }
371079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
3720896268b97674d009d609476acfa1eed5dfea350RALOVICH, Kristóf   return head.next;
373079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis}
374079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis
375bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian Høgsberg_X_HIDDEN void
376bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian HøgsbergdriDestroyConfigs(const __DRIconfig **configs)
377bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian Høgsberg{
378bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian Høgsberg   int i;
379bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian Høgsberg
380bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian Høgsberg   for (i = 0; configs[i]; i++)
381bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian Høgsberg      free((__DRIconfig *) configs[i]);
382bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian Høgsberg   free(configs);
383bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian Høgsberg}
384bab13969d8bf3ff9259524c3f4ab96d81485ccefKristian Høgsberg
385c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg_X_HIDDEN __GLXDRIdrawable *
386c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian HøgsbergdriFetchDrawable(struct glx_context *gc, GLXDrawable glxDrawable)
387c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg{
388c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   struct glx_display *const priv = __glXInitialize(gc->psc->dpy);
389c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   __GLXDRIdrawable *pdraw;
390c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   struct glx_screen *psc;
391c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg
392c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   if (priv == NULL)
393c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg      return NULL;
394c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg
395c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   psc = priv->screens[gc->screen];
396c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   if (priv->drawHash == NULL)
397c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg      return NULL;
398c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg
399bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin   if (__glxHashLookup(priv->drawHash, glxDrawable, (void *) &pdraw) == 0) {
400bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin      pdraw->refcount ++;
401c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg      return pdraw;
402bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin   }
403c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg
404c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   pdraw = psc->driScreen->createDrawable(psc, glxDrawable,
405c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg                                          glxDrawable, gc->config);
4067a6324dbfe8d354b9b5f3181af0ce6bebbb374ccWang YanQing
4077a6324dbfe8d354b9b5f3181af0ce6bebbb374ccWang YanQing   if (pdraw == NULL) {
4087a6324dbfe8d354b9b5f3181af0ce6bebbb374ccWang YanQing      ErrorMessageF("failed to create drawable\n");
4097a6324dbfe8d354b9b5f3181af0ce6bebbb374ccWang YanQing      return NULL;
4107a6324dbfe8d354b9b5f3181af0ce6bebbb374ccWang YanQing   }
4117a6324dbfe8d354b9b5f3181af0ce6bebbb374ccWang YanQing
412c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   if (__glxHashInsert(priv->drawHash, glxDrawable, pdraw)) {
413c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg      (*pdraw->destroyDrawable) (pdraw);
414c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg      return NULL;
415c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   }
416bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin   pdraw->refcount = 1;
417c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg
418c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg   return pdraw;
419c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg}
420c491e585e43d48a2aeec96ccc4008da6c443fb42Kristian Høgsberg
42116887d042a917fa4773e4d853f50051b54e9948cKristian Høgsberg_X_HIDDEN void
42216887d042a917fa4773e4d853f50051b54e9948cKristian HøgsbergdriReleaseDrawables(struct glx_context *gc)
42316887d042a917fa4773e4d853f50051b54e9948cKristian Høgsberg{
4240f20e2e18f902b4319851643e1775a18c2aacb3dHenri Verbeet   const struct glx_display *priv = gc->psc->display;
42516887d042a917fa4773e4d853f50051b54e9948cKristian Høgsberg   __GLXDRIdrawable *pdraw;
42616887d042a917fa4773e4d853f50051b54e9948cKristian Høgsberg
42716887d042a917fa4773e4d853f50051b54e9948cKristian Høgsberg   if (priv == NULL)
42816887d042a917fa4773e4d853f50051b54e9948cKristian Høgsberg      return;
42916887d042a917fa4773e4d853f50051b54e9948cKristian Høgsberg
43016887d042a917fa4773e4d853f50051b54e9948cKristian Høgsberg   if (__glxHashLookup(priv->drawHash,
43116887d042a917fa4773e4d853f50051b54e9948cKristian Høgsberg		       gc->currentDrawable, (void *) &pdraw) == 0) {
4324b70fe8421f5132c585ff1dfb8d90229be26e71fKristian Høgsberg      if (pdraw->drawable == pdraw->xDrawable) {
433bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin	 pdraw->refcount --;
434bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin	 if (pdraw->refcount == 0) {
435bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin	    (*pdraw->destroyDrawable)(pdraw);
436bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin	    __glxHashDelete(priv->drawHash, gc->currentDrawable);
437bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin	 }
4384b70fe8421f5132c585ff1dfb8d90229be26e71fKristian Høgsberg      }
43916887d042a917fa4773e4d853f50051b54e9948cKristian Høgsberg   }
44016887d042a917fa4773e4d853f50051b54e9948cKristian Høgsberg
441bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin   if (__glxHashLookup(priv->drawHash,
44216887d042a917fa4773e4d853f50051b54e9948cKristian Høgsberg		       gc->currentReadable, (void *) &pdraw) == 0) {
4434b70fe8421f5132c585ff1dfb8d90229be26e71fKristian Høgsberg      if (pdraw->drawable == pdraw->xDrawable) {
444bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin	 pdraw->refcount --;
445bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin	 if (pdraw->refcount == 0) {
446bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin	    (*pdraw->destroyDrawable)(pdraw);
447bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin	    __glxHashDelete(priv->drawHash, gc->currentReadable);
448bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin	 }
4494b70fe8421f5132c585ff1dfb8d90229be26e71fKristian Høgsberg      }
45016887d042a917fa4773e4d853f50051b54e9948cKristian Høgsberg   }
451bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin
452bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin   gc->currentDrawable = None;
453bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin   gc->currentReadable = None;
454bf69ce37f0dcbb479078ee676d5100ac63e20750Stéphane Marchesin
45516887d042a917fa4773e4d853f50051b54e9948cKristian Høgsberg}
45616887d042a917fa4773e4d853f50051b54e9948cKristian Høgsberg
457b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick_X_HIDDEN bool
458b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanickdri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
459b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick			 unsigned *major_ver, unsigned *minor_ver,
460a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick			 uint32_t *flags, unsigned *api, int *reset,
461a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick                         unsigned *error)
462b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick{
463b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   unsigned i;
464b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   bool got_profile = false;
465b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   uint32_t profile;
466b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   int render_type = GLX_RGBA_TYPE;
467b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick
46810a6fde333f0170fbac70924581c647e531aba3eKenneth Graunke   if (num_attribs == 0) {
46910a6fde333f0170fbac70924581c647e531aba3eKenneth Graunke      *api = __DRI_API_OPENGL;
470b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      return true;
47110a6fde333f0170fbac70924581c647e531aba3eKenneth Graunke   }
472b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick
473b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   /* This is actually an internal error, but what the heck.
474b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick    */
475b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   if (attribs == NULL) {
476b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
477b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      return false;
478b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   }
479b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick
480b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   *major_ver = 1;
481b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   *minor_ver = 0;
482a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick   *reset = __DRI_CTX_RESET_NO_NOTIFICATION;
483b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick
484b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   for (i = 0; i < num_attribs; i++) {
485b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      switch (attribs[i * 2]) {
486b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      case GLX_CONTEXT_MAJOR_VERSION_ARB:
487b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 *major_ver = attribs[i * 2 + 1];
488b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 break;
489b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      case GLX_CONTEXT_MINOR_VERSION_ARB:
490b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 *minor_ver = attribs[i * 2 + 1];
491b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 break;
492b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      case GLX_CONTEXT_FLAGS_ARB:
493b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 *flags = attribs[i * 2 + 1];
494b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 break;
495b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      case GLX_CONTEXT_PROFILE_MASK_ARB:
496b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 profile = attribs[i * 2 + 1];
497b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 got_profile = true;
498b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 break;
499b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      case GLX_RENDER_TYPE:
500b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 render_type = attribs[i * 2 + 1];
501b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 break;
502a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick      case GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB:
503a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick         switch (attribs[i * 2 + 1]) {
504a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick         case GLX_NO_RESET_NOTIFICATION_ARB:
505a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick            *reset = __DRI_CTX_RESET_NO_NOTIFICATION;
506a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick            break;
507a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick         case GLX_LOSE_CONTEXT_ON_RESET_ARB:
508a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick            *reset = __DRI_CTX_RESET_LOSE_CONTEXT;
509a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick            break;
510a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick         default:
511a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick            *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
512a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick            return false;
513a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick         }
514a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick         break;
515b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      default:
516b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 /* If an unknown attribute is received, fail.
517b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	  */
518b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
519b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 return false;
520b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      }
521b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   }
522b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick
523b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   *api = __DRI_API_OPENGL;
524b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   if (!got_profile) {
525b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      if (*major_ver > 3 || (*major_ver == 3 && *minor_ver >= 2))
526b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 *api = __DRI_API_OPENGL_CORE;
527b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   } else {
528b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      switch (profile) {
529b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      case GLX_CONTEXT_CORE_PROFILE_BIT_ARB:
530b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 /* There are no profiles before OpenGL 3.2.  The
531b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	  * GLX_ARB_create_context_profile spec says:
532b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	  *
533b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	  *     "If the requested OpenGL version is less than 3.2,
534b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	  *     GLX_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality
535b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	  *     of the context is determined solely by the requested version."
536b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	  */
537b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 *api = (*major_ver > 3 || (*major_ver == 3 && *minor_ver >= 2))
538b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	    ? __DRI_API_OPENGL_CORE : __DRI_API_OPENGL;
539b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 break;
540b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      case GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
541b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 *api = __DRI_API_OPENGL;
542b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 break;
543e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick      case GLX_CONTEXT_ES2_PROFILE_BIT_EXT:
544e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick	 *api = __DRI_API_GLES2;
545e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick	 break;
546b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      default:
547b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 *error = __DRI_CTX_ERROR_BAD_API;
548b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick	 return false;
549b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      }
550b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   }
551b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick
552b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   /* Unknown flag value.
553b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick    */
554a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick   if (*flags & ~(__DRI_CTX_FLAG_DEBUG | __DRI_CTX_FLAG_FORWARD_COMPATIBLE
555a8724d85f8cb2f0fb73b9c6c1f268f9084c6d473Ian Romanick                  | __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS)) {
556b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      *error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
557b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      return false;
558b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   }
559b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick
560b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   /* There are no forward-compatible contexts before OpenGL 3.0.  The
561b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick    * GLX_ARB_create_context spec says:
562b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick    *
563b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick    *     "Forward-compatible contexts are defined only for OpenGL versions
564b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick    *     3.0 and later."
565b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick    */
566b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   if (*major_ver < 3 && (*flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0) {
567b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      *error = __DRI_CTX_ERROR_BAD_FLAG;
568b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      return false;
569b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   }
570b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick
571b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   if (*major_ver >= 3 && render_type == GLX_COLOR_INDEX_TYPE) {
572b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      *error = __DRI_CTX_ERROR_BAD_FLAG;
573b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick      return false;
574b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   }
575b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick
576e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick   /* The GLX_EXT_create_context_es2_profile spec says:
577e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick    *
578e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick    *     "... If the version requested is 2.0, and the
579e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick    *     GLX_CONTEXT_ES2_PROFILE_BIT_EXT bit is set in the
580e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick    *     GLX_CONTEXT_PROFILE_MASK_ARB attribute (see below), then the context
581e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick    *     returned will implement OpenGL ES 2.0. This is the only way in which
582e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick    *     an implementation may request an OpenGL ES 2.0 context."
583e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick    */
584e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick   if (*api == __DRI_API_GLES2 && (*major_ver != 2 || *minor_ver != 0)) {
585e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick      *error = __DRI_CTX_ERROR_BAD_API;
586e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick      return false;
587e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick   }
588e6280c3ba9579bf01f8b82e19497ba8f142a8d09Ian Romanick
589b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   *error = __DRI_CTX_ERROR_SUCCESS;
590b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick   return true;
591b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick}
592b45f77dc4c9662a774c19db764bb8f95c4f61073Ian Romanick
593079345703901b497f2c09714051b33bb2dff1b4fGeorge Sapountzis#endif /* GLX_DIRECT_RENDERING */
594