Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1901 serge 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 "mtypes.h"
38
 
39
enum {
40
   DISABLE = 0,
41
   GL  = 1 << API_OPENGL,
42
   ES1 = 1 << API_OPENGLES,
43
   ES2 = 1 << API_OPENGLES2,
44
};
45
 
46
/**
47
 * \brief An element of the \c extension_table.
48
 */
49
struct extension {
50
   /** Name of extension, such as "GL_ARB_depth_clamp". */
51
   const char *name;
52
 
53
   /** Offset (in bytes) of the corresponding member in struct gl_extensions. */
54
   size_t offset;
55
 
56
   /** Set of API's in which the extension exists, as a bitset. */
57
   uint8_t api_set;
58
};
59
 
60
 
61
/**
62
 * Given a member \c x of struct gl_extensions, return offset of
63
 * \c x in bytes.
64
 */
65
#define o(x) offsetof(struct gl_extensions, x)
66
 
67
 
68
/**
69
 * \brief Table of supported OpenGL extensions for all API's.
70
 *
71
 * Note: The GL_MESAX_* extensions are placeholders for future ARB extensions.
72
 */
73
static const struct extension extension_table[] = {
74
   /* ARB Extensions */
75
   { "GL_ARB_ES2_compatibility",                   o(ARB_ES2_compatibility),                   GL             },
76
   { "GL_ARB_blend_func_extended",                 o(ARB_blend_func_extended),                 GL             },
77
   { "GL_ARB_copy_buffer",                         o(ARB_copy_buffer),                         GL             },
78
   { "GL_ARB_depth_buffer_float",                  o(ARB_depth_buffer_float),                  GL             },
79
   { "GL_ARB_depth_clamp",                         o(ARB_depth_clamp),                         GL             },
80
   { "GL_ARB_depth_texture",                       o(ARB_depth_texture),                       GL             },
81
   { "GL_ARB_draw_buffers",                        o(ARB_draw_buffers),                        GL             },
82
   { "GL_ARB_draw_elements_base_vertex",           o(ARB_draw_elements_base_vertex),           GL             },
83
   { "GL_ARB_draw_instanced",                      o(ARB_draw_instanced),                      GL             },
84
   { "GL_ARB_explicit_attrib_location",            o(ARB_explicit_attrib_location),            GL             },
85
   { "GL_ARB_fragment_coord_conventions",          o(ARB_fragment_coord_conventions),          GL             },
86
   { "GL_ARB_fragment_program",                    o(ARB_fragment_program),                    GL             },
87
   { "GL_ARB_fragment_program_shadow",             o(ARB_fragment_program_shadow),             GL             },
88
   { "GL_ARB_fragment_shader",                     o(ARB_fragment_shader),                     GL             },
89
   { "GL_ARB_framebuffer_object",                  o(ARB_framebuffer_object),                  GL             },
90
   { "GL_ARB_half_float_pixel",                    o(ARB_half_float_pixel),                    GL             },
91
   { "GL_ARB_half_float_vertex",                   o(ARB_half_float_vertex),                   GL             },
92
   { "GL_ARB_instanced_arrays",                    o(ARB_instanced_arrays),                    GL             },
93
   { "GL_ARB_map_buffer_range",                    o(ARB_map_buffer_range),                    GL             },
94
   { "GL_ARB_multisample",                         o(ARB_multisample),                         GL             },
95
   { "GL_ARB_multitexture",                        o(ARB_multitexture),                        GL             },
96
   { "GL_ARB_occlusion_query2",                    o(ARB_occlusion_query2),                    GL             },
97
   { "GL_ARB_occlusion_query",                     o(ARB_occlusion_query),                     GL             },
98
   { "GL_ARB_pixel_buffer_object",                 o(EXT_pixel_buffer_object),                 GL             },
99
   { "GL_ARB_point_parameters",                    o(EXT_point_parameters),                    GL             },
100
   { "GL_ARB_point_sprite",                        o(ARB_point_sprite),                        GL             },
101
   { "GL_ARB_provoking_vertex",                    o(EXT_provoking_vertex),                    GL             },
102
   { "GL_ARB_sampler_objects",                     o(ARB_sampler_objects),                     GL             },
103
   { "GL_ARB_seamless_cube_map",                   o(ARB_seamless_cube_map),                   GL             },
104
   { "GL_ARB_shader_objects",                      o(ARB_shader_objects),                      GL             },
105
   { "GL_ARB_shader_stencil_export",               o(ARB_shader_stencil_export),               GL             },
106
   { "GL_ARB_shading_language_100",                o(ARB_shading_language_100),                GL             },
107
   { "GL_ARB_shadow_ambient",                      o(ARB_shadow_ambient),                      GL             },
108
   { "GL_ARB_shadow",                              o(ARB_shadow),                              GL             },
109
   { "GL_ARB_sync",                                o(ARB_sync),                                GL             },
110
   { "GL_ARB_texture_border_clamp",                o(ARB_texture_border_clamp),                GL             },
111
   { "GL_ARB_texture_buffer_object",               o(ARB_texture_buffer_object),               GL             },
112
   { "GL_ARB_texture_compression",                 o(ARB_texture_compression),                 GL             },
113
   { "GL_ARB_texture_compression_rgtc",            o(ARB_texture_compression_rgtc),            GL             },
114
   { "GL_ARB_texture_cube_map",                    o(ARB_texture_cube_map),                    GL             },
115
   { "GL_ARB_texture_env_add",                     o(EXT_texture_env_add),                     GL             },
116
   { "GL_ARB_texture_env_combine",                 o(ARB_texture_env_combine),                 GL             },
117
   { "GL_ARB_texture_env_crossbar",                o(ARB_texture_env_crossbar),                GL             },
118
   { "GL_ARB_texture_env_dot3",                    o(ARB_texture_env_dot3),                    GL             },
119
   { "GL_ARB_texture_mirrored_repeat",             o(ARB_texture_mirrored_repeat),             GL             },
120
   { "GL_ARB_texture_multisample",                 o(ARB_texture_multisample),                 GL             },
121
   { "GL_ARB_texture_non_power_of_two",            o(ARB_texture_non_power_of_two),            GL             },
122
   { "GL_ARB_texture_rectangle",                   o(NV_texture_rectangle),                    GL             },
123
   { "GL_ARB_texture_rgb10_a2ui",                  o(ARB_texture_rgb10_a2ui),                  GL             },
124
   { "GL_ARB_texture_rg",                          o(ARB_texture_rg),                          GL             },
125
   { "GL_ARB_texture_swizzle",                     o(EXT_texture_swizzle),                     GL             },
126
   { "GL_ARB_transform_feedback2",                 o(ARB_transform_feedback2),                 GL             },
127
   { "GL_ARB_transpose_matrix",                    o(ARB_transpose_matrix),                    GL             },
128
   { "GL_ARB_uniform_buffer_object",               o(ARB_uniform_buffer_object),               GL             },
129
   { "GL_ARB_vertex_array_bgra",                   o(EXT_vertex_array_bgra),                   GL             },
130
   { "GL_ARB_vertex_array_object",                 o(ARB_vertex_array_object),                 GL             },
131
   { "GL_ARB_vertex_buffer_object",                o(ARB_vertex_buffer_object),                GL             },
132
   { "GL_ARB_vertex_program",                      o(ARB_vertex_program),                      GL             },
133
   { "GL_ARB_vertex_shader",                       o(ARB_vertex_shader),                       GL             },
134
   { "GL_ARB_vertex_type_2_10_10_10_rev",          o(ARB_vertex_type_2_10_10_10_rev),          GL             },
135
   { "GL_ARB_window_pos",                          o(ARB_window_pos),                          GL             },
136
 
137
   /* EXT extensions */
138
   { "GL_EXT_abgr",                                o(EXT_abgr),                                GL             },
139
   { "GL_EXT_bgra",                                o(EXT_bgra),                                GL             },
140
   { "GL_EXT_blend_color",                         o(EXT_blend_color),                         GL             },
141
   { "GL_EXT_blend_equation_separate",             o(EXT_blend_equation_separate),             GL             },
142
   { "GL_EXT_blend_func_separate",                 o(EXT_blend_func_separate),                 GL             },
143
   { "GL_EXT_blend_logic_op",                      o(EXT_blend_logic_op),                      GL             },
144
   { "GL_EXT_blend_minmax",                        o(EXT_blend_minmax),                        GL | ES1 | ES2 },
145
   { "GL_EXT_blend_subtract",                      o(EXT_blend_subtract),                      GL             },
146
   { "GL_EXT_clip_volume_hint",                    o(EXT_clip_volume_hint),                    GL             },
147
   { "GL_EXT_compiled_vertex_array",               o(EXT_compiled_vertex_array),               GL             },
148
   { "GL_EXT_copy_texture",                        o(EXT_copy_texture),                        GL             },
149
   { "GL_EXT_depth_bounds_test",                   o(EXT_depth_bounds_test),                   GL             },
150
   { "GL_EXT_draw_buffers2",                       o(EXT_draw_buffers2),                       GL             },
151
   { "GL_EXT_draw_instanced",                      o(ARB_draw_instanced),                      GL             },
152
   { "GL_EXT_draw_range_elements",                 o(EXT_draw_range_elements),                 GL             },
153
   { "GL_EXT_fog_coord",                           o(EXT_fog_coord),                           GL             },
154
   { "GL_EXT_framebuffer_blit",                    o(EXT_framebuffer_blit),                    GL             },
155
   { "GL_EXT_framebuffer_multisample",             o(EXT_framebuffer_multisample),             GL             },
156
   { "GL_EXT_framebuffer_object",                  o(EXT_framebuffer_object),                  GL             },
157
   { "GL_EXT_framebuffer_sRGB",                    o(EXT_framebuffer_sRGB),                    GL             },
158
   { "GL_EXT_gpu_program_parameters",              o(EXT_gpu_program_parameters),              GL             },
159
   { "GL_EXT_gpu_shader4",                         o(EXT_gpu_shader4),                         GL             },
160
   { "GL_EXT_multi_draw_arrays",                   o(EXT_multi_draw_arrays),                   GL | ES1 | ES2 },
161
   { "GL_EXT_packed_depth_stencil",                o(EXT_packed_depth_stencil),                GL             },
162
   { "GL_EXT_packed_float",                        o(EXT_packed_float),                        GL             },
163
   { "GL_EXT_packed_pixels",                       o(EXT_packed_pixels),                       GL             },
164
   { "GL_EXT_paletted_texture",                    o(EXT_paletted_texture),                    GL             },
165
   { "GL_EXT_pixel_buffer_object",                 o(EXT_pixel_buffer_object),                 GL             },
166
   { "GL_EXT_point_parameters",                    o(EXT_point_parameters),                    GL             },
167
   { "GL_EXT_polygon_offset",                      o(EXT_polygon_offset),                      GL             },
168
   { "GL_EXT_provoking_vertex",                    o(EXT_provoking_vertex),                    GL             },
169
   { "GL_EXT_rescale_normal",                      o(EXT_rescale_normal),                      GL             },
170
   { "GL_EXT_secondary_color",                     o(EXT_secondary_color),                     GL             },
171
   { "GL_EXT_separate_shader_objects",             o(EXT_separate_shader_objects),             GL             },
172
   { "GL_EXT_separate_specular_color",             o(EXT_separate_specular_color),             GL             },
173
   { "GL_EXT_shadow_funcs",                        o(EXT_shadow_funcs),                        GL             },
174
   { "GL_EXT_shared_texture_palette",              o(EXT_shared_texture_palette),              GL             },
175
   { "GL_EXT_stencil_two_side",                    o(EXT_stencil_two_side),                    GL             },
176
   { "GL_EXT_stencil_wrap",                        o(EXT_stencil_wrap),                        GL             },
177
   { "GL_EXT_subtexture",                          o(EXT_subtexture),                          GL             },
178
   { "GL_EXT_texture3D",                           o(EXT_texture3D),                           GL             },
179
   { "GL_EXT_texture_array",                       o(EXT_texture_array),                       GL             },
180
   { "GL_EXT_texture_compression_dxt1",            o(EXT_texture_compression_s3tc),            GL | ES1 | ES2 },
181
   { "GL_EXT_texture_compression_rgtc",            o(ARB_texture_compression_rgtc),            GL             },
182
   { "GL_EXT_texture_compression_s3tc",            o(EXT_texture_compression_s3tc),            GL             },
183
   { "GL_EXT_texture_cube_map",                    o(ARB_texture_cube_map),                    GL             },
184
   { "GL_EXT_texture_edge_clamp",                  o(SGIS_texture_edge_clamp),                 GL             },
185
   { "GL_EXT_texture_env_add",                     o(EXT_texture_env_add),                     GL             },
186
   { "GL_EXT_texture_env_combine",                 o(EXT_texture_env_combine),                 GL             },
187
   { "GL_EXT_texture_env_dot3",                    o(EXT_texture_env_dot3),                    GL             },
188
   { "GL_EXT_texture_filter_anisotropic",          o(EXT_texture_filter_anisotropic),          GL | ES1 | ES2 },
189
   { "GL_EXT_texture_format_BGRA8888",             o(EXT_texture_format_BGRA8888),                  ES1 | ES2 },
190
   { "GL_EXT_texture_integer",                     o(EXT_texture_integer),                     GL             },
191
   { "GL_EXT_texture_lod_bias",                    o(EXT_texture_lod_bias),                    GL | ES1       },
192
   { "GL_EXT_texture_mirror_clamp",                o(EXT_texture_mirror_clamp),                GL             },
193
   { "GL_EXT_texture_object",                      o(EXT_texture_object),                      GL             },
194
   { "GL_EXT_texture",                             o(EXT_texture),                             GL             },
195
   { "GL_EXT_texture_rectangle",                   o(NV_texture_rectangle),                    GL             },
196
   { "GL_EXT_texture_shared_exponent",             o(EXT_texture_shared_exponent),             GL             },
197
   { "GL_EXT_texture_sRGB",                        o(EXT_texture_sRGB),                        GL             },
198
   { "GL_EXT_texture_swizzle",                     o(EXT_texture_swizzle),                     GL             },
199
   { "GL_EXT_texture_type_2_10_10_10_REV",         o(dummy_true),                                         ES2 },
200
   { "GL_EXT_timer_query",                         o(EXT_timer_query),                         GL             },
201
   { "GL_EXT_transform_feedback",                  o(EXT_transform_feedback),                  GL             },
202
   { "GL_EXT_vertex_array_bgra",                   o(EXT_vertex_array_bgra),                   GL             },
203
   { "GL_EXT_vertex_array",                        o(EXT_vertex_array),                        GL             },
204
   { "GL_EXT_vertex_array_set",                    o(EXT_vertex_array_set),                    GL             },
205
 
206
   /* OES extensions */
207
   { "GL_OES_blend_equation_separate",             o(EXT_blend_equation_separate),                  ES1       },
208
   { "GL_OES_blend_func_separate",                 o(EXT_blend_func_separate),                      ES1       },
209
   { "GL_OES_blend_subtract",                      o(EXT_blend_subtract),                           ES1       },
210
   { "GL_OES_byte_coordinates",                    o(dummy_true),                                   ES1       },
211
   { "GL_OES_compressed_paletted_texture",         o(dummy_false),                     DISABLE                },
212
   { "GL_OES_depth24",                             o(EXT_framebuffer_object),                       ES1 | ES2 },
213
   { "GL_OES_depth32",                             o(dummy_false),                     DISABLE                },
214
   { "GL_OES_depth_texture",                       o(ARB_depth_texture),                                  ES2 },
215
#if FEATURE_OES_draw_texture
216
   { "GL_OES_draw_texture",                        o(OES_draw_texture),                             ES1 | ES2 },
217
#endif
218
#if FEATURE_OES_EGL_image
219
   /*  FIXME: Mesa expects GL_OES_EGL_image to be available in OpenGL contexts. */
220
   { "GL_OES_EGL_image",                           o(OES_EGL_image),                           GL | ES1 | ES2 },
221
#endif
222
   { "GL_OES_element_index_uint",                  o(EXT_vertex_array),                             ES1 | ES2 },
223
   { "GL_OES_fbo_render_mipmap",                   o(EXT_framebuffer_object),                       ES1 | ES2 },
224
   { "GL_OES_fixed_point",                         o(dummy_true),                                   ES1       },
225
   { "GL_OES_framebuffer_object",                  o(EXT_framebuffer_object),                       ES1       },
226
   { "GL_OES_mapbuffer",                           o(ARB_vertex_buffer_object),                     ES1 | ES2 },
227
   { "GL_OES_matrix_get",                          o(dummy_true),                                   ES1       },
228
   { "GL_OES_packed_depth_stencil",                o(EXT_packed_depth_stencil),                     ES1 | ES2 },
229
   { "GL_OES_point_size_array",                    o(dummy_true),                                   ES1       },
230
   { "GL_OES_point_sprite",                        o(ARB_point_sprite),                             ES1       },
231
   { "GL_OES_query_matrix",                        o(dummy_true),                                   ES1       },
232
   { "GL_OES_read_format",                         o(OES_read_format),                         GL | ES1       },
233
   { "GL_OES_rgb8_rgba8",                          o(EXT_framebuffer_object),                       ES1 | ES2 },
234
   { "GL_OES_single_precision",                    o(dummy_true),                                   ES1       },
235
   { "GL_OES_standard_derivatives",                o(OES_standard_derivatives),                           ES2 },
236
   { "GL_OES_stencil1",                            o(dummy_false),                     DISABLE                },
237
   { "GL_OES_stencil4",                            o(dummy_false),                     DISABLE                },
238
   { "GL_OES_stencil8",                            o(EXT_framebuffer_object),                       ES1 | ES2 },
239
   { "GL_OES_stencil_wrap",                        o(EXT_stencil_wrap),                             ES1       },
240
   /* GL_OES_texture_3D is disabled due to missing GLSL support. */
241
   { "GL_OES_texture_3D",                          o(EXT_texture3D),                   DISABLE                },
242
   { "GL_OES_texture_cube_map",                    o(ARB_texture_cube_map),                         ES1       },
243
   { "GL_OES_texture_env_crossbar",                o(ARB_texture_env_crossbar),                     ES1       },
244
   { "GL_OES_texture_mirrored_repeat",             o(ARB_texture_mirrored_repeat),                  ES1       },
245
   { "GL_OES_texture_npot",                        o(ARB_texture_non_power_of_two),                       ES2 },
246
 
247
   /* Vendor extensions */
248
   { "GL_3DFX_texture_compression_FXT1",           o(TDFX_texture_compression_FXT1),           GL             },
249
   { "GL_APPLE_client_storage",                    o(APPLE_client_storage),                    GL             },
250
   { "GL_APPLE_object_purgeable",                  o(APPLE_object_purgeable),                  GL             },
251
   { "GL_APPLE_packed_pixels",                     o(APPLE_packed_pixels),                     GL             },
252
   { "GL_APPLE_vertex_array_object",               o(APPLE_vertex_array_object),               GL             },
253
   { "GL_ATI_blend_equation_separate",             o(EXT_blend_equation_separate),             GL             },
254
   { "GL_ATI_envmap_bumpmap",                      o(ATI_envmap_bumpmap),                      GL             },
255
   { "GL_ATI_fragment_shader",                     o(ATI_fragment_shader),                     GL             },
256
   { "GL_ATI_separate_stencil",                    o(ATI_separate_stencil),                    GL             },
257
   { "GL_ATI_texture_env_combine3",                o(ATI_texture_env_combine3),                GL             },
258
   { "GL_ATI_texture_mirror_once",                 o(ATI_texture_mirror_once),                 GL             },
259
   { "GL_IBM_multimode_draw_arrays",               o(IBM_multimode_draw_arrays),               GL             },
260
   { "GL_IBM_rasterpos_clip",                      o(IBM_rasterpos_clip),                      GL             },
261
   { "GL_IBM_texture_mirrored_repeat",             o(ARB_texture_mirrored_repeat),             GL             },
262
   { "GL_INGR_blend_func_separate",                o(EXT_blend_func_separate),                 GL             },
263
   { "GL_MESA_pack_invert",                        o(MESA_pack_invert),                        GL             },
264
   { "GL_MESA_resize_buffers",                     o(MESA_resize_buffers),                     GL             },
265
   { "GL_MESA_texture_array",                      o(MESA_texture_array),                      GL             },
266
   { "GL_MESA_texture_signed_rgba",                o(MESA_texture_signed_rgba),                GL             },
267
   { "GL_MESA_window_pos",                         o(ARB_window_pos),                          GL             },
268
   { "GL_MESAX_texture_float",                     o(ARB_texture_float),                       GL             },
269
   { "GL_MESA_ycbcr_texture",                      o(MESA_ycbcr_texture),                      GL             },
270
   { "GL_NV_blend_square",                         o(NV_blend_square),                         GL             },
271
   { "GL_NV_conditional_render",                   o(NV_conditional_render),                   GL             },
272
   { "GL_NV_depth_clamp",                          o(ARB_depth_clamp),                         GL             },
273
   { "GL_NV_fragment_program",                     o(NV_fragment_program),                     GL             },
274
   { "GL_NV_fragment_program_option",              o(NV_fragment_program_option),              GL             },
275
   { "GL_NV_light_max_exponent",                   o(NV_light_max_exponent),                   GL             },
276
   { "GL_NV_packed_depth_stencil",                 o(EXT_packed_depth_stencil),                GL             },
277
   { "GL_NV_point_sprite",                         o(NV_point_sprite),                         GL             },
278
   { "GL_NV_primitive_restart",                    o(NV_primitive_restart),                    GL             },
279
   { "GL_NV_texgen_reflection",                    o(NV_texgen_reflection),                    GL             },
280
   { "GL_NV_texture_env_combine4",                 o(NV_texture_env_combine4),                 GL             },
281
   { "GL_NV_texture_rectangle",                    o(NV_texture_rectangle),                    GL             },
282
   { "GL_NV_vertex_program1_1",                    o(NV_vertex_program1_1),                    GL             },
283
   { "GL_NV_vertex_program",                       o(NV_vertex_program),                       GL             },
284
   { "GL_S3_s3tc",                                 o(S3_s3tc),                                 GL             },
285
   { "GL_SGIS_generate_mipmap",                    o(SGIS_generate_mipmap),                    GL             },
286
   { "GL_SGIS_texture_border_clamp",               o(ARB_texture_border_clamp),                GL             },
287
   { "GL_SGIS_texture_edge_clamp",                 o(SGIS_texture_edge_clamp),                 GL             },
288
   { "GL_SGIS_texture_lod",                        o(SGIS_texture_lod),                        GL             },
289
   { "GL_SGI_texture_color_table",                 o(SGI_texture_color_table),                 GL             },
290
   { "GL_SUN_multi_draw_arrays",                   o(EXT_multi_draw_arrays),                   GL             },
291
 
292
   { 0, 0, 0 },
293
};
294
 
295
 
296
/**
297
 * Given an extension name, lookup up the corresponding member of struct
298
 * gl_extensions and return that member's offset (in bytes).  If the name is
299
 * not found in the \c extension_table, return 0.
300
 *
301
 * \param name Name of extension.
302
 * \return Offset of member in struct gl_extensions.
303
 */
304
static size_t
305
name_to_offset(const char* name)
306
{
307
   const struct extension *i;
308
 
309
   if (name == 0)
310
      return 0;
311
 
312
   for (i = extension_table; i->name != 0; ++i) {
313
      if (strcmp(name, i->name) == 0)
314
	 return i->offset;
315
   }
316
 
317
   return 0;
318
}
319
 
320
 
321
/**
322
 * \brief Extensions enabled by default.
323
 *
324
 * These extensions are enabled by _mesa_init_extensions().
325
 *
326
 * XXX: Should these defaults also apply to GLES?
327
 */
328
static const size_t default_extensions[] = {
329
   o(ARB_copy_buffer),
330
   o(ARB_draw_buffers),
331
   o(ARB_multisample),
332
   o(ARB_texture_compression),
333
   o(ARB_transpose_matrix),
334
   o(ARB_vertex_buffer_object),
335
   o(ARB_window_pos),
336
 
337
   o(EXT_abgr),
338
   o(EXT_bgra),
339
   o(EXT_compiled_vertex_array),
340
   o(EXT_copy_texture),
341
   o(EXT_draw_range_elements),
342
   o(EXT_multi_draw_arrays),
343
   o(EXT_packed_pixels),
344
   o(EXT_polygon_offset),
345
   o(EXT_rescale_normal),
346
   o(EXT_separate_specular_color),
347
   o(EXT_subtexture),
348
   o(EXT_texture),
349
   o(EXT_texture3D),
350
   o(EXT_texture_object),
351
   o(EXT_vertex_array),
352
 
353
   o(OES_read_format),
354
   o(OES_standard_derivatives),
355
 
356
   /* Vendor Extensions */
357
   o(APPLE_packed_pixels),
358
   o(IBM_multimode_draw_arrays),
359
   o(IBM_rasterpos_clip),
360
   o(NV_light_max_exponent),
361
   o(NV_texgen_reflection),
362
   o(SGIS_generate_mipmap),
363
   o(SGIS_texture_edge_clamp),
364
   o(SGIS_texture_lod),
365
 
366
   0,
367
};
368
 
369
 
370
/**
371
 * Enable all extensions suitable for a software-only renderer.
372
 * This is a convenience function used by the XMesa, OSMesa, GGI drivers, etc.
373
 */
374
void
375
_mesa_enable_sw_extensions(struct gl_context *ctx)
376
{
377
   /*ctx->Extensions.ARB_copy_buffer = GL_TRUE;*/
378
   ctx->Extensions.ARB_depth_clamp = GL_TRUE;
379
   ctx->Extensions.ARB_depth_texture = GL_TRUE;
380
   /*ctx->Extensions.ARB_draw_buffers = GL_TRUE;*/
381
   ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE;
382
   ctx->Extensions.ARB_explicit_attrib_location = GL_TRUE;
383
   ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
384
#if FEATURE_ARB_fragment_program
385
   ctx->Extensions.ARB_fragment_program = GL_TRUE;
386
   ctx->Extensions.ARB_fragment_program_shadow = GL_TRUE;
387
#endif
388
#if FEATURE_ARB_fragment_shader
389
   ctx->Extensions.ARB_fragment_shader = GL_TRUE;
390
#endif
391
#if FEATURE_ARB_framebuffer_object
392
   ctx->Extensions.ARB_framebuffer_object = GL_TRUE;
393
#endif
394
#if FEATURE_ARB_geometry_shader4 && 0
395
   /* XXX re-enable when GLSL compiler again supports geometry shaders */
396
   ctx->Extensions.ARB_geometry_shader4 = GL_TRUE;
397
#endif
398
   ctx->Extensions.ARB_half_float_pixel = GL_TRUE;
399
   ctx->Extensions.ARB_half_float_vertex = GL_TRUE;
400
   ctx->Extensions.ARB_map_buffer_range = GL_TRUE;
401
   ctx->Extensions.ARB_multitexture = GL_TRUE;
402
#if FEATURE_queryobj
403
   ctx->Extensions.ARB_occlusion_query = GL_TRUE;
404
#endif
405
   ctx->Extensions.ARB_point_sprite = GL_TRUE;
406
#if FEATURE_ARB_shader_objects
407
   ctx->Extensions.ARB_shader_objects = GL_TRUE;
408
   ctx->Extensions.EXT_separate_shader_objects = GL_TRUE;
409
#endif
410
#if FEATURE_ARB_shading_language_100
411
   ctx->Extensions.ARB_shading_language_100 = GL_TRUE;
412
#endif
413
   ctx->Extensions.ARB_shadow = GL_TRUE;
414
   ctx->Extensions.ARB_shadow_ambient = GL_TRUE;
415
   ctx->Extensions.ARB_texture_border_clamp = GL_TRUE;
416
   ctx->Extensions.ARB_texture_cube_map = GL_TRUE;
417
   ctx->Extensions.ARB_texture_env_combine = GL_TRUE;
418
   ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE;
419
   ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE;
420
   /*ctx->Extensions.ARB_texture_float = GL_TRUE;*/
421
   ctx->Extensions.ARB_texture_mirrored_repeat = GL_TRUE;
422
   ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
423
   ctx->Extensions.ARB_texture_rg = GL_TRUE;
424
   ctx->Extensions.ARB_vertex_array_object = GL_TRUE;
425
#if FEATURE_ARB_vertex_program
426
   ctx->Extensions.ARB_vertex_program = GL_TRUE;
427
#endif
428
#if FEATURE_ARB_vertex_shader
429
   ctx->Extensions.ARB_vertex_shader = GL_TRUE;
430
#endif
431
#if FEATURE_ARB_vertex_buffer_object
432
   /*ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;*/
433
#endif
434
#if FEATURE_ARB_sync
435
   ctx->Extensions.ARB_sync = GL_TRUE;
436
#endif
437
   ctx->Extensions.APPLE_vertex_array_object = GL_TRUE;
438
#if FEATURE_APPLE_object_purgeable
439
   ctx->Extensions.APPLE_object_purgeable = GL_TRUE;
440
#endif
441
   ctx->Extensions.ATI_envmap_bumpmap = GL_TRUE;
442
#if FEATURE_ATI_fragment_shader
443
   ctx->Extensions.ATI_fragment_shader = GL_TRUE;
444
#endif
445
   ctx->Extensions.ATI_texture_env_combine3 = GL_TRUE;
446
   ctx->Extensions.ATI_texture_mirror_once = GL_TRUE;
447
   ctx->Extensions.ATI_separate_stencil = GL_TRUE;
448
   ctx->Extensions.EXT_blend_color = GL_TRUE;
449
   ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
450
   ctx->Extensions.EXT_blend_func_separate = GL_TRUE;
451
   ctx->Extensions.EXT_blend_logic_op = GL_TRUE;
452
   ctx->Extensions.EXT_blend_minmax = GL_TRUE;
453
   ctx->Extensions.EXT_blend_subtract = GL_TRUE;
454
   ctx->Extensions.EXT_depth_bounds_test = GL_TRUE;
455
   ctx->Extensions.EXT_draw_buffers2 = GL_TRUE;
456
   ctx->Extensions.EXT_fog_coord = GL_TRUE;
457
#if FEATURE_EXT_framebuffer_object
458
   ctx->Extensions.EXT_framebuffer_object = GL_TRUE;
459
#endif
460
#if FEATURE_EXT_framebuffer_blit
461
   ctx->Extensions.EXT_framebuffer_blit = GL_TRUE;
462
#endif
463
#if FEATURE_ARB_framebuffer_object
464
   ctx->Extensions.EXT_framebuffer_multisample = GL_TRUE;
465
#endif
466
   /*ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE;*/
467
   ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE;
468
   ctx->Extensions.EXT_paletted_texture = GL_TRUE;
469
#if FEATURE_EXT_pixel_buffer_object
470
   ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE;
471
#endif
472
   ctx->Extensions.EXT_point_parameters = GL_TRUE;
473
   ctx->Extensions.EXT_provoking_vertex = GL_TRUE;
474
   ctx->Extensions.EXT_shadow_funcs = GL_TRUE;
475
   ctx->Extensions.EXT_secondary_color = GL_TRUE;
476
   ctx->Extensions.EXT_shared_texture_palette = GL_TRUE;
477
   ctx->Extensions.EXT_stencil_wrap = GL_TRUE;
478
   ctx->Extensions.EXT_stencil_two_side = GL_TRUE;
479
   ctx->Extensions.EXT_texture_array = GL_TRUE;
480
   ctx->Extensions.EXT_texture_env_add = GL_TRUE;
481
   ctx->Extensions.EXT_texture_env_combine = GL_TRUE;
482
   ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE;
483
   ctx->Extensions.EXT_texture_mirror_clamp = GL_TRUE;
484
   ctx->Extensions.EXT_texture_lod_bias = GL_TRUE;
485
#if FEATURE_EXT_texture_sRGB
486
   ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
487
#endif
488
   ctx->Extensions.EXT_texture_swizzle = GL_TRUE;
489
#if FEATURE_EXT_transform_feedback
490
   /*ctx->Extensions.EXT_transform_feedback = GL_TRUE;*/
491
#endif
492
   ctx->Extensions.EXT_vertex_array_bgra = GL_TRUE;
493
   /*ctx->Extensions.IBM_multimode_draw_arrays = GL_TRUE;*/
494
   ctx->Extensions.MESA_pack_invert = GL_TRUE;
495
   ctx->Extensions.MESA_resize_buffers = GL_TRUE;
496
   ctx->Extensions.MESA_texture_array = GL_TRUE;
497
   ctx->Extensions.MESA_ycbcr_texture = GL_TRUE;
498
   ctx->Extensions.NV_blend_square = GL_TRUE;
499
   ctx->Extensions.NV_conditional_render = GL_TRUE;
500
   /*ctx->Extensions.NV_light_max_exponent = GL_TRUE;*/
501
   ctx->Extensions.NV_point_sprite = GL_TRUE;
502
   ctx->Extensions.NV_texture_env_combine4 = GL_TRUE;
503
   ctx->Extensions.NV_texture_rectangle = GL_TRUE;
504
   /*ctx->Extensions.NV_texgen_reflection = GL_TRUE;*/
505
#if FEATURE_NV_vertex_program
506
   ctx->Extensions.NV_vertex_program = GL_TRUE;
507
   ctx->Extensions.NV_vertex_program1_1 = GL_TRUE;
508
#endif
509
#if FEATURE_NV_fragment_program
510
   ctx->Extensions.NV_fragment_program = GL_TRUE;
511
#endif
512
#if FEATURE_NV_fragment_program && FEATURE_ARB_fragment_program
513
   ctx->Extensions.NV_fragment_program_option = GL_TRUE;
514
#endif
515
   ctx->Extensions.SGI_texture_color_table = GL_TRUE;
516
   /*ctx->Extensions.SGIS_generate_mipmap = GL_TRUE;*/
517
   ctx->Extensions.SGIS_texture_edge_clamp = GL_TRUE;
518
#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
519
   ctx->Extensions.EXT_gpu_program_parameters = GL_TRUE;
520
#endif
521
#if FEATURE_texture_fxt1
522
   _mesa_enable_extension(ctx, "GL_3DFX_texture_compression_FXT1");
523
#endif
524
#if FEATURE_texture_s3tc
525
   if (ctx->Mesa_DXTn) {
526
      _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
527
      _mesa_enable_extension(ctx, "GL_S3_s3tc");
528
   }
529
#endif
530
}
531
 
532
 
533
/**
534
 * Enable common EXT extensions in the ARB_imaging subset.
535
 */
536
void
537
_mesa_enable_imaging_extensions(struct gl_context *ctx)
538
{
539
   ctx->Extensions.EXT_blend_color = GL_TRUE;
540
   ctx->Extensions.EXT_blend_logic_op = GL_TRUE;
541
   ctx->Extensions.EXT_blend_minmax = GL_TRUE;
542
   ctx->Extensions.EXT_blend_subtract = GL_TRUE;
543
}
544
 
545
 
546
 
547
/**
548
 * Enable all OpenGL 1.3 features and extensions.
549
 * A convenience function to be called by drivers.
550
 */
551
void
552
_mesa_enable_1_3_extensions(struct gl_context *ctx)
553
{
554
   /*ctx->Extensions.ARB_multisample = GL_TRUE;*/
555
   ctx->Extensions.ARB_multitexture = GL_TRUE;
556
   ctx->Extensions.ARB_texture_border_clamp = GL_TRUE;
557
   /*ctx->Extensions.ARB_texture_compression = GL_TRUE;*/
558
   ctx->Extensions.ARB_texture_cube_map = GL_TRUE;
559
   ctx->Extensions.ARB_texture_env_combine = GL_TRUE;
560
   ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE;
561
   ctx->Extensions.EXT_texture_env_add = GL_TRUE;
562
   /*ctx->Extensions.ARB_transpose_matrix = GL_TRUE;*/
563
}
564
 
565
 
566
 
567
/**
568
 * Enable all OpenGL 1.4 features and extensions.
569
 * A convenience function to be called by drivers.
570
 */
571
void
572
_mesa_enable_1_4_extensions(struct gl_context *ctx)
573
{
574
   ctx->Extensions.ARB_depth_texture = GL_TRUE;
575
   ctx->Extensions.ARB_shadow = GL_TRUE;
576
   ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE;
577
   ctx->Extensions.ARB_texture_mirrored_repeat = GL_TRUE;
578
   ctx->Extensions.ARB_window_pos = GL_TRUE;
579
   ctx->Extensions.EXT_blend_color = GL_TRUE;
580
   ctx->Extensions.EXT_blend_func_separate = GL_TRUE;
581
   ctx->Extensions.EXT_blend_minmax = GL_TRUE;
582
   ctx->Extensions.EXT_blend_subtract = GL_TRUE;
583
   ctx->Extensions.EXT_fog_coord = GL_TRUE;
584
   /*ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE;*/
585
   ctx->Extensions.EXT_point_parameters = GL_TRUE;
586
   ctx->Extensions.EXT_secondary_color = GL_TRUE;
587
   ctx->Extensions.EXT_stencil_wrap = GL_TRUE;
588
   ctx->Extensions.EXT_texture_lod_bias = GL_TRUE;
589
   /*ctx->Extensions.SGIS_generate_mipmap = GL_TRUE;*/
590
}
591
 
592
 
593
/**
594
 * Enable all OpenGL 1.5 features and extensions.
595
 * A convenience function to be called by drivers.
596
 */
597
void
598
_mesa_enable_1_5_extensions(struct gl_context *ctx)
599
{
600
   ctx->Extensions.ARB_occlusion_query = GL_TRUE;
601
   /*ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;*/
602
   ctx->Extensions.EXT_shadow_funcs = GL_TRUE;
603
}
604
 
605
 
606
/**
607
 * Enable all OpenGL 2.0 features and extensions.
608
 * A convenience function to be called by drivers.
609
 */
610
void
611
_mesa_enable_2_0_extensions(struct gl_context *ctx)
612
{
613
   /*ctx->Extensions.ARB_draw_buffers = GL_TRUE;*/
614
#if FEATURE_ARB_fragment_shader
615
   ctx->Extensions.ARB_fragment_shader = GL_TRUE;
616
#endif
617
   ctx->Extensions.ARB_point_sprite = GL_TRUE;
618
   ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
619
   ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
620
#if FEATURE_ARB_shader_objects
621
   ctx->Extensions.ARB_shader_objects = GL_TRUE;
622
#endif
623
#if FEATURE_ARB_shading_language_100
624
   ctx->Extensions.ARB_shading_language_100 = GL_TRUE;
625
#endif
626
   ctx->Extensions.EXT_stencil_two_side = GL_TRUE;
627
#if FEATURE_ARB_vertex_shader
628
   ctx->Extensions.ARB_vertex_shader = GL_TRUE;
629
#endif
630
}
631
 
632
 
633
/**
634
 * Enable all OpenGL 2.1 features and extensions.
635
 * A convenience function to be called by drivers.
636
 */
637
void
638
_mesa_enable_2_1_extensions(struct gl_context *ctx)
639
{
640
#if FEATURE_EXT_pixel_buffer_object
641
   ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE;
642
#endif
643
#if FEATURE_EXT_texture_sRGB
644
   ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
645
#endif
646
}
647
 
648
 
649
/**
650
 * Either enable or disable the named extension.
651
 * \return GL_TRUE for success, GL_FALSE if invalid extension name
652
 */
653
static GLboolean
654
set_extension( struct gl_context *ctx, const char *name, GLboolean state )
655
{
656
   size_t offset;
657
 
658
   if (ctx->Extensions.String) {
659
      /* The string was already queried - can't change it now! */
660
      _mesa_problem(ctx, "Trying to enable/disable extension after glGetString(GL_EXTENSIONS): %s", name);
661
      return GL_FALSE;
662
   }
663
 
664
   offset = name_to_offset(name);
665
   if (offset == 0) {
666
      _mesa_problem(ctx, "Trying to enable/disable unknown extension %s",
667
	            name);
668
      return GL_FALSE;
669
   } else if (offset == o(dummy_true) && state == GL_FALSE) {
670
      _mesa_problem(ctx, "Trying to disable a permanently enabled extension: "
671
	                  "%s", name);
672
      return GL_FALSE;
673
   } else {
674
      GLboolean *base = (GLboolean *) &ctx->Extensions;
675
      base[offset] = state;
676
      return GL_TRUE;
677
   }
678
}
679
 
680
 
681
/**
682
 * Enable the named extension.
683
 * Typically called by drivers.
684
 */
685
void
686
_mesa_enable_extension( struct gl_context *ctx, const char *name )
687
{
688
   if (!set_extension(ctx, name, GL_TRUE))
689
      _mesa_problem(ctx, "Trying to enable unknown extension: %s", name);
690
}
691
 
692
 
693
/**
694
 * Disable the named extension.
695
 * XXX is this really needed???
696
 */
697
void
698
_mesa_disable_extension( struct gl_context *ctx, const char *name )
699
{
700
   if (!set_extension(ctx, name, GL_FALSE))
701
      _mesa_problem(ctx, "Trying to disable unknown extension: %s", name);
702
}
703
 
704
 
705
/**
706
 * Test if the named extension is enabled in this context.
707
 */
708
GLboolean
709
_mesa_extension_is_enabled( struct gl_context *ctx, const char *name )
710
{
711
   size_t offset;
712
   GLboolean *base;
713
 
714
   if (name == 0)
715
      return GL_FALSE;
716
 
717
   offset = name_to_offset(name);
718
   if (offset == 0)
719
      return GL_FALSE;
720
   base = (GLboolean *) &ctx->Extensions;
721
   return base[offset];
722
}
723
 
724
 
725
/**
726
 * Append string 'b' onto string 'a'.  Free 'a' and return new string.
727
 */
728
static char *
729
append(const char *a, const char *b)
730
{
731
   const GLuint aLen = a ? strlen(a) : 0;
732
   const GLuint bLen = b ? strlen(b) : 0;
733
   char *s = calloc(1, aLen + bLen + 1);
734
   if (s) {
735
      if (a)
736
         memcpy(s, a, aLen);
737
      if (b)
738
         memcpy(s + aLen, b, bLen);
739
      s[aLen + bLen] = '\0';
740
   }
741
   if (a)
742
      free((void *) a);
743
   return s;
744
}
745
 
746
 
747
/**
748
 * Check the MESA_EXTENSION_OVERRIDE env var.
749
 * For extension names that are recognized, turn them on.  For extension
750
 * names that are recognized and prefixed with '-', turn them off.
751
 * Return a string of the unknown/leftover names.
752
 *
753
 * Returnd string needs to be freed.
754
 */
755
static char *
756
get_extension_override( struct gl_context *ctx )
757
{
758
   const char *envExt = _mesa_getenv("MESA_EXTENSION_OVERRIDE");
759
   char *extraExt = NULL;
760
   char ext[1000];
761
   GLuint extLen = 0;
762
   GLuint i;
763
   GLboolean disableExt = GL_FALSE;
764
 
765
   if (!envExt)
766
      return NULL;
767
 
768
   for (i = 0; ; i++) {
769
      if (envExt[i] == '\0' || envExt[i] == ' ') {
770
         /* terminate/process 'ext' if extLen > 0 */
771
         if (extLen > 0) {
772
            assert(extLen < sizeof(ext));
773
            /* enable extension named by 'ext' */
774
            ext[extLen] = 0;
775
            if (!set_extension(ctx, ext, !disableExt)) {
776
               /* unknown extension name, append it to extraExt */
777
               if (extraExt) {
778
                  extraExt = append(extraExt, " ");
779
               }
780
               extraExt = append(extraExt, ext);
781
            }
782
            extLen = 0;
783
            disableExt = GL_FALSE;
784
         }
785
         if (envExt[i] == '\0')
786
            break;
787
      }
788
      else if (envExt[i] == '-') {
789
         disableExt = GL_TRUE;
790
      }
791
      else {
792
         /* accumulate this non-space character */
793
         ext[extLen++] = envExt[i];
794
      }
795
   }
796
 
797
   return extraExt;
798
}
799
 
800
 
801
/**
802
 * \brief Initialize extension tables and enable default extensions.
803
 *
804
 * This should be called during context initialization.
805
 * Note: Sets gl_extensions.dummy_true to true.
806
 */
807
void
808
_mesa_init_extensions( struct gl_context *ctx )
809
{
810
   GLboolean *base = (GLboolean *) &ctx->Extensions;
811
   GLboolean *sentinel = base + o(extension_sentinel);
812
   GLboolean *i;
813
   const size_t *j;
814
 
815
   /* First, turn all extensions off. */
816
   for (i = base; i != sentinel; ++i)
817
      *i = GL_FALSE;
818
 
819
   /* Then, selectively turn default extensions on. */
820
   ctx->Extensions.dummy_true = GL_TRUE;
821
   for (j = default_extensions; *j != 0; ++j)
822
      base[*j] = GL_TRUE;
823
}
824
 
825
 
826
/**
827
 * Construct the GL_EXTENSIONS string.  Called the first time that
828
 * glGetString(GL_EXTENSIONS) is called.
829
 */
830
GLubyte*
831
_mesa_make_extension_string(struct gl_context *ctx)
832
{
833
   /* The extension string. */
834
   char *exts = 0;
835
   /* Length of extension string. */
836
   size_t length = 0;
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
 
842
   /* Compute length of the extension string. */
843
   for (i = extension_table; i->name != 0; ++i) {
844
      if (base[i->offset] && (i->api_set & (1 << ctx->API))) {
845
	 length += strlen(i->name) + 1; /* +1 for space */
846
      }
847
   }
848
   if (extra_extensions != NULL)
849
      length += 1 + strlen(extra_extensions); /* +1 for space */
850
 
851
   exts = (char *) calloc(length + 1, sizeof(char));
852
   if (exts == NULL) {
853
      free(extra_extensions);
854
      return NULL;
855
   }
856
 
857
   /* Build the extension string.*/
858
   for (i = extension_table; i->name != 0; ++i) {
859
      if (base[i->offset] && (i->api_set & (1 << ctx->API))) {
860
         strcat(exts, i->name);
861
         strcat(exts, " ");
862
      }
863
   }
864
   if (extra_extensions != 0) {
865
      strcat(exts, extra_extensions);
866
      free(extra_extensions);
867
   }
868
 
869
   return (GLubyte *) exts;
870
}
871
 
872
/**
873
 * Return number of enabled extensions.
874
 */
875
GLuint
876
_mesa_get_extension_count(struct gl_context *ctx)
877
{
878
   GLboolean *base;
879
   const struct extension *i;
880
 
881
   /* only count once */
882
   if (ctx->Extensions.Count != 0)
883
      return ctx->Extensions.Count;
884
 
885
   base = (GLboolean *) &ctx->Extensions;
886
   for (i = extension_table; i->name != 0; ++i) {
887
      if (base[i->offset]) {
888
	 ctx->Extensions.Count++;
889
      }
890
   }
891
   return ctx->Extensions.Count;
892
}
893
 
894
/**
895
 * Return name of i-th enabled extension
896
 */
897
const GLubyte *
898
_mesa_get_enabled_extension(struct gl_context *ctx, GLuint index)
899
{
900
   const GLboolean *base;
901
   size_t n;
902
   const struct extension *i;
903
 
904
   if (index < 0)
905
      return NULL;
906
 
907
   base = (GLboolean*) &ctx->Extensions;
908
   n = 0;
909
   for (i = extension_table; i->name != 0; ++i) {
910
      if (n == index && base[i->offset]) {
911
	 return (GLubyte*) i->name;
912
      } else if (base[i->offset]) {
913
	 ++n;
914
      }
915
   }
916
 
917
   return NULL;
918
}