Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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