2 * Copyright © 2008 Red Hat, Inc
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without
6 * fee, provided that the above copyright notice appear in all copies
7 * and that both that copyright notice and this permission notice
8 * appear in supporting documentation, and that the name of the
9 * copyright holders not be used in advertising or publicity
10 * pertaining to distribution of the software without specific,
11 * written prior permission. The copyright holders make no
12 * representations about the suitability of this software for any
13 * purpose. It is provided "as is" without express or implied
16 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
17 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
21 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
22 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
26 #ifdef HAVE_DIX_CONFIG_H
27 #include <dix-config.h>
35 #include <GL/glxtokens.h>
36 #include <GL/internal/dri_interface.h>
38 #include "glxserver.h"
40 #include "glxcontext.h"
41 #include "glxscreens.h"
42 #include "glxdricommon.h"
52 if (gettimeofday(&tv
, NULL
) == 0) {
53 ust
[0] = (tv
.tv_sec
* 1000000) + tv
.tv_usec
;
61 const __DRIsystemTimeExtension systemTimeExtension
= {
62 {__DRI_SYSTEM_TIME
, 1},
67 #define __ATTRIB(attrib, field) \
68 { attrib, offsetof(__GLXconfig, field) }
71 unsigned int attrib
, offset
;
73 __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE
, rgbBits
),
74 __ATTRIB(__DRI_ATTRIB_LEVEL
, level
),
75 __ATTRIB(__DRI_ATTRIB_RED_SIZE
, redBits
),
76 __ATTRIB(__DRI_ATTRIB_GREEN_SIZE
, greenBits
),
77 __ATTRIB(__DRI_ATTRIB_BLUE_SIZE
, blueBits
),
78 __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE
, alphaBits
),
79 __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE
, depthBits
),
80 __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE
, stencilBits
),
81 __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE
, accumRedBits
),
82 __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE
, accumGreenBits
),
83 __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE
, accumBlueBits
),
84 __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE
, accumAlphaBits
),
85 __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS
, sampleBuffers
),
86 __ATTRIB(__DRI_ATTRIB_SAMPLES
, samples
),
87 __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER
, doubleBufferMode
),
88 __ATTRIB(__DRI_ATTRIB_STEREO
, stereoMode
),
89 __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS
, numAuxBuffers
),
90 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE
, transparentPixel
),
91 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE
, transparentPixel
),
92 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE
, transparentRed
),
93 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE
, transparentGreen
),
94 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE
, transparentBlue
),
95 __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE
, transparentAlpha
),
96 __ATTRIB(__DRI_ATTRIB_RED_MASK
, redMask
),
97 __ATTRIB(__DRI_ATTRIB_GREEN_MASK
, greenMask
),
98 __ATTRIB(__DRI_ATTRIB_BLUE_MASK
, blueMask
),
99 __ATTRIB(__DRI_ATTRIB_ALPHA_MASK
, alphaMask
),
100 __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH
, maxPbufferWidth
),
101 __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT
, maxPbufferHeight
),
102 __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS
, maxPbufferPixels
),
103 __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH
, optimalPbufferWidth
),
104 __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT
, optimalPbufferHeight
),
105 __ATTRIB(__DRI_ATTRIB_SWAP_METHOD
, swapMethod
),
106 __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB
, bindToTextureRgb
),
107 __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA
, bindToTextureRgba
),
108 __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE
, bindToMipmapTexture
),
109 __ATTRIB(__DRI_ATTRIB_YINVERTED
, yInverted
),
110 __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE
, sRGBCapable
),
114 setScalar(__GLXconfig
* config
, unsigned int attrib
, unsigned int value
)
118 for (i
= 0; i
< ARRAY_SIZE(attribMap
); i
++)
119 if (attribMap
[i
].attrib
== attrib
) {
120 *(unsigned int *) ((char *) config
+ attribMap
[i
].offset
) = value
;
126 createModeFromConfig(const __DRIcoreExtension
* core
,
127 const __DRIconfig
* driConfig
,
128 unsigned int visualType
, unsigned int drawableType
)
130 __GLXDRIconfig
*config
;
131 GLint renderType
= 0;
132 unsigned int attrib
, value
;
135 config
= calloc(1, sizeof *config
);
137 config
->driConfig
= driConfig
;
140 while (core
->indexConfigAttrib(driConfig
, i
++, &attrib
, &value
)) {
142 case __DRI_ATTRIB_RENDER_TYPE
:
143 if (value
& __DRI_ATTRIB_RGBA_BIT
)
144 renderType
|= GLX_RGBA_BIT
;
145 if (value
& __DRI_ATTRIB_COLOR_INDEX_BIT
)
146 renderType
|= GLX_COLOR_INDEX_BIT
;
147 if (value
& __DRI_ATTRIB_FLOAT_BIT
)
148 renderType
|= GLX_RGBA_FLOAT_BIT_ARB
;
149 if (value
& __DRI_ATTRIB_UNSIGNED_FLOAT_BIT
)
150 renderType
|= GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT
;
152 case __DRI_ATTRIB_CONFIG_CAVEAT
:
153 if (value
& __DRI_ATTRIB_NON_CONFORMANT_CONFIG
)
154 config
->config
.visualRating
= GLX_NON_CONFORMANT_CONFIG
;
155 else if (value
& __DRI_ATTRIB_SLOW_BIT
)
156 config
->config
.visualRating
= GLX_SLOW_CONFIG
;
158 config
->config
.visualRating
= GLX_NONE
;
160 case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS
:
161 config
->config
.bindToTextureTargets
= 0;
162 if (value
& __DRI_ATTRIB_TEXTURE_1D_BIT
)
163 config
->config
.bindToTextureTargets
|= GLX_TEXTURE_1D_BIT_EXT
;
164 if (value
& __DRI_ATTRIB_TEXTURE_2D_BIT
)
165 config
->config
.bindToTextureTargets
|= GLX_TEXTURE_2D_BIT_EXT
;
166 if (value
& __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT
)
167 config
->config
.bindToTextureTargets
|=
168 GLX_TEXTURE_RECTANGLE_BIT_EXT
;
171 setScalar(&config
->config
, attrib
, value
);
176 config
->config
.next
= NULL
;
177 config
->config
.xRenderable
= GL_TRUE
;
178 config
->config
.visualType
= visualType
;
179 config
->config
.renderType
= renderType
;
180 config
->config
.drawableType
= drawableType
;
181 config
->config
.yInverted
= GL_TRUE
;
183 return &config
->config
;
187 render_type_is_pbuffer_only(unsigned renderType
)
189 /* The GL_ARB_color_buffer_float spec says:
191 * "Note that floating point rendering is only supported for
192 * GLXPbuffer drawables. The GLX_DRAWABLE_TYPE attribute of the
193 * GLXFBConfig must have the GLX_PBUFFER_BIT bit set and the
194 * GLX_RENDER_TYPE attribute must have the GLX_RGBA_FLOAT_BIT set."
196 return !!(renderType
& (__DRI_ATTRIB_UNSIGNED_FLOAT_BIT
197 | __DRI_ATTRIB_FLOAT_BIT
));
201 glxConvertConfigs(const __DRIcoreExtension
* core
,
202 const __DRIconfig
** configs
, unsigned int drawableType
)
204 __GLXconfig head
, *tail
;
210 for (i
= 0; configs
[i
]; i
++) {
211 unsigned renderType
= 0;
212 if (core
->getConfigAttrib(configs
[i
], __DRI_ATTRIB_RENDER_TYPE
,
214 if (render_type_is_pbuffer_only(renderType
) &&
215 !(drawableType
& GLX_PBUFFER_BIT
))
218 /* Add all the others */
219 tail
->next
= createModeFromConfig(core
,
220 configs
[i
], GLX_TRUE_COLOR
,
222 if (tail
->next
== NULL
)
228 for (i
= 0; configs
[i
]; i
++) {
230 if (core
->getConfigAttrib(configs
[i
], __DRI_ATTRIB_RENDER_TYPE
,
232 if (render_type_is_pbuffer_only(renderType
) &&
233 !(drawableType
& GLX_PBUFFER_BIT
))
236 /* Add all the others */
237 tail
->next
= createModeFromConfig(core
,
238 configs
[i
], GLX_DIRECT_COLOR
,
240 if (tail
->next
== NULL
)
249 static const char dri_driver_path
[] = DRI_DRIVER_PATH
;
251 /* Temporary define to allow building without a dri_interface.h from
252 * updated Mesa. Some day when we don't care about Mesa that old any
253 * more this can be removed.
255 #ifndef __DRI_DRIVER_GET_EXTENSIONS
256 #define __DRI_DRIVER_GET_EXTENSIONS "__driDriverGetExtensions"
260 glxProbeDriver(const char *driverName
,
261 void **coreExt
, const char *coreName
, int coreVersion
,
262 void **renderExt
, const char *renderName
, int renderVersion
)
266 char filename
[PATH_MAX
];
267 char *get_extensions_name
;
268 const __DRIextension
**extensions
= NULL
;
270 snprintf(filename
, sizeof filename
, "%s/%s_dri.so",
271 dri_driver_path
, driverName
);
273 driver
= dlopen(filename
, RTLD_LAZY
| RTLD_LOCAL
);
274 if (driver
== NULL
) {
275 LogMessage(X_ERROR
, "AIGLX error: dlopen of %s failed (%s)\n",
276 filename
, dlerror());
277 goto cleanup_failure
;
280 if (asprintf(&get_extensions_name
, "%s_%s",
281 __DRI_DRIVER_GET_EXTENSIONS
, driverName
) != -1) {
282 const __DRIextension
**(*get_extensions
)(void);
284 get_extensions
= dlsym(driver
, get_extensions_name
);
286 extensions
= get_extensions();
287 free(get_extensions_name
);
291 extensions
= dlsym(driver
, __DRI_DRIVER_EXTENSIONS
);
292 if (extensions
== NULL
) {
293 LogMessage(X_ERROR
, "AIGLX error: %s exports no extensions (%s)\n",
294 driverName
, dlerror());
295 goto cleanup_failure
;
298 for (i
= 0; extensions
[i
]; i
++) {
299 if (strcmp(extensions
[i
]->name
, coreName
) == 0 &&
300 extensions
[i
]->version
>= coreVersion
) {
301 *coreExt
= (void *) extensions
[i
];
304 if (strcmp(extensions
[i
]->name
, renderName
) == 0 &&
305 extensions
[i
]->version
>= renderVersion
) {
306 *renderExt
= (void *) extensions
[i
];
310 if (*coreExt
== NULL
|| *renderExt
== NULL
) {
312 "AIGLX error: %s does not export required DRI extension\n",
314 goto cleanup_failure
;
321 *coreExt
= *renderExt
= NULL
;