2 * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
3 * Copyright © 2008 Red Hat, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Soft-
7 * ware"), to deal in the Software without restriction, including without
8 * limitation the rights to use, copy, modify, merge, publish, distribute,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, provided that the above copyright
11 * notice(s) and this permission notice appear in all copies of the Soft-
12 * ware and that both the above copyright notice(s) and this permission
13 * notice appear in supporting documentation.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
17 * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
18 * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
19 * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
20 * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
23 * MANCE OF THIS SOFTWARE.
25 * Except as contained in this notice, the name of a copyright holder shall
26 * not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization of
28 * the copyright holder.
31 * Kevin E. Martin <kevin@precisioninsight.com>
32 * Brian Paul <brian@precisioninsight.com>
33 * Kristian Høgsberg (krh@redhat.com)
36 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
41 #include "glxclient.h"
42 #include "glcontextmodes.h"
43 #include "dri_common.h"
53 InfoMessageF(const char *f
, ...)
58 if ((env
= getenv("LIBGL_DEBUG")) && strstr(env
, "verbose")) {
59 fprintf(stderr
, "libGL: ");
61 vfprintf(stderr
, f
, args
);
67 * Print error to stderr, unless LIBGL_DEBUG=="quiet".
70 ErrorMessageF(const char *f
, ...)
75 if ((env
= getenv("LIBGL_DEBUG")) && !strstr(env
, "quiet")) {
76 fprintf(stderr
, "libGL error: ");
78 vfprintf(stderr
, f
, args
);
83 #ifndef DEFAULT_DRIVER_DIR
84 /* this is normally defined in Mesa/configs/default with DRI_DRIVER_SEARCH_PATH */
85 #define DEFAULT_DRIVER_DIR "/usr/local/lib/dri"
89 * Try to \c dlopen the named driver.
91 * This function adds the "_dri.so" suffix to the driver name and searches the
92 * directories specified by the \c LIBGL_DRIVERS_PATH environment variable in
93 * order to find the driver.
95 * \param driverName - a name like "tdfx", "i810", "mga", etc.
98 * A handle from \c dlopen, or \c NULL if driver file not found.
101 driOpenDriver(const char *driverName
)
103 void *glhandle
, *handle
;
104 const char *libPaths
, *p
, *next
;
105 char realDriverName
[200];
108 /* Attempt to make sure libGL symbols will be visible to the driver */
109 glhandle
= dlopen("libGL.so.1", RTLD_NOW
| RTLD_GLOBAL
);
112 if (geteuid() == getuid()) {
113 /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
114 libPaths
= getenv("LIBGL_DRIVERS_PATH");
116 libPaths
= getenv("LIBGL_DRIVERS_DIR"); /* deprecated */
118 if (libPaths
== NULL
)
119 libPaths
= DEFAULT_DRIVER_DIR
;
122 for (p
= libPaths
; *p
; p
= next
) {
123 next
= strchr(p
, ':');
134 snprintf(realDriverName
, sizeof realDriverName
,
135 "%.*s/tls/%s_dri.so", len
, p
, driverName
);
136 InfoMessageF("OpenDriver: trying %s\n", realDriverName
);
137 handle
= dlopen(realDriverName
, RTLD_NOW
| RTLD_GLOBAL
);
140 if (handle
== NULL
) {
141 snprintf(realDriverName
, sizeof realDriverName
,
142 "%.*s/%s_dri.so", len
, p
, driverName
);
143 InfoMessageF("OpenDriver: trying %s\n", realDriverName
);
144 handle
= dlopen(realDriverName
, RTLD_NOW
| RTLD_GLOBAL
);
150 ErrorMessageF("dlopen %s failed (%s)\n", realDriverName
, dlerror());
154 ErrorMessageF("unable to load driver: %s_dri.so\n", driverName
);
163 __driGetMSCRate(__DRIdrawable
*draw
,
164 int32_t * numerator
, int32_t * denominator
,
167 __GLXDRIdrawable
*glxDraw
= loaderPrivate
;
169 return __glxGetMscRate(glxDraw
, numerator
, denominator
);
172 _X_HIDDEN
const __DRIsystemTimeExtension systemTimeExtension
= {
173 {__DRI_SYSTEM_TIME
, __DRI_SYSTEM_TIME_VERSION
},
178 #define __ATTRIB(attrib, field) \
179 { attrib, offsetof(struct glx_config, field) }
183 unsigned int attrib
, offset
;
185 __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE
, rgbBits
),
186 __ATTRIB(__DRI_ATTRIB_LEVEL
, level
),
187 __ATTRIB(__DRI_ATTRIB_RED_SIZE
, redBits
),
188 __ATTRIB(__DRI_ATTRIB_GREEN_SIZE
, greenBits
),
189 __ATTRIB(__DRI_ATTRIB_BLUE_SIZE
, blueBits
),
190 __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE
, alphaBits
),
191 __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE
, depthBits
),
192 __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE
, stencilBits
),
193 __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE
, accumRedBits
),
194 __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE
, accumGreenBits
),
195 __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE
, accumBlueBits
),
196 __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE
, accumAlphaBits
),
197 __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS
, sampleBuffers
),
198 __ATTRIB(__DRI_ATTRIB_SAMPLES
, samples
),
199 __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER
, doubleBufferMode
),
200 __ATTRIB(__DRI_ATTRIB_STEREO
, stereoMode
),
201 __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS
, numAuxBuffers
),
203 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE
, transparentPixel
),
204 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE
, transparentIndex
),
205 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE
, transparentRed
),
206 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE
, transparentGreen
),
207 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE
, transparentBlue
),
208 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE
, transparentAlpha
),
209 __ATTRIB(__DRI_ATTRIB_RED_MASK
, redMask
),
210 __ATTRIB(__DRI_ATTRIB_GREEN_MASK
, greenMask
),
211 __ATTRIB(__DRI_ATTRIB_BLUE_MASK
, blueMask
),
212 __ATTRIB(__DRI_ATTRIB_ALPHA_MASK
, alphaMask
),
214 __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH
, maxPbufferWidth
),
215 __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT
, maxPbufferHeight
),
216 __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS
, maxPbufferPixels
),
217 __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH
, optimalPbufferWidth
),
218 __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT
, optimalPbufferHeight
),
220 __ATTRIB(__DRI_ATTRIB_SWAP_METHOD
, swapMethod
),
222 __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB
, bindToTextureRgb
),
223 __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA
, bindToTextureRgba
),
224 __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE
,
225 bindToMipmapTexture
),
226 __ATTRIB(__DRI_ATTRIB_YINVERTED
, yInverted
),};
229 scalarEqual(struct glx_config
*mode
, unsigned int attrib
, unsigned int value
)
231 unsigned int glxValue
;
234 for (i
= 0; i
< ARRAY_SIZE(attribMap
); i
++)
235 if (attribMap
[i
].attrib
== attrib
) {
236 glxValue
= *(unsigned int *) ((char *) mode
+ attribMap
[i
].offset
);
237 return glxValue
== GLX_DONT_CARE
|| glxValue
== value
;
240 return GL_TRUE
; /* Is a non-existing attribute equal to value? */
244 driConfigEqual(const __DRIcoreExtension
*core
,
245 struct glx_config
*config
, const __DRIconfig
*driConfig
)
247 unsigned int attrib
, value
, glxValue
;
251 while (core
->indexConfigAttrib(driConfig
, i
++, &attrib
, &value
)) {
253 case __DRI_ATTRIB_RENDER_TYPE
:
255 if (value
& __DRI_ATTRIB_RGBA_BIT
) {
256 glxValue
|= GLX_RGBA_BIT
;
258 else if (value
& __DRI_ATTRIB_COLOR_INDEX_BIT
) {
259 glxValue
|= GLX_COLOR_INDEX_BIT
;
261 if (glxValue
!= config
->renderType
)
265 case __DRI_ATTRIB_CONFIG_CAVEAT
:
266 if (value
& __DRI_ATTRIB_NON_CONFORMANT_CONFIG
)
267 glxValue
= GLX_NON_CONFORMANT_CONFIG
;
268 else if (value
& __DRI_ATTRIB_SLOW_BIT
)
269 glxValue
= GLX_SLOW_CONFIG
;
272 if (glxValue
!= config
->visualRating
)
276 case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS
:
278 if (value
& __DRI_ATTRIB_TEXTURE_1D_BIT
)
279 glxValue
|= GLX_TEXTURE_1D_BIT_EXT
;
280 if (value
& __DRI_ATTRIB_TEXTURE_2D_BIT
)
281 glxValue
|= GLX_TEXTURE_2D_BIT_EXT
;
282 if (value
& __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT
)
283 glxValue
|= GLX_TEXTURE_RECTANGLE_BIT_EXT
;
284 if (config
->bindToTextureTargets
!= GLX_DONT_CARE
&&
285 glxValue
!= config
->bindToTextureTargets
)
290 if (!scalarEqual(config
, attrib
, value
))
298 static struct glx_config
*
299 createDriMode(const __DRIcoreExtension
* core
,
300 struct glx_config
*config
, const __DRIconfig
**driConfigs
)
302 __GLXDRIconfigPrivate
*driConfig
;
305 for (i
= 0; driConfigs
[i
]; i
++) {
306 if (driConfigEqual(core
, config
, driConfigs
[i
]))
310 if (driConfigs
[i
] == NULL
)
313 driConfig
= Xmalloc(sizeof *driConfig
);
314 if (driConfig
== NULL
)
317 driConfig
->base
= *config
;
318 driConfig
->driConfig
= driConfigs
[i
];
320 return &driConfig
->base
;
323 _X_HIDDEN
struct glx_config
*
324 driConvertConfigs(const __DRIcoreExtension
* core
,
325 struct glx_config
*configs
, const __DRIconfig
**driConfigs
)
327 struct glx_config head
, *tail
, *m
;
331 for (m
= configs
; m
; m
= m
->next
) {
332 tail
->next
= createDriMode(core
, m
, driConfigs
);
333 if (tail
->next
== NULL
) {
334 /* no matching dri config for m */
342 glx_config_destroy_list(configs
);
348 driDestroyConfigs(const __DRIconfig
**configs
)
352 for (i
= 0; configs
[i
]; i
++)
353 free((__DRIconfig
*) configs
[i
]);
357 #endif /* GLX_DIRECT_RENDERING */