glxextensions.c revision cdc920a0
1cdc920a0Smrg/* 2cdc920a0Smrg * (C) Copyright IBM Corporation 2002, 2004 3cdc920a0Smrg * All Rights Reserved. 4cdc920a0Smrg * 5cdc920a0Smrg * Permission is hereby granted, free of charge, to any person obtaining a 6cdc920a0Smrg * copy of this software and associated documentation files (the "Software"), 7cdc920a0Smrg * to deal in the Software without restriction, including without limitation 8cdc920a0Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub 9cdc920a0Smrg * license, and/or sell copies of the Software, and to permit persons to whom 10cdc920a0Smrg * the Software is furnished to do so, subject to the following conditions: 11cdc920a0Smrg * 12cdc920a0Smrg * The above copyright notice and this permission notice (including the next 13cdc920a0Smrg * paragraph) shall be included in all copies or substantial portions of the 14cdc920a0Smrg * Software. 15cdc920a0Smrg * 16cdc920a0Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17cdc920a0Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18cdc920a0Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19cdc920a0Smrg * THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20cdc920a0Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21cdc920a0Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22cdc920a0Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. 23cdc920a0Smrg */ 24cdc920a0Smrg 25cdc920a0Smrg/** 26cdc920a0Smrg * \file glxextensions.c 27cdc920a0Smrg * 28cdc920a0Smrg * \author Ian Romanick <idr@us.ibm.com> 29cdc920a0Smrg */ 30cdc920a0Smrg 31cdc920a0Smrg#include "glxclient.h" 32cdc920a0Smrg#include <X11/extensions/extutil.h> 33cdc920a0Smrg#include <X11/extensions/Xext.h> 34cdc920a0Smrg#include <string.h> 35cdc920a0Smrg#include "glxextensions.h" 36cdc920a0Smrg 37cdc920a0Smrg 38cdc920a0Smrg#define SET_BIT(m,b) (m[ (b) / 8 ] |= (1U << ((b) % 8))) 39cdc920a0Smrg#define CLR_BIT(m,b) (m[ (b) / 8 ] &= ~(1U << ((b) % 8))) 40cdc920a0Smrg#define IS_SET(m,b) ((m[ (b) / 8 ] & (1U << ((b) % 8))) != 0) 41cdc920a0Smrg#define CONCAT(a,b) a ## b 42cdc920a0Smrg#define GLX(n) "GLX_" # n, 4 + sizeof( # n ) - 1, CONCAT(n,_bit) 43cdc920a0Smrg#define GL(n) "GL_" # n, 3 + sizeof( # n ) - 1, GL_ ## n ## _bit 44cdc920a0Smrg#define VER(a,b) a, b 45cdc920a0Smrg#define Y 1 46cdc920a0Smrg#define N 0 47cdc920a0Smrg#define EXT_ENABLED(bit,supported) (IS_SET( supported, bit )) 48cdc920a0Smrg 49cdc920a0Smrg 50cdc920a0Smrgstruct extension_info 51cdc920a0Smrg{ 52cdc920a0Smrg const char *const name; 53cdc920a0Smrg unsigned name_len; 54cdc920a0Smrg 55cdc920a0Smrg unsigned char bit; 56cdc920a0Smrg 57cdc920a0Smrg /* This is the lowest version of GLX that "requires" this extension. 58cdc920a0Smrg * For example, GLX 1.3 requires SGIX_fbconfig, SGIX_pbuffer, and 59cdc920a0Smrg * SGI_make_current_read. If the extension is not required by any known 60cdc920a0Smrg * version of GLX, use 0, 0. 61cdc920a0Smrg */ 62cdc920a0Smrg unsigned char version_major; 63cdc920a0Smrg unsigned char version_minor; 64cdc920a0Smrg unsigned char client_support; 65cdc920a0Smrg unsigned char direct_support; 66cdc920a0Smrg unsigned char client_only; /** Is the extension client-side only? */ 67cdc920a0Smrg unsigned char direct_only; /** Is the extension for direct 68cdc920a0Smrg * contexts only? 69cdc920a0Smrg */ 70cdc920a0Smrg}; 71cdc920a0Smrg 72cdc920a0Smrg/* *INDENT-OFF* */ 73cdc920a0Smrgstatic const struct extension_info known_glx_extensions[] = { 74cdc920a0Smrg { GLX(ARB_get_proc_address), VER(1,4), Y, N, Y, N }, 75cdc920a0Smrg { GLX(ARB_multisample), VER(1,4), Y, Y, N, N }, 76cdc920a0Smrg { GLX(ARB_render_texture), VER(0,0), N, N, N, N }, 77cdc920a0Smrg { GLX(ATI_pixel_format_float), VER(0,0), N, N, N, N }, 78cdc920a0Smrg#ifdef GLX_USE_APPLEGL 79cdc920a0Smrg { GLX(EXT_import_context), VER(0,0), N, N, N, N }, 80cdc920a0Smrg { GLX(EXT_visual_info), VER(0,0), N, N, N, N }, 81cdc920a0Smrg#else 82cdc920a0Smrg { GLX(EXT_import_context), VER(0,0), Y, Y, N, N }, 83cdc920a0Smrg { GLX(EXT_visual_info), VER(0,0), Y, Y, N, N }, 84cdc920a0Smrg#endif 85cdc920a0Smrg { GLX(EXT_visual_rating), VER(0,0), Y, Y, N, N }, 86cdc920a0Smrg#ifdef GLX_USE_APPLEGL 87cdc920a0Smrg { GLX(MESA_agp_offset), VER(0,0), N, N, N, N }, /* Deprecated */ 88cdc920a0Smrg { GLX(MESA_allocate_memory), VER(0,0), N, N, N, N }, 89cdc920a0Smrg { GLX(MESA_copy_sub_buffer), VER(0,0), N, N, N, N }, 90cdc920a0Smrg#else 91cdc920a0Smrg { GLX(MESA_agp_offset), VER(0,0), N, N, N, Y }, /* Deprecated */ 92cdc920a0Smrg { GLX(MESA_allocate_memory), VER(0,0), Y, N, N, Y }, 93cdc920a0Smrg { GLX(MESA_copy_sub_buffer), VER(0,0), Y, N, N, N }, 94cdc920a0Smrg#endif 95cdc920a0Smrg { GLX(MESA_pixmap_colormap), VER(0,0), N, N, N, N }, /* Deprecated */ 96cdc920a0Smrg { GLX(MESA_release_buffers), VER(0,0), N, N, N, N }, /* Deprecated */ 97cdc920a0Smrg#ifdef GLX_USE_APPLEGL 98cdc920a0Smrg { GLX(MESA_swap_control), VER(0,0), N, N, N, N }, 99cdc920a0Smrg { GLX(MESA_swap_frame_usage), VER(0,0), N, N, N, N }, 100cdc920a0Smrg#else 101cdc920a0Smrg { GLX(MESA_swap_control), VER(0,0), Y, N, N, Y }, 102cdc920a0Smrg { GLX(MESA_swap_frame_usage), VER(0,0), Y, N, N, Y }, 103cdc920a0Smrg#endif 104cdc920a0Smrg { GLX(NV_float_buffer), VER(0,0), N, N, N, N }, 105cdc920a0Smrg { GLX(NV_render_depth_texture), VER(0,0), N, N, N, N }, 106cdc920a0Smrg { GLX(NV_render_texture_rectangle), VER(0,0), N, N, N, N }, 107cdc920a0Smrg#ifdef GLX_USE_APPLEGL 108cdc920a0Smrg { GLX(NV_vertex_array_range), VER(0,0), N, N, N, N }, /* Deprecated */ 109cdc920a0Smrg { GLX(OML_swap_method), VER(0,0), N, N, N, N }, 110cdc920a0Smrg { GLX(OML_sync_control), VER(0,0), N, N, N, N }, 111cdc920a0Smrg { GLX(SGI_make_current_read), VER(1,3), N, N, N, N }, 112cdc920a0Smrg { GLX(SGI_swap_control), VER(0,0), N, N, N, N }, 113cdc920a0Smrg { GLX(SGI_video_sync), VER(0,0), N, N, N, N }, 114cdc920a0Smrg#else 115cdc920a0Smrg { GLX(NV_vertex_array_range), VER(0,0), N, N, N, Y }, /* Deprecated */ 116cdc920a0Smrg { GLX(OML_swap_method), VER(0,0), Y, Y, N, N }, 117cdc920a0Smrg { GLX(OML_sync_control), VER(0,0), Y, N, N, Y }, 118cdc920a0Smrg { GLX(SGI_make_current_read), VER(1,3), Y, N, N, N }, 119cdc920a0Smrg { GLX(SGI_swap_control), VER(0,0), Y, N, N, N }, 120cdc920a0Smrg { GLX(SGI_video_sync), VER(0,0), Y, N, N, Y }, 121cdc920a0Smrg#endif 122cdc920a0Smrg { GLX(SGIS_blended_overlay), VER(0,0), N, N, N, N }, 123cdc920a0Smrg { GLX(SGIS_color_range), VER(0,0), N, N, N, N }, 124cdc920a0Smrg#ifdef GLX_USE_APPLEGL 125cdc920a0Smrg { GLX(SGIS_multisample), VER(0,0), N, N, N, N }, 126cdc920a0Smrg#else 127cdc920a0Smrg { GLX(SGIS_multisample), VER(0,0), Y, Y, N, N }, 128cdc920a0Smrg#endif 129cdc920a0Smrg { GLX(SGIX_fbconfig), VER(1,3), Y, Y, N, N }, 130cdc920a0Smrg#ifdef GLX_USE_APPLEGL 131cdc920a0Smrg { GLX(SGIX_pbuffer), VER(1,3), N, N, N, N }, 132cdc920a0Smrg#else 133cdc920a0Smrg { GLX(SGIX_pbuffer), VER(1,3), Y, Y, N, N }, 134cdc920a0Smrg#endif 135cdc920a0Smrg { GLX(SGIX_swap_barrier), VER(0,0), N, N, N, N }, 136cdc920a0Smrg { GLX(SGIX_swap_group), VER(0,0), N, N, N, N }, 137cdc920a0Smrg#ifdef GLX_USE_APPLEGL 138cdc920a0Smrg { GLX(SGIX_visual_select_group), VER(0,0), N, N, N, N }, 139cdc920a0Smrg { GLX(EXT_texture_from_pixmap), VER(0,0), N, N, N, N }, 140cdc920a0Smrg#else 141cdc920a0Smrg { GLX(SGIX_visual_select_group), VER(0,0), Y, Y, N, N }, 142cdc920a0Smrg { GLX(EXT_texture_from_pixmap), VER(0,0), Y, N, N, N }, 143cdc920a0Smrg#endif 144cdc920a0Smrg { GLX(INTEL_swap_event), VER(1,4), Y, Y, N, N }, 145cdc920a0Smrg { NULL } 146cdc920a0Smrg}; 147cdc920a0Smrg 148cdc920a0Smrgstatic const struct extension_info known_gl_extensions[] = { 149cdc920a0Smrg { GL(ARB_depth_texture), VER(1,4), Y, N, N, N }, 150cdc920a0Smrg { GL(ARB_draw_buffers), VER(0,0), Y, N, N, N }, 151cdc920a0Smrg { GL(ARB_fragment_program), VER(0,0), Y, N, N, N }, 152cdc920a0Smrg { GL(ARB_fragment_program_shadow), VER(0,0), Y, N, N, N }, 153cdc920a0Smrg { GL(ARB_framebuffer_object), VER(0,0), Y, N, N, N }, 154cdc920a0Smrg { GL(ARB_imaging), VER(0,0), Y, N, N, N }, 155cdc920a0Smrg { GL(ARB_multisample), VER(1,3), Y, N, N, N }, 156cdc920a0Smrg { GL(ARB_multitexture), VER(1,3), Y, N, N, N }, 157cdc920a0Smrg { GL(ARB_occlusion_query), VER(1,5), Y, N, N, N }, 158cdc920a0Smrg { GL(ARB_point_parameters), VER(1,4), Y, N, N, N }, 159cdc920a0Smrg { GL(ARB_point_sprite), VER(0,0), Y, N, N, N }, 160cdc920a0Smrg { GL(ARB_shadow), VER(1,4), Y, N, N, N }, 161cdc920a0Smrg { GL(ARB_shadow_ambient), VER(0,0), Y, N, N, N }, 162cdc920a0Smrg { GL(ARB_texture_border_clamp), VER(1,3), Y, N, N, N }, 163cdc920a0Smrg { GL(ARB_texture_compression), VER(1,3), Y, N, N, N }, 164cdc920a0Smrg { GL(ARB_texture_cube_map), VER(1,3), Y, N, N, N }, 165cdc920a0Smrg { GL(ARB_texture_env_add), VER(1,3), Y, N, N, N }, 166cdc920a0Smrg { GL(ARB_texture_env_combine), VER(1,3), Y, N, N, N }, 167cdc920a0Smrg { GL(ARB_texture_env_crossbar), VER(1,4), Y, N, N, N }, 168cdc920a0Smrg { GL(ARB_texture_env_dot3), VER(1,3), Y, N, N, N }, 169cdc920a0Smrg { GL(ARB_texture_mirrored_repeat), VER(1,4), Y, N, N, N }, 170cdc920a0Smrg { GL(ARB_texture_non_power_of_two), VER(1,5), Y, N, N, N }, 171cdc920a0Smrg { GL(ARB_texture_rectangle), VER(0,0), Y, N, N, N }, 172cdc920a0Smrg { GL(ARB_transpose_matrix), VER(1,3), Y, N, Y, N }, 173cdc920a0Smrg { GL(ARB_vertex_buffer_object), VER(1,5), N, N, N, N }, 174cdc920a0Smrg { GL(ARB_vertex_program), VER(0,0), Y, N, N, N }, 175cdc920a0Smrg { GL(ARB_window_pos), VER(1,4), Y, N, N, N }, 176cdc920a0Smrg { GL(EXT_abgr), VER(0,0), Y, N, N, N }, 177cdc920a0Smrg { GL(EXT_bgra), VER(1,2), Y, N, N, N }, 178cdc920a0Smrg { GL(EXT_blend_color), VER(1,4), Y, N, N, N }, 179cdc920a0Smrg { GL(EXT_blend_equation_separate), VER(0,0), Y, N, N, N }, 180cdc920a0Smrg { GL(EXT_blend_func_separate), VER(1,4), Y, N, N, N }, 181cdc920a0Smrg { GL(EXT_blend_logic_op), VER(1,4), Y, N, N, N }, 182cdc920a0Smrg { GL(EXT_blend_minmax), VER(1,4), Y, N, N, N }, 183cdc920a0Smrg { GL(EXT_blend_subtract), VER(1,4), Y, N, N, N }, 184cdc920a0Smrg { GL(EXT_clip_volume_hint), VER(0,0), Y, N, N, N }, 185cdc920a0Smrg { GL(EXT_compiled_vertex_array), VER(0,0), N, N, N, N }, 186cdc920a0Smrg { GL(EXT_convolution), VER(0,0), N, N, N, N }, 187cdc920a0Smrg { GL(EXT_copy_texture), VER(1,1), Y, N, N, N }, 188cdc920a0Smrg { GL(EXT_cull_vertex), VER(0,0), N, N, N, N }, 189cdc920a0Smrg { GL(EXT_depth_bounds_test), VER(0,0), N, N, N, N }, 190cdc920a0Smrg { GL(EXT_draw_range_elements), VER(1,2), Y, N, Y, N }, 191cdc920a0Smrg { GL(EXT_fog_coord), VER(1,4), Y, N, N, N }, 192cdc920a0Smrg { GL(EXT_framebuffer_blit), VER(0,0), Y, N, N, N }, 193cdc920a0Smrg { GL(EXT_framebuffer_multisample), VER(0,0), Y, N, N, N }, 194cdc920a0Smrg { GL(EXT_framebuffer_object), VER(0,0), Y, N, N, N }, 195cdc920a0Smrg { GL(EXT_multi_draw_arrays), VER(1,4), Y, N, Y, N }, 196cdc920a0Smrg { GL(EXT_packed_depth_stencil), VER(0,0), Y, N, N, N }, 197cdc920a0Smrg { GL(EXT_packed_pixels), VER(1,2), Y, N, N, N }, 198cdc920a0Smrg { GL(EXT_paletted_texture), VER(0,0), Y, N, N, N }, 199cdc920a0Smrg { GL(EXT_pixel_buffer_object), VER(0,0), N, N, N, N }, 200cdc920a0Smrg { GL(EXT_point_parameters), VER(1,4), Y, N, N, N }, 201cdc920a0Smrg { GL(EXT_polygon_offset), VER(1,1), Y, N, N, N }, 202cdc920a0Smrg { GL(EXT_rescale_normal), VER(1,2), Y, N, N, N }, 203cdc920a0Smrg { GL(EXT_secondary_color), VER(1,4), Y, N, N, N }, 204cdc920a0Smrg { GL(EXT_separate_specular_color), VER(1,2), Y, N, N, N }, 205cdc920a0Smrg { GL(EXT_shadow_funcs), VER(1,5), Y, N, N, N }, 206cdc920a0Smrg { GL(EXT_shared_texture_palette), VER(0,0), Y, N, N, N }, 207cdc920a0Smrg { GL(EXT_stencil_two_side), VER(0,0), Y, N, N, N }, 208cdc920a0Smrg { GL(EXT_stencil_wrap), VER(1,4), Y, N, N, N }, 209cdc920a0Smrg { GL(EXT_subtexture), VER(1,1), Y, N, N, N }, 210cdc920a0Smrg { GL(EXT_texture), VER(1,1), Y, N, N, N }, 211cdc920a0Smrg { GL(EXT_texture3D), VER(1,2), Y, N, N, N }, 212cdc920a0Smrg { GL(EXT_texture_compression_dxt1), VER(0,0), Y, N, N, N }, 213cdc920a0Smrg { GL(EXT_texture_compression_s3tc), VER(0,0), Y, N, N, N }, 214cdc920a0Smrg { GL(EXT_texture_edge_clamp), VER(1,2), Y, N, N, N }, 215cdc920a0Smrg { GL(EXT_texture_env_add), VER(1,3), Y, N, N, N }, 216cdc920a0Smrg { GL(EXT_texture_env_combine), VER(1,3), Y, N, N, N }, 217cdc920a0Smrg { GL(EXT_texture_env_dot3), VER(0,0), Y, N, N, N }, 218cdc920a0Smrg { GL(EXT_texture_filter_anisotropic), VER(0,0), Y, N, N, N }, 219cdc920a0Smrg { GL(EXT_texture_lod), VER(1,2), Y, N, N, N }, 220cdc920a0Smrg { GL(EXT_texture_lod_bias), VER(1,4), Y, N, N, N }, 221cdc920a0Smrg { GL(EXT_texture_mirror_clamp), VER(0,0), Y, N, N, N }, 222cdc920a0Smrg { GL(EXT_texture_object), VER(1,1), Y, N, N, N }, 223cdc920a0Smrg { GL(EXT_texture_rectangle), VER(0,0), Y, N, N, N }, 224cdc920a0Smrg { GL(EXT_vertex_array), VER(0,0), Y, N, N, N }, 225cdc920a0Smrg { GL(3DFX_texture_compression_FXT1), VER(0,0), Y, N, N, N }, 226cdc920a0Smrg { GL(APPLE_packed_pixels), VER(1,2), Y, N, N, N }, 227cdc920a0Smrg { GL(APPLE_ycbcr_422), VER(0,0), Y, N, N, N }, 228cdc920a0Smrg { GL(ATI_draw_buffers), VER(0,0), Y, N, N, N }, 229cdc920a0Smrg { GL(ATI_text_fragment_shader), VER(0,0), Y, N, N, N }, 230cdc920a0Smrg { GL(ATI_texture_env_combine3), VER(0,0), Y, N, N, N }, 231cdc920a0Smrg { GL(ATI_texture_float), VER(0,0), Y, N, N, N }, 232cdc920a0Smrg { GL(ATI_texture_mirror_once), VER(0,0), Y, N, N, N }, 233cdc920a0Smrg { GL(ATIX_texture_env_combine3), VER(0,0), Y, N, N, N }, 234cdc920a0Smrg { GL(HP_convolution_border_modes), VER(0,0), Y, N, N, N }, 235cdc920a0Smrg { GL(HP_occlusion_test), VER(0,0), Y, N, N, N }, 236cdc920a0Smrg { GL(IBM_cull_vertex), VER(0,0), Y, N, N, N }, 237cdc920a0Smrg { GL(IBM_pixel_filter_hint), VER(0,0), Y, N, N, N }, 238cdc920a0Smrg { GL(IBM_rasterpos_clip), VER(0,0), Y, N, N, N }, 239cdc920a0Smrg { GL(IBM_texture_clamp_nodraw), VER(0,0), Y, N, N, N }, 240cdc920a0Smrg { GL(IBM_texture_mirrored_repeat), VER(0,0), Y, N, N, N }, 241cdc920a0Smrg { GL(INGR_blend_func_separate), VER(0,0), Y, N, N, N }, 242cdc920a0Smrg { GL(INGR_interlace_read), VER(0,0), Y, N, N, N }, 243cdc920a0Smrg { GL(MESA_pack_invert), VER(0,0), Y, N, N, N }, 244cdc920a0Smrg { GL(MESA_ycbcr_texture), VER(0,0), Y, N, N, N }, 245cdc920a0Smrg { GL(NV_blend_square), VER(1,4), Y, N, N, N }, 246cdc920a0Smrg { GL(NV_copy_depth_to_color), VER(0,0), Y, N, N, N }, 247cdc920a0Smrg { GL(NV_depth_clamp), VER(0,0), Y, N, N, N }, 248cdc920a0Smrg { GL(NV_fog_distance), VER(0,0), Y, N, N, N }, 249cdc920a0Smrg { GL(NV_fragment_program), VER(0,0), Y, N, N, N }, 250cdc920a0Smrg { GL(NV_fragment_program_option), VER(0,0), Y, N, N, N }, 251cdc920a0Smrg { GL(NV_fragment_program2), VER(0,0), Y, N, N, N }, 252cdc920a0Smrg { GL(NV_light_max_exponent), VER(0,0), Y, N, N, N }, 253cdc920a0Smrg { GL(NV_multisample_filter_hint), VER(0,0), Y, N, N, N }, 254cdc920a0Smrg { GL(NV_packed_depth_stencil), VER(0,0), Y, N, N, N }, 255cdc920a0Smrg { GL(NV_point_sprite), VER(0,0), Y, N, N, N }, 256cdc920a0Smrg { GL(NV_texgen_reflection), VER(0,0), Y, N, N, N }, 257cdc920a0Smrg { GL(NV_texture_compression_vtc), VER(0,0), Y, N, N, N }, 258cdc920a0Smrg { GL(NV_texture_env_combine4), VER(0,0), Y, N, N, N }, 259cdc920a0Smrg { GL(NV_texture_rectangle), VER(0,0), Y, N, N, N }, 260cdc920a0Smrg { GL(NV_vertex_program), VER(0,0), Y, N, N, N }, 261cdc920a0Smrg { GL(NV_vertex_program1_1), VER(0,0), Y, N, N, N }, 262cdc920a0Smrg { GL(NV_vertex_program2), VER(0,0), Y, N, N, N }, 263cdc920a0Smrg { GL(NV_vertex_program2_option), VER(0,0), Y, N, N, N }, 264cdc920a0Smrg { GL(NV_vertex_program3), VER(0,0), Y, N, N, N }, 265cdc920a0Smrg { GL(OES_read_format), VER(0,0), Y, N, N, N }, 266cdc920a0Smrg { GL(OES_compressed_paletted_texture),VER(0,0), Y, N, N, N }, 267cdc920a0Smrg { GL(SGI_color_matrix), VER(0,0), Y, N, N, N }, 268cdc920a0Smrg { GL(SGI_color_table), VER(0,0), Y, N, N, N }, 269cdc920a0Smrg { GL(SGI_texture_color_table), VER(0,0), Y, N, N, N }, 270cdc920a0Smrg { GL(SGIS_generate_mipmap), VER(1,4), Y, N, N, N }, 271cdc920a0Smrg { GL(SGIS_multisample), VER(0,0), Y, N, N, N }, 272cdc920a0Smrg { GL(SGIS_texture_border_clamp), VER(1,3), Y, N, N, N }, 273cdc920a0Smrg { GL(SGIS_texture_edge_clamp), VER(1,2), Y, N, N, N }, 274cdc920a0Smrg { GL(SGIS_texture_lod), VER(1,2), Y, N, N, N }, 275cdc920a0Smrg { GL(SGIX_blend_alpha_minmax), VER(0,0), Y, N, N, N }, 276cdc920a0Smrg { GL(SGIX_clipmap), VER(0,0), Y, N, N, N }, 277cdc920a0Smrg { GL(SGIX_depth_texture), VER(0,0), Y, N, N, N }, 278cdc920a0Smrg { GL(SGIX_fog_offset), VER(0,0), Y, N, N, N }, 279cdc920a0Smrg { GL(SGIX_shadow), VER(0,0), Y, N, N, N }, 280cdc920a0Smrg { GL(SGIX_shadow_ambient), VER(0,0), Y, N, N, N }, 281cdc920a0Smrg { GL(SGIX_texture_coordinate_clamp), VER(0,0), Y, N, N, N }, 282cdc920a0Smrg { GL(SGIX_texture_lod_bias), VER(0,0), Y, N, N, N }, 283cdc920a0Smrg { GL(SGIX_texture_range), VER(0,0), Y, N, N, N }, 284cdc920a0Smrg { GL(SGIX_texture_scale_bias), VER(0,0), Y, N, N, N }, 285cdc920a0Smrg { GL(SGIX_vertex_preclip), VER(0,0), Y, N, N, N }, 286cdc920a0Smrg { GL(SGIX_vertex_preclip_hint), VER(0,0), Y, N, N, N }, 287cdc920a0Smrg { GL(SGIX_ycrcb), VER(0,0), Y, N, N, N }, 288cdc920a0Smrg { GL(SUN_convolution_border_modes), VER(0,0), Y, N, N, N }, 289cdc920a0Smrg { GL(SUN_multi_draw_arrays), VER(0,0), Y, N, Y, N }, 290cdc920a0Smrg { GL(SUN_slice_accum), VER(0,0), Y, N, N, N }, 291cdc920a0Smrg { NULL } 292cdc920a0Smrg}; 293cdc920a0Smrg/* *INDENT-ON* */ 294cdc920a0Smrg 295cdc920a0Smrg 296cdc920a0Smrg/* global bit-fields of available extensions and their characteristics */ 297cdc920a0Smrgstatic unsigned char client_glx_support[8]; 298cdc920a0Smrgstatic unsigned char client_glx_only[8]; 299cdc920a0Smrgstatic unsigned char direct_glx_only[8]; 300cdc920a0Smrgstatic unsigned char client_gl_support[__GL_EXT_BYTES]; 301cdc920a0Smrgstatic unsigned char client_gl_only[__GL_EXT_BYTES]; 302cdc920a0Smrg 303cdc920a0Smrg/** 304cdc920a0Smrg * Bits representing the set of extensions that are enabled by default in all 305cdc920a0Smrg * direct rendering drivers. 306cdc920a0Smrg */ 307cdc920a0Smrgstatic unsigned char direct_glx_support[8]; 308cdc920a0Smrg 309cdc920a0Smrg/** 310cdc920a0Smrg * Highest core GL version that can be supported for indirect rendering. 311cdc920a0Smrg */ 312cdc920a0Smrgstatic const unsigned gl_major = 1; 313cdc920a0Smrgstatic const unsigned gl_minor = 4; 314cdc920a0Smrg 315cdc920a0Smrg/* client extensions string */ 316cdc920a0Smrgstatic const char *__glXGLXClientExtensions = NULL; 317cdc920a0Smrg 318cdc920a0Smrgstatic void __glXExtensionsCtr(void); 319cdc920a0Smrgstatic void __glXExtensionsCtrScreen(__GLXscreenConfigs * psc); 320cdc920a0Smrgstatic void __glXProcessServerString(const struct extension_info *ext, 321cdc920a0Smrg const char *server_string, 322cdc920a0Smrg unsigned char *server_support); 323cdc920a0Smrg 324cdc920a0Smrg/** 325cdc920a0Smrg * Set the state of a GLX extension. 326cdc920a0Smrg * 327cdc920a0Smrg * \param name Name of the extension. 328cdc920a0Smrg * \param name_len Length, in characters, of the extension name. 329cdc920a0Smrg * \param state New state (either enabled or disabled) of the extension. 330cdc920a0Smrg * \param supported Table in which the state of the extension is to be set. 331cdc920a0Smrg */ 332cdc920a0Smrgstatic void 333cdc920a0Smrgset_glx_extension(const struct extension_info *ext, 334cdc920a0Smrg const char *name, unsigned name_len, GLboolean state, 335cdc920a0Smrg unsigned char *supported) 336cdc920a0Smrg{ 337cdc920a0Smrg unsigned i; 338cdc920a0Smrg 339cdc920a0Smrg 340cdc920a0Smrg for (i = 0; ext[i].name != NULL; i++) { 341cdc920a0Smrg if ((name_len == ext[i].name_len) 342cdc920a0Smrg && (strncmp(ext[i].name, name, name_len) == 0)) { 343cdc920a0Smrg if (state) { 344cdc920a0Smrg SET_BIT(supported, ext[i].bit); 345cdc920a0Smrg } 346cdc920a0Smrg else { 347cdc920a0Smrg CLR_BIT(supported, ext[i].bit); 348cdc920a0Smrg } 349cdc920a0Smrg 350cdc920a0Smrg return; 351cdc920a0Smrg } 352cdc920a0Smrg } 353cdc920a0Smrg} 354cdc920a0Smrg 355cdc920a0Smrg 356cdc920a0Smrg#define NUL '\0' 357cdc920a0Smrg#define SEPARATOR ' ' 358cdc920a0Smrg 359cdc920a0Smrg/** 360cdc920a0Smrg * Convert the server's extension string to a bit-field. 361cdc920a0Smrg * 362cdc920a0Smrg * \param server_string GLX extension string from the server. 363cdc920a0Smrg * \param server_support Bit-field of supported extensions. 364cdc920a0Smrg * 365cdc920a0Smrg * \note 366cdc920a0Smrg * This function is used to process both GLX and GL extension strings. The 367cdc920a0Smrg * bit-fields used to track each of these have different sizes. Therefore, 368cdc920a0Smrg * the data pointed by \c server_support must be preinitialized to zero. 369cdc920a0Smrg */ 370cdc920a0Smrgstatic void 371cdc920a0Smrg__glXProcessServerString(const struct extension_info *ext, 372cdc920a0Smrg const char *server_string, 373cdc920a0Smrg unsigned char *server_support) 374cdc920a0Smrg{ 375cdc920a0Smrg unsigned base; 376cdc920a0Smrg unsigned len; 377cdc920a0Smrg 378cdc920a0Smrg for (base = 0; server_string[base] != NUL; /* empty */ ) { 379cdc920a0Smrg /* Determine the length of the next extension name. 380cdc920a0Smrg */ 381cdc920a0Smrg for (len = 0; (server_string[base + len] != SEPARATOR) 382cdc920a0Smrg && (server_string[base + len] != NUL); len++) { 383cdc920a0Smrg /* empty */ 384cdc920a0Smrg } 385cdc920a0Smrg 386cdc920a0Smrg /* Set the bit for the extension in the server_support table. 387cdc920a0Smrg */ 388cdc920a0Smrg set_glx_extension(ext, &server_string[base], len, GL_TRUE, 389cdc920a0Smrg server_support); 390cdc920a0Smrg 391cdc920a0Smrg 392cdc920a0Smrg /* Advance to the next extension string. This means that we skip 393cdc920a0Smrg * over the previous string and any trialing white-space. 394cdc920a0Smrg */ 395cdc920a0Smrg for (base += len; (server_string[base] == SEPARATOR) 396cdc920a0Smrg && (server_string[base] != NUL); base++) { 397cdc920a0Smrg /* empty */ 398cdc920a0Smrg } 399cdc920a0Smrg } 400cdc920a0Smrg} 401cdc920a0Smrg 402cdc920a0Smrgvoid 403cdc920a0Smrg__glXEnableDirectExtension(__GLXscreenConfigs * psc, const char *name) 404cdc920a0Smrg{ 405cdc920a0Smrg __glXExtensionsCtr(); 406cdc920a0Smrg __glXExtensionsCtrScreen(psc); 407cdc920a0Smrg 408cdc920a0Smrg set_glx_extension(known_glx_extensions, 409cdc920a0Smrg name, strlen(name), GL_TRUE, psc->direct_support); 410cdc920a0Smrg} 411cdc920a0Smrg 412cdc920a0Smrg/** 413cdc920a0Smrg * Initialize global extension support tables. 414cdc920a0Smrg */ 415cdc920a0Smrg 416cdc920a0Smrgstatic void 417cdc920a0Smrg__glXExtensionsCtr(void) 418cdc920a0Smrg{ 419cdc920a0Smrg unsigned i; 420cdc920a0Smrg static GLboolean ext_list_first_time = GL_TRUE; 421cdc920a0Smrg 422cdc920a0Smrg 423cdc920a0Smrg if (ext_list_first_time) { 424cdc920a0Smrg ext_list_first_time = GL_FALSE; 425cdc920a0Smrg 426cdc920a0Smrg (void) memset(client_glx_support, 0, sizeof(client_glx_support)); 427cdc920a0Smrg (void) memset(direct_glx_support, 0, sizeof(direct_glx_support)); 428cdc920a0Smrg (void) memset(client_glx_only, 0, sizeof(client_glx_only)); 429cdc920a0Smrg (void) memset(direct_glx_only, 0, sizeof(direct_glx_only)); 430cdc920a0Smrg 431cdc920a0Smrg (void) memset(client_gl_support, 0, sizeof(client_gl_support)); 432cdc920a0Smrg (void) memset(client_gl_only, 0, sizeof(client_gl_only)); 433cdc920a0Smrg 434cdc920a0Smrg for (i = 0; known_glx_extensions[i].name != NULL; i++) { 435cdc920a0Smrg const unsigned bit = known_glx_extensions[i].bit; 436cdc920a0Smrg 437cdc920a0Smrg if (known_glx_extensions[i].client_support) { 438cdc920a0Smrg SET_BIT(client_glx_support, bit); 439cdc920a0Smrg } 440cdc920a0Smrg 441cdc920a0Smrg if (known_glx_extensions[i].direct_support) { 442cdc920a0Smrg SET_BIT(direct_glx_support, bit); 443cdc920a0Smrg } 444cdc920a0Smrg 445cdc920a0Smrg if (known_glx_extensions[i].client_only) { 446cdc920a0Smrg SET_BIT(client_glx_only, bit); 447cdc920a0Smrg } 448cdc920a0Smrg 449cdc920a0Smrg if (known_glx_extensions[i].direct_only) { 450cdc920a0Smrg SET_BIT(direct_glx_only, bit); 451cdc920a0Smrg } 452cdc920a0Smrg } 453cdc920a0Smrg 454cdc920a0Smrg for (i = 0; known_gl_extensions[i].name != NULL; i++) { 455cdc920a0Smrg const unsigned bit = known_gl_extensions[i].bit; 456cdc920a0Smrg 457cdc920a0Smrg if (known_gl_extensions[i].client_support) { 458cdc920a0Smrg SET_BIT(client_gl_support, bit); 459cdc920a0Smrg } 460cdc920a0Smrg 461cdc920a0Smrg if (known_gl_extensions[i].client_only) { 462cdc920a0Smrg SET_BIT(client_gl_only, bit); 463cdc920a0Smrg } 464cdc920a0Smrg } 465cdc920a0Smrg 466cdc920a0Smrg#if 0 467cdc920a0Smrg fprintf(stderr, "[%s:%u] Maximum client library version: %u.%u\n", 468cdc920a0Smrg __func__, __LINE__, gl_major, gl_minor); 469cdc920a0Smrg#endif 470cdc920a0Smrg } 471cdc920a0Smrg} 472cdc920a0Smrg 473cdc920a0Smrg 474cdc920a0Smrg/** 475cdc920a0Smrg * Make sure that per-screen direct-support table is initialized. 476cdc920a0Smrg * 477cdc920a0Smrg * \param psc Pointer to GLX per-screen record. 478cdc920a0Smrg */ 479cdc920a0Smrg 480cdc920a0Smrgstatic void 481cdc920a0Smrg__glXExtensionsCtrScreen(__GLXscreenConfigs * psc) 482cdc920a0Smrg{ 483cdc920a0Smrg if (psc->ext_list_first_time) { 484cdc920a0Smrg psc->ext_list_first_time = GL_FALSE; 485cdc920a0Smrg (void) memcpy(psc->direct_support, direct_glx_support, 486cdc920a0Smrg sizeof(direct_glx_support)); 487cdc920a0Smrg } 488cdc920a0Smrg} 489cdc920a0Smrg 490cdc920a0Smrg 491cdc920a0Smrg/** 492cdc920a0Smrg * Check if a certain extension is enabled on a given screen. 493cdc920a0Smrg * 494cdc920a0Smrg * \param psc Pointer to GLX per-screen record. 495cdc920a0Smrg * \param bit Bit index in the direct-support table. 496cdc920a0Smrg * \returns If the extension bit is enabled for the screen, \c GL_TRUE is 497cdc920a0Smrg * returned. If the extension bit is not enabled or if \c psc is 498cdc920a0Smrg * \c NULL, then \c GL_FALSE is returned. 499cdc920a0Smrg */ 500cdc920a0SmrgGLboolean 501cdc920a0Smrg__glXExtensionBitIsEnabled(__GLXscreenConfigs * psc, unsigned bit) 502cdc920a0Smrg{ 503cdc920a0Smrg GLboolean enabled = GL_FALSE; 504cdc920a0Smrg 505cdc920a0Smrg if (psc != NULL) { 506cdc920a0Smrg __glXExtensionsCtr(); 507cdc920a0Smrg __glXExtensionsCtrScreen(psc); 508cdc920a0Smrg enabled = EXT_ENABLED(bit, psc->direct_support); 509cdc920a0Smrg } 510cdc920a0Smrg 511cdc920a0Smrg return enabled; 512cdc920a0Smrg} 513cdc920a0Smrg 514cdc920a0Smrg 515cdc920a0Smrg/** 516cdc920a0Smrg * Check if a certain extension is enabled in a given context. 517cdc920a0Smrg * 518cdc920a0Smrg */ 519cdc920a0SmrgGLboolean 520cdc920a0Smrg__glExtensionBitIsEnabled(const __GLXcontext * gc, unsigned bit) 521cdc920a0Smrg{ 522cdc920a0Smrg GLboolean enabled = GL_FALSE; 523cdc920a0Smrg 524cdc920a0Smrg if (gc != NULL) { 525cdc920a0Smrg enabled = EXT_ENABLED(bit, gc->gl_extension_bits); 526cdc920a0Smrg } 527cdc920a0Smrg 528cdc920a0Smrg return enabled; 529cdc920a0Smrg} 530cdc920a0Smrg 531cdc920a0Smrg 532cdc920a0Smrg 533cdc920a0Smrg/** 534cdc920a0Smrg * Convert a bit-field to a string of supported extensions. 535cdc920a0Smrg */ 536cdc920a0Smrgstatic char * 537cdc920a0Smrg__glXGetStringFromTable(const struct extension_info *ext, 538cdc920a0Smrg const unsigned char *supported) 539cdc920a0Smrg{ 540cdc920a0Smrg unsigned i; 541cdc920a0Smrg unsigned ext_str_len; 542cdc920a0Smrg char *ext_str; 543cdc920a0Smrg char *point; 544cdc920a0Smrg 545cdc920a0Smrg 546cdc920a0Smrg ext_str_len = 0; 547cdc920a0Smrg for (i = 0; ext[i].name != NULL; i++) { 548cdc920a0Smrg if (EXT_ENABLED(ext[i].bit, supported)) { 549cdc920a0Smrg ext_str_len += ext[i].name_len + 1; 550cdc920a0Smrg } 551cdc920a0Smrg } 552cdc920a0Smrg 553cdc920a0Smrg ext_str = Xmalloc(ext_str_len + 1); 554cdc920a0Smrg if (ext_str != NULL) { 555cdc920a0Smrg point = ext_str; 556cdc920a0Smrg 557cdc920a0Smrg for (i = 0; ext[i].name != NULL; i++) { 558cdc920a0Smrg if (EXT_ENABLED(ext[i].bit, supported)) { 559cdc920a0Smrg (void) memcpy(point, ext[i].name, ext[i].name_len); 560cdc920a0Smrg point += ext[i].name_len; 561cdc920a0Smrg 562cdc920a0Smrg *point = ' '; 563cdc920a0Smrg point++; 564cdc920a0Smrg } 565cdc920a0Smrg } 566cdc920a0Smrg 567cdc920a0Smrg *point = '\0'; 568cdc920a0Smrg } 569cdc920a0Smrg 570cdc920a0Smrg return ext_str; 571cdc920a0Smrg} 572cdc920a0Smrg 573cdc920a0Smrg 574cdc920a0Smrg/** 575cdc920a0Smrg * Get the string of client library supported extensions. 576cdc920a0Smrg */ 577cdc920a0Smrgconst char * 578cdc920a0Smrg__glXGetClientExtensions(void) 579cdc920a0Smrg{ 580cdc920a0Smrg if (__glXGLXClientExtensions == NULL) { 581cdc920a0Smrg __glXExtensionsCtr(); 582cdc920a0Smrg __glXGLXClientExtensions = __glXGetStringFromTable(known_glx_extensions, 583cdc920a0Smrg client_glx_support); 584cdc920a0Smrg } 585cdc920a0Smrg 586cdc920a0Smrg return __glXGLXClientExtensions; 587cdc920a0Smrg} 588cdc920a0Smrg 589cdc920a0Smrg 590cdc920a0Smrg/** 591cdc920a0Smrg * Calculate the list of application usable extensions. The resulting 592cdc920a0Smrg * string is stored in \c psc->effectiveGLXexts. 593cdc920a0Smrg * 594cdc920a0Smrg * \param psc Pointer to GLX per-screen record. 595cdc920a0Smrg * \param display_is_direct_capable True if the display is capable of 596cdc920a0Smrg * direct rendering. 597cdc920a0Smrg * \param minor_version GLX minor version from the server. 598cdc920a0Smrg */ 599cdc920a0Smrg 600cdc920a0Smrgvoid 601cdc920a0Smrg__glXCalculateUsableExtensions(__GLXscreenConfigs * psc, 602cdc920a0Smrg GLboolean display_is_direct_capable, 603cdc920a0Smrg int minor_version) 604cdc920a0Smrg{ 605cdc920a0Smrg unsigned char server_support[8]; 606cdc920a0Smrg unsigned char usable[8]; 607cdc920a0Smrg unsigned i; 608cdc920a0Smrg 609cdc920a0Smrg __glXExtensionsCtr(); 610cdc920a0Smrg __glXExtensionsCtrScreen(psc); 611cdc920a0Smrg 612cdc920a0Smrg (void) memset(server_support, 0, sizeof(server_support)); 613cdc920a0Smrg __glXProcessServerString(known_glx_extensions, 614cdc920a0Smrg psc->serverGLXexts, server_support); 615cdc920a0Smrg 616cdc920a0Smrg 617cdc920a0Smrg /* This is a hack. Some servers support GLX 1.3 but don't export 618cdc920a0Smrg * all of the extensions implied by GLX 1.3. If the server claims 619cdc920a0Smrg * support for GLX 1.3, enable support for the extensions that can be 620cdc920a0Smrg * "emulated" as well. 621cdc920a0Smrg */ 622cdc920a0Smrg 623cdc920a0Smrg if (minor_version >= 3) { 624cdc920a0Smrg SET_BIT(server_support, EXT_visual_info_bit); 625cdc920a0Smrg SET_BIT(server_support, EXT_visual_rating_bit); 626cdc920a0Smrg SET_BIT(server_support, SGI_make_current_read_bit); 627cdc920a0Smrg SET_BIT(server_support, SGIX_fbconfig_bit); 628cdc920a0Smrg SET_BIT(server_support, SGIX_pbuffer_bit); 629cdc920a0Smrg 630cdc920a0Smrg /* This one is a little iffy. GLX 1.3 doesn't incorporate all of this 631cdc920a0Smrg * extension. However, the only part that is not strictly client-side 632cdc920a0Smrg * is shared. That's the glXQueryContext / glXQueryContextInfoEXT 633cdc920a0Smrg * function. 634cdc920a0Smrg */ 635cdc920a0Smrg 636cdc920a0Smrg SET_BIT(server_support, EXT_import_context_bit); 637cdc920a0Smrg } 638cdc920a0Smrg 639cdc920a0Smrg 640cdc920a0Smrg /* An extension is supported if the client-side (i.e., libGL) supports 641cdc920a0Smrg * it and the "server" supports it. In this case that means that either 642cdc920a0Smrg * the true server supports it or it is only for direct-rendering and 643cdc920a0Smrg * the direct rendering driver supports it. 644cdc920a0Smrg * 645cdc920a0Smrg * If the display is not capable of direct rendering, then the extension 646cdc920a0Smrg * is enabled if and only if the client-side library and the server 647cdc920a0Smrg * support it. 648cdc920a0Smrg */ 649cdc920a0Smrg 650cdc920a0Smrg if (display_is_direct_capable) { 651cdc920a0Smrg for (i = 0; i < 8; i++) { 652cdc920a0Smrg usable[i] = (client_glx_support[i] & client_glx_only[i]) 653cdc920a0Smrg | (client_glx_support[i] & psc->direct_support[i] & 654cdc920a0Smrg server_support[i]) 655cdc920a0Smrg | (client_glx_support[i] & psc->direct_support[i] & 656cdc920a0Smrg direct_glx_only[i]); 657cdc920a0Smrg } 658cdc920a0Smrg } 659cdc920a0Smrg else { 660cdc920a0Smrg for (i = 0; i < 8; i++) { 661cdc920a0Smrg usable[i] = (client_glx_support[i] & client_glx_only[i]) 662cdc920a0Smrg | (client_glx_support[i] & server_support[i]); 663cdc920a0Smrg } 664cdc920a0Smrg } 665cdc920a0Smrg 666cdc920a0Smrg psc->effectiveGLXexts = __glXGetStringFromTable(known_glx_extensions, 667cdc920a0Smrg usable); 668cdc920a0Smrg} 669cdc920a0Smrg 670cdc920a0Smrg 671cdc920a0Smrg/** 672cdc920a0Smrg * Calculate the list of application usable extensions. The resulting 673cdc920a0Smrg * string is stored in \c gc->extensions. 674cdc920a0Smrg * 675cdc920a0Smrg * \param gc Pointer to GLX context. 676cdc920a0Smrg * \param server_string Extension string from the server. 677cdc920a0Smrg * \param major_version GL major version from the server. 678cdc920a0Smrg * \param minor_version GL minor version from the server. 679cdc920a0Smrg */ 680cdc920a0Smrg 681cdc920a0Smrgvoid 682cdc920a0Smrg__glXCalculateUsableGLExtensions(__GLXcontext * gc, 683cdc920a0Smrg const char *server_string, 684cdc920a0Smrg int major_version, int minor_version) 685cdc920a0Smrg{ 686cdc920a0Smrg unsigned char server_support[__GL_EXT_BYTES]; 687cdc920a0Smrg unsigned char usable[__GL_EXT_BYTES]; 688cdc920a0Smrg unsigned i; 689cdc920a0Smrg 690cdc920a0Smrg 691cdc920a0Smrg __glXExtensionsCtr(); 692cdc920a0Smrg 693cdc920a0Smrg (void) memset(server_support, 0, sizeof(server_support)); 694cdc920a0Smrg __glXProcessServerString(known_gl_extensions, server_string, 695cdc920a0Smrg server_support); 696cdc920a0Smrg 697cdc920a0Smrg 698cdc920a0Smrg /* Handle lazy servers that don't export all the extensions strings that 699cdc920a0Smrg * are part of the GL core version that they support. 700cdc920a0Smrg */ 701cdc920a0Smrg 702cdc920a0Smrg for (i = 0; i < __GL_EXT_BYTES; i++) { 703cdc920a0Smrg if ((known_gl_extensions[i].version_major != 0) 704cdc920a0Smrg && ((major_version > known_gl_extensions[i].version_major) 705cdc920a0Smrg || ((major_version == known_gl_extensions[i].version_major) 706cdc920a0Smrg && (minor_version >= 707cdc920a0Smrg known_gl_extensions[i].version_minor)))) { 708cdc920a0Smrg SET_BIT(server_support, known_gl_extensions[i].bit); 709cdc920a0Smrg } 710cdc920a0Smrg } 711cdc920a0Smrg 712cdc920a0Smrg 713cdc920a0Smrg /* An extension is supported if the client-side (i.e., libGL) supports 714cdc920a0Smrg * it and the server supports it or the client-side library supports it 715cdc920a0Smrg * and it only needs client-side support. 716cdc920a0Smrg */ 717cdc920a0Smrg 718cdc920a0Smrg for (i = 0; i < __GL_EXT_BYTES; i++) { 719cdc920a0Smrg usable[i] = (client_gl_support[i] & client_gl_only[i]) 720cdc920a0Smrg | (client_gl_support[i] & server_support[i]); 721cdc920a0Smrg } 722cdc920a0Smrg 723cdc920a0Smrg gc->extensions = (unsigned char *) 724cdc920a0Smrg __glXGetStringFromTable(known_gl_extensions, usable); 725cdc920a0Smrg (void) memcpy(gc->gl_extension_bits, usable, sizeof(usable)); 726cdc920a0Smrg} 727cdc920a0Smrg 728cdc920a0Smrg 729cdc920a0Smrg/** 730cdc920a0Smrg * Calculates the maximum core GL version that can be supported for indirect 731cdc920a0Smrg * rendering. 732cdc920a0Smrg */ 733cdc920a0Smrgvoid 734cdc920a0Smrg__glXGetGLVersion(int *major_version, int *minor_version) 735cdc920a0Smrg{ 736cdc920a0Smrg __glXExtensionsCtr(); 737cdc920a0Smrg *major_version = gl_major; 738cdc920a0Smrg *minor_version = gl_minor; 739cdc920a0Smrg} 740cdc920a0Smrg 741cdc920a0Smrg 742cdc920a0Smrg/** 743cdc920a0Smrg * Get a string representing the set of extensions supported by the client 744cdc920a0Smrg * library. This is currently only used to send the list of extensions 745cdc920a0Smrg * supported by the client to the server. 746cdc920a0Smrg */ 747cdc920a0Smrgchar * 748cdc920a0Smrg__glXGetClientGLExtensionString(void) 749cdc920a0Smrg{ 750cdc920a0Smrg __glXExtensionsCtr(); 751cdc920a0Smrg return __glXGetStringFromTable(known_gl_extensions, client_gl_support); 752cdc920a0Smrg} 753