[Mesa-dev] [PATCH v2] glsl: reuse main extension table to appropriate restrict extensions

Ilia Mirkin imirkin at alum.mit.edu
Wed Jun 22 15:28:11 UTC 2016


Urgh, just realized that I also need to teach glcpp about this stuff,
otherwise we can end up with e.g. GL_ARB_gpu_shader5 defined but not
enableable in a compat context. Also a discussion with Jakob on IRC
pointed out that we currently allow GL_ARB_gpu_shader5 to be enabled
in compat contexts, but with this patch, this will no longer be
allowed. IMHO this is correct, but just wanted to point it out. Will
send a v3 that accounts for glcpp later in the week probably.

On Tue, Jun 21, 2016 at 2:24 PM, Ilia Mirkin <imirkin at alum.mit.edu> wrote:
> Ping? I got a R-b from Eric Engestrom (thanks!) but I was hoping some
> more experienced Mesa contributors could give this a look and see if
> this makes sense or if I'm still missing some crucial bits.
>
> On Mon, Jun 13, 2016 at 11:43 PM, Ilia Mirkin <imirkin at alum.mit.edu> wrote:
>> Previously we were only restricting based on ES/non-ES-ness and whether
>> the overall enable bit had been flipped on. However we have been adding
>> more fine-grained restrictions, such as based on compat profiles, as
>> well as specific ES versions. Most of the time this doesn't matter, but
>> it can create awkward situations and duplication of logic.
>>
>> Here we separate the main extension table into a separate object file,
>> linked to the glsl compiler, which makes use of it with a custom
>> function which takes the ES-ness of the shader into account (thus
>> allowing desktop shaders to properly use ES extensions that would
>> otherwise have been disallowed.)
>>
>> The effect of this change should be nil in most cases.
>>
>> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
>> ---
>>
>> v1 -> v2:
>>  - use a final enum to obtain number of extensions
>>  - move calculation of the gl version to be once per shader, for better reuse
>>  - bake GL version into the "supported_versions" struct
>>  - while we're at it, fix supported_versions size, it was off by 1 since ES 3.20
>>    "support" was added.
>>
>>  src/Makefile.am                          |   1 +
>>  src/compiler/SConscript.glsl             |   2 +
>>  src/compiler/glsl/glsl_parser_extras.cpp | 244 +++++++++++++++----------------
>>  src/compiler/glsl/glsl_parser_extras.h   |   4 +-
>>  src/mesa/Android.libmesa_glsl_utils.mk   |   2 +
>>  src/mesa/Makefile.sources                |   1 +
>>  src/mesa/main/extensions.c               |  33 +----
>>  src/mesa/main/extensions.h               |   1 +
>>  src/mesa/main/extensions_table.c         |  51 +++++++
>>  9 files changed, 190 insertions(+), 149 deletions(-)
>>  create mode 100644 src/mesa/main/extensions_table.c
>>
>> diff --git a/src/Makefile.am b/src/Makefile.am
>> index 32372da..d38f7c4 100644
>> --- a/src/Makefile.am
>> +++ b/src/Makefile.am
>> @@ -114,6 +114,7 @@ AM_CPPFLAGS = \
>>  noinst_LTLIBRARIES = libglsl_util.la
>>
>>  libglsl_util_la_SOURCES = \
>> +       mesa/main/extensions_table.c \
>>         mesa/main/imports.c \
>>         mesa/program/prog_hash_table.c \
>>         mesa/program/symbol_table.c \
>> diff --git a/src/compiler/SConscript.glsl b/src/compiler/SConscript.glsl
>> index 4252ce1..31d8f6d 100644
>> --- a/src/compiler/SConscript.glsl
>> +++ b/src/compiler/SConscript.glsl
>> @@ -70,6 +70,7 @@ if env['msvc']:
>>  # Copy these files to avoid generation object files into src/mesa/program
>>  env.Prepend(CPPPATH = ['#src/mesa/main'])
>>  env.Command('glsl/imports.c', '#src/mesa/main/imports.c', Copy('$TARGET', '$SOURCE'))
>> +env.Command('glsl/extensions_table.c', '#src/mesa/main/extensions_table.c', Copy('$TARGET', '$SOURCE'))
>>  # Copy these files to avoid generation object files into src/mesa/program
>>  env.Prepend(CPPPATH = ['#src/mesa/program'])
>>  env.Command('glsl/prog_hash_table.c', '#src/mesa/program/prog_hash_table.c', Copy('$TARGET', '$SOURCE'))
>> @@ -79,6 +80,7 @@ env.Command('glsl/dummy_errors.c', '#src/mesa/program/dummy_errors.c', Copy('$TA
>>  compiler_objs = env.StaticObject(source_lists['GLSL_COMPILER_CXX_FILES'])
>>
>>  mesa_objs = env.StaticObject([
>> +    'glsl/extensions_table.c',
>>      'glsl/imports.c',
>>      'glsl/prog_hash_table.c',
>>      'glsl/symbol_table.c',
>> diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp
>> index ce2c3e8..0e9f152 100644
>> --- a/src/compiler/glsl/glsl_parser_extras.cpp
>> +++ b/src/compiler/glsl/glsl_parser_extras.cpp
>> @@ -50,6 +50,8 @@ glsl_compute_version_string(void *mem_ctx, bool is_es, unsigned version)
>>
>>  static const unsigned known_desktop_glsl_versions[] =
>>     { 110, 120, 130, 140, 150, 330, 400, 410, 420, 430, 440, 450 };
>> +static const unsigned known_desktop_gl_versions[] =
>> +   {  20,  21,  30,  31,  32,  33,  40,  41,  42,  43,  44,  45 };
>>
>>
>>  _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
>> @@ -74,6 +76,7 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
>>     /* Set default language version and extensions */
>>     this->language_version = 110;
>>     this->forced_language_version = ctx->Const.ForceGLSLVersion;
>> +   this->gl_version = 20;
>>     this->es_shader = false;
>>     this->ARB_texture_rectangle_enable = true;
>>
>> @@ -194,9 +197,9 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
>>     this->subroutine_types = NULL;
>>
>>     /* supported_versions should be large enough to support the known desktop
>> -    * GLSL versions plus 3 GLES versions (ES 1.00, ES 3.00, and ES 3.10))
>> +    * GLSL versions plus 4 GLES versions (ES 1.00, ES 3.00, ES 3.10, ES 3.20)
>>      */
>> -   STATIC_ASSERT((ARRAY_SIZE(known_desktop_glsl_versions) + 3) ==
>> +   STATIC_ASSERT((ARRAY_SIZE(known_desktop_glsl_versions) + 4) ==
>>                   ARRAY_SIZE(this->supported_versions));
>>
>>     /* Populate the list of supported GLSL versions */
>> @@ -211,6 +214,8 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
>>           if (known_desktop_glsl_versions[i] <= ctx->Const.GLSLVersion) {
>>              this->supported_versions[this->num_supported_versions].ver
>>                 = known_desktop_glsl_versions[i];
>> +            this->supported_versions[this->num_supported_versions].gl_ver
>> +               = known_desktop_gl_versions[i];
>>              this->supported_versions[this->num_supported_versions].es = false;
>>              this->num_supported_versions++;
>>           }
>> @@ -218,22 +223,26 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
>>     }
>>     if (ctx->API == API_OPENGLES2 || ctx->Extensions.ARB_ES2_compatibility) {
>>        this->supported_versions[this->num_supported_versions].ver = 100;
>> +      this->supported_versions[this->num_supported_versions].gl_ver = 20;
>>        this->supported_versions[this->num_supported_versions].es = true;
>>        this->num_supported_versions++;
>>     }
>>     if (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility) {
>>        this->supported_versions[this->num_supported_versions].ver = 300;
>> +      this->supported_versions[this->num_supported_versions].gl_ver = 30;
>>        this->supported_versions[this->num_supported_versions].es = true;
>>        this->num_supported_versions++;
>>     }
>>     if (_mesa_is_gles31(ctx) || ctx->Extensions.ARB_ES3_1_compatibility) {
>>        this->supported_versions[this->num_supported_versions].ver = 310;
>> +      this->supported_versions[this->num_supported_versions].gl_ver = 31;
>>        this->supported_versions[this->num_supported_versions].es = true;
>>        this->num_supported_versions++;
>>     }
>>     if ((ctx->API == API_OPENGLES2 && ctx->Version >= 32) ||
>>         ctx->Extensions.ARB_ES3_2_compatibility) {
>>        this->supported_versions[this->num_supported_versions].ver = 320;
>> +      this->supported_versions[this->num_supported_versions].gl_ver = 32;
>>        this->supported_versions[this->num_supported_versions].es = true;
>>        this->num_supported_versions++;
>>     }
>> @@ -398,6 +407,7 @@ _mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version,
>>     for (unsigned i = 0; i < this->num_supported_versions; i++) {
>>        if (this->supported_versions[i].ver == this->language_version
>>            && this->supported_versions[i].es == this->es_shader) {
>> +         this->gl_version = this->supported_versions[i].gl_ver;
>>           supported = true;
>>           break;
>>        }
>> @@ -510,28 +520,12 @@ struct _mesa_glsl_extension {
>>      */
>>     const char *name;
>>
>> -   /** True if this extension is available to desktop GL shaders */
>> -   bool avail_in_GL;
>> -
>> -   /** True if this extension is available to GLES shaders */
>> -   bool avail_in_ES;
>> -
>>     /**
>> -    * Flag in the gl_extensions struct indicating whether this
>> -    * extension is supported by the driver, or
>> -    * &gl_extensions::dummy_true if supported by all drivers.
>> -    *
>> -    * Note: the type (GLboolean gl_extensions::*) is a "pointer to
>> -    * member" type, the type-safe alternative to the "offsetof" macro.
>> -    * In a nutshell:
>> -    *
>> -    * - foo bar::* p declares p to be an "offset" to a field of type
>> -    *   foo that exists within struct bar
>> -    * - &bar::baz computes the "offset" of field baz within struct bar
>> -    * - x.*p accesses the field of x that exists at "offset" p
>> -    * - x->*p is equivalent to (*x).*p
>> +    * Predicate that checks whether the relevant extension is available for
>> +    * this context.
>>      */
>> -   const GLboolean gl_extensions::* supported_flag;
>> +   bool (*available_pred)(const struct gl_context *,
>> +                          gl_api api, uint8_t version);
>>
>>     /**
>>      * Flag in the _mesa_glsl_parse_state struct that should be set
>> @@ -552,12 +546,24 @@ struct _mesa_glsl_extension {
>>     bool _mesa_glsl_parse_state::* warn_flag;
>>
>>
>> -   bool compatible_with_state(const _mesa_glsl_parse_state *state) const;
>> +   bool compatible_with_state(const _mesa_glsl_parse_state *state,
>> +                              gl_api api, uint8_t gl_version) const;
>>     void set_flags(_mesa_glsl_parse_state *state, ext_behavior behavior) const;
>>  };
>>
>> -#define EXT(NAME, GL, ES, SUPPORTED_FLAG)                   \
>> -   { "GL_" #NAME, GL, ES, &gl_extensions::SUPPORTED_FLAG,   \
>> +/** Checks if the context supports a user-facing extension */
>> +#define EXT(name_str, driver_cap, ...) \
>> +static MAYBE_UNUSED bool \
>> +has_##name_str(const struct gl_context *ctx, gl_api api, uint8_t version) \
>> +{ \
>> +   return ctx->Extensions.driver_cap && (version >= \
>> +          _mesa_extension_table[MESA_EXTENSION_##name_str].version[api]); \
>> +}
>> +#include "main/extensions_table.h"
>> +#undef EXT
>> +
>> +#define EXT(NAME)                                           \
>> +   { "GL_" #NAME, has_##NAME,                         \
>>           &_mesa_glsl_parse_state::NAME##_enable,            \
>>           &_mesa_glsl_parse_state::NAME##_warn }
>>
>> @@ -566,93 +572,90 @@ struct _mesa_glsl_extension {
>>   * and the conditions under which they are supported.
>>   */
>>  static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
>> -   /*                                  API availability */
>> -   /* name                             GL     ES         supported flag */
>> -
>>     /* ARB extensions go here, sorted alphabetically.
>>      */
>> -   EXT(ARB_ES3_1_compatibility,          true,  false,     ARB_ES3_1_compatibility),
>> -   EXT(ARB_ES3_2_compatibility,          true,  false,     ARB_ES3_2_compatibility),
>> -   EXT(ARB_arrays_of_arrays,             true,  false,     ARB_arrays_of_arrays),
>> -   EXT(ARB_compute_shader,               true,  false,     ARB_compute_shader),
>> -   EXT(ARB_conservative_depth,           true,  false,     ARB_conservative_depth),
>> -   EXT(ARB_cull_distance,                true,  false,     ARB_cull_distance),
>> -   EXT(ARB_derivative_control,           true,  false,     ARB_derivative_control),
>> -   EXT(ARB_draw_buffers,                 true,  false,     dummy_true),
>> -   EXT(ARB_draw_instanced,               true,  false,     ARB_draw_instanced),
>> -   EXT(ARB_enhanced_layouts,             true,  false,     ARB_enhanced_layouts),
>> -   EXT(ARB_explicit_attrib_location,     true,  false,     ARB_explicit_attrib_location),
>> -   EXT(ARB_explicit_uniform_location,    true,  false,     ARB_explicit_uniform_location),
>> -   EXT(ARB_fragment_coord_conventions,   true,  false,     ARB_fragment_coord_conventions),
>> -   EXT(ARB_fragment_layer_viewport,      true,  false,     ARB_fragment_layer_viewport),
>> -   EXT(ARB_gpu_shader5,                  true,  false,     ARB_gpu_shader5),
>> -   EXT(ARB_gpu_shader_fp64,              true,  false,     ARB_gpu_shader_fp64),
>> -   EXT(ARB_sample_shading,               true,  false,     ARB_sample_shading),
>> -   EXT(ARB_separate_shader_objects,      true,  false,     dummy_true),
>> -   EXT(ARB_shader_atomic_counter_ops,    true,  false,     ARB_shader_atomic_counter_ops),
>> -   EXT(ARB_shader_atomic_counters,       true,  false,     ARB_shader_atomic_counters),
>> -   EXT(ARB_shader_bit_encoding,          true,  false,     ARB_shader_bit_encoding),
>> -   EXT(ARB_shader_clock,                 true,  false,     ARB_shader_clock),
>> -   EXT(ARB_shader_draw_parameters,       true,  false,     ARB_shader_draw_parameters),
>> -   EXT(ARB_shader_group_vote,            true,  false,     ARB_shader_group_vote),
>> -   EXT(ARB_shader_image_load_store,      true,  false,     ARB_shader_image_load_store),
>> -   EXT(ARB_shader_image_size,            true,  false,     ARB_shader_image_size),
>> -   EXT(ARB_shader_precision,             true,  false,     ARB_shader_precision),
>> -   EXT(ARB_shader_stencil_export,        true,  false,     ARB_shader_stencil_export),
>> -   EXT(ARB_shader_storage_buffer_object, true,  true,      ARB_shader_storage_buffer_object),
>> -   EXT(ARB_shader_subroutine,            true,  false,     ARB_shader_subroutine),
>> -   EXT(ARB_shader_texture_image_samples, true,  false,     ARB_shader_texture_image_samples),
>> -   EXT(ARB_shader_texture_lod,           true,  false,     ARB_shader_texture_lod),
>> -   EXT(ARB_shading_language_420pack,     true,  false,     ARB_shading_language_420pack),
>> -   EXT(ARB_shading_language_packing,     true,  false,     ARB_shading_language_packing),
>> -   EXT(ARB_tessellation_shader,          true,  false,     ARB_tessellation_shader),
>> -   EXT(ARB_texture_cube_map_array,       true,  false,     ARB_texture_cube_map_array),
>> -   EXT(ARB_texture_gather,               true,  false,     ARB_texture_gather),
>> -   EXT(ARB_texture_multisample,          true,  false,     ARB_texture_multisample),
>> -   EXT(ARB_texture_query_levels,         true,  false,     ARB_texture_query_levels),
>> -   EXT(ARB_texture_query_lod,            true,  false,     ARB_texture_query_lod),
>> -   EXT(ARB_texture_rectangle,            true,  false,     dummy_true),
>> -   EXT(ARB_uniform_buffer_object,        true,  false,     ARB_uniform_buffer_object),
>> -   EXT(ARB_vertex_attrib_64bit,          true,  false,     ARB_vertex_attrib_64bit),
>> -   EXT(ARB_viewport_array,               true,  false,     ARB_viewport_array),
>> +   EXT(ARB_ES3_1_compatibility),
>> +   EXT(ARB_ES3_2_compatibility),
>> +   EXT(ARB_arrays_of_arrays),
>> +   EXT(ARB_compute_shader),
>> +   EXT(ARB_conservative_depth),
>> +   EXT(ARB_cull_distance),
>> +   EXT(ARB_derivative_control),
>> +   EXT(ARB_draw_buffers),
>> +   EXT(ARB_draw_instanced),
>> +   EXT(ARB_enhanced_layouts),
>> +   EXT(ARB_explicit_attrib_location),
>> +   EXT(ARB_explicit_uniform_location),
>> +   EXT(ARB_fragment_coord_conventions),
>> +   EXT(ARB_fragment_layer_viewport),
>> +   EXT(ARB_gpu_shader5),
>> +   EXT(ARB_gpu_shader_fp64),
>> +   EXT(ARB_sample_shading),
>> +   EXT(ARB_separate_shader_objects),
>> +   EXT(ARB_shader_atomic_counter_ops),
>> +   EXT(ARB_shader_atomic_counters),
>> +   EXT(ARB_shader_bit_encoding),
>> +   EXT(ARB_shader_clock),
>> +   EXT(ARB_shader_draw_parameters),
>> +   EXT(ARB_shader_group_vote),
>> +   EXT(ARB_shader_image_load_store),
>> +   EXT(ARB_shader_image_size),
>> +   EXT(ARB_shader_precision),
>> +   EXT(ARB_shader_stencil_export),
>> +   EXT(ARB_shader_storage_buffer_object),
>> +   EXT(ARB_shader_subroutine),
>> +   EXT(ARB_shader_texture_image_samples),
>> +   EXT(ARB_shader_texture_lod),
>> +   EXT(ARB_shading_language_420pack),
>> +   EXT(ARB_shading_language_packing),
>> +   EXT(ARB_tessellation_shader),
>> +   EXT(ARB_texture_cube_map_array),
>> +   EXT(ARB_texture_gather),
>> +   EXT(ARB_texture_multisample),
>> +   EXT(ARB_texture_query_levels),
>> +   EXT(ARB_texture_query_lod),
>> +   EXT(ARB_texture_rectangle),
>> +   EXT(ARB_uniform_buffer_object),
>> +   EXT(ARB_vertex_attrib_64bit),
>> +   EXT(ARB_viewport_array),
>>
>>     /* KHR extensions go here, sorted alphabetically.
>>      */
>>
>>     /* OES extensions go here, sorted alphabetically.
>>      */
>> -   EXT(OES_EGL_image_external,         false, true,      OES_EGL_image_external),
>> -   EXT(OES_geometry_point_size,        false, true,      OES_geometry_shader),
>> -   EXT(OES_geometry_shader,            false, true,      OES_geometry_shader),
>> -   EXT(OES_gpu_shader5,                false, true,      ARB_gpu_shader5),
>> -   EXT(OES_primitive_bounding_box,     false, true,      OES_primitive_bounding_box),
>> -   EXT(OES_sample_variables,           false, true,      OES_sample_variables),
>> -   EXT(OES_shader_image_atomic,        false, true,      ARB_shader_image_load_store),
>> -   EXT(OES_shader_io_blocks,           false, true,      OES_shader_io_blocks),
>> -   EXT(OES_shader_multisample_interpolation, false, true, OES_sample_variables),
>> -   EXT(OES_standard_derivatives,       false, true,      OES_standard_derivatives),
>> -   EXT(OES_texture_3D,                 false, true,      dummy_true),
>> -   EXT(OES_texture_buffer,             false, true,      OES_texture_buffer),
>> -   EXT(OES_texture_storage_multisample_2d_array, false, true, ARB_texture_multisample),
>> +   EXT(OES_EGL_image_external),
>> +   EXT(OES_geometry_point_size),
>> +   EXT(OES_geometry_shader),
>> +   EXT(OES_gpu_shader5),
>> +   EXT(OES_primitive_bounding_box),
>> +   EXT(OES_sample_variables),
>> +   EXT(OES_shader_image_atomic),
>> +   EXT(OES_shader_io_blocks),
>> +   EXT(OES_shader_multisample_interpolation),
>> +   EXT(OES_standard_derivatives),
>> +   EXT(OES_texture_3D),
>> +   EXT(OES_texture_buffer),
>> +   EXT(OES_texture_storage_multisample_2d_array),
>>
>>     /* All other extensions go here, sorted alphabetically.
>>      */
>> -   EXT(AMD_conservative_depth,         true,  false,     ARB_conservative_depth),
>> -   EXT(AMD_shader_stencil_export,      true,  false,     ARB_shader_stencil_export),
>> -   EXT(AMD_shader_trinary_minmax,      true,  false,     dummy_true),
>> -   EXT(AMD_vertex_shader_layer,        true,  false,     AMD_vertex_shader_layer),
>> -   EXT(AMD_vertex_shader_viewport_index, true,  false,   AMD_vertex_shader_viewport_index),
>> -   EXT(EXT_blend_func_extended,        false,  true,     ARB_blend_func_extended),
>> -   EXT(EXT_draw_buffers,               false,  true,     dummy_true),
>> -   EXT(EXT_clip_cull_distance,         false, true,      ARB_cull_distance),
>> -   EXT(EXT_gpu_shader5,                false, true,      ARB_gpu_shader5),
>> -   EXT(EXT_primitive_bounding_box,     false, true,      OES_primitive_bounding_box),
>> -   EXT(EXT_separate_shader_objects,    false, true,      dummy_true),
>> -   EXT(EXT_shader_integer_mix,         true,  true,      EXT_shader_integer_mix),
>> -   EXT(EXT_shader_io_blocks,           false, true,      OES_shader_io_blocks),
>> -   EXT(EXT_shader_samples_identical,   true,  true,      EXT_shader_samples_identical),
>> -   EXT(EXT_texture_array,              true,  false,     EXT_texture_array),
>> -   EXT(EXT_texture_buffer,             false, true,      OES_texture_buffer),
>> +   EXT(AMD_conservative_depth),
>> +   EXT(AMD_shader_stencil_export),
>> +   EXT(AMD_shader_trinary_minmax),
>> +   EXT(AMD_vertex_shader_layer),
>> +   EXT(AMD_vertex_shader_viewport_index),
>> +   EXT(EXT_blend_func_extended),
>> +   EXT(EXT_draw_buffers),
>> +   EXT(EXT_clip_cull_distance),
>> +   EXT(EXT_gpu_shader5),
>> +   EXT(EXT_primitive_bounding_box),
>> +   EXT(EXT_separate_shader_objects),
>> +   EXT(EXT_shader_integer_mix),
>> +   EXT(EXT_shader_io_blocks),
>> +   EXT(EXT_shader_samples_identical),
>> +   EXT(EXT_texture_array),
>> +   EXT(EXT_texture_buffer),
>>  };
>>
>>  #undef EXT
>> @@ -662,26 +665,10 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
>>   * Determine whether a given extension is compatible with the target,
>>   * API, and extension information in the current parser state.
>>   */
>> -bool _mesa_glsl_extension::compatible_with_state(const _mesa_glsl_parse_state *
>> -                                                 state) const
>> +bool _mesa_glsl_extension::compatible_with_state(
>> +      const _mesa_glsl_parse_state *state, gl_api api, uint8_t gl_version) const
>>  {
>> -   /* Check that this extension matches whether we are compiling
>> -    * for desktop GL or GLES.
>> -    */
>> -   if (state->es_shader) {
>> -      if (!this->avail_in_ES) return false;
>> -   } else {
>> -      if (!this->avail_in_GL) return false;
>> -   }
>> -
>> -   /* Check that this extension is supported by the OpenGL
>> -    * implementation.
>> -    *
>> -    * Note: the ->* operator indexes into state->extensions by the
>> -    * offset this->supported_flag.  See
>> -    * _mesa_glsl_extension::supported_flag for more info.
>> -    */
>> -   return state->extensions->*(this->supported_flag);
>> +   return this->available_pred(state->ctx, api, gl_version);
>>  }
>>
>>  /**
>> @@ -719,6 +706,8 @@ _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
>>                              const char *behavior_string, YYLTYPE *behavior_locp,
>>                              _mesa_glsl_parse_state *state)
>>  {
>> +   uint8_t gl_version = state->ctx->Extensions.Version;
>> +   gl_api api = state->ctx->API;
>>     ext_behavior behavior;
>>     if (strcmp(behavior_string, "warn") == 0) {
>>        behavior = extension_warn;
>> @@ -735,6 +724,17 @@ _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
>>        return false;
>>     }
>>
>> +   /* If we're in a desktop context but with an ES shader, use an ES API enum
>> +    * to verify extension availability.
>> +    */
>> +   if (state->es_shader && api != API_OPENGLES2)
>> +      api = API_OPENGLES2;
>> +   /* Use the language-version derived GL version to extension checks, unless
>> +    * we're using meta, which sets the version to the max.
>> +    */
>> +   if (gl_version != 0xff)
>> +      gl_version = state->gl_version;
>> +
>>     if (strcmp(name, "all") == 0) {
>>        if ((behavior == extension_enable) || (behavior == extension_require)) {
>>          _mesa_glsl_error(name_locp, state, "cannot %s all extensions",
>> @@ -746,14 +746,14 @@ _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
>>                i < ARRAY_SIZE(_mesa_glsl_supported_extensions); ++i) {
>>              const _mesa_glsl_extension *extension
>>                 = &_mesa_glsl_supported_extensions[i];
>> -            if (extension->compatible_with_state(state)) {
>> +            if (extension->compatible_with_state(state, api, gl_version)) {
>>                 _mesa_glsl_supported_extensions[i].set_flags(state, behavior);
>>              }
>>           }
>>        }
>>     } else {
>>        const _mesa_glsl_extension *extension = find_extension(name);
>> -      if (extension && extension->compatible_with_state(state)) {
>> +      if (extension && extension->compatible_with_state(state, api, gl_version)) {
>>           extension->set_flags(state, behavior);
>>        } else {
>>           static const char fmt[] = "extension `%s' unsupported in %s shader";
>> diff --git a/src/compiler/glsl/glsl_parser_extras.h b/src/compiler/glsl/glsl_parser_extras.h
>> index 622a809..4cfc8af 100644
>> --- a/src/compiler/glsl/glsl_parser_extras.h
>> +++ b/src/compiler/glsl/glsl_parser_extras.h
>> @@ -300,12 +300,14 @@ struct _mesa_glsl_parse_state {
>>     unsigned num_supported_versions;
>>     struct {
>>        unsigned ver;
>> +      uint8_t gl_ver;
>>        bool es;
>> -   } supported_versions[15];
>> +   } supported_versions[16];
>>
>>     bool es_shader;
>>     unsigned language_version;
>>     unsigned forced_language_version;
>> +   unsigned gl_version;
>>     gl_shader_stage stage;
>>
>>     /**
>> diff --git a/src/mesa/Android.libmesa_glsl_utils.mk b/src/mesa/Android.libmesa_glsl_utils.mk
>> index 5a80f22..dfea801 100644
>> --- a/src/mesa/Android.libmesa_glsl_utils.mk
>> +++ b/src/mesa/Android.libmesa_glsl_utils.mk
>> @@ -42,6 +42,7 @@ LOCAL_C_INCLUDES := \
>>         $(MESA_TOP)/src/gallium/auxiliary
>>
>>  LOCAL_SRC_FILES := \
>> +       main/extensions_table.c \
>>         main/imports.c \
>>         program/prog_hash_table.c \
>>         program/symbol_table.c \
>> @@ -67,6 +68,7 @@ LOCAL_C_INCLUDES := \
>>         $(MESA_TOP)/src/gallium/auxiliary
>>
>>  LOCAL_SRC_FILES := \
>> +       main/extensions_table.c \
>>         main/imports.c \
>>         program/prog_hash_table.c \
>>         program/symbol_table.c \
>> diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources
>> index bc5133c..6435a64 100644
>> --- a/src/mesa/Makefile.sources
>> +++ b/src/mesa/Makefile.sources
>> @@ -81,6 +81,7 @@ MAIN_FILES = \
>>         main/execmem.c \
>>         main/extensions.c \
>>         main/extensions.h \
>> +       main/extensions_table.c \
>>         main/extensions_table.h \
>>         main/fbobject.c \
>>         main/fbobject.h \
>> diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
>> index fa50cb6..62a7316 100644
>> --- a/src/mesa/main/extensions.c
>> +++ b/src/mesa/main/extensions.c
>> @@ -48,26 +48,7 @@ static char *extra_extensions = NULL;
>>   */
>>  #define o(x) offsetof(struct gl_extensions, x)
>>
>> -
>> -/**
>> - * \brief Table of supported OpenGL extensions for all API's.
>> - */
>> -const struct mesa_extension _mesa_extension_table[] = {
>> -#define EXT(name_str, driver_cap, gll_ver, glc_ver, gles_ver, gles2_ver, yyyy) \
>> -        { .name = "GL_" #name_str, .offset = o(driver_cap), \
>> -          .version = { \
>> -            [API_OPENGL_COMPAT] = gll_ver, \
>> -            [API_OPENGL_CORE]   = glc_ver, \
>> -            [API_OPENGLES]      = gles_ver, \
>> -            [API_OPENGLES2]     = gles2_ver, \
>> -           }, \
>> -           .year = yyyy \
>> -        },
>> -#include "extensions_table.h"
>> -#undef EXT
>> -};
>> -
>> -static bool disabled_extensions[ARRAY_SIZE(_mesa_extension_table)];
>> +static bool disabled_extensions[MESA_EXTENSION_COUNT];
>>
>>  /**
>>   * Given an extension name, lookup up the corresponding member of struct
>> @@ -85,7 +66,7 @@ name_to_index(const char* name)
>>     if (name == 0)
>>        return -1;
>>
>> -   for (i = 0; i < ARRAY_SIZE(_mesa_extension_table); ++i) {
>> +   for (i = 0; i < MESA_EXTENSION_COUNT; ++i) {
>>        if (strcmp(name, _mesa_extension_table[i].name) == 0)
>>          return i;
>>     }
>> @@ -107,7 +88,7 @@ override_extensions_in_context(struct gl_context *ctx)
>>        (GLboolean*) &_mesa_extension_override_disables;
>>     GLboolean *ctx_ext = (GLboolean*)&ctx->Extensions;
>>
>> -   for (i = 0; i < ARRAY_SIZE(_mesa_extension_table); ++i) {
>> +   for (i = 0; i < MESA_EXTENSION_COUNT; ++i) {
>>        size_t offset = _mesa_extension_table[i].offset;
>>
>>        assert(!enables[offset] || !disables[offset]);
>> @@ -447,7 +428,7 @@ _mesa_make_extension_string(struct gl_context *ctx)
>>
>>     /* Compute length of the extension string. */
>>     count = 0;
>> -   for (k = 0; k < ARRAY_SIZE(_mesa_extension_table); ++k) {
>> +   for (k = 0; k < MESA_EXTENSION_COUNT; ++k) {
>>        const struct mesa_extension *i = _mesa_extension_table + k;
>>
>>        if (i->year <= maxYear &&
>> @@ -478,7 +459,7 @@ _mesa_make_extension_string(struct gl_context *ctx)
>>      * expect will fit into that buffer.
>>      */
>>     j = 0;
>> -   for (k = 0; k < ARRAY_SIZE(_mesa_extension_table); ++k) {
>> +   for (k = 0; k < MESA_EXTENSION_COUNT; ++k) {
>>        if (_mesa_extension_table[k].year <= maxYear &&
>>           _mesa_extension_supported(ctx, k)) {
>>           extension_indices[j++] = k;
>> @@ -516,7 +497,7 @@ _mesa_get_extension_count(struct gl_context *ctx)
>>     if (ctx->Extensions.Count != 0)
>>        return ctx->Extensions.Count;
>>
>> -   for (k = 0; k < ARRAY_SIZE(_mesa_extension_table); ++k) {
>> +   for (k = 0; k < MESA_EXTENSION_COUNT; ++k) {
>>        if (_mesa_extension_supported(ctx, k))
>>          ctx->Extensions.Count++;
>>     }
>> @@ -532,7 +513,7 @@ _mesa_get_enabled_extension(struct gl_context *ctx, GLuint index)
>>     size_t n = 0;
>>     unsigned i;
>>
>> -   for (i = 0; i < ARRAY_SIZE(_mesa_extension_table); ++i) {
>> +   for (i = 0; i < MESA_EXTENSION_COUNT; ++i) {
>>        if (_mesa_extension_supported(ctx, i)) {
>>           if (n == index)
>>              return (const GLubyte*) _mesa_extension_table[i].name;
>> diff --git a/src/mesa/main/extensions.h b/src/mesa/main/extensions.h
>> index 43ef6aa..efef1be 100644
>> --- a/src/mesa/main/extensions.h
>> +++ b/src/mesa/main/extensions.h
>> @@ -89,6 +89,7 @@ enum {
>>  #define EXT(name_str, ...) MESA_EXTENSION_##name_str,
>>  #include "extensions_table.h"
>>  #undef EXT
>> +MESA_EXTENSION_COUNT
>>  };
>>
>>
>> diff --git a/src/mesa/main/extensions_table.c b/src/mesa/main/extensions_table.c
>> new file mode 100644
>> index 0000000..1e37fbc
>> --- /dev/null
>> +++ b/src/mesa/main/extensions_table.c
>> @@ -0,0 +1,51 @@
>> +/*
>> + * Mesa 3-D graphics library
>> + *
>> + * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
>> + * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
>> + *
>> + * Permission is hereby granted, free of charge, to any person obtaining a
>> + * copy of this software and associated documentation files (the "Software"),
>> + * to deal in the Software without restriction, including without limitation
>> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
>> + * and/or sell copies of the Software, and to permit persons to whom the
>> + * Software is furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice shall be included
>> + * in all copies or substantial portions of the Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
>> + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
>> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
>> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>> + * OTHER DEALINGS IN THE SOFTWARE.
>> + */
>> +
>> +#include "main/mtypes.h"
>> +#include "main/extensions.h"
>> +
>> +/**
>> + * Given a member \c x of struct gl_extensions, return offset of
>> + * \c x in bytes.
>> + */
>> +#define o(x) offsetof(struct gl_extensions, x)
>> +
>> +/**
>> + * \brief Table of supported OpenGL extensions for all API's.
>> + */
>> +const struct mesa_extension _mesa_extension_table[] = {
>> +#define EXT(name_str, driver_cap, gll_ver, glc_ver, gles_ver, gles2_ver, yyyy) \
>> +        { .name = "GL_" #name_str, .offset = o(driver_cap), \
>> +          .version = { \
>> +            [API_OPENGL_COMPAT] = gll_ver, \
>> +            [API_OPENGL_CORE]   = glc_ver, \
>> +            [API_OPENGLES]      = gles_ver, \
>> +            [API_OPENGLES2]     = gles2_ver, \
>> +           }, \
>> +           .year = yyyy \
>> +        },
>> +#include "extensions_table.h"
>> +#undef EXT
>> +};
>> --
>> 2.7.3
>>


More information about the mesa-dev mailing list