Subversion Repositories shark

Rev

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

Rev Author Line No. Line
55 pj 1
/* $Id: extensions.c,v 1.1 2003-02-28 11:42:00 pj Exp $ */
2
 
3
/*
4
 * Mesa 3-D graphics library
5
 * Version:  4.1
6
 *
7
 * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a
10
 * copy of this software and associated documentation files (the "Software"),
11
 * to deal in the Software without restriction, including without limitation
12
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13
 * and/or sell copies of the Software, and to permit persons to whom the
14
 * Software is furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included
17
 * in all copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 */
26
 
27
#include "glheader.h"
28
#include "imports.h"
29
#include "context.h"
30
#include "extensions.h"
31
#include "simple_list.h"
32
#include "mtypes.h"
33
 
34
 
35
#define MAX_EXT_NAMELEN 80
36
 
37
struct extension {
38
   struct extension *next, *prev;
39
   GLint enabled;
40
   GLboolean *flag;                     /* optional flag stored elsewhere */
41
   char name[MAX_EXT_NAMELEN+1];
42
   void (*notify)( GLcontext *, GLboolean );
43
};
44
 
45
#define F(x) (int)&(((struct gl_extensions *)0)->x)
46
#define ON GL_TRUE
47
#define OFF GL_FALSE
48
 
49
static struct {
50
   GLboolean enabled;
51
   const char *name;
52
   int flag_offset;
53
} default_extensions[] = {
54
   { OFF, "GL_ARB_depth_texture",              F(ARB_depth_texture) },
55
   { OFF, "GL_ARB_imaging",                    F(ARB_imaging) },
56
   { OFF, "GL_ARB_multisample",                F(ARB_multisample) },
57
   { OFF, "GL_ARB_multitexture",               F(ARB_multitexture) },
58
   { OFF, "GL_ARB_point_parameters",           F(EXT_point_parameters) },
59
   { OFF, "GL_ARB_shadow",                     F(ARB_shadow) },
60
   { OFF, "GL_ARB_shadow_ambient",             F(SGIX_shadow_ambient) },
61
   { OFF, "GL_ARB_texture_border_clamp",       F(ARB_texture_border_clamp) },
62
   { OFF, "GL_ARB_texture_compression",        F(ARB_texture_compression) },
63
   { OFF, "GL_ARB_texture_cube_map",           F(ARB_texture_cube_map) },
64
   { OFF, "GL_ARB_texture_env_add",            F(EXT_texture_env_add) },
65
   { OFF, "GL_ARB_texture_env_combine",        F(ARB_texture_env_combine) },
66
   { OFF, "GL_ARB_texture_env_crossbar",       F(ARB_texture_env_crossbar) },
67
   { OFF, "GL_ARB_texture_env_dot3",           F(ARB_texture_env_dot3) },
68
   { OFF, "GL_ARB_texture_mirrored_repeat",    F(ARB_texture_mirrored_repeat)},
69
   { ON,  "GL_ARB_transpose_matrix",           0 },
70
   { ON,  "GL_ARB_window_pos",                 F(ARB_window_pos) },
71
   { OFF, "GL_ATI_texture_mirror_once",        F(ATI_texture_mirror_once)},
72
   { ON,  "GL_EXT_abgr",                       0 },
73
   { ON,  "GL_EXT_bgra",                       0 },
74
   { OFF, "GL_EXT_blend_color",                F(EXT_blend_color) },
75
   { OFF, "GL_EXT_blend_func_separate",        F(EXT_blend_func_separate) },
76
   { OFF, "GL_EXT_blend_logic_op",             F(EXT_blend_logic_op) },
77
   { OFF, "GL_EXT_blend_minmax",               F(EXT_blend_minmax) },
78
   { OFF, "GL_EXT_blend_subtract",             F(EXT_blend_subtract) },
79
   { ON,  "GL_EXT_clip_volume_hint",           F(EXT_clip_volume_hint) },
80
   { OFF, "GL_EXT_convolution",                F(EXT_convolution) },
81
   { ON,  "GL_EXT_compiled_vertex_array",      F(EXT_compiled_vertex_array) },
82
   { OFF, "GL_EXT_fog_coord",                  F(EXT_fog_coord) },
83
   { OFF, "GL_EXT_histogram",                  F(EXT_histogram) },
84
   { OFF, "GL_EXT_multi_draw_arrays",          F(EXT_multi_draw_arrays) },
85
   { ON,  "GL_EXT_packed_pixels",              F(EXT_packed_pixels) },
86
   { OFF, "GL_EXT_paletted_texture",           F(EXT_paletted_texture) },
87
   { OFF, "GL_EXT_point_parameters",           F(EXT_point_parameters) },
88
   { ON,  "GL_EXT_polygon_offset",             F(EXT_polygon_offset) },
89
   { ON,  "GL_EXT_rescale_normal",             F(EXT_rescale_normal) },
90
   { OFF, "GL_EXT_secondary_color",            F(EXT_secondary_color) },
91
   { OFF, "GL_EXT_shadow_funcs",               F(EXT_shadow_funcs) },
92
   { OFF, "GL_EXT_shared_texture_palette",     F(EXT_shared_texture_palette) },
93
   { OFF, "GL_EXT_stencil_wrap",               F(EXT_stencil_wrap) },
94
   { OFF, "GL_EXT_stencil_two_side",           F(EXT_stencil_two_side) },
95
   { ON,  "GL_EXT_texture3D",                  F(EXT_texture3D) },
96
   { OFF, "GL_EXT_texture_compression_s3tc",   F(EXT_texture_compression_s3tc) },
97
   { OFF, "GL_EXT_texture_edge_clamp",         F(SGIS_texture_edge_clamp) },
98
   { OFF, "GL_EXT_texture_env_add",            F(EXT_texture_env_add) },
99
   { OFF, "GL_EXT_texture_env_combine",        F(EXT_texture_env_combine) },
100
   { OFF, "GL_EXT_texture_env_dot3",           F(EXT_texture_env_dot3) },
101
   { OFF, "GL_EXT_texture_filter_anisotropic", F(EXT_texture_filter_anisotropic) },
102
   { ON,  "GL_EXT_texture_object",             F(EXT_texture_object) },
103
   { OFF, "GL_EXT_texture_lod_bias",           F(EXT_texture_lod_bias) },
104
   { ON,  "GL_EXT_vertex_array",               0 },
105
   { OFF, "GL_EXT_vertex_array_set",           F(EXT_vertex_array_set) },
106
   { OFF, "GL_HP_occlusion_test",              F(HP_occlusion_test) },
107
   { ON,  "GL_IBM_rasterpos_clip",             F(IBM_rasterpos_clip) },
108
   { OFF, "GL_IBM_texture_mirrored_repeat",    F(ARB_texture_mirrored_repeat)},
109
   { OFF, "GL_INGR_blend_func_separate",       F(INGR_blend_func_separate) },
110
   { OFF, "GL_MESA_pack_invert",               F(MESA_pack_invert) },
111
   { OFF, "GL_MESA_packed_depth_stencil",      0 },
112
   { OFF, "GL_MESA_resize_buffers",            F(MESA_resize_buffers) },
113
   { OFF, "GL_MESA_ycbcr_texture",             F(MESA_ycbcr_texture) },
114
   { ON,  "GL_MESA_window_pos",                F(MESA_window_pos) },
115
   { OFF, "GL_NV_blend_square",                F(NV_blend_square) },
116
   { OFF, "GL_NV_point_sprite",                F(NV_point_sprite) },
117
   { OFF, "GL_NV_texture_rectangle",           F(NV_texture_rectangle) },
118
   { ON,  "GL_NV_texgen_reflection",           F(NV_texgen_reflection) },
119
   { OFF, "GL_NV_vertex_program",              F(NV_vertex_program) },
120
   { OFF, "GL_NV_vertex_program1_1",           F(NV_vertex_program1_1) },
121
   { OFF, "GL_SGI_color_matrix",               F(SGI_color_matrix) },
122
   { OFF, "GL_SGI_color_table",                F(SGI_color_table) },
123
   { OFF, "GL_SGIS_generate_mipmap",           F(SGIS_generate_mipmap) },
124
   { OFF, "GL_SGIS_pixel_texture",             F(SGIS_pixel_texture) },
125
   { OFF, "GL_SGIS_texture_border_clamp",      F(ARB_texture_border_clamp) },
126
   { OFF, "GL_SGIS_texture_edge_clamp",        F(SGIS_texture_edge_clamp) },
127
   { OFF, "GL_SGIX_depth_texture",             F(SGIX_depth_texture) },
128
   { OFF, "GL_SGIX_pixel_texture",             F(SGIX_pixel_texture) },
129
   { OFF, "GL_SGIX_shadow",                    F(SGIX_shadow) },
130
   { OFF, "GL_SGIX_shadow_ambient",            F(SGIX_shadow_ambient) },
131
   { OFF, "GL_3DFX_texture_compression_FXT1",  F(TDFX_texture_compression_FXT1) },
132
   { OFF, "GL_APPLE_client_storage",           F(APPLE_client_storage) }
133
};
134
 
135
 
136
 
137
 
138
/*
139
 * Enable all extensions suitable for a software-only renderer.
140
 * This is a convenience function used by the XMesa, OSMesa, GGI drivers, etc.
141
 */
142
void
143
_mesa_enable_sw_extensions(GLcontext *ctx)
144
{
145
   const char *extensions[] = {
146
      "GL_ARB_depth_texture",
147
      "GL_ARB_imaging",
148
      "GL_ARB_multitexture",
149
      "GL_ARB_point_parameters",
150
      "GL_ARB_shadow",
151
      "GL_ARB_shadow_ambient",
152
      "GL_ARB_texture_border_clamp",
153
      "GL_ARB_texture_cube_map",
154
      "GL_ARB_texture_env_add",
155
      "GL_ARB_texture_env_combine",
156
      "GL_ARB_texture_env_crossbar",
157
      "GL_ARB_texture_env_dot3",
158
      "GL_ARB_texture_mirrored_repeat",
159
      "GL_ATI_texture_mirror_once",
160
      "GL_EXT_blend_color",
161
      "GL_EXT_blend_func_separate",
162
      "GL_EXT_blend_logic_op",
163
      "GL_EXT_blend_minmax",
164
      "GL_EXT_blend_subtract",
165
      "GL_EXT_convolution",
166
      "GL_EXT_fog_coord",
167
      "GL_EXT_histogram",
168
      "GL_EXT_paletted_texture",
169
      "GL_EXT_point_parameters",
170
      "GL_EXT_shadow_funcs",
171
      "GL_EXT_secondary_color",
172
      "GL_EXT_shared_texture_palette",
173
      "GL_EXT_stencil_wrap",
174
      "GL_EXT_stencil_two_side",
175
      "GL_EXT_texture_edge_clamp",
176
      "GL_EXT_texture_env_add",
177
      "GL_EXT_texture_env_combine",
178
      "GL_EXT_texture_env_dot3",
179
      "GL_EXT_texture_lod_bias",
180
      "GL_HP_occlusion_test",
181
      "GL_IBM_texture_mirrored_repeat",
182
      "GL_INGR_blend_func_separate",
183
      "GL_MESA_pack_invert",
184
      "GL_MESA_resize_buffers",
185
      "GL_MESA_ycbcr_texture",
186
      "GL_NV_blend_square",
187
      "GL_NV_point_sprite",
188
      "GL_NV_texture_rectangle",
189
      "GL_NV_texgen_reflection",
190
#if FEATURE_NV_vertex_program
191
      "GL_NV_vertex_program",
192
      "GL_NV_vertex_program1_1",
193
#endif
194
      "GL_SGI_color_matrix",
195
      "GL_SGI_color_table",
196
      "GL_SGIS_generate_mipmap",
197
      "GL_SGIS_pixel_texture",
198
      "GL_SGIS_texture_edge_clamp",
199
      "GL_SGIS_texture_border_clamp",
200
      "GL_SGIX_depth_texture",
201
      "GL_SGIX_pixel_texture",
202
      "GL_SGIX_shadow",
203
      "GL_SGIX_shadow_ambient",
204
      NULL
205
   };
206
   GLuint i;
207
 
208
   for (i = 0; extensions[i]; i++) {
209
      _mesa_enable_extension(ctx, extensions[i]);
210
   }
211
}
212
 
213
 
214
/*
215
 * Enable GL_ARB_imaging and all the EXT extensions that are subsets of it.
216
 */
217
void
218
_mesa_enable_imaging_extensions(GLcontext *ctx)
219
{
220
   const char *extensions[] = {
221
      "GL_ARB_imaging",
222
      "GL_EXT_blend_color",
223
      "GL_EXT_blend_minmax",
224
      "GL_EXT_blend_subtract",
225
      "GL_EXT_convolution",
226
      "GL_EXT_histogram",
227
      "GL_SGI_color_matrix",
228
      "GL_SGI_color_table",
229
      NULL
230
   };
231
   GLuint i;
232
 
233
   for (i = 0; extensions[i]; i++) {
234
      _mesa_enable_extension(ctx, extensions[i]);
235
   }
236
}
237
 
238
 
239
 
240
/*
241
 * Enable all OpenGL 1.3 features and extensions.
242
 */
243
void
244
_mesa_enable_1_3_extensions(GLcontext *ctx)
245
{
246
   const char *extensions[] = {
247
      "GL_ARB_multisample",
248
      "GL_ARB_multitexture",
249
      "GL_ARB_texture_border_clamp",
250
      "GL_ARB_texture_compression",
251
      "GL_ARB_texture_cube_map",
252
      "GL_ARB_texture_env_add",
253
      "GL_ARB_texture_env_combine",
254
      "GL_ARB_texture_env_dot3",
255
      "GL_ARB_transpose_matrix",
256
      NULL
257
   };
258
   GLuint i;
259
 
260
   for (i = 0; extensions[i]; i++) {
261
      _mesa_enable_extension(ctx, extensions[i]);
262
   }
263
}
264
 
265
 
266
 
267
/*
268
 * Enable all OpenGL 1.4 features and extensions.
269
 */
270
void
271
_mesa_enable_1_4_extensions(GLcontext *ctx)
272
{
273
   const char *extensions[] = {
274
      "GL_ARB_depth_texture",
275
      "GL_ARB_point_parameters",
276
      "GL_ARB_shadow",
277
      "GL_ARB_texture_env_crossbar",
278
      "GL_ARB_texture_mirrored_repeat",
279
      "GL_ARB_window_pos",
280
      "GL_EXT_blend_color",
281
      "GL_EXT_blend_func_separate",
282
      "GL_EXT_blend_logic_op",
283
      "GL_EXT_blend_minmax",
284
      "GL_EXT_blend_subtract",
285
      "GL_EXT_fog_coord",
286
      "GL_EXT_multi_draw_arrays",
287
      "GL_EXT_secondary_color",
288
      "GL_EXT_stencil_wrap",
289
      "GL_SGIS_generate_mipmap",
290
      NULL
291
   };
292
   GLuint i;
293
 
294
   for (i = 0; extensions[i]; i++) {
295
      _mesa_enable_extension(ctx, extensions[i]);
296
   }
297
}
298
 
299
 
300
 
301
/*
302
 * Add a new extenstion.  This would be called from a Mesa driver.
303
 */
304
void
305
_mesa_add_extension( GLcontext *ctx,
306
                     GLboolean enabled,
307
                     const char *name,
308
                     GLboolean *flag_ptr )
309
{
310
   /* We should never try to add an extension after
311
    * _mesa_extensions_get_string() has been called!
312
    */
313
   assert(ctx->Extensions.ext_string == 0);
314
 
315
   {
316
      struct extension *t = MALLOC_STRUCT(extension);
317
      t->enabled = enabled;
318
      _mesa_strncpy(t->name, name, MAX_EXT_NAMELEN);
319
      t->name[MAX_EXT_NAMELEN] = 0;
320
      t->flag = flag_ptr;
321
      if (t->flag)
322
         *t->flag = enabled;
323
      insert_at_tail( ctx->Extensions.ext_list, t );
324
   }
325
}
326
 
327
 
328
/*
329
 * Either enable or disable the named extension.
330
 */
331
static void
332
set_extension( GLcontext *ctx, const char *name, GLint state )
333
{
334
   /* XXX we should assert that ext_string is null.  We should never be
335
    * enabling/disabling extensions after _mesa_extensions_get_string()
336
    * has been called!
337
    */
338
   struct extension *i;
339
   foreach( i, ctx->Extensions.ext_list )
340
      if (_mesa_strncmp(i->name, name, MAX_EXT_NAMELEN) == 0)
341
         break;
342
 
343
   if (i == ctx->Extensions.ext_list) {
344
      /* this is an error.  Drivers should never try to enable/disable
345
       * an extension which is unknown to Mesa or wasn't added by calling
346
       * _mesa_add_extension().
347
       */
348
      return;
349
   }
350
 
351
   if (i->flag)
352
      *(i->flag) = state;
353
   i->enabled = state;
354
}
355
 
356
 
357
 
358
void
359
_mesa_enable_extension( GLcontext *ctx, const char *name )
360
{
361
   if (ctx->Extensions.ext_string == 0)
362
      set_extension( ctx, name, 1 );
363
}
364
 
365
 
366
void
367
_mesa_disable_extension( GLcontext *ctx, const char *name )
368
{
369
   if (ctx->Extensions.ext_string == 0)
370
      set_extension( ctx, name, 0 );
371
}
372
 
373
 
374
/*
375
 * Test if the named extension is enabled in this context.
376
 */
377
GLboolean
378
_mesa_extension_is_enabled( GLcontext *ctx, const char *name)
379
{
380
   struct extension *i;
381
   foreach( i, ctx->Extensions.ext_list )
382
      if (_mesa_strncmp(i->name, name, MAX_EXT_NAMELEN) == 0) {
383
         if (i->enabled)
384
            return GL_TRUE;
385
         else
386
            return GL_FALSE;
387
      }
388
 
389
   return GL_FALSE;
390
}
391
 
392
 
393
void
394
_mesa_extensions_dtr( GLcontext *ctx )
395
{
396
   struct extension *i, *nexti;
397
 
398
   if (ctx->Extensions.ext_string) {
399
      FREE( ctx->Extensions.ext_string );
400
      ctx->Extensions.ext_string = 0;
401
   }
402
 
403
   if (ctx->Extensions.ext_list) {
404
      foreach_s( i, nexti, ctx->Extensions.ext_list ) {
405
         remove_from_list( i );
406
         FREE( i );
407
      }
408
 
409
      FREE(ctx->Extensions.ext_list);
410
      ctx->Extensions.ext_list = 0;
411
   }
412
}
413
 
414
 
415
void
416
_mesa_extensions_ctr( GLcontext *ctx )
417
{
418
   GLuint i;
419
   GLboolean *base = (GLboolean *)&ctx->Extensions;
420
 
421
   ctx->Extensions.ext_string = NULL;
422
   ctx->Extensions.ext_list = MALLOC_STRUCT(extension);
423
   make_empty_list( ctx->Extensions.ext_list );
424
 
425
   for (i = 0 ; i < Elements(default_extensions) ; i++) {
426
      GLboolean *ptr = NULL;
427
 
428
      if (default_extensions[i].flag_offset)
429
         ptr = base + default_extensions[i].flag_offset;
430
 
431
      (void) _mesa_add_extension( ctx,
432
                                  default_extensions[i].enabled,
433
                                  default_extensions[i].name,
434
                                  ptr);
435
   }
436
}
437
 
438
 
439
const char *
440
_mesa_extensions_get_string( GLcontext *ctx )
441
{
442
   if (ctx->Extensions.ext_string == 0)
443
   {
444
      struct extension *i;
445
      char *str;
446
      GLuint len = 0;
447
      foreach (i, ctx->Extensions.ext_list)
448
         if (i->enabled)
449
            len += _mesa_strlen(i->name) + 1;
450
 
451
      if (len == 0)
452
         return "";
453
 
454
      str = (char *) _mesa_malloc(len * sizeof(char));
455
      ctx->Extensions.ext_string = str;
456
 
457
      foreach (i, ctx->Extensions.ext_list)
458
         if (i->enabled) {
459
            _mesa_strcpy(str, i->name);
460
            str += _mesa_strlen(str);
461
            *str++ = ' ';
462
         }
463
 
464
      *(str-1) = 0;
465
   }
466
 
467
   return ctx->Extensions.ext_string;
468
}