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"
36 #include "glxextensions.h"
37 #include "simple_list.h"
39 #define SET_BIT(m,b) (m[ (b) / 8 ] |= (1U << ((b) % 8)))
40 #define CLR_BIT(m,b) (m[ (b) / 8 ] &= ~(1U << ((b) % 8)))
41 #define IS_SET(m,b) ((m[ (b) / 8 ] & (1U << ((b) % 8))) != 0)
42 #define CONCAT(a,b) a ## b
43 #define GLX(n) "GLX_" # n, 4 + sizeof( # n ) - 1, CONCAT(n,_bit)
44 #define GL(n) "GL_" # n, 3 + sizeof( # n ) - 1, GL_ ## n ## _bit
48 #define EXT_ENABLED(bit,supported) (IS_SET( supported, bit ))
51 struct extension_info
{
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
;
64 unsigned char client_support
;
65 unsigned char direct_support
;
66 unsigned char client_only
; /** Is the extension client-side only? */
67 unsigned char direct_only
; /** Is the extension for direct
72 static const struct extension_info known_glx_extensions
[] = {
73 { GLX(ARB_get_proc_address
), VER(1,4), Y
, N
, Y
, N
},
74 { GLX(ARB_multisample
), VER(1,4), Y
, Y
, N
, N
},
75 { GLX(ARB_render_texture
), VER(0,0), N
, N
, N
, N
},
76 { GLX(ATI_pixel_format_float
), VER(0,0), N
, N
, N
, N
},
77 { GLX(EXT_import_context
), VER(0,0), Y
, Y
, N
, N
},
78 { GLX(EXT_visual_info
), VER(0,0), Y
, Y
, N
, N
},
79 { GLX(EXT_visual_rating
), VER(0,0), Y
, Y
, N
, N
},
80 { GLX(MESA_agp_offset
), VER(0,0), N
, N
, N
, Y
}, /* Deprecated */
81 { GLX(MESA_allocate_memory
), VER(0,0), Y
, N
, N
, Y
},
82 { GLX(MESA_copy_sub_buffer
), VER(0,0), N
, N
, N
, N
}, /* Deprecated? */
83 { GLX(MESA_pixmap_colormap
), VER(0,0), N
, N
, N
, N
}, /* Deprecated */
84 { GLX(MESA_release_buffers
), VER(0,0), N
, N
, N
, N
}, /* Deprecated */
85 { GLX(MESA_set_3dfx_mode
), VER(0,0), N
, N
, N
, N
}, /* Deprecated */
86 { GLX(MESA_swap_control
), VER(0,0), Y
, N
, N
, Y
},
87 { GLX(MESA_swap_frame_usage
), VER(0,0), Y
, N
, N
, Y
},
88 { GLX(NV_float_buffer
), VER(0,0), N
, N
, N
, N
},
89 { GLX(NV_render_depth_texture
), VER(0,0), N
, N
, N
, N
},
90 { GLX(NV_render_texture_rectangle
), VER(0,0), N
, N
, N
, N
},
91 { GLX(NV_vertex_array_range
), VER(0,0), N
, N
, N
, Y
}, /* Deprecated */
92 { GLX(OML_swap_method
), VER(0,0), Y
, N
, N
, N
},
93 { GLX(OML_sync_control
), VER(0,0), Y
, N
, N
, Y
},
94 { GLX(SGI_cushion
), VER(0,0), N
, N
, N
, N
},
95 { GLX(SGI_make_current_read
), VER(1,3), Y
, N
, N
, N
},
96 { GLX(SGI_swap_control
), VER(0,0), Y
, N
, N
, N
},
97 { GLX(SGI_video_sync
), VER(0,0), Y
, N
, N
, Y
},
98 { GLX(SGIS_blended_overlay
), VER(0,0), N
, N
, N
, N
},
99 { GLX(SGIS_color_range
), VER(0,0), N
, N
, N
, N
},
100 { GLX(SGIS_multisample
), VER(0,0), Y
, Y
, N
, N
},
101 { GLX(SGIX_dm_buffer
), VER(0,0), N
, N
, N
, N
},
102 { GLX(SGIX_fbconfig
), VER(1,3), Y
, N
, N
, N
},
103 { GLX(SGIX_pbuffer
), VER(1,3), Y
, N
, N
, N
},
104 { GLX(SGIX_swap_barrier
), VER(0,0), N
, N
, N
, N
},
105 { GLX(SGIX_swap_group
), VER(0,0), N
, N
, N
, N
},
106 { GLX(SGIX_video_resize
), VER(0,0), N
, N
, N
, N
},
107 { GLX(SGIX_video_source
), VER(0,0), N
, N
, N
, N
},
108 { GLX(SGIX_visual_select_group
), VER(0,0), Y
, Y
, N
, N
},
109 { GLX(SUN_get_transparent_index
), VER(0,0), N
, N
, N
, N
},
113 static const struct extension_info known_gl_extensions
[] = {
114 { GL(ARB_depth_texture
), VER(1,4), Y
, N
, N
, N
},
115 { GL(ARB_fragment_program
), VER(0,0), N
, N
, N
, N
},
116 { GL(ARB_imaging
), VER(0,0), Y
, N
, N
, N
},
117 { GL(ARB_multisample
), VER(1,3), Y
, N
, N
, N
},
118 { GL(ARB_multitexture
), VER(1,3), Y
, N
, N
, N
},
119 { GL(ARB_occlusion_query
), VER(1,5), N
, N
, N
, N
},
120 { GL(ARB_point_parameters
), VER(1,4), Y
, N
, N
, N
},
121 { GL(ARB_point_sprite
), VER(0,0), Y
, N
, N
, N
},
122 { GL(ARB_shadow
), VER(1,4), Y
, N
, N
, N
},
123 { GL(ARB_shadow_ambient
), VER(0,0), Y
, N
, N
, N
},
124 { GL(ARB_texture_border_clamp
), VER(1,3), Y
, N
, N
, N
},
125 { GL(ARB_texture_compression
), VER(1,3), Y
, N
, N
, N
},
126 { GL(ARB_texture_cube_map
), VER(1,3), Y
, N
, N
, N
},
127 { GL(ARB_texture_env_add
), VER(1,3), Y
, N
, N
, N
},
128 { GL(ARB_texture_env_combine
), VER(1,3), Y
, N
, N
, N
},
129 { GL(ARB_texture_env_crossbar
), VER(1,4), Y
, N
, N
, N
},
130 { GL(ARB_texture_env_dot3
), VER(1,3), Y
, N
, N
, N
},
131 { GL(ARB_texture_mirrored_repeat
), VER(1,4), Y
, N
, N
, N
},
132 { GL(ARB_texture_non_power_of_two
), VER(1,5), Y
, N
, N
, N
},
133 { GL(ARB_texture_rectangle
), VER(0,0), Y
, N
, N
, N
},
134 { GL(ARB_transpose_matrix
), VER(1,3), Y
, N
, Y
, N
},
135 { GL(ARB_vertex_buffer_object
), VER(1,5), N
, N
, N
, N
},
136 { GL(ARB_window_pos
), VER(1,4), Y
, N
, N
, N
},
137 { GL(EXT_abgr
), VER(0,0), Y
, N
, N
, N
},
138 { GL(EXT_bgra
), VER(1,2), Y
, N
, N
, N
},
139 { GL(EXT_blend_color
), VER(1,4), Y
, N
, N
, N
},
140 { GL(EXT_blend_equation_separate
), VER(0,0), N
, N
, N
, N
},
141 { GL(EXT_blend_func_separate
), VER(1,4), Y
, N
, N
, N
},
142 { GL(EXT_blend_logic_op
), VER(1,4), Y
, N
, N
, N
},
143 { GL(EXT_blend_minmax
), VER(1,4), Y
, N
, N
, N
},
144 { GL(EXT_blend_subtract
), VER(1,4), Y
, N
, N
, N
},
145 { GL(EXT_clip_volume_hint
), VER(0,0), Y
, N
, N
, N
},
146 { GL(EXT_compiled_vertex_array
), VER(0,0), N
, N
, N
, N
},
147 { GL(EXT_convolution
), VER(0,0), N
, N
, N
, N
},
148 { GL(EXT_copy_texture
), VER(1,1), Y
, N
, N
, N
},
149 { GL(EXT_cull_vertex
), VER(0,0), N
, N
, N
, N
},
150 { GL(EXT_depth_bounds_test
), VER(0,0), N
, N
, N
, N
},
151 { GL(EXT_draw_range_elements
), VER(1,2), Y
, N
, Y
, N
},
152 { GL(EXT_fog_coord
), VER(1,4), Y
, N
, N
, N
},
153 { GL(EXT_multi_draw_arrays
), VER(1,4), Y
, N
, Y
, N
},
154 { GL(EXT_packed_pixels
), VER(1,2), Y
, N
, N
, N
},
155 { GL(EXT_paletted_texture
), VER(0,0), Y
, N
, N
, N
},
156 { GL(EXT_pixel_buffer_object
), VER(0,0), N
, N
, N
, N
},
157 { GL(EXT_point_parameters
), VER(1,4), Y
, N
, N
, N
},
158 { GL(EXT_polygon_offset
), VER(1,1), Y
, N
, N
, N
},
159 { GL(EXT_rescale_normal
), VER(1,2), Y
, N
, N
, N
},
160 { GL(EXT_secondary_color
), VER(1,4), Y
, N
, N
, N
},
161 { GL(EXT_separate_specular_color
), VER(1,2), Y
, N
, N
, N
},
162 { GL(EXT_shadow_funcs
), VER(1,5), Y
, N
, N
, N
},
163 { GL(EXT_shared_texture_palette
), VER(0,0), Y
, N
, N
, N
},
164 { GL(EXT_stencil_two_side
), VER(0,0), Y
, N
, N
, N
},
165 { GL(EXT_stencil_wrap
), VER(1,4), Y
, N
, N
, N
},
166 { GL(EXT_subtexture
), VER(1,1), Y
, N
, N
, N
},
167 { GL(EXT_texture
), VER(1,1), Y
, N
, N
, N
},
168 { GL(EXT_texture3D
), VER(1,2), Y
, N
, N
, N
},
169 { GL(EXT_texture_compression_dxt1
), VER(0,0), Y
, N
, N
, N
},
170 { GL(EXT_texture_compression_s3tc
), VER(0,0), Y
, N
, N
, N
},
171 { GL(EXT_texture_edge_clamp
), VER(1,2), Y
, N
, N
, N
},
172 { GL(EXT_texture_env_add
), VER(1,3), Y
, N
, N
, N
},
173 { GL(EXT_texture_env_combine
), VER(1,3), Y
, N
, N
, N
},
174 { GL(EXT_texture_env_dot3
), VER(0,0), Y
, N
, N
, N
},
175 { GL(EXT_texture_filter_anisotropic
), VER(0,0), Y
, N
, N
, N
},
176 { GL(EXT_texture_lod
), VER(1,2), Y
, N
, N
, N
},
177 { GL(EXT_texture_lod_bias
), VER(1,4), Y
, N
, N
, N
},
178 { GL(EXT_texture_mirror_clamp
), VER(0,0), Y
, N
, N
, N
},
179 { GL(EXT_texture_object
), VER(1,1), Y
, N
, N
, N
},
180 { GL(EXT_texture_rectangle
), VER(0,0), Y
, N
, N
, N
},
181 { GL(EXT_vertex_array
), VER(0,0), Y
, N
, N
, N
},
182 { GL(3DFX_texture_compression_FXT1
), VER(0,0), Y
, N
, N
, N
},
183 { GL(APPLE_packed_pixels
), VER(1,2), Y
, N
, N
, N
},
184 { GL(APPLE_ycbcr_422
), VER(0,0), Y
, N
, N
, N
},
185 { GL(ATI_texture_env_combine3
), VER(0,0), Y
, N
, N
, N
},
186 { GL(ATI_texture_float
), VER(0,0), Y
, N
, N
, N
},
187 { GL(ATI_texture_mirror_once
), VER(0,0), Y
, N
, N
, N
},
188 { GL(ATIX_texture_env_combine3
), VER(0,0), Y
, N
, N
, N
},
189 { GL(HP_convolution_border_modes
), VER(0,0), Y
, N
, N
, N
},
190 { GL(HP_occlusion_test
), VER(0,0), Y
, N
, N
, N
},
191 { GL(IBM_cull_vertex
), VER(0,0), Y
, N
, N
, N
},
192 { GL(IBM_pixel_filter_hint
), VER(0,0), Y
, N
, N
, N
},
193 { GL(IBM_rasterpos_clip
), VER(0,0), Y
, N
, N
, N
},
194 { GL(IBM_texture_clamp_nodraw
), VER(0,0), Y
, N
, N
, N
},
195 { GL(IBM_texture_mirrored_repeat
), VER(0,0), Y
, N
, N
, N
},
196 { GL(INGR_blend_func_separate
), VER(0,0), Y
, N
, N
, N
},
197 { GL(INGR_interlace_read
), VER(0,0), Y
, N
, N
, N
},
198 { GL(MESA_pack_invert
), VER(0,0), Y
, N
, N
, N
},
199 { GL(MESA_ycbcr_texture
), VER(0,0), Y
, N
, N
, N
},
200 { GL(NV_blend_square
), VER(1,4), Y
, N
, N
, N
},
201 { GL(NV_copy_depth_to_color
), VER(0,0), Y
, N
, N
, N
},
202 { GL(NV_depth_clamp
), VER(0,0), Y
, N
, N
, N
},
203 { GL(NV_fog_distance
), VER(0,0), Y
, N
, N
, N
},
204 { GL(NV_light_max_exponent
), VER(0,0), Y
, N
, N
, N
},
205 { GL(NV_multisample_filter_hint
), VER(0,0), Y
, N
, N
, N
},
206 { GL(NV_point_sprite
), VER(0,0), Y
, N
, N
, N
},
207 { GL(NV_texgen_reflection
), VER(0,0), Y
, N
, N
, N
},
208 { GL(NV_texture_compression_vtc
), VER(0,0), Y
, N
, N
, N
},
209 { GL(NV_texture_env_combine4
), VER(0,0), Y
, N
, N
, N
},
210 { GL(NV_texture_rectangle
), VER(0,0), Y
, N
, N
, N
},
211 { GL(OES_read_format
), VER(0,0), Y
, N
, N
, N
},
212 { GL(OES_compressed_paletted_texture
),VER(0,0), Y
, N
, N
, N
},
213 { GL(SGI_color_matrix
), VER(0,0), Y
, N
, N
, N
},
214 { GL(SGI_texture_color_table
), VER(0,0), Y
, N
, N
, N
},
215 { GL(SGIS_generate_mipmap
), VER(1,4), Y
, N
, N
, N
},
216 { GL(SGIS_multisample
), VER(0,0), Y
, N
, N
, N
},
217 { GL(SGIS_texture_border_clamp
), VER(1,3), Y
, N
, N
, N
},
218 { GL(SGIS_texture_edge_clamp
), VER(1,2), Y
, N
, N
, N
},
219 { GL(SGIS_texture_lod
), VER(1,2), Y
, N
, N
, N
},
220 { GL(SGIX_blend_alpha_minmax
), VER(0,0), Y
, N
, N
, N
},
221 { GL(SGIX_clipmap
), VER(0,0), Y
, N
, N
, N
},
222 { GL(SGIX_depth_texture
), VER(0,0), Y
, N
, N
, N
},
223 { GL(SGIX_fog_offset
), VER(0,0), Y
, N
, N
, N
},
224 { GL(SGIX_shadow
), VER(0,0), Y
, N
, N
, N
},
225 { GL(SGIX_shadow_ambient
), VER(0,0), Y
, N
, N
, N
},
226 { GL(SGIX_texture_coordinate_clamp
), VER(0,0), Y
, N
, N
, N
},
227 { GL(SGIX_texture_lod_bias
), VER(0,0), Y
, N
, N
, N
},
228 { GL(SGIX_texture_range
), VER(0,0), Y
, N
, N
, N
},
229 { GL(SGIX_texture_scale_bias
), VER(0,0), Y
, N
, N
, N
},
230 { GL(SGIX_vertex_preclip
), VER(0,0), Y
, N
, N
, N
},
231 { GL(SGIX_vertex_preclip_hint
), VER(0,0), Y
, N
, N
, N
},
232 { GL(SGIX_ycrcb
), VER(0,0), Y
, N
, N
, N
},
233 { GL(SUN_convolution_border_modes
), VER(0,0), Y
, N
, N
, N
},
234 { GL(SUN_multi_draw_arrays
), VER(0,0), Y
, N
, Y
, N
},
235 { GL(SUN_slice_accum
), VER(0,0), Y
, N
, N
, N
},
240 #define __GL_EXT_BYTES ((__NUM_GL_EXTS + 7) / 8)
242 /* global bit-fields of available extensions and their characteristics */
243 static unsigned char client_glx_support
[8];
244 static unsigned char client_glx_only
[8];
245 static unsigned char direct_glx_only
[8];
246 static unsigned char client_gl_support
[ __GL_EXT_BYTES
];
247 static unsigned char client_gl_only
[ __GL_EXT_BYTES
];
250 * Bits representing the set of extensions that are enabled by default in all
251 * direct rendering drivers.
253 static unsigned char direct_glx_support
[8];
256 * Highest core GL version that can be supported for indirect rendering.
258 static unsigned gl_major
= 0;
259 static unsigned gl_minor
= 0;
261 /* client extensions string */
262 static const char * __glXGLXClientExtensions
= NULL
;
264 static void __glXExtensionsCtr( void );
265 static void __glXExtensionsCtrScreen( __GLXscreenConfigs
*psc
);
266 static void __glXProcessServerString( const struct extension_info
* ext
,
267 const char * server_string
, unsigned char * server_support
);
270 * Set the state of a GLX extension.
272 * \param name Name of the extension.
273 * \param name_len Length, in characters, of the extension name.
274 * \param state New state (either enabled or disabled) of the extension.
275 * \param supported Table in which the state of the extension is to be set.
278 set_glx_extension( const struct extension_info
* ext
,
279 const char * name
, unsigned name_len
, GLboolean state
,
280 unsigned char * supported
)
285 for ( i
= 0 ; ext
[i
].name
!= NULL
; i
++ ) {
286 if ( (name_len
== ext
[i
].name_len
)
287 && (strncmp( ext
[i
].name
, name
, name_len
) == 0) ) {
289 SET_BIT( supported
, ext
[i
].bit
);
292 CLR_BIT( supported
, ext
[i
].bit
);
302 #define SEPARATOR ' '
305 * Convert the server's extension string to a bit-field.
307 * \param server_string GLX extension string from the server.
308 * \param server_support Bit-field of supported extensions.
311 __glXProcessServerString( const struct extension_info
* ext
,
312 const char * server_string
,
313 unsigned char * server_support
)
318 (void) memset( server_support
, 0, sizeof( server_support
) );
320 for ( base
= 0 ; server_string
[ base
] != NUL
; /* empty */ ) {
321 /* Determine the length of the next extension name.
324 ; (server_string
[ base
+ len
] != SEPARATOR
)
325 && (server_string
[ base
+ len
] != NUL
)
330 /* Set the bit for the extension in the server_support table.
332 set_glx_extension( ext
, & server_string
[ base
], len
, GL_TRUE
,
336 /* Advance to the next extension string. This means that we skip
337 * over the previous string and any trialing white-space.
340 (server_string
[ base
] == SEPARATOR
)
341 && (server_string
[ base
] != NUL
)
350 * Enable a named GLX extension on a given screen.
351 * Drivers should not call this function directly. They should instead use
352 * \c glXGetProcAddress to obtain a pointer to the function.
354 * \param psc Pointer to GLX per-screen record.
355 * \param name Name of the extension to enable.
357 * \sa glXGetProcAddress
359 * \since Internal API version 20030813.
362 __glXScrEnableExtension( __GLXscreenConfigs
*psc
, const char * name
)
364 __glXExtensionsCtr();
365 __glXExtensionsCtrScreen(psc
);
366 set_glx_extension( known_glx_extensions
, name
, strlen( name
), GL_TRUE
,
367 psc
->direct_support
);
372 * Initialize global extension support tables.
376 __glXExtensionsCtr( void )
378 static const char major_table
[32] = { 1, 1, 1, 1, 1, 1, 2, };
379 static const char minor_table
[32] = { 0, 1, 2, 3, 4, 5, 0, };
381 static GLboolean ext_list_first_time
= GL_TRUE
;
382 unsigned full_support
= ~0;
385 if ( ext_list_first_time
) {
386 ext_list_first_time
= GL_FALSE
;
388 (void) memset( client_glx_support
, 0, sizeof( client_glx_support
) );
389 (void) memset( direct_glx_support
, 0, sizeof( direct_glx_support
) );
390 (void) memset( client_glx_only
, 0, sizeof( client_glx_only
) );
391 (void) memset( direct_glx_only
, 0, sizeof( direct_glx_only
) );
393 (void) memset( client_gl_support
, 0, sizeof( client_gl_support
) );
394 (void) memset( client_gl_only
, 0, sizeof( client_gl_only
) );
396 for ( i
= 0 ; known_glx_extensions
[i
].name
!= NULL
; i
++ ) {
397 const unsigned bit
= known_glx_extensions
[i
].bit
;
399 if ( known_glx_extensions
[i
].client_support
) {
400 SET_BIT( client_glx_support
, bit
);
403 if ( known_glx_extensions
[i
].direct_support
) {
404 SET_BIT( direct_glx_support
, bit
);
407 if ( known_glx_extensions
[i
].client_only
) {
408 SET_BIT( client_glx_only
, bit
);
411 if ( known_glx_extensions
[i
].direct_only
) {
412 SET_BIT( direct_glx_only
, bit
);
416 for ( i
= 0 ; known_gl_extensions
[i
].name
!= NULL
; i
++ ) {
417 const unsigned bit
= known_gl_extensions
[i
].bit
;
419 if ( known_gl_extensions
[i
].client_support
) {
420 SET_BIT( client_gl_support
, bit
);
422 else if ( known_gl_extensions
[i
].version_major
!= 0 ) {
423 /* If an extension that is required for some core GL version is
424 * not supported, clear the bit for that core GL version as well.
427 unsigned ver_bit
= (6 * (known_gl_extensions
[i
].version_major
- 1))
428 + (known_gl_extensions
[i
].version_minor
);
430 full_support
&= ~(1U << ver_bit
);
433 if ( known_gl_extensions
[i
].client_only
) {
434 SET_BIT( client_gl_only
, bit
);
438 /* Determine the lowest unsupported core GL version. The version before
439 * that is, therefore, the highest supported core GL version.
441 for ( i
= 0 ; (full_support
& (1 << i
)) != 0 ; i
++ )
445 gl_major
= major_table
[i
];
446 gl_minor
= minor_table
[i
];
448 fprintf( stderr
, "[%s:%u] Maximum client library version: %u.%u\n",
449 __func__
, __LINE__
, gl_major
, gl_minor
);
456 * Make sure that per-screen direct-support table is initialized.
458 * \param psc Pointer to GLX per-screen record.
462 __glXExtensionsCtrScreen( __GLXscreenConfigs
*psc
)
464 if (psc
->ext_list_first_time
) {
465 psc
->ext_list_first_time
= GL_FALSE
;
466 (void) memcpy( psc
->direct_support
, direct_glx_support
,
467 sizeof( direct_glx_support
) );
473 * Check if a certain extension is enabled on a given screen.
475 * \param psc Pointer to GLX per-screen record.
476 * \param bit Bit index in the direct-support table.
477 * \returns If the extension bit is enabled for the screen, \c GL_TRUE is
478 * returned. If the extension bit is not enabled or if \c psc is
479 * \c NULL, then \c GL_FALSE is returned.
482 __glXExtensionBitIsEnabled( __GLXscreenConfigs
*psc
, unsigned bit
)
484 GLboolean enabled
= GL_FALSE
;
487 __glXExtensionsCtr();
488 __glXExtensionsCtrScreen( psc
);
489 enabled
= EXT_ENABLED( bit
, psc
->direct_support
);
497 * Convert a bit-field to a string of supported extensions.
500 __glXGetStringFromTable( const struct extension_info
* ext
,
501 const unsigned char * supported
)
504 unsigned ext_str_len
;
510 for ( i
= 0 ; ext
[i
].name
!= NULL
; i
++ ) {
511 if ( EXT_ENABLED( ext
[i
].bit
, supported
) ) {
512 ext_str_len
+= ext
[i
].name_len
+ 1;
516 ext_str
= Xmalloc( ext_str_len
+ 1 );
517 if ( ext_str
!= NULL
) {
520 for ( i
= 0 ; ext
[i
].name
!= NULL
; i
++ ) {
521 if ( EXT_ENABLED( ext
[i
].bit
, supported
) ) {
522 (void) memcpy( point
, ext
[i
].name
, ext
[i
].name_len
);
523 point
+= ext
[i
].name_len
;
538 * Get the string of client library supported extensions.
541 __glXGetClientExtensions( void )
543 if ( __glXGLXClientExtensions
== NULL
) {
544 __glXExtensionsCtr();
545 __glXGLXClientExtensions
= __glXGetStringFromTable( known_glx_extensions
,
546 client_glx_support
);
549 return __glXGLXClientExtensions
;
554 * Calculate the list of application usable extensions. The resulting
555 * string is stored in \c psc->effectiveGLXexts.
557 * \param psc Pointer to GLX per-screen record.
558 * \param display_is_direct_capable True if the display is capable of
560 * \param minor_version GLX minor version from the server.
564 __glXCalculateUsableExtensions( __GLXscreenConfigs
*psc
,
565 GLboolean display_is_direct_capable
,
568 unsigned char server_support
[8];
569 unsigned char usable
[8];
572 __glXExtensionsCtr();
573 __glXExtensionsCtrScreen( psc
);
574 __glXProcessServerString( known_glx_extensions
,
575 psc
->serverGLXexts
, server_support
);
578 /* This is a hack. Some servers support GLX 1.3 but don't export
579 * all of the extensions implied by GLX 1.3. If the server claims
580 * support for GLX 1.3, enable support for the extensions that can be
581 * "emulated" as well.
584 if ( minor_version
>= 3 ) {
585 SET_BIT( server_support
, EXT_visual_info_bit
);
586 SET_BIT( server_support
, EXT_visual_rating_bit
);
587 SET_BIT( server_support
, SGI_make_current_read_bit
);
588 SET_BIT( server_support
, SGIX_fbconfig_bit
);
589 SET_BIT( server_support
, SGIX_pbuffer_bit
);
591 /* This one is a little iffy. GLX 1.3 doesn't incorporate all of this
592 * extension. However, the only part that is not strictly client-side
593 * is shared. That's the glXQueryContext / glXQueryContextInfoEXT
597 SET_BIT( server_support
, EXT_import_context_bit
);
601 /* An extension is supported if the client-side (i.e., libGL) supports
602 * it and the "server" supports it. In this case that means that either
603 * the true server supports it or it is only for direct-rendering and
604 * the direct rendering driver supports it.
606 * If the display is not capable of direct rendering, then the extension
607 * is enabled if and only if the client-side library and the server
611 if ( display_is_direct_capable
) {
612 for ( i
= 0 ; i
< 8 ; i
++ ) {
613 usable
[i
] = (client_glx_support
[i
] & client_glx_only
[i
])
614 | (client_glx_support
[i
] & psc
->direct_support
[i
] & server_support
[i
])
615 | (client_glx_support
[i
] & psc
->direct_support
[i
] & direct_glx_only
[i
]);
619 for ( i
= 0 ; i
< 8 ; i
++ ) {
620 usable
[i
] = (client_glx_support
[i
] & client_glx_only
[i
])
621 | (client_glx_support
[i
] & server_support
[i
]);
625 psc
->effectiveGLXexts
= __glXGetStringFromTable( known_glx_extensions
,
631 * Calculate the list of application usable extensions. The resulting
632 * string is stored in \c gc->extensions.
634 * \param gc Pointer to GLX context.
635 * \param server_string Extension string from the server.
636 * \param major_version GL major version from the server.
637 * \param minor_version GL minor version from the server.
641 __glXCalculateUsableGLExtensions( __GLXcontext
* gc
,
642 const char * server_string
,
643 int major_version
, int minor_version
)
645 unsigned char server_support
[ __GL_EXT_BYTES
];
646 unsigned char usable
[ __GL_EXT_BYTES
];
650 __glXExtensionsCtr();
652 (void) memset( server_support
, 0, sizeof( server_support
) );
653 __glXProcessServerString( known_gl_extensions
, server_string
,
657 /* Handle lazy servers that don't export all the extensions strings that
658 * are part of the GL core version that they support.
661 for ( i
= 0 ; i
< __GL_EXT_BYTES
; i
++ ) {
662 if ( (known_gl_extensions
[i
].version_major
!= 0)
663 && ((major_version
> known_gl_extensions
[i
].version_major
)
664 || ((major_version
== known_gl_extensions
[i
].version_major
)
665 && (minor_version
>= known_gl_extensions
[i
].version_minor
))) ) {
666 SET_BIT( server_support
, known_gl_extensions
[i
].bit
);
671 /* An extension is supported if the client-side (i.e., libGL) supports
672 * it and the server supports it or the client-side library supports it
673 * and it only needs client-side support.
676 for ( i
= 0 ; i
< __GL_EXT_BYTES
; i
++ ) {
677 usable
[i
] = (client_gl_support
[i
] & client_gl_only
[i
])
678 | (client_gl_support
[i
] & server_support
[i
]);
681 gc
->extensions
= (unsigned char *)
682 __glXGetStringFromTable( known_gl_extensions
, usable
);
687 * Calculates the maximum core GL version that can be supported for indirect
691 __glXGetGLVersion( int * major_version
, int * minor_version
)
693 __glXExtensionsCtr();
694 *major_version
= gl_major
;
695 *minor_version
= gl_minor
;
700 * Get a string representing the set of extensions supported by the client
701 * library. This is currently only used to send the list of extensions
702 * supported by the client to the server.
705 __glXGetClientGLExtensionString( void )
707 __glXExtensionsCtr();
708 return __glXGetStringFromTable( known_gl_extensions
, client_gl_support
);