*/
static const struct extension extension_table[] = {
/* ARB Extensions */
+ { "GL_ARB_ES2_compatibility", o(ARB_ES2_compatibility), GL },
{ "GL_ARB_blend_func_extended", o(ARB_blend_func_extended), GL },
{ "GL_ARB_copy_buffer", o(ARB_copy_buffer), GL },
{ "GL_ARB_depth_buffer_float", o(ARB_depth_buffer_float), GL },
{ "GL_ARB_depth_clamp", o(ARB_depth_clamp), GL },
{ "GL_ARB_depth_texture", o(ARB_depth_texture), GL },
{ "GL_ARB_draw_buffers", o(ARB_draw_buffers), GL },
+ { "GL_ARB_draw_buffers_blend", o(ARB_draw_buffers_blend), GL },
{ "GL_ARB_draw_elements_base_vertex", o(ARB_draw_elements_base_vertex), GL },
{ "GL_ARB_draw_instanced", o(ARB_draw_instanced), GL },
{ "GL_ARB_explicit_attrib_location", o(ARB_explicit_attrib_location), GL },
{ "GL_ARB_fragment_program_shadow", o(ARB_fragment_program_shadow), GL },
{ "GL_ARB_fragment_shader", o(ARB_fragment_shader), GL },
{ "GL_ARB_framebuffer_object", o(ARB_framebuffer_object), GL },
+ { "GL_ARB_framebuffer_sRGB", o(EXT_framebuffer_sRGB), GL },
{ "GL_ARB_half_float_pixel", o(ARB_half_float_pixel), GL },
{ "GL_ARB_half_float_vertex", o(ARB_half_float_vertex), GL },
{ "GL_ARB_instanced_arrays", o(ARB_instanced_arrays), GL },
{ "GL_EXT_texture_rectangle", o(NV_texture_rectangle), GL },
{ "GL_EXT_texture_shared_exponent", o(EXT_texture_shared_exponent), GL },
{ "GL_EXT_texture_sRGB", o(EXT_texture_sRGB), GL },
+ { "GL_EXT_texture_sRGB_decode", o(EXT_texture_sRGB_decode), GL },
{ "GL_EXT_texture_swizzle", o(EXT_texture_swizzle), GL },
{ "GL_EXT_texture_type_2_10_10_10_REV", o(dummy_true), ES2 },
{ "GL_EXT_timer_query", o(EXT_timer_query), GL },
{ "GL_OES_read_format", o(OES_read_format), GL | ES1 },
{ "GL_OES_rgb8_rgba8", o(EXT_framebuffer_object), ES1 | ES2 },
{ "GL_OES_single_precision", o(dummy_true), ES1 },
- { "GL_OES_standard_derivatives", o(ARB_fragment_shader), ES2 },
+ { "GL_OES_standard_derivatives", o(OES_standard_derivatives), ES2 },
{ "GL_OES_stencil1", o(dummy_false), DISABLE },
{ "GL_OES_stencil4", o(dummy_false), DISABLE },
{ "GL_OES_stencil8", o(EXT_framebuffer_object), ES1 | ES2 },
/* Vendor extensions */
{ "GL_3DFX_texture_compression_FXT1", o(TDFX_texture_compression_FXT1), GL },
+ { "GL_AMD_conservative_depth", o(AMD_conservative_depth), GL },
{ "GL_APPLE_client_storage", o(APPLE_client_storage), GL },
{ "GL_APPLE_object_purgeable", o(APPLE_object_purgeable), GL },
{ "GL_APPLE_packed_pixels", o(APPLE_packed_pixels), GL },
static size_t
name_to_offset(const char* name)
{
+ const struct extension *i;
+
if (name == 0)
return 0;
- for (const struct extension *i = extension_table; i->name != 0; ++i) {
+ for (i = extension_table; i->name != 0; ++i) {
if (strcmp(name, i->name) == 0)
return i->offset;
}
o(EXT_vertex_array),
o(OES_read_format),
+ o(OES_standard_derivatives),
/* Vendor Extensions */
o(APPLE_packed_pixels),
ctx->Extensions.ARB_depth_texture = GL_TRUE;
/*ctx->Extensions.ARB_draw_buffers = GL_TRUE;*/
ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE;
+ ctx->Extensions.ARB_draw_instanced = GL_TRUE;
ctx->Extensions.ARB_explicit_attrib_location = GL_TRUE;
ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
#if FEATURE_ARB_fragment_program
ctx->Extensions.EXT_texture_lod_bias = GL_TRUE;
#if FEATURE_EXT_texture_sRGB
ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
+ ctx->Extensions.EXT_texture_sRGB_decode = GL_TRUE;
#endif
ctx->Extensions.EXT_texture_swizzle = GL_TRUE;
#if FEATURE_EXT_transform_feedback
static GLboolean
set_extension( struct gl_context *ctx, const char *name, GLboolean state )
{
+ size_t offset;
+
if (ctx->Extensions.String) {
/* The string was already queried - can't change it now! */
_mesa_problem(ctx, "Trying to enable/disable extension after glGetString(GL_EXTENSIONS): %s", name);
return GL_FALSE;
}
- size_t offset = name_to_offset(name);
+ offset = name_to_offset(name);
if (offset == 0) {
_mesa_problem(ctx, "Trying to enable/disable unknown extension %s",
name);
GLboolean
_mesa_extension_is_enabled( struct gl_context *ctx, const char *name )
{
+ size_t offset;
+ GLboolean *base;
+
if (name == 0)
return GL_FALSE;
- size_t offset = name_to_offset(name);
+ offset = name_to_offset(name);
if (offset == 0)
return GL_FALSE;
- GLboolean *base = (GLboolean *) &ctx->Extensions;
+ base = (GLboolean *) &ctx->Extensions;
return base[offset];
}
/**
- * Append string 'b' onto string 'a'. Free 'a' and return new string.
- */
-static char *
-append(const char *a, const char *b)
-{
- const GLuint aLen = a ? strlen(a) : 0;
- const GLuint bLen = b ? strlen(b) : 0;
- char *s = calloc(1, aLen + bLen + 1);
- if (s) {
- if (a)
- memcpy(s, a, aLen);
- if (b)
- memcpy(s + aLen, b, bLen);
- s[aLen + bLen] = '\0';
- }
- if (a)
- free((void *) a);
- return s;
-}
-
-
-/**
- * Check the MESA_EXTENSION_OVERRIDE env var.
- * For extension names that are recognized, turn them on. For extension
- * names that are recognized and prefixed with '-', turn them off.
- * Return a string of the unknown/leftover names.
+ * \brief Apply the \c MESA_EXTENSION_OVERRIDE environment variable.
*
- * Returnd string needs to be freed.
+ * \c MESA_EXTENSION_OVERRIDE is a space-separated list of extensions to
+ * enable or disable. The list is processed thus:
+ * - Enable recognized extension names that are prefixed with '+'.
+ * - Disable recognized extension names that are prefixed with '-'.
+ * - Enable recognized extension names that are not prefixed.
+ * - Collect unrecognized extension names in a new string.
+ *
+ * \return Space-separated list of unrecognized extension names (which must
+ * be freed). Does not return \c NULL.
*/
static char *
get_extension_override( struct gl_context *ctx )
{
- const char *envExt = _mesa_getenv("MESA_EXTENSION_OVERRIDE");
- char *extraExt = NULL;
- char ext[1000];
- GLuint extLen = 0;
- GLuint i;
- GLboolean disableExt = GL_FALSE;
-
- if (!envExt)
- return NULL;
+ const char *env_const= _mesa_getenv("MESA_EXTENSION_OVERRIDE");
+ char *env;
+ char *ext;
+ char *extra_exts;
+ int len;
+
+ if (env_const == NULL) {
+ /* Return the empty string rather than NULL. This simplifies the logic
+ * of client functions. */
+ return calloc(1, sizeof(char));
+ }
- for (i = 0; ; i++) {
- if (envExt[i] == '\0' || envExt[i] == ' ') {
- /* terminate/process 'ext' if extLen > 0 */
- if (extLen > 0) {
- assert(extLen < sizeof(ext));
- /* enable extension named by 'ext' */
- ext[extLen] = 0;
- if (!set_extension(ctx, ext, !disableExt)) {
- /* unknown extension name, append it to extraExt */
- if (extraExt) {
- extraExt = append(extraExt, " ");
- }
- extraExt = append(extraExt, ext);
- }
- extLen = 0;
- disableExt = GL_FALSE;
- }
- if (envExt[i] == '\0')
- break;
+ /* extra_exts: List of unrecognized extensions. */
+ extra_exts = calloc(strlen(env_const), sizeof(char));
+
+ /* Copy env_const because strtok() is destructive. */
+ env = strdup(env_const);
+ for (ext = strtok(env, " "); ext != NULL; ext = strtok(NULL, " ")) {
+ int enable;
+ int recognized;
+ switch (ext[0]) {
+ case '+':
+ enable = 1;
+ ++ext;
+ break;
+ case '-':
+ enable = 0;
+ ++ext;
+ break;
+ default:
+ enable = 1;
+ break;
}
- else if (envExt[i] == '-') {
- disableExt = GL_TRUE;
- }
- else {
- /* accumulate this non-space character */
- ext[extLen++] = envExt[i];
+ recognized = set_extension(ctx, ext, enable);
+ if (!recognized) {
+ strcat(extra_exts, ext);
+ strcat(extra_exts, " ");
}
}
- return extraExt;
+ /* Remove trailing space. */
+ len = strlen(extra_exts);
+ if (extra_exts[len - 1] == ' ')
+ extra_exts[len - 1] = '\0';
+
+ return extra_exts;
}
{
GLboolean *base = (GLboolean *) &ctx->Extensions;
GLboolean *sentinel = base + o(extension_sentinel);
+ GLboolean *i;
+ const size_t *j;
/* First, turn all extensions off. */
- for (GLboolean *i = base; i != sentinel; ++i)
+ for (i = base; i != sentinel; ++i)
*i = GL_FALSE;
/* Then, selectively turn default extensions on. */
ctx->Extensions.dummy_true = GL_TRUE;
- for (const size_t *i = default_extensions; *i != 0; ++i)
- base[*i] = GL_TRUE;
+ for (j = default_extensions; *j != 0; ++j)
+ base[*j] = GL_TRUE;
}
/* String of extra extensions. */
char *extra_extensions = get_extension_override(ctx);
GLboolean *base = (GLboolean *) &ctx->Extensions;
+ const struct extension *i;
/* Compute length of the extension string. */
- for (const struct extension *i = extension_table; i->name != 0; ++i) {
+ for (i = extension_table; i->name != 0; ++i) {
if (base[i->offset] && (i->api_set & (1 << ctx->API))) {
length += strlen(i->name) + 1; /* +1 for space */
}
}
/* Build the extension string.*/
- for (const struct extension *i = extension_table; i->name != 0; ++i) {
+ for (i = extension_table; i->name != 0; ++i) {
if (base[i->offset] && (i->api_set & (1 << ctx->API))) {
strcat(exts, i->name);
strcat(exts, " ");
GLuint
_mesa_get_extension_count(struct gl_context *ctx)
{
+ GLboolean *base;
+ const struct extension *i;
+
/* only count once */
if (ctx->Extensions.Count != 0)
return ctx->Extensions.Count;
- GLboolean *base = (GLboolean *) &ctx->Extensions;
- for (const struct extension *i = extension_table; i->name != 0; ++i) {
+ base = (GLboolean *) &ctx->Extensions;
+ for (i = extension_table; i->name != 0; ++i) {
if (base[i->offset]) {
ctx->Extensions.Count++;
}
const GLubyte *
_mesa_get_enabled_extension(struct gl_context *ctx, GLuint index)
{
+ const GLboolean *base;
+ size_t n;
+ const struct extension *i;
+
if (index < 0)
return NULL;
- const GLboolean *base = (GLboolean*) &ctx->Extensions;
- size_t n = 0;
- for (const struct extension *i = extension_table; i->name != 0; ++i) {
+ base = (GLboolean*) &ctx->Extensions;
+ n = 0;
+ for (i = extension_table; i->name != 0; ++i) {
if (n == index && base[i->offset]) {
return (GLubyte*) i->name;
} else if (base[i->offset]) {