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 | }>><>><>>><>><>><> |