2 * (C) Copyright IBM Corporation 2002, 2004
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * \file glxextensions.c
28 * \author Ian Romanick <idr@us.ibm.com>
31 #include "glxclient.h"
32 #include <X11/extensions/extutil.h>
33 #include <X11/extensions/Xext.h>
35 #include "glxextensions.h"
38 #define SET_BIT(m,b) (m[ (b) / 8 ] |= (1U << ((b) % 8)))
39 #define CLR_BIT(m,b) (m[ (b) / 8 ] &= ~(1U << ((b) % 8)))
40 #define IS_SET(m,b) ((m[ (b) / 8 ] & (1U << ((b) % 8))) != 0)
41 #define CONCAT(a,b) a ## b
42 #define GLX(n) "GLX_" # n, 4 + sizeof( # n ) - 1, CONCAT(n,_bit)
43 #define GL(n) "GL_" # n, 3 + sizeof( # n ) - 1, GL_ ## n ## _bit
47 #define EXT_ENABLED(bit,supported) (IS_SET( supported, bit ))
52 const char *const name
;
57 /* This is the lowest version of GLX that "requires" this extension.
58 * For example, GLX 1.3 requires SGIX_fbconfig, SGIX_pbuffer, and
59 * SGI_make_current_read. If the extension is not required by any known
60 * version of GLX, use 0, 0.
62 unsigned char version_major
;
63 unsigned char version_minor
;
66 * The client (i.e., libGL) supports this extension.
68 * Except during bring up, all extensions should have this set to Y. There
69 * are a few cases of extensions that have partial (or speculative)
70 * support, but these are rare. There also shouldn't be any new ones
73 * Generally, extensions require server support and ::client_support to be
74 * enabled. If the display is capable of direct rendering,
75 * ::direct_support is also required.
79 unsigned char client_support
;
82 * The direct-renderer (e.g., i965_dri.so) supports this extension.
84 * For cases where all of the infrastructure to support the extension is a
85 * required part of the loader/driver interface, this can default to Y.
86 * For most cases, extended functionality, usually in the form of DRI2
87 * extensions, is necessary to support the extension. The loader will set
88 * the flag true if all the requirements are met.
90 * If the display is capable of direct rendering, ::direct_support is
91 * required for the extension to be enabled.
93 unsigned char direct_support
;
96 * The extension depends only on client support.
98 * This is for extensions like GLX_ARB_get_proc_address that are contained
99 * entirely in the client library. There is no dependency on the server or
100 * the direct-renderer.
102 * These extensions will be enabled if ::client_support is set.
105 * An extension \b cannot be both client-only and direct-only because being
106 * direct-only implies a dependency on the direct renderer.
108 * \sa ::client_support, ::direct_only
110 unsigned char client_only
;
113 * The extension only functions with direct-rendering contexts
115 * The extension has no GLX protocol, and, therefore, no explicit
116 * dependency on the server. The functionality is contained entirely in
117 * the client library and the direct renderer. A few of the swap-related
118 * extensions are intended to behave this way.
120 * These extensions will be enabled if both ::client_support and
121 * ::direct_support are set.
124 * An extension \b cannot be both client-only and direct-only because being
125 * client-only implies that all functionality is outside the
128 * \sa ::direct_support, ::client_only
130 unsigned char direct_only
;
134 static const struct extension_info known_glx_extensions
[] = {
135 { GLX(ARB_create_context
), VER(0,0), Y
, N
, N
, N
},
136 { GLX(ARB_create_context_profile
), VER(0,0), Y
, N
, N
, N
},
137 { GLX(ARB_create_context_robustness
), VER(0,0), Y
, N
, N
, N
},
138 { GLX(ARB_fbconfig_float
), VER(0,0), Y
, Y
, N
, N
},
139 { GLX(ARB_framebuffer_sRGB
), VER(0,0), Y
, Y
, N
, N
},
140 { GLX(ARB_get_proc_address
), VER(1,4), Y
, N
, Y
, N
},
141 { GLX(ARB_multisample
), VER(1,4), Y
, Y
, N
, N
},
142 { GLX(ATI_pixel_format_float
), VER(0,0), N
, N
, N
, N
},
143 { GLX(EXT_import_context
), VER(0,0), Y
, Y
, N
, N
},
144 { GLX(EXT_visual_info
), VER(0,0), Y
, Y
, N
, N
},
145 { GLX(EXT_visual_rating
), VER(0,0), Y
, Y
, N
, N
},
146 { GLX(EXT_fbconfig_packed_float
), VER(0,0), Y
, Y
, N
, N
},
147 { GLX(EXT_framebuffer_sRGB
), VER(0,0), Y
, Y
, N
, N
},
148 { GLX(EXT_create_context_es2_profile
), VER(0,0), Y
, N
, N
, N
},
149 { GLX(MESA_copy_sub_buffer
), VER(0,0), Y
, N
, N
, N
},
150 { GLX(MESA_multithread_makecurrent
),VER(0,0), Y
, N
, Y
, N
},
151 { GLX(MESA_query_renderer
), VER(0,0), Y
, N
, N
, Y
},
152 { GLX(MESA_swap_control
), VER(0,0), Y
, N
, N
, Y
},
153 { GLX(NV_float_buffer
), VER(0,0), N
, N
, N
, N
},
154 { GLX(OML_swap_method
), VER(0,0), Y
, Y
, N
, N
},
155 { GLX(OML_sync_control
), VER(0,0), Y
, N
, N
, Y
},
156 { GLX(SGI_make_current_read
), VER(1,3), Y
, N
, N
, N
},
157 { GLX(SGI_swap_control
), VER(0,0), Y
, N
, N
, N
},
158 { GLX(SGI_video_sync
), VER(0,0), Y
, N
, N
, Y
},
159 { GLX(SGIS_multisample
), VER(0,0), Y
, Y
, N
, N
},
160 { GLX(SGIX_fbconfig
), VER(1,3), Y
, Y
, N
, N
},
161 { GLX(SGIX_pbuffer
), VER(1,3), Y
, Y
, N
, N
},
162 { GLX(SGIX_swap_barrier
), VER(0,0), N
, N
, N
, N
},
163 { GLX(SGIX_swap_group
), VER(0,0), N
, N
, N
, N
},
164 { GLX(SGIX_visual_select_group
), VER(0,0), Y
, Y
, N
, N
},
165 { GLX(EXT_texture_from_pixmap
), VER(0,0), Y
, N
, N
, N
},
166 { GLX(INTEL_swap_event
), VER(0,0), Y
, N
, N
, N
},
167 { GLX(EXT_buffer_age
), VER(0,0), Y
, N
, N
, Y
},
171 static const struct extension_info known_gl_extensions
[] = {
172 { GL(ARB_depth_texture
), VER(1,4), Y
, N
, N
, N
},
173 { GL(ARB_draw_buffers
), VER(0,0), Y
, N
, N
, N
},
174 { GL(ARB_fragment_program
), VER(0,0), Y
, N
, N
, N
},
175 { GL(ARB_fragment_program_shadow
), VER(0,0), Y
, N
, N
, N
},
176 { GL(ARB_framebuffer_object
), VER(0,0), Y
, N
, N
, N
},
177 { GL(ARB_imaging
), VER(0,0), Y
, N
, N
, N
},
178 { GL(ARB_multisample
), VER(1,3), Y
, N
, N
, N
},
179 { GL(ARB_multitexture
), VER(1,3), Y
, N
, N
, N
},
180 { GL(ARB_occlusion_query
), VER(1,5), Y
, N
, N
, N
},
181 { GL(ARB_point_parameters
), VER(1,4), Y
, N
, N
, N
},
182 { GL(ARB_point_sprite
), VER(0,0), Y
, N
, N
, N
},
183 { GL(ARB_shadow
), VER(1,4), Y
, N
, N
, N
},
184 { GL(ARB_shadow_ambient
), VER(0,0), Y
, N
, N
, N
},
185 { GL(ARB_texture_border_clamp
), VER(1,3), Y
, N
, N
, N
},
186 { GL(ARB_texture_compression
), VER(1,3), Y
, N
, N
, N
},
187 { GL(ARB_texture_cube_map
), VER(1,3), Y
, N
, N
, N
},
188 { GL(ARB_texture_env_add
), VER(1,3), Y
, N
, N
, N
},
189 { GL(ARB_texture_env_combine
), VER(1,3), Y
, N
, N
, N
},
190 { GL(ARB_texture_env_crossbar
), VER(1,4), Y
, N
, N
, N
},
191 { GL(ARB_texture_env_dot3
), VER(1,3), Y
, N
, N
, N
},
192 { GL(ARB_texture_mirrored_repeat
), VER(1,4), Y
, N
, N
, N
},
193 { GL(ARB_texture_non_power_of_two
), VER(1,5), Y
, N
, N
, N
},
194 { GL(ARB_texture_rectangle
), VER(0,0), Y
, N
, N
, N
},
195 { GL(ARB_texture_rg
), VER(0,0), Y
, N
, N
, N
},
196 { GL(ARB_transpose_matrix
), VER(1,3), Y
, N
, Y
, N
},
197 { GL(ARB_vertex_buffer_object
), VER(1,5), N
, N
, N
, N
},
198 { GL(ARB_vertex_program
), VER(0,0), Y
, N
, N
, N
},
199 { GL(ARB_window_pos
), VER(1,4), Y
, N
, N
, N
},
200 { GL(EXT_abgr
), VER(0,0), Y
, N
, N
, N
},
201 { GL(EXT_bgra
), VER(1,2), Y
, N
, N
, N
},
202 { GL(EXT_blend_color
), VER(1,4), Y
, N
, N
, N
},
203 { GL(EXT_blend_equation_separate
), VER(0,0), Y
, N
, N
, N
},
204 { GL(EXT_blend_func_separate
), VER(1,4), Y
, N
, N
, N
},
205 { GL(EXT_blend_logic_op
), VER(1,4), Y
, N
, N
, N
},
206 { GL(EXT_blend_minmax
), VER(1,4), Y
, N
, N
, N
},
207 { GL(EXT_blend_subtract
), VER(1,4), Y
, N
, N
, N
},
208 { GL(EXT_clip_volume_hint
), VER(0,0), Y
, N
, N
, N
},
209 { GL(EXT_compiled_vertex_array
), VER(0,0), N
, N
, N
, N
},
210 { GL(EXT_convolution
), VER(0,0), N
, N
, N
, N
},
211 { GL(EXT_copy_texture
), VER(1,1), Y
, N
, N
, N
},
212 { GL(EXT_cull_vertex
), VER(0,0), N
, N
, N
, N
},
213 { GL(EXT_depth_bounds_test
), VER(0,0), N
, N
, N
, N
},
214 { GL(EXT_draw_range_elements
), VER(1,2), Y
, N
, Y
, N
},
215 { GL(EXT_fog_coord
), VER(1,4), Y
, N
, N
, N
},
216 { GL(EXT_framebuffer_blit
), VER(0,0), Y
, N
, N
, N
},
217 { GL(EXT_framebuffer_multisample
), VER(0,0), Y
, N
, N
, N
},
218 { GL(EXT_framebuffer_object
), VER(0,0), Y
, N
, N
, N
},
219 { GL(EXT_framebuffer_sRGB
), VER(0,0), Y
, N
, N
, N
},
220 { GL(EXT_multi_draw_arrays
), VER(1,4), Y
, N
, Y
, N
},
221 { GL(EXT_packed_depth_stencil
), VER(0,0), Y
, N
, N
, N
},
222 { GL(EXT_packed_pixels
), VER(1,2), Y
, N
, N
, N
},
223 { GL(EXT_paletted_texture
), VER(0,0), Y
, N
, N
, N
},
224 { GL(EXT_pixel_buffer_object
), VER(0,0), N
, N
, N
, N
},
225 { GL(EXT_point_parameters
), VER(1,4), Y
, N
, N
, N
},
226 { GL(EXT_polygon_offset
), VER(1,1), Y
, N
, N
, N
},
227 { GL(EXT_rescale_normal
), VER(1,2), Y
, N
, N
, N
},
228 { GL(EXT_secondary_color
), VER(1,4), Y
, N
, N
, N
},
229 { GL(EXT_separate_specular_color
), VER(1,2), Y
, N
, N
, N
},
230 { GL(EXT_shadow_funcs
), VER(1,5), Y
, N
, N
, N
},
231 { GL(EXT_shared_texture_palette
), VER(0,0), Y
, N
, N
, N
},
232 { GL(EXT_stencil_two_side
), VER(0,0), Y
, N
, N
, N
},
233 { GL(EXT_stencil_wrap
), VER(1,4), Y
, N
, N
, N
},
234 { GL(EXT_subtexture
), VER(1,1), Y
, N
, N
, N
},
235 { GL(EXT_texture
), VER(1,1), Y
, N
, N
, N
},
236 { GL(EXT_texture3D
), VER(1,2), Y
, N
, N
, N
},
237 { GL(EXT_texture_compression_dxt1
), VER(0,0), Y
, N
, N
, N
},
238 { GL(EXT_texture_compression_s3tc
), VER(0,0), Y
, N
, N
, N
},
239 { GL(EXT_texture_edge_clamp
), VER(1,2), Y
, N
, N
, N
},
240 { GL(EXT_texture_env_add
), VER(1,3), Y
, N
, N
, N
},
241 { GL(EXT_texture_env_combine
), VER(1,3), Y
, N
, N
, N
},
242 { GL(EXT_texture_env_dot3
), VER(0,0), Y
, N
, N
, N
},
243 { GL(EXT_texture_filter_anisotropic
), VER(0,0), Y
, N
, N
, N
},
244 { GL(EXT_texture_integer
), VER(0,0), Y
, N
, N
, N
},
245 { GL(EXT_texture_lod
), VER(1,2), Y
, N
, N
, N
},
246 { GL(EXT_texture_lod_bias
), VER(1,4), Y
, N
, N
, N
},
247 { GL(EXT_texture_mirror_clamp
), VER(0,0), Y
, N
, N
, N
},
248 { GL(EXT_texture_object
), VER(1,1), Y
, N
, N
, N
},
249 { GL(EXT_texture_rectangle
), VER(0,0), Y
, N
, N
, N
},
250 { GL(EXT_vertex_array
), VER(0,0), Y
, N
, N
, N
},
251 { GL(3DFX_texture_compression_FXT1
), VER(0,0), Y
, N
, N
, N
},
252 { GL(APPLE_packed_pixels
), VER(1,2), Y
, N
, N
, N
},
253 { GL(APPLE_ycbcr_422
), VER(0,0), Y
, N
, N
, N
},
254 { GL(ATI_draw_buffers
), VER(0,0), Y
, N
, N
, N
},
255 { GL(ATI_text_fragment_shader
), VER(0,0), Y
, N
, N
, N
},
256 { GL(ATI_texture_env_combine3
), VER(0,0), Y
, N
, N
, N
},
257 { GL(ATI_texture_float
), VER(0,0), Y
, N
, N
, N
},
258 { GL(ATI_texture_mirror_once
), VER(0,0), Y
, N
, N
, N
},
259 { GL(ATIX_texture_env_combine3
), VER(0,0), Y
, N
, N
, N
},
260 { GL(HP_convolution_border_modes
), VER(0,0), Y
, N
, N
, N
},
261 { GL(HP_occlusion_test
), VER(0,0), Y
, N
, N
, N
},
262 { GL(IBM_cull_vertex
), VER(0,0), Y
, N
, N
, N
},
263 { GL(IBM_pixel_filter_hint
), VER(0,0), Y
, N
, N
, N
},
264 { GL(IBM_rasterpos_clip
), VER(0,0), Y
, N
, N
, N
},
265 { GL(IBM_texture_clamp_nodraw
), VER(0,0), Y
, N
, N
, N
},
266 { GL(IBM_texture_mirrored_repeat
), VER(0,0), Y
, N
, N
, N
},
267 { GL(INGR_blend_func_separate
), VER(0,0), Y
, N
, N
, N
},
268 { GL(INGR_interlace_read
), VER(0,0), Y
, N
, N
, N
},
269 { GL(MESA_pack_invert
), VER(0,0), Y
, N
, N
, N
},
270 { GL(MESA_ycbcr_texture
), VER(0,0), Y
, N
, N
, N
},
271 { GL(NV_blend_square
), VER(1,4), Y
, N
, N
, N
},
272 { GL(NV_copy_depth_to_color
), VER(0,0), Y
, N
, N
, N
},
273 { GL(NV_depth_clamp
), VER(0,0), Y
, N
, N
, N
},
274 { GL(NV_fog_distance
), VER(0,0), Y
, N
, N
, N
},
275 { GL(NV_fragment_program
), VER(0,0), Y
, N
, N
, N
},
276 { GL(NV_fragment_program_option
), VER(0,0), Y
, N
, N
, N
},
277 { GL(NV_fragment_program2
), VER(0,0), Y
, N
, N
, N
},
278 { GL(NV_light_max_exponent
), VER(0,0), Y
, N
, N
, N
},
279 { GL(NV_multisample_filter_hint
), VER(0,0), Y
, N
, N
, N
},
280 { GL(NV_packed_depth_stencil
), VER(0,0), Y
, N
, N
, N
},
281 { GL(NV_point_sprite
), VER(0,0), Y
, N
, N
, N
},
282 { GL(NV_texgen_reflection
), VER(0,0), Y
, N
, N
, N
},
283 { GL(NV_texture_compression_vtc
), VER(0,0), Y
, N
, N
, N
},
284 { GL(NV_texture_env_combine4
), VER(0,0), Y
, N
, N
, N
},
285 { GL(NV_texture_rectangle
), VER(0,0), Y
, N
, N
, N
},
286 { GL(NV_vertex_program
), VER(0,0), Y
, N
, N
, N
},
287 { GL(NV_vertex_program1_1
), VER(0,0), Y
, N
, N
, N
},
288 { GL(NV_vertex_program2
), VER(0,0), Y
, N
, N
, N
},
289 { GL(NV_vertex_program2_option
), VER(0,0), Y
, N
, N
, N
},
290 { GL(NV_vertex_program3
), VER(0,0), Y
, N
, N
, N
},
291 { GL(OES_read_format
), VER(0,0), Y
, N
, N
, N
},
292 { GL(OES_compressed_paletted_texture
),VER(0,0), Y
, N
, N
, N
},
293 { GL(SGI_color_matrix
), VER(0,0), Y
, N
, N
, N
},
294 { GL(SGI_color_table
), VER(0,0), Y
, N
, N
, N
},
295 { GL(SGI_texture_color_table
), VER(0,0), Y
, N
, N
, N
},
296 { GL(SGIS_generate_mipmap
), VER(1,4), Y
, N
, N
, N
},
297 { GL(SGIS_multisample
), VER(0,0), Y
, N
, N
, N
},
298 { GL(SGIS_texture_border_clamp
), VER(1,3), Y
, N
, N
, N
},
299 { GL(SGIS_texture_edge_clamp
), VER(1,2), Y
, N
, N
, N
},
300 { GL(SGIS_texture_lod
), VER(1,2), Y
, N
, N
, N
},
301 { GL(SGIX_blend_alpha_minmax
), VER(0,0), Y
, N
, N
, N
},
302 { GL(SGIX_clipmap
), VER(0,0), Y
, N
, N
, N
},
303 { GL(SGIX_depth_texture
), VER(0,0), Y
, N
, N
, N
},
304 { GL(SGIX_fog_offset
), VER(0,0), Y
, N
, N
, N
},
305 { GL(SGIX_shadow
), VER(0,0), Y
, N
, N
, N
},
306 { GL(SGIX_shadow_ambient
), VER(0,0), Y
, N
, N
, N
},
307 { GL(SGIX_texture_coordinate_clamp
), VER(0,0), Y
, N
, N
, N
},
308 { GL(SGIX_texture_lod_bias
), VER(0,0), Y
, N
, N
, N
},
309 { GL(SGIX_texture_range
), VER(0,0), Y
, N
, N
, N
},
310 { GL(SGIX_texture_scale_bias
), VER(0,0), Y
, N
, N
, N
},
311 { GL(SGIX_vertex_preclip
), VER(0,0), Y
, N
, N
, N
},
312 { GL(SGIX_vertex_preclip_hint
), VER(0,0), Y
, N
, N
, N
},
313 { GL(SGIX_ycrcb
), VER(0,0), Y
, N
, N
, N
},
314 { GL(SUN_convolution_border_modes
), VER(0,0), Y
, N
, N
, N
},
315 { GL(SUN_multi_draw_arrays
), VER(0,0), Y
, N
, Y
, N
},
316 { GL(SUN_slice_accum
), VER(0,0), Y
, N
, N
, N
},
322 /* global bit-fields of available extensions and their characteristics */
323 static unsigned char client_glx_support
[8];
324 static unsigned char client_glx_only
[8];
325 static unsigned char direct_glx_only
[8];
326 static unsigned char client_gl_support
[__GL_EXT_BYTES
];
327 static unsigned char client_gl_only
[__GL_EXT_BYTES
];
330 * Bits representing the set of extensions that are enabled by default in all
331 * direct rendering drivers.
333 static unsigned char direct_glx_support
[8];
336 * Highest core GL version that can be supported for indirect rendering.
338 static const unsigned gl_major
= 1;
339 static const unsigned gl_minor
= 4;
341 /* client extensions string */
342 static const char *__glXGLXClientExtensions
= NULL
;
344 static void __glXExtensionsCtr(void);
345 static void __glXExtensionsCtrScreen(struct glx_screen
* psc
);
346 static void __glXProcessServerString(const struct extension_info
*ext
,
347 const char *server_string
,
348 unsigned char *server_support
);
351 * Set the state of a GLX extension.
353 * \param name Name of the extension.
354 * \param name_len Length, in characters, of the extension name.
355 * \param state New state (either enabled or disabled) of the extension.
356 * \param supported Table in which the state of the extension is to be set.
359 set_glx_extension(const struct extension_info
*ext
,
360 const char *name
, unsigned name_len
, GLboolean state
,
361 unsigned char *supported
)
366 for (i
= 0; ext
[i
].name
!= NULL
; i
++) {
367 if ((name_len
== ext
[i
].name_len
)
368 && (strncmp(ext
[i
].name
, name
, name_len
) == 0)) {
370 SET_BIT(supported
, ext
[i
].bit
);
373 CLR_BIT(supported
, ext
[i
].bit
);
383 #define SEPARATOR ' '
386 * Convert the server's extension string to a bit-field.
388 * \param server_string GLX extension string from the server.
389 * \param server_support Bit-field of supported extensions.
392 * This function is used to process both GLX and GL extension strings. The
393 * bit-fields used to track each of these have different sizes. Therefore,
394 * the data pointed by \c server_support must be preinitialized to zero.
397 __glXProcessServerString(const struct extension_info
*ext
,
398 const char *server_string
,
399 unsigned char *server_support
)
404 for (base
= 0; server_string
[base
] != NUL
; /* empty */ ) {
405 /* Determine the length of the next extension name.
407 for (len
= 0; (server_string
[base
+ len
] != SEPARATOR
)
408 && (server_string
[base
+ len
] != NUL
); len
++) {
412 /* Set the bit for the extension in the server_support table.
414 set_glx_extension(ext
, &server_string
[base
], len
, GL_TRUE
,
418 /* Advance to the next extension string. This means that we skip
419 * over the previous string and any trialing white-space.
421 for (base
+= len
; (server_string
[base
] == SEPARATOR
)
422 && (server_string
[base
] != NUL
); base
++) {
429 __glXEnableDirectExtension(struct glx_screen
* psc
, const char *name
)
431 __glXExtensionsCtr();
432 __glXExtensionsCtrScreen(psc
);
434 set_glx_extension(known_glx_extensions
,
435 name
, strlen(name
), GL_TRUE
, psc
->direct_support
);
439 * Initialize global extension support tables.
443 __glXExtensionsCtr(void)
446 static GLboolean ext_list_first_time
= GL_TRUE
;
449 if (ext_list_first_time
) {
450 ext_list_first_time
= GL_FALSE
;
452 (void) memset(client_glx_support
, 0, sizeof(client_glx_support
));
453 (void) memset(direct_glx_support
, 0, sizeof(direct_glx_support
));
454 (void) memset(client_glx_only
, 0, sizeof(client_glx_only
));
455 (void) memset(direct_glx_only
, 0, sizeof(direct_glx_only
));
457 (void) memset(client_gl_support
, 0, sizeof(client_gl_support
));
458 (void) memset(client_gl_only
, 0, sizeof(client_gl_only
));
460 for (i
= 0; known_glx_extensions
[i
].name
!= NULL
; i
++) {
461 const unsigned bit
= known_glx_extensions
[i
].bit
;
463 if (known_glx_extensions
[i
].client_support
) {
464 SET_BIT(client_glx_support
, bit
);
467 if (known_glx_extensions
[i
].direct_support
) {
468 SET_BIT(direct_glx_support
, bit
);
471 if (known_glx_extensions
[i
].client_only
) {
472 SET_BIT(client_glx_only
, bit
);
475 if (known_glx_extensions
[i
].direct_only
) {
476 SET_BIT(direct_glx_only
, bit
);
480 for (i
= 0; known_gl_extensions
[i
].name
!= NULL
; i
++) {
481 const unsigned bit
= known_gl_extensions
[i
].bit
;
483 if (known_gl_extensions
[i
].client_support
) {
484 SET_BIT(client_gl_support
, bit
);
487 if (known_gl_extensions
[i
].client_only
) {
488 SET_BIT(client_gl_only
, bit
);
493 fprintf(stderr
, "[%s:%u] Maximum client library version: %u.%u\n",
494 __func__
, __LINE__
, gl_major
, gl_minor
);
501 * Make sure that per-screen direct-support table is initialized.
503 * \param psc Pointer to GLX per-screen record.
507 __glXExtensionsCtrScreen(struct glx_screen
* psc
)
509 if (psc
->ext_list_first_time
) {
510 psc
->ext_list_first_time
= GL_FALSE
;
511 (void) memcpy(psc
->direct_support
, direct_glx_support
,
512 sizeof(direct_glx_support
));
518 * Check if a certain extension is enabled on a given screen.
520 * \param psc Pointer to GLX per-screen record.
521 * \param bit Bit index in the direct-support table.
522 * \returns If the extension bit is enabled for the screen, \c GL_TRUE is
523 * returned. If the extension bit is not enabled or if \c psc is
524 * \c NULL, then \c GL_FALSE is returned.
527 __glXExtensionBitIsEnabled(struct glx_screen
* psc
, unsigned bit
)
529 GLboolean enabled
= GL_FALSE
;
532 __glXExtensionsCtr();
533 __glXExtensionsCtrScreen(psc
);
534 enabled
= EXT_ENABLED(bit
, psc
->direct_support
);
542 * Check if a certain extension is enabled in a given context.
546 __glExtensionBitIsEnabled(struct glx_context
*gc
, unsigned bit
)
548 GLboolean enabled
= GL_FALSE
;
551 enabled
= EXT_ENABLED(bit
, gc
->gl_extension_bits
);
560 * Convert a bit-field to a string of supported extensions.
563 __glXGetStringFromTable(const struct extension_info
*ext
,
564 const unsigned char *supported
)
567 unsigned ext_str_len
;
573 for (i
= 0; ext
[i
].name
!= NULL
; i
++) {
574 if (EXT_ENABLED(ext
[i
].bit
, supported
)) {
575 ext_str_len
+= ext
[i
].name_len
+ 1;
579 ext_str
= malloc(ext_str_len
+ 1);
580 if (ext_str
!= NULL
) {
583 for (i
= 0; ext
[i
].name
!= NULL
; i
++) {
584 if (EXT_ENABLED(ext
[i
].bit
, supported
)) {
585 (void) memcpy(point
, ext
[i
].name
, ext
[i
].name_len
);
586 point
+= ext
[i
].name_len
;
601 * Get the string of client library supported extensions.
604 __glXGetClientExtensions(void)
606 if (__glXGLXClientExtensions
== NULL
) {
607 __glXExtensionsCtr();
608 __glXGLXClientExtensions
= __glXGetStringFromTable(known_glx_extensions
,
612 return __glXGLXClientExtensions
;
617 * Calculate the list of application usable extensions. The resulting
618 * string is stored in \c psc->effectiveGLXexts.
620 * \param psc Pointer to GLX per-screen record.
621 * \param display_is_direct_capable True if the display is capable of
623 * \param minor_version GLX minor version from the server.
627 __glXCalculateUsableExtensions(struct glx_screen
* psc
,
628 GLboolean display_is_direct_capable
,
631 unsigned char server_support
[8];
632 unsigned char usable
[8];
635 __glXExtensionsCtr();
636 __glXExtensionsCtrScreen(psc
);
638 (void) memset(server_support
, 0, sizeof(server_support
));
639 __glXProcessServerString(known_glx_extensions
,
640 psc
->serverGLXexts
, server_support
);
643 /* This is a hack. Some servers support GLX 1.3 but don't export
644 * all of the extensions implied by GLX 1.3. If the server claims
645 * support for GLX 1.3, enable support for the extensions that can be
646 * "emulated" as well.
648 #ifndef GLX_USE_APPLEGL
649 if (minor_version
>= 3) {
650 SET_BIT(server_support
, EXT_visual_info_bit
);
651 SET_BIT(server_support
, EXT_visual_rating_bit
);
652 SET_BIT(server_support
, SGI_make_current_read_bit
);
653 SET_BIT(server_support
, SGIX_fbconfig_bit
);
654 SET_BIT(server_support
, SGIX_pbuffer_bit
);
656 /* This one is a little iffy. GLX 1.3 doesn't incorporate all of this
657 * extension. However, the only part that is not strictly client-side
658 * is shared. That's the glXQueryContext / glXQueryContextInfoEXT
662 SET_BIT(server_support
, EXT_import_context_bit
);
666 /* An extension is supported if the client-side (i.e., libGL) supports
667 * it and the "server" supports it. In this case that means that either
668 * the true server supports it or it is only for direct-rendering and
669 * the direct rendering driver supports it.
671 * If the display is not capable of direct rendering, then the extension
672 * is enabled if and only if the client-side library and the server
676 if (display_is_direct_capable
) {
677 for (i
= 0; i
< 8; i
++) {
678 usable
[i
] = (client_glx_support
[i
] & client_glx_only
[i
])
679 | (client_glx_support
[i
] & psc
->direct_support
[i
] &
681 | (client_glx_support
[i
] & psc
->direct_support
[i
] &
686 for (i
= 0; i
< 8; i
++) {
687 usable
[i
] = (client_glx_support
[i
] & client_glx_only
[i
])
688 | (client_glx_support
[i
] & server_support
[i
]);
692 psc
->effectiveGLXexts
= __glXGetStringFromTable(known_glx_extensions
,
698 * Calculate the list of application usable extensions. The resulting
699 * string is stored in \c gc->extensions.
701 * \param gc Pointer to GLX context.
702 * \param server_string Extension string from the server.
703 * \param major_version GL major version from the server.
704 * \param minor_version GL minor version from the server.
708 __glXCalculateUsableGLExtensions(struct glx_context
* gc
,
709 const char *server_string
,
710 int major_version
, int minor_version
)
712 unsigned char server_support
[__GL_EXT_BYTES
];
713 unsigned char usable
[__GL_EXT_BYTES
];
717 __glXExtensionsCtr();
719 (void) memset(server_support
, 0, sizeof(server_support
));
720 __glXProcessServerString(known_gl_extensions
, server_string
,
724 /* Handle lazy servers that don't export all the extensions strings that
725 * are part of the GL core version that they support.
728 for (i
= 0; i
< __GL_EXT_BYTES
; i
++) {
729 if ((known_gl_extensions
[i
].version_major
!= 0)
730 && ((major_version
> known_gl_extensions
[i
].version_major
)
731 || ((major_version
== known_gl_extensions
[i
].version_major
)
733 known_gl_extensions
[i
].version_minor
)))) {
734 SET_BIT(server_support
, known_gl_extensions
[i
].bit
);
739 /* An extension is supported if the client-side (i.e., libGL) supports
740 * it and the server supports it or the client-side library supports it
741 * and it only needs client-side support.
744 for (i
= 0; i
< __GL_EXT_BYTES
; i
++) {
745 usable
[i
] = (client_gl_support
[i
] & client_gl_only
[i
])
746 | (client_gl_support
[i
] & server_support
[i
]);
749 gc
->extensions
= (unsigned char *)
750 __glXGetStringFromTable(known_gl_extensions
, usable
);
751 (void) memcpy(gc
->gl_extension_bits
, usable
, sizeof(usable
));
756 * Calculates the maximum core GL version that can be supported for indirect
760 __glXGetGLVersion(int *major_version
, int *minor_version
)
762 __glXExtensionsCtr();
763 *major_version
= gl_major
;
764 *minor_version
= gl_minor
;
769 * Get a string representing the set of extensions supported by the client
770 * library. This is currently only used to send the list of extensions
771 * supported by the client to the server.
774 __glXGetClientGLExtensionString(void)
776 __glXExtensionsCtr();
777 return __glXGetStringFromTable(known_gl_extensions
, client_gl_support
);