Home | History | Annotate | Download | only in main
      1 /*
      2  * Mesa 3-D graphics library
      3  * Version:  7.6
      4  *
      5  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
      6  * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
      7  *
      8  * Permission is hereby granted, free of charge, to any person obtaining a
      9  * copy of this software and associated documentation files (the "Software"),
     10  * to deal in the Software without restriction, including without limitation
     11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     12  * and/or sell copies of the Software, and to permit persons to whom the
     13  * Software is furnished to do so, subject to the following conditions:
     14  *
     15  * The above copyright notice and this permission notice shall be included
     16  * in all copies or substantial portions of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     21  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     22  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  */
     25 
     26 
     27 /**
     28  * \file
     29  * \brief Extension handling
     30  */
     31 
     32 
     33 #include "glheader.h"
     34 #include "imports.h"
     35 #include "context.h"
     36 #include "extensions.h"
     37 #include "mfeatures.h"
     38 #include "mtypes.h"
     39 
     40 #define ALIGN(value, alignment)  (((value) + alignment - 1) & ~(alignment - 1))
     41 
     42 enum {
     43    DISABLE = 0,
     44    GLL = 1 << API_OPENGL,       /* GL Legacy / Compatibility */
     45    GLC = 1 << API_OPENGL_CORE,  /* GL Core */
     46    GL  = (1 << API_OPENGL) | (1 << API_OPENGL_CORE),
     47    ES1 = 1 << API_OPENGLES,
     48    ES2 = 1 << API_OPENGLES2,
     49 };
     50 
     51 /**
     52  * \brief An element of the \c extension_table.
     53  */
     54 struct extension {
     55    /** Name of extension, such as "GL_ARB_depth_clamp". */
     56    const char *name;
     57 
     58    /** Offset (in bytes) of the corresponding member in struct gl_extensions. */
     59    size_t offset;
     60 
     61    /** Set of API's in which the extension exists, as a bitset. */
     62    uint8_t api_set;
     63 
     64    /** Year the extension was proposed or approved.  Used to sort the
     65     * extension string chronologically. */
     66    uint16_t year;
     67 };
     68 
     69 
     70 /**
     71  * Given a member \c x of struct gl_extensions, return offset of
     72  * \c x in bytes.
     73  */
     74 #define o(x) offsetof(struct gl_extensions, x)
     75 
     76 
     77 /**
     78  * \brief Table of supported OpenGL extensions for all API's.
     79  */
     80 static const struct extension extension_table[] = {
     81    /* ARB Extensions */
     82    { "GL_ARB_ES2_compatibility",                   o(ARB_ES2_compatibility),                   GL,             2009 },
     83    { "GL_ARB_base_instance",                       o(ARB_base_instance),                       GL,             2011 },
     84    { "GL_ARB_blend_func_extended",                 o(ARB_blend_func_extended),                 GL,             2009 },
     85    { "GL_ARB_color_buffer_float",                  o(ARB_color_buffer_float),                  GL,             2004 },
     86    { "GL_ARB_copy_buffer",                         o(ARB_copy_buffer),                         GL,             2008 },
     87    { "GL_ARB_conservative_depth",                  o(ARB_conservative_depth),                  GL,             2011 },
     88    { "GL_ARB_debug_output",                        o(dummy_true),                              GL,             2009 },
     89    { "GL_ARB_depth_buffer_float",                  o(ARB_depth_buffer_float),                  GL,             2008 },
     90    { "GL_ARB_depth_clamp",                         o(ARB_depth_clamp),                         GL,             2003 },
     91    { "GL_ARB_depth_texture",                       o(ARB_depth_texture),                       GLL,            2001 },
     92    { "GL_ARB_draw_buffers",                        o(dummy_true),                              GL,             2002 },
     93    { "GL_ARB_draw_buffers_blend",                  o(ARB_draw_buffers_blend),                  GL,             2009 },
     94    { "GL_ARB_draw_elements_base_vertex",           o(ARB_draw_elements_base_vertex),           GL,             2009 },
     95    { "GL_ARB_draw_instanced",                      o(ARB_draw_instanced),                      GL,             2008 },
     96    { "GL_ARB_explicit_attrib_location",            o(ARB_explicit_attrib_location),            GL,             2009 },
     97    { "GL_ARB_fragment_coord_conventions",          o(ARB_fragment_coord_conventions),          GL,             2009 },
     98    { "GL_ARB_fragment_program",                    o(ARB_fragment_program),                    GLL,            2002 },
     99    { "GL_ARB_fragment_program_shadow",             o(ARB_fragment_program_shadow),             GLL,            2003 },
    100    { "GL_ARB_fragment_shader",                     o(ARB_fragment_shader),                     GL,             2002 },
    101    { "GL_ARB_framebuffer_object",                  o(ARB_framebuffer_object),                  GL,             2005 },
    102    { "GL_ARB_framebuffer_sRGB",                    o(EXT_framebuffer_sRGB),                    GL,             1998 },
    103    { "GL_ARB_half_float_pixel",                    o(ARB_half_float_pixel),                    GL,             2003 },
    104    { "GL_ARB_half_float_vertex",                   o(ARB_half_float_vertex),                   GL,             2008 },
    105    { "GL_ARB_instanced_arrays",                    o(ARB_instanced_arrays),                    GL,             2008 },
    106    { "GL_ARB_invalidate_subdata",                  o(dummy_true),                              GL,             2012 },
    107    { "GL_ARB_map_buffer_range",                    o(ARB_map_buffer_range),                    GL,             2008 },
    108    { "GL_ARB_multisample",                         o(dummy_true),                              GLL,            1994 },
    109    { "GL_ARB_multitexture",                        o(dummy_true),                              GLL,            1998 },
    110    { "GL_ARB_occlusion_query2",                    o(ARB_occlusion_query2),                    GL,             2003 },
    111    { "GL_ARB_occlusion_query",                     o(ARB_occlusion_query),                     GLL,            2001 },
    112    { "GL_ARB_pixel_buffer_object",                 o(EXT_pixel_buffer_object),                 GL,             2004 },
    113    { "GL_ARB_point_parameters",                    o(EXT_point_parameters),                    GLL,            1997 },
    114    { "GL_ARB_point_sprite",                        o(ARB_point_sprite),                        GL,             2003 },
    115    { "GL_ARB_provoking_vertex",                    o(EXT_provoking_vertex),                    GL,             2009 },
    116    { "GL_ARB_robustness",                          o(dummy_true),                              GL,             2010 },
    117    { "GL_ARB_sampler_objects",                     o(dummy_true),                              GL,             2009 },
    118    { "GL_ARB_seamless_cube_map",                   o(ARB_seamless_cube_map),                   GL,             2009 },
    119    { "GL_ARB_shader_bit_encoding",                 o(ARB_shader_bit_encoding),                 GL,             2010 },
    120    { "GL_ARB_shader_objects",                      o(ARB_shader_objects),                      GL,             2002 },
    121    { "GL_ARB_shader_stencil_export",               o(ARB_shader_stencil_export),               GL,             2009 },
    122    { "GL_ARB_shader_texture_lod",                  o(ARB_shader_texture_lod),                  GL,             2009 },
    123    { "GL_ARB_shading_language_100",                o(ARB_shading_language_100),                GLL,            2003 },
    124    { "GL_ARB_shadow",                              o(ARB_shadow),                              GLL,            2001 },
    125    { "GL_ARB_sync",                                o(ARB_sync),                                GL,             2003 },
    126    { "GL_ARB_texture_border_clamp",                o(ARB_texture_border_clamp),                GLL,            2000 },
    127    { "GL_ARB_texture_buffer_object",               o(ARB_texture_buffer_object),               GL,             2008 },
    128    { "GL_ARB_texture_compression",                 o(dummy_true),                              GLL,            2000 },
    129    { "GL_ARB_texture_compression_rgtc",            o(ARB_texture_compression_rgtc),            GL,             2004 },
    130    { "GL_ARB_texture_cube_map",                    o(ARB_texture_cube_map),                    GLL,            1999 },
    131    { "GL_ARB_texture_env_add",                     o(dummy_true),                              GLL,            1999 },
    132    { "GL_ARB_texture_env_combine",                 o(ARB_texture_env_combine),                 GLL,            2001 },
    133    { "GL_ARB_texture_env_crossbar",                o(ARB_texture_env_crossbar),                GLL,            2001 },
    134    { "GL_ARB_texture_env_dot3",                    o(ARB_texture_env_dot3),                    GLL,            2001 },
    135    { "GL_ARB_texture_float",                       o(ARB_texture_float),                       GL,             2004 },
    136    { "GL_ARB_texture_mirrored_repeat",             o(dummy_true),                              GLL,            2001 },
    137    { "GL_ARB_texture_multisample",                 o(ARB_texture_multisample),                 GL,             2009 },
    138    { "GL_ARB_texture_non_power_of_two",            o(ARB_texture_non_power_of_two),            GL,             2003 },
    139    { "GL_ARB_texture_rectangle",                   o(NV_texture_rectangle),                    GL,             2004 },
    140    { "GL_ARB_texture_rgb10_a2ui",                  o(ARB_texture_rgb10_a2ui),                  GL,             2009 },
    141    { "GL_ARB_texture_rg",                          o(ARB_texture_rg),                          GL,             2008 },
    142    { "GL_ARB_texture_storage",                     o(ARB_texture_storage),                     GL,             2011 },
    143    { "GL_ARB_texture_swizzle",                     o(EXT_texture_swizzle),                     GL,             2008 },
    144    { "GL_ARB_timer_query",                         o(ARB_timer_query),                         GL,             2010 },
    145    { "GL_ARB_transform_feedback2",                 o(ARB_transform_feedback2),                 GL,             2010 },
    146    { "GL_ARB_transform_feedback3",                 o(ARB_transform_feedback3),                 GL,             2010 },
    147    { "GL_ARB_transform_feedback_instanced",        o(ARB_transform_feedback_instanced),        GL,             2011 },
    148    { "GL_ARB_transpose_matrix",                    o(ARB_transpose_matrix),                    GLL,            1999 },
    149    { "GL_ARB_uniform_buffer_object",               o(ARB_uniform_buffer_object),               GL,             2009 },
    150    { "GL_ARB_vertex_array_bgra",                   o(EXT_vertex_array_bgra),                   GL,             2008 },
    151    { "GL_ARB_vertex_array_object",                 o(dummy_true),                              GL,             2006 },
    152    { "GL_ARB_vertex_buffer_object",                o(dummy_true),                              GLL,            2003 },
    153    { "GL_ARB_vertex_program",                      o(ARB_vertex_program),                      GLL,            2002 },
    154    { "GL_ARB_vertex_shader",                       o(ARB_vertex_shader),                       GL,             2002 },
    155    { "GL_ARB_vertex_type_2_10_10_10_rev",          o(ARB_vertex_type_2_10_10_10_rev),          GL,             2009 },
    156    { "GL_ARB_window_pos",                          o(ARB_window_pos),                          GLL,            2001 },
    157    /* EXT extensions */
    158    { "GL_EXT_abgr",                                o(dummy_true),                              GL,             1995 },
    159    { "GL_EXT_bgra",                                o(dummy_true),                              GLL,            1995 },
    160    { "GL_EXT_blend_color",                         o(EXT_blend_color),                         GLL,            1995 },
    161    { "GL_EXT_blend_equation_separate",             o(EXT_blend_equation_separate),             GL,             2003 },
    162    { "GL_EXT_blend_func_separate",                 o(EXT_blend_func_separate),                 GLL,            1999 },
    163    { "GL_EXT_blend_minmax",                        o(EXT_blend_minmax),                        GLL | ES1 | ES2, 1995 },
    164    { "GL_EXT_blend_subtract",                      o(dummy_true),                              GLL,            1995 },
    165    { "GL_EXT_clip_volume_hint",                    o(EXT_clip_volume_hint),                    GL,             1996 },
    166    { "GL_EXT_compiled_vertex_array",               o(EXT_compiled_vertex_array),               GLL,            1996 },
    167    { "GL_EXT_copy_texture",                        o(dummy_true),                              GLL,            1995 },
    168    { "GL_EXT_depth_bounds_test",                   o(EXT_depth_bounds_test),                   GL,             2002 },
    169    { "GL_EXT_draw_buffers2",                       o(EXT_draw_buffers2),                       GL,             2006 },
    170    { "GL_EXT_draw_instanced",                      o(ARB_draw_instanced),                      GL,             2006 },
    171    { "GL_EXT_draw_range_elements",                 o(EXT_draw_range_elements),                 GLL,            1997 },
    172    { "GL_EXT_fog_coord",                           o(EXT_fog_coord),                           GLL,            1999 },
    173    { "GL_EXT_framebuffer_blit",                    o(EXT_framebuffer_blit),                    GL,             2005 },
    174    { "GL_EXT_framebuffer_multisample",             o(EXT_framebuffer_multisample),             GL,             2005 },
    175    { "GL_EXT_framebuffer_object",                  o(EXT_framebuffer_object),                  GL,             2000 },
    176    { "GL_EXT_framebuffer_sRGB",                    o(EXT_framebuffer_sRGB),                    GL,             1998 },
    177    { "GL_EXT_gpu_program_parameters",              o(EXT_gpu_program_parameters),              GLL,            2006 },
    178    { "GL_EXT_gpu_shader4",                         o(EXT_gpu_shader4),                         GL,             2006 },
    179    { "GL_EXT_multi_draw_arrays",                   o(dummy_true),                              GLL | ES1 | ES2, 1999 },
    180    { "GL_EXT_packed_depth_stencil",                o(EXT_packed_depth_stencil),                GL,             2005 },
    181    { "GL_EXT_packed_float",                        o(EXT_packed_float),                        GL,             2004 },
    182    { "GL_EXT_packed_pixels",                       o(EXT_packed_pixels),                       GLL,            1997 },
    183    { "GL_EXT_pixel_buffer_object",                 o(EXT_pixel_buffer_object),                 GL,             2004 },
    184    { "GL_EXT_point_parameters",                    o(EXT_point_parameters),                    GLL,            1997 },
    185    { "GL_EXT_polygon_offset",                      o(dummy_true),                              GLL,            1995 },
    186    { "GL_EXT_provoking_vertex",                    o(EXT_provoking_vertex),                    GL,             2009 },
    187    { "GL_EXT_rescale_normal",                      o(EXT_rescale_normal),                      GLL,            1997 },
    188    { "GL_EXT_secondary_color",                     o(EXT_secondary_color),                     GLL,            1999 },
    189    { "GL_EXT_separate_shader_objects",             o(EXT_separate_shader_objects),             GLL,            2008 },
    190    { "GL_EXT_separate_specular_color",             o(EXT_separate_specular_color),             GLL,            1997 },
    191    { "GL_EXT_shadow_funcs",                        o(EXT_shadow_funcs),                        GLL,            2002 },
    192    { "GL_EXT_stencil_two_side",                    o(EXT_stencil_two_side),                    GLL,            2001 },
    193    { "GL_EXT_stencil_wrap",                        o(dummy_true),                              GLL,            2002 },
    194    { "GL_EXT_subtexture",                          o(dummy_true),                              GLL,            1995 },
    195    { "GL_EXT_texture3D",                           o(EXT_texture3D),                           GLL,            1996 },
    196    { "GL_EXT_texture_array",                       o(EXT_texture_array),                       GL,             2006 },
    197    { "GL_EXT_texture_compression_dxt1",            o(EXT_texture_compression_s3tc),            GL | ES1 | ES2, 2004 },
    198    { "GL_EXT_texture_compression_latc",            o(EXT_texture_compression_latc),            GL,             2006 },
    199    { "GL_EXT_texture_compression_rgtc",            o(ARB_texture_compression_rgtc),            GL,             2004 },
    200    { "GL_EXT_texture_compression_s3tc",            o(EXT_texture_compression_s3tc),            GL,             2000 },
    201    { "GL_EXT_texture_cube_map",                    o(ARB_texture_cube_map),                    GLL,            2001 },
    202    { "GL_EXT_texture_edge_clamp",                  o(dummy_true),                              GLL,            1997 },
    203    { "GL_EXT_texture_env_add",                     o(dummy_true),                              GLL,            1999 },
    204    { "GL_EXT_texture_env_combine",                 o(dummy_true),                              GLL,            2000 },
    205    { "GL_EXT_texture_env_dot3",                    o(EXT_texture_env_dot3),                    GLL,            2000 },
    206    { "GL_EXT_texture_filter_anisotropic",          o(EXT_texture_filter_anisotropic),          GL | ES1 | ES2, 1999 },
    207    { "GL_EXT_texture_format_BGRA8888",             o(dummy_true),                                   ES1 | ES2, 2005 },
    208    { "GL_EXT_texture_rg",                          o(ARB_texture_rg),                                     ES2, 2011 },
    209    { "GL_EXT_read_format_bgra",                    o(dummy_true),                                   ES1 | ES2, 2009 },
    210    { "GL_EXT_texture_integer",                     o(EXT_texture_integer),                     GL,             2006 },
    211    { "GL_EXT_texture_lod_bias",                    o(dummy_true),                              GLL | ES1,      1999 },
    212    { "GL_EXT_texture_mirror_clamp",                o(EXT_texture_mirror_clamp),                GL,             2004 },
    213    { "GL_EXT_texture_object",                      o(dummy_true),                              GLL,            1995 },
    214    { "GL_EXT_texture",                             o(dummy_true),                              GLL,            1996 },
    215    { "GL_EXT_texture_rectangle",                   o(NV_texture_rectangle),                    GLL,            2004 },
    216    { "GL_EXT_texture_shared_exponent",             o(EXT_texture_shared_exponent),             GL,             2004 },
    217    { "GL_EXT_texture_snorm",                       o(EXT_texture_snorm),                       GL,             2009 },
    218    { "GL_EXT_texture_sRGB",                        o(EXT_texture_sRGB),                        GL,             2004 },
    219    { "GL_EXT_texture_sRGB_decode",                 o(EXT_texture_sRGB_decode),                        GL,      2006 },
    220    { "GL_EXT_texture_swizzle",                     o(EXT_texture_swizzle),                     GL,             2008 },
    221    { "GL_EXT_texture_type_2_10_10_10_REV",         o(dummy_true),                                         ES2, 2008 },
    222    { "GL_EXT_timer_query",                         o(EXT_timer_query),                         GL,             2006 },
    223    { "GL_EXT_transform_feedback",                  o(EXT_transform_feedback),                  GL,             2011 },
    224    { "GL_EXT_unpack_subimage",                     o(dummy_true),                                         ES2, 2011 },
    225    { "GL_EXT_vertex_array_bgra",                   o(EXT_vertex_array_bgra),                   GL,             2008 },
    226    { "GL_EXT_vertex_array",                        o(dummy_true),                              GLL,            1995 },
    227 
    228    /* OES extensions */
    229    { "GL_OES_blend_equation_separate",             o(EXT_blend_equation_separate),                  ES1,       2009 },
    230    { "GL_OES_blend_func_separate",                 o(EXT_blend_func_separate),                      ES1,       2009 },
    231    { "GL_OES_blend_subtract",                      o(dummy_true),                                   ES1,       2009 },
    232    { "GL_OES_byte_coordinates",                    o(dummy_true),                                   ES1,       2002 },
    233    { "GL_OES_compressed_ETC1_RGB8_texture",        o(OES_compressed_ETC1_RGB8_texture),             ES1 | ES2, 2005 },
    234    { "GL_OES_compressed_paletted_texture",         o(dummy_true),                                   ES1,       2003 },
    235    { "GL_OES_depth24",                             o(EXT_framebuffer_object),                       ES1 | ES2, 2005 },
    236    { "GL_OES_depth32",                             o(dummy_false),                     DISABLE,                2005 },
    237    { "GL_OES_depth_texture",                       o(ARB_depth_texture),                                  ES2, 2006 },
    238 #if FEATURE_OES_draw_texture
    239    { "GL_OES_draw_texture",                        o(OES_draw_texture),                             ES1,       2004 },
    240 #endif
    241 #if FEATURE_OES_EGL_image
    242    /*  FIXME: Mesa expects GL_OES_EGL_image to be available in OpenGL contexts. */
    243    { "GL_OES_EGL_image",                           o(OES_EGL_image),                           GL | ES1 | ES2, 2006 },
    244    { "GL_OES_EGL_image_external",                  o(OES_EGL_image_external),                       ES1 | ES2, 2010 },
    245 #endif
    246    { "GL_OES_element_index_uint",                  o(dummy_true),                                   ES1 | ES2, 2005 },
    247    { "GL_OES_fbo_render_mipmap",                   o(EXT_framebuffer_object),                       ES1 | ES2, 2005 },
    248    { "GL_OES_fixed_point",                         o(dummy_true),                                   ES1,       2002 },
    249    { "GL_OES_framebuffer_object",                  o(EXT_framebuffer_object),                       ES1,       2005 },
    250    { "GL_OES_mapbuffer",                           o(dummy_true),                                   ES1 | ES2, 2005 },
    251    { "GL_OES_matrix_get",                          o(dummy_true),                                   ES1,       2004 },
    252    { "GL_OES_packed_depth_stencil",                o(EXT_packed_depth_stencil),                     ES1 | ES2, 2007 },
    253    { "GL_OES_point_size_array",                    o(dummy_true),                                   ES1,       2004 },
    254    { "GL_OES_point_sprite",                        o(ARB_point_sprite),                             ES1,       2004 },
    255    { "GL_OES_query_matrix",                        o(dummy_true),                                   ES1,       2003 },
    256    { "GL_OES_read_format",                         o(dummy_true),                              GL | ES1,       2003 },
    257    { "GL_OES_rgb8_rgba8",                          o(EXT_framebuffer_object),                       ES1 | ES2, 2005 },
    258    { "GL_OES_single_precision",                    o(dummy_true),                                   ES1,       2003 },
    259    { "GL_OES_standard_derivatives",                o(OES_standard_derivatives),                           ES2, 2005 },
    260    { "GL_OES_stencil1",                            o(dummy_false),                     DISABLE,                2005 },
    261    { "GL_OES_stencil4",                            o(dummy_false),                     DISABLE,                2005 },
    262    { "GL_OES_stencil8",                            o(EXT_framebuffer_object),                       ES1 | ES2, 2005 },
    263    { "GL_OES_stencil_wrap",                        o(dummy_true),                                   ES1,       2002 },
    264    { "GL_OES_texture_3D",                          o(EXT_texture3D),                                      ES2, 2005 },
    265    { "GL_OES_texture_cube_map",                    o(ARB_texture_cube_map),                         ES1,       2007 },
    266    { "GL_OES_texture_env_crossbar",                o(ARB_texture_env_crossbar),                     ES1,       2005 },
    267    { "GL_OES_texture_mirrored_repeat",             o(dummy_true),                                   ES1,       2005 },
    268    { "GL_OES_texture_npot",                        o(ARB_texture_non_power_of_two),                       ES2, 2005 },
    269    { "GL_OES_vertex_array_object",                 o(dummy_true),                                   ES1 | ES2, 2010 },
    270 
    271    /* Vendor extensions */
    272    { "GL_3DFX_texture_compression_FXT1",           o(TDFX_texture_compression_FXT1),           GL,             1999 },
    273    { "GL_AMD_conservative_depth",                  o(ARB_conservative_depth),                  GL,             2009 },
    274    { "GL_AMD_draw_buffers_blend",                  o(ARB_draw_buffers_blend),                  GL,             2009 },
    275    { "GL_AMD_seamless_cubemap_per_texture",        o(AMD_seamless_cubemap_per_texture),        GL,             2009 },
    276    { "GL_AMD_shader_stencil_export",               o(ARB_shader_stencil_export),               GL,             2009 },
    277    { "GL_APPLE_object_purgeable",                  o(APPLE_object_purgeable),                  GL,             2006 },
    278    { "GL_APPLE_packed_pixels",                     o(APPLE_packed_pixels),                     GLL,            2002 },
    279    { "GL_APPLE_texture_max_level",                 o(dummy_true),                                   ES1 | ES2, 2009 },
    280    { "GL_APPLE_vertex_array_object",               o(dummy_true),                              GLL,            2002 },
    281    { "GL_ATI_blend_equation_separate",             o(EXT_blend_equation_separate),             GL,             2003 },
    282    { "GL_ATI_draw_buffers",                        o(dummy_true),                              GLL,            2002 },
    283    { "GL_ATI_envmap_bumpmap",                      o(ATI_envmap_bumpmap),                      GLL,            2001 },
    284    { "GL_ATI_fragment_shader",                     o(ATI_fragment_shader),                     GLL,            2001 },
    285    { "GL_ATI_separate_stencil",                    o(ATI_separate_stencil),                    GLL,            2006 },
    286    { "GL_ATI_texture_compression_3dc",             o(ATI_texture_compression_3dc),             GL,             2004 },
    287    { "GL_ATI_texture_env_combine3",                o(ATI_texture_env_combine3),                GLL,            2002 },
    288    { "GL_ATI_texture_float",                       o(ARB_texture_float),                       GL,             2002 },
    289    { "GL_ATI_texture_mirror_once",                 o(ATI_texture_mirror_once),                 GL,             2006 },
    290    { "GL_IBM_multimode_draw_arrays",               o(IBM_multimode_draw_arrays),               GL,             1998 },
    291    { "GL_IBM_rasterpos_clip",                      o(IBM_rasterpos_clip),                      GLL,            1996 },
    292    { "GL_IBM_texture_mirrored_repeat",             o(dummy_true),                              GLL,            1998 },
    293    { "GL_INGR_blend_func_separate",                o(EXT_blend_func_separate),                 GLL,            1999 },
    294    { "GL_MESA_pack_invert",                        o(MESA_pack_invert),                        GL,             2002 },
    295    { "GL_MESA_resize_buffers",                     o(MESA_resize_buffers),                     GL,             1999 },
    296    { "GL_MESA_texture_array",                      o(MESA_texture_array),                      GLL,            2007 },
    297    { "GL_MESA_texture_signed_rgba",                o(EXT_texture_snorm),                       GL,             2009 },
    298    { "GL_MESA_window_pos",                         o(ARB_window_pos),                          GLL,            2000 },
    299    { "GL_MESA_ycbcr_texture",                      o(MESA_ycbcr_texture),                      GL,             2002 },
    300    { "GL_NV_blend_square",                         o(NV_blend_square),                         GLL,            1999 },
    301    { "GL_NV_conditional_render",                   o(NV_conditional_render),                   GL,             2008 },
    302    { "GL_NV_depth_clamp",                          o(ARB_depth_clamp),                         GL,             2001 },
    303    { "GL_NV_draw_buffers",                         o(dummy_true),                                         ES2, 2011 },
    304    { "GL_NV_fbo_color_attachments",                o(EXT_framebuffer_object),                             ES2, 2010 },
    305    { "GL_NV_fog_distance",                         o(NV_fog_distance),                         GLL,            2001 },
    306    { "GL_NV_fragment_program",                     o(NV_fragment_program),                     GLL,            2001 },
    307    { "GL_NV_fragment_program_option",              o(NV_fragment_program_option),              GLL,            2005 },
    308    { "GL_NV_light_max_exponent",                   o(NV_light_max_exponent),                   GLL,            1999 },
    309    { "GL_NV_packed_depth_stencil",                 o(EXT_packed_depth_stencil),                GL,             2000 },
    310    { "GL_NV_point_sprite",                         o(NV_point_sprite),                         GL,             2001 },
    311    { "GL_NV_primitive_restart",                    o(NV_primitive_restart),                    GLL,            2002 },
    312    { "GL_NV_read_buffer",                          o(dummy_true),                              ES2,            2011 },
    313    { "GL_NV_texgen_reflection",                    o(NV_texgen_reflection),                    GLL,            1999 },
    314    { "GL_NV_texture_barrier",                      o(NV_texture_barrier),                      GL,             2009 },
    315    { "GL_NV_texture_env_combine4",                 o(NV_texture_env_combine4),                 GLL,            1999 },
    316    { "GL_NV_texture_rectangle",                    o(NV_texture_rectangle),                    GLL,            2000 },
    317    { "GL_NV_vertex_program1_1",                    o(NV_vertex_program1_1),                    GLL,            2001 },
    318    { "GL_NV_vertex_program",                       o(NV_vertex_program),                       GLL,            2000 },
    319    { "GL_S3_s3tc",                                 o(S3_s3tc),                                 GL,             1999 },
    320    { "GL_SGIS_generate_mipmap",                    o(dummy_true),                              GLL,            1997 },
    321    { "GL_SGIS_texture_border_clamp",               o(ARB_texture_border_clamp),                GLL,            1997 },
    322    { "GL_SGIS_texture_edge_clamp",                 o(dummy_true),                              GLL,            1997 },
    323    { "GL_SGIS_texture_lod",                        o(SGIS_texture_lod),                        GLL,            1997 },
    324    { "GL_SUN_multi_draw_arrays",                   o(dummy_true),                              GLL,            1999 },
    325 
    326    { 0, 0, 0, 0 },
    327 };
    328 
    329 
    330 /**
    331  * Given an extension name, lookup up the corresponding member of struct
    332  * gl_extensions and return that member's offset (in bytes).  If the name is
    333  * not found in the \c extension_table, return 0.
    334  *
    335  * \param name Name of extension.
    336  * \return Offset of member in struct gl_extensions.
    337  */
    338 static size_t
    339 name_to_offset(const char* name)
    340 {
    341    const struct extension *i;
    342 
    343    if (name == 0)
    344       return 0;
    345 
    346    for (i = extension_table; i->name != 0; ++i) {
    347       if (strcmp(name, i->name) == 0)
    348 	 return i->offset;
    349    }
    350 
    351    return 0;
    352 }
    353 
    354 
    355 /**
    356  * \brief Extensions enabled by default.
    357  *
    358  * These extensions are enabled by _mesa_init_extensions().
    359  *
    360  * XXX: Should these defaults also apply to GLES?
    361  */
    362 static const size_t default_extensions[] = {
    363    o(ARB_copy_buffer),
    364    o(ARB_transpose_matrix),
    365    o(ARB_window_pos),
    366 
    367    o(EXT_compiled_vertex_array),
    368    o(EXT_draw_range_elements),
    369    o(EXT_packed_pixels),
    370    o(EXT_rescale_normal),
    371    o(EXT_separate_specular_color),
    372    o(EXT_texture3D),
    373 
    374    o(OES_standard_derivatives),
    375 
    376    /* Vendor Extensions */
    377    o(APPLE_packed_pixels),
    378    o(IBM_multimode_draw_arrays),
    379    o(IBM_rasterpos_clip),
    380    o(NV_light_max_exponent),
    381    o(NV_texgen_reflection),
    382    o(SGIS_texture_lod),
    383 
    384    0,
    385 };
    386 
    387 
    388 /**
    389  * Enable all extensions suitable for a software-only renderer.
    390  * This is a convenience function used by the XMesa, OSMesa, GGI drivers, etc.
    391  */
    392 void
    393 _mesa_enable_sw_extensions(struct gl_context *ctx)
    394 {
    395    /*ctx->Extensions.ARB_copy_buffer = GL_TRUE;*/
    396    ctx->Extensions.ARB_depth_clamp = GL_TRUE;
    397    ctx->Extensions.ARB_depth_texture = GL_TRUE;
    398    ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE;
    399    ctx->Extensions.ARB_draw_instanced = GL_TRUE;
    400    ctx->Extensions.ARB_explicit_attrib_location = GL_TRUE;
    401    ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
    402 #if FEATURE_ARB_fragment_program
    403    ctx->Extensions.ARB_fragment_program = GL_TRUE;
    404    ctx->Extensions.ARB_fragment_program_shadow = GL_TRUE;
    405 #endif
    406 #if FEATURE_ARB_fragment_shader
    407    ctx->Extensions.ARB_fragment_shader = GL_TRUE;
    408 #endif
    409 #if FEATURE_ARB_framebuffer_object
    410    ctx->Extensions.ARB_framebuffer_object = GL_TRUE;
    411 #endif
    412 #if FEATURE_ARB_geometry_shader4 && 0
    413    /* XXX re-enable when GLSL compiler again supports geometry shaders */
    414    ctx->Extensions.ARB_geometry_shader4 = GL_TRUE;
    415 #endif
    416    ctx->Extensions.ARB_half_float_pixel = GL_TRUE;
    417    ctx->Extensions.ARB_half_float_vertex = GL_TRUE;
    418    ctx->Extensions.ARB_map_buffer_range = GL_TRUE;
    419 #if FEATURE_queryobj
    420    ctx->Extensions.ARB_occlusion_query = GL_TRUE;
    421    ctx->Extensions.ARB_occlusion_query2 = GL_TRUE;
    422 #endif
    423    ctx->Extensions.ARB_point_sprite = GL_TRUE;
    424 #if FEATURE_ARB_shader_objects
    425    ctx->Extensions.ARB_shader_objects = GL_TRUE;
    426    ctx->Extensions.EXT_separate_shader_objects = GL_TRUE;
    427 #endif
    428 #if FEATURE_ARB_shading_language_100
    429    ctx->Extensions.ARB_shading_language_100 = GL_TRUE;
    430 #endif
    431    ctx->Extensions.ARB_shadow = GL_TRUE;
    432    ctx->Extensions.ARB_texture_border_clamp = GL_TRUE;
    433    ctx->Extensions.ARB_texture_cube_map = GL_TRUE;
    434    ctx->Extensions.ARB_texture_env_combine = GL_TRUE;
    435    ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE;
    436    ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE;
    437    /*ctx->Extensions.ARB_texture_float = GL_TRUE;*/
    438    ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
    439    ctx->Extensions.ARB_texture_rg = GL_TRUE;
    440    ctx->Extensions.ARB_texture_compression_rgtc = GL_TRUE;
    441    ctx->Extensions.ARB_texture_storage = GL_TRUE;
    442 #if FEATURE_ARB_vertex_program
    443    ctx->Extensions.ARB_vertex_program = GL_TRUE;
    444 #endif
    445 #if FEATURE_ARB_vertex_shader
    446    ctx->Extensions.ARB_vertex_shader = GL_TRUE;
    447 #endif
    448 #if FEATURE_ARB_sync
    449    ctx->Extensions.ARB_sync = GL_TRUE;
    450 #endif
    451 #if FEATURE_APPLE_object_purgeable
    452    ctx->Extensions.APPLE_object_purgeable = GL_TRUE;
    453 #endif
    454    ctx->Extensions.ATI_envmap_bumpmap = GL_TRUE;
    455 #if FEATURE_ATI_fragment_shader
    456    ctx->Extensions.ATI_fragment_shader = GL_TRUE;
    457 #endif
    458    ctx->Extensions.ATI_texture_compression_3dc = GL_TRUE;
    459    ctx->Extensions.ATI_texture_env_combine3 = GL_TRUE;
    460    ctx->Extensions.ATI_texture_mirror_once = GL_TRUE;
    461    ctx->Extensions.ATI_separate_stencil = GL_TRUE;
    462    ctx->Extensions.EXT_blend_color = GL_TRUE;
    463    ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
    464    ctx->Extensions.EXT_blend_func_separate = GL_TRUE;
    465    ctx->Extensions.EXT_blend_minmax = GL_TRUE;
    466    ctx->Extensions.EXT_depth_bounds_test = GL_TRUE;
    467    ctx->Extensions.EXT_draw_buffers2 = GL_TRUE;
    468    ctx->Extensions.EXT_fog_coord = GL_TRUE;
    469 #if FEATURE_EXT_framebuffer_object
    470    ctx->Extensions.EXT_framebuffer_object = GL_TRUE;
    471 #endif
    472 #if FEATURE_EXT_framebuffer_blit
    473    ctx->Extensions.EXT_framebuffer_blit = GL_TRUE;
    474 #endif
    475    ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE;
    476 #if FEATURE_EXT_pixel_buffer_object
    477    ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE;
    478 #endif
    479    ctx->Extensions.EXT_point_parameters = GL_TRUE;
    480    ctx->Extensions.EXT_provoking_vertex = GL_TRUE;
    481    ctx->Extensions.EXT_shadow_funcs = GL_TRUE;
    482    ctx->Extensions.EXT_secondary_color = GL_TRUE;
    483    ctx->Extensions.EXT_stencil_two_side = GL_TRUE;
    484    ctx->Extensions.EXT_texture_array = GL_TRUE;
    485    ctx->Extensions.EXT_texture_compression_latc = GL_TRUE;
    486    ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE;
    487    ctx->Extensions.EXT_texture_filter_anisotropic = GL_TRUE;
    488    ctx->Extensions.EXT_texture_mirror_clamp = GL_TRUE;
    489    ctx->Extensions.EXT_texture_shared_exponent = GL_TRUE;
    490 #if FEATURE_EXT_texture_sRGB
    491    ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
    492    ctx->Extensions.EXT_texture_sRGB_decode = GL_TRUE;
    493 #endif
    494    ctx->Extensions.EXT_texture_swizzle = GL_TRUE;
    495 #if FEATURE_EXT_transform_feedback
    496    /*ctx->Extensions.EXT_transform_feedback = GL_TRUE;*/
    497 #endif
    498    ctx->Extensions.EXT_vertex_array_bgra = GL_TRUE;
    499    /*ctx->Extensions.IBM_multimode_draw_arrays = GL_TRUE;*/
    500    ctx->Extensions.MESA_pack_invert = GL_TRUE;
    501    ctx->Extensions.MESA_resize_buffers = GL_TRUE;
    502    ctx->Extensions.MESA_texture_array = GL_TRUE;
    503    ctx->Extensions.MESA_ycbcr_texture = GL_TRUE;
    504    ctx->Extensions.NV_blend_square = GL_TRUE;
    505    ctx->Extensions.NV_conditional_render = GL_TRUE;
    506    /*ctx->Extensions.NV_light_max_exponent = GL_TRUE;*/
    507    ctx->Extensions.NV_point_sprite = GL_TRUE;
    508    ctx->Extensions.NV_texture_env_combine4 = GL_TRUE;
    509    ctx->Extensions.NV_texture_rectangle = GL_TRUE;
    510    /*ctx->Extensions.NV_texgen_reflection = GL_TRUE;*/
    511 #if FEATURE_NV_vertex_program
    512    ctx->Extensions.NV_vertex_program = GL_TRUE;
    513    ctx->Extensions.NV_vertex_program1_1 = GL_TRUE;
    514 #endif
    515 #if FEATURE_NV_fragment_program
    516    ctx->Extensions.NV_fragment_program = GL_TRUE;
    517 #endif
    518 #if FEATURE_NV_fragment_program && FEATURE_ARB_fragment_program
    519    ctx->Extensions.NV_fragment_program_option = GL_TRUE;
    520 #endif
    521 #if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
    522    ctx->Extensions.EXT_gpu_program_parameters = GL_TRUE;
    523 #endif
    524 #if FEATURE_texture_fxt1
    525    _mesa_enable_extension(ctx, "GL_3DFX_texture_compression_FXT1");
    526 #endif
    527 #if FEATURE_texture_s3tc
    528    if (ctx->Mesa_DXTn) {
    529       _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
    530       _mesa_enable_extension(ctx, "GL_S3_s3tc");
    531    }
    532 #endif
    533 }
    534 
    535 
    536 /**
    537  * Enable all OpenGL 1.3 features and extensions.
    538  * A convenience function to be called by drivers.
    539  */
    540 void
    541 _mesa_enable_1_3_extensions(struct gl_context *ctx)
    542 {
    543    ctx->Extensions.ARB_texture_border_clamp = GL_TRUE;
    544    ctx->Extensions.ARB_texture_cube_map = GL_TRUE;
    545    ctx->Extensions.ARB_texture_env_combine = GL_TRUE;
    546    ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE;
    547    /*ctx->Extensions.ARB_transpose_matrix = GL_TRUE;*/
    548 }
    549 
    550 
    551 
    552 /**
    553  * Enable all OpenGL 1.4 features and extensions.
    554  * A convenience function to be called by drivers.
    555  */
    556 void
    557 _mesa_enable_1_4_extensions(struct gl_context *ctx)
    558 {
    559    ctx->Extensions.ARB_depth_texture = GL_TRUE;
    560    ctx->Extensions.ARB_shadow = GL_TRUE;
    561    ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE;
    562    ctx->Extensions.ARB_window_pos = GL_TRUE;
    563    ctx->Extensions.EXT_blend_color = GL_TRUE;
    564    ctx->Extensions.EXT_blend_func_separate = GL_TRUE;
    565    ctx->Extensions.EXT_blend_minmax = GL_TRUE;
    566    ctx->Extensions.EXT_fog_coord = GL_TRUE;
    567    ctx->Extensions.EXT_point_parameters = GL_TRUE;
    568    ctx->Extensions.EXT_secondary_color = GL_TRUE;
    569 }
    570 
    571 
    572 /**
    573  * Enable all OpenGL 1.5 features and extensions.
    574  * A convenience function to be called by drivers.
    575  */
    576 void
    577 _mesa_enable_1_5_extensions(struct gl_context *ctx)
    578 {
    579    ctx->Extensions.ARB_occlusion_query = GL_TRUE;
    580    ctx->Extensions.EXT_shadow_funcs = GL_TRUE;
    581 }
    582 
    583 
    584 /**
    585  * Enable all OpenGL 2.0 features and extensions.
    586  * A convenience function to be called by drivers.
    587  */
    588 void
    589 _mesa_enable_2_0_extensions(struct gl_context *ctx)
    590 {
    591 #if FEATURE_ARB_fragment_shader
    592    ctx->Extensions.ARB_fragment_shader = GL_TRUE;
    593 #endif
    594    ctx->Extensions.ARB_point_sprite = GL_TRUE;
    595    ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
    596    ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
    597 #if FEATURE_ARB_shader_objects
    598    ctx->Extensions.ARB_shader_objects = GL_TRUE;
    599 #endif
    600 #if FEATURE_ARB_shading_language_100
    601    ctx->Extensions.ARB_shading_language_100 = GL_TRUE;
    602 #endif
    603    ctx->Extensions.EXT_stencil_two_side = GL_TRUE;
    604 #if FEATURE_ARB_vertex_shader
    605    ctx->Extensions.ARB_vertex_shader = GL_TRUE;
    606 #endif
    607 }
    608 
    609 
    610 /**
    611  * Enable all OpenGL 2.1 features and extensions.
    612  * A convenience function to be called by drivers.
    613  */
    614 void
    615 _mesa_enable_2_1_extensions(struct gl_context *ctx)
    616 {
    617 #if FEATURE_EXT_pixel_buffer_object
    618    ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE;
    619 #endif
    620 #if FEATURE_EXT_texture_sRGB
    621    ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
    622 #endif
    623 }
    624 
    625 
    626 /**
    627  * Either enable or disable the named extension.
    628  * \return GL_TRUE for success, GL_FALSE if invalid extension name
    629  */
    630 static GLboolean
    631 set_extension( struct gl_context *ctx, const char *name, GLboolean state )
    632 {
    633    size_t offset;
    634 
    635    if (ctx->Extensions.String) {
    636       /* The string was already queried - can't change it now! */
    637       _mesa_problem(ctx, "Trying to enable/disable extension after glGetString(GL_EXTENSIONS): %s", name);
    638       return GL_FALSE;
    639    }
    640 
    641    offset = name_to_offset(name);
    642    if (offset == 0) {
    643       _mesa_problem(ctx, "Trying to enable/disable unknown extension %s",
    644 	            name);
    645       return GL_FALSE;
    646    } else if (offset == o(dummy_true) && state == GL_FALSE) {
    647       _mesa_problem(ctx, "Trying to disable a permanently enabled extension: "
    648 	                  "%s", name);
    649       return GL_FALSE;
    650    } else {
    651       GLboolean *base = (GLboolean *) &ctx->Extensions;
    652       base[offset] = state;
    653       return GL_TRUE;
    654    }
    655 }
    656 
    657 
    658 /**
    659  * Enable the named extension.
    660  * Typically called by drivers.
    661  */
    662 void
    663 _mesa_enable_extension( struct gl_context *ctx, const char *name )
    664 {
    665    if (!set_extension(ctx, name, GL_TRUE))
    666       _mesa_problem(ctx, "Trying to enable unknown extension: %s", name);
    667 }
    668 
    669 
    670 /**
    671  * Disable the named extension.
    672  * XXX is this really needed???
    673  */
    674 void
    675 _mesa_disable_extension( struct gl_context *ctx, const char *name )
    676 {
    677    if (!set_extension(ctx, name, GL_FALSE))
    678       _mesa_problem(ctx, "Trying to disable unknown extension: %s", name);
    679 }
    680 
    681 
    682 /**
    683  * Test if the named extension is enabled in this context.
    684  */
    685 GLboolean
    686 _mesa_extension_is_enabled( struct gl_context *ctx, const char *name )
    687 {
    688    size_t offset;
    689    GLboolean *base;
    690 
    691    if (name == 0)
    692       return GL_FALSE;
    693 
    694    offset = name_to_offset(name);
    695    if (offset == 0)
    696       return GL_FALSE;
    697    base = (GLboolean *) &ctx->Extensions;
    698    return base[offset];
    699 }
    700 
    701 
    702 /**
    703  * \brief Apply the \c MESA_EXTENSION_OVERRIDE environment variable.
    704  *
    705  * \c MESA_EXTENSION_OVERRIDE is a space-separated list of extensions to
    706  * enable or disable. The list is processed thus:
    707  *    - Enable recognized extension names that are prefixed with '+'.
    708  *    - Disable recognized extension names that are prefixed with '-'.
    709  *    - Enable recognized extension names that are not prefixed.
    710  *    - Collect unrecognized extension names in a new string.
    711  *
    712  * \return Space-separated list of unrecognized extension names (which must
    713  *    be freed). Does not return \c NULL.
    714  */
    715 static char *
    716 get_extension_override( struct gl_context *ctx )
    717 {
    718    const char *env_const = _mesa_getenv("MESA_EXTENSION_OVERRIDE");
    719    char *env;
    720    char *ext;
    721    char *extra_exts;
    722    int len;
    723 
    724    if (env_const == NULL) {
    725       /* Return the empty string rather than NULL. This simplifies the logic
    726        * of client functions. */
    727       return calloc(4, sizeof(char));
    728    }
    729 
    730    /* extra_exts: List of unrecognized extensions. */
    731    extra_exts = calloc(ALIGN(strlen(env_const) + 2, 4), sizeof(char));
    732 
    733    /* Copy env_const because strtok() is destructive. */
    734    env = strdup(env_const);
    735    for (ext = strtok(env, " "); ext != NULL; ext = strtok(NULL, " ")) {
    736       int enable;
    737       int recognized;
    738       switch (ext[0]) {
    739       case '+':
    740          enable = 1;
    741          ++ext;
    742          break;
    743       case '-':
    744          enable = 0;
    745          ++ext;
    746          break;
    747       default:
    748          enable = 1;
    749          break;
    750       }
    751       recognized = set_extension(ctx, ext, enable);
    752       if (!recognized) {
    753          strcat(extra_exts, ext);
    754          strcat(extra_exts, " ");
    755       }
    756    }
    757 
    758    free(env);
    759 
    760    /* Remove trailing space. */
    761    len = strlen(extra_exts);
    762    if (len > 0 && extra_exts[len - 1] == ' ')
    763       extra_exts[len - 1] = '\0';
    764 
    765    return extra_exts;
    766 }
    767 
    768 
    769 /**
    770  * \brief Initialize extension tables and enable default extensions.
    771  *
    772  * This should be called during context initialization.
    773  * Note: Sets gl_extensions.dummy_true to true.
    774  */
    775 void
    776 _mesa_init_extensions( struct gl_context *ctx )
    777 {
    778    GLboolean *base = (GLboolean *) &ctx->Extensions;
    779    GLboolean *sentinel = base + o(extension_sentinel);
    780    GLboolean *i;
    781    const size_t *j;
    782 
    783    /* First, turn all extensions off. */
    784    for (i = base; i != sentinel; ++i)
    785       *i = GL_FALSE;
    786 
    787    /* Then, selectively turn default extensions on. */
    788    ctx->Extensions.dummy_true = GL_TRUE;
    789    for (j = default_extensions; *j != 0; ++j)
    790       base[*j] = GL_TRUE;
    791 }
    792 
    793 
    794 typedef unsigned short extension_index;
    795 
    796 
    797 /**
    798  * Compare two entries of the extensions table.  Sorts first by year,
    799  * then by name.
    800  *
    801  * Arguments are indices into extension_table.
    802  */
    803 static int
    804 extension_compare(const void *p1, const void *p2)
    805 {
    806    extension_index i1 = * (const extension_index *) p1;
    807    extension_index i2 = * (const extension_index *) p2;
    808    const struct extension *e1 = &extension_table[i1];
    809    const struct extension *e2 = &extension_table[i2];
    810    int res;
    811 
    812    res = (int)e1->year - (int)e2->year;
    813 
    814    if (res == 0) {
    815       res = strcmp(e1->name, e2->name);
    816    }
    817 
    818    return res;
    819 }
    820 
    821 
    822 /**
    823  * Construct the GL_EXTENSIONS string.  Called the first time that
    824  * glGetString(GL_EXTENSIONS) is called.
    825  */
    826 GLubyte*
    827 _mesa_make_extension_string(struct gl_context *ctx)
    828 {
    829    /* The extension string. */
    830    char *exts = 0;
    831    /* Length of extension string. */
    832    size_t length = 0;
    833    /* Number of extensions */
    834    unsigned count;
    835    /* Indices of the extensions sorted by year */
    836    extension_index *extension_indices;
    837    /* String of extra extensions. */
    838    char *extra_extensions = get_extension_override(ctx);
    839    GLboolean *base = (GLboolean *) &ctx->Extensions;
    840    const struct extension *i;
    841    unsigned j;
    842    unsigned maxYear = ~0;
    843 
    844    /* Check if the MESA_EXTENSION_MAX_YEAR env var is set */
    845    {
    846       const char *env = getenv("MESA_EXTENSION_MAX_YEAR");
    847       if (env) {
    848          maxYear = atoi(env);
    849          _mesa_debug(ctx, "Note: limiting GL extensions to %u or earlier\n",
    850                      maxYear);
    851       }
    852    }
    853 
    854    /* Compute length of the extension string. */
    855    count = 0;
    856    for (i = extension_table; i->name != 0; ++i) {
    857       if (base[i->offset] &&
    858           i->year <= maxYear &&
    859           (i->api_set & (1 << ctx->API))) {
    860 	 length += strlen(i->name) + 1; /* +1 for space */
    861 	 ++count;
    862       }
    863    }
    864    if (extra_extensions != NULL)
    865       length += 1 + strlen(extra_extensions); /* +1 for space */
    866 
    867    exts = (char *) calloc(ALIGN(length + 1, 4), sizeof(char));
    868    if (exts == NULL) {
    869       free(extra_extensions);
    870       return NULL;
    871    }
    872 
    873    extension_indices = malloc(count * sizeof(extension_index));
    874    if (extension_indices == NULL) {
    875       free(exts);
    876       free(extra_extensions);
    877       return NULL;
    878    }
    879 
    880    /* Sort extensions in chronological order because certain old applications (e.g.,
    881     * Quake3 demo) store the extension list in a static size buffer so chronologically
    882     * order ensure that the extensions that such applications expect will fit into
    883     * that buffer.
    884     */
    885    j = 0;
    886    for (i = extension_table; i->name != 0; ++i) {
    887       if (base[i->offset] &&
    888           i->year <= maxYear &&
    889           (i->api_set & (1 << ctx->API))) {
    890          extension_indices[j++] = i - extension_table;
    891       }
    892    }
    893    assert(j == count);
    894    qsort(extension_indices, count, sizeof *extension_indices, extension_compare);
    895 
    896    /* Build the extension string.*/
    897    for (j = 0; j < count; ++j) {
    898       i = &extension_table[extension_indices[j]];
    899       assert(base[i->offset] && (i->api_set & (1 << ctx->API)));
    900       strcat(exts, i->name);
    901       strcat(exts, " ");
    902    }
    903    free(extension_indices);
    904    if (extra_extensions != 0) {
    905       strcat(exts, extra_extensions);
    906       free(extra_extensions);
    907    }
    908 
    909    return (GLubyte *) exts;
    910 }
    911 
    912 /**
    913  * Return number of enabled extensions.
    914  */
    915 GLuint
    916 _mesa_get_extension_count(struct gl_context *ctx)
    917 {
    918    GLboolean *base;
    919    const struct extension *i;
    920 
    921    /* only count once */
    922    if (ctx->Extensions.Count != 0)
    923       return ctx->Extensions.Count;
    924 
    925    base = (GLboolean *) &ctx->Extensions;
    926    for (i = extension_table; i->name != 0; ++i) {
    927       if (base[i->offset] && (i->api_set & (1 << ctx->API))) {
    928 	 ctx->Extensions.Count++;
    929       }
    930    }
    931    return ctx->Extensions.Count;
    932 }
    933 
    934 /**
    935  * Return name of i-th enabled extension
    936  */
    937 const GLubyte *
    938 _mesa_get_enabled_extension(struct gl_context *ctx, GLuint index)
    939 {
    940    const GLboolean *base;
    941    size_t n;
    942    const struct extension *i;
    943 
    944    base = (GLboolean*) &ctx->Extensions;
    945    n = 0;
    946    for (i = extension_table; i->name != 0; ++i) {
    947       if (base[i->offset] && (i->api_set & (1 << ctx->API))) {
    948          if (n == index)
    949             return (const GLubyte*) i->name;
    950          else
    951             ++n;
    952       }
    953    }
    954 
    955    return NULL;
    956 }
    957