[Mesa-dev] [PATCH v3] glsl: reuse main extension table to appropriately restrict extensions

Ilia Mirkin imirkin at alum.mit.edu
Thu Jul 21 00:34:59 UTC 2016


Thanks to the kind folks at Intel, this has been run through their CI
system, which runs against piglit, as well as CTS. This turned up just
a handful of regressions:

(a) GL_OES_texture_storage_multisample_2d_array define test used
#version 300 es in piglit instead of 310, fixed by
https://patchwork.freedesktop.org/patch/100107/
(b) piglit.es3-cts.shaders.shader_integer_mix.define -- This uses
#version 100, according to Timothy Arceri, while the ext requires ES
3.0. I believe it's correct not to have it defined in that case.
(c) piglit.es31-cts.shader_integer_mix.define -- I strongly suspect
this is the same issue as the ES3 version.

It also fixes some failures due to missing
GL_AMD_shader_stencil_export define string, as well as exts being
exposed in compat when they shouldn't be, like all the layer/viewport
stuff.

  -ilia


On Mon, Jul 18, 2016 at 5:03 PM, Ilia Mirkin <imirkin at alum.mit.edu> wrote:
> Well, I have a basic review on this from Eric Engestrom, who is not a
> mesa expert (yet?) but has been giving out a lot of good review
> comments lately, and nobody else has piped up saying they hate this,
> so I'm going to push this in the next few days unless I hear any
> objections. IMHO this is a nice simplification of the glsl parser
> boilerplate, and removes the oft-forgotten glcpp annoyance.
>
> On Tue, Jul 12, 2016 at 11:07 AM, Ilia Mirkin <imirkin at alum.mit.edu> wrote:
>> ping^2
>>
>> On Tue, Jul 5, 2016 at 6:41 PM, Ilia Mirkin <imirkin at alum.mit.edu> wrote:
>>> ping
>>>
>>> On Fri, Jun 24, 2016 at 1:42 AM, 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. However in some
>>>> situations, extensions like GL_ARB_gpu_shader5 which were formerly
>>>> available in compat contexts on the GLSL side of things will now become
>>>> inaccessible.
>>>>
>>>> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
>>>> Reviewed-by: Eric Engestrom <eric.engestrom at imgtec.com> (v2)
>>>> v2 -> v3: integrate glcpp defines into the same mechanism
>>>> ---
>>>>
>>>> FWIW I hate the method I had to invent to get this information to
>>>> glcpp. A callback that takes a callback. Ugh. Sorry. If someone can
>>>> come up with something cleaner, I'm all ears.
>>>>
>>>> This does appear to pass some basic testing.
>>>>
>>>>  src/Makefile.am                          |   1 +
>>>>  src/compiler/SConscript.glsl             |   2 +
>>>>  src/compiler/glsl/glcpp/glcpp-parse.y    | 204 +---------------------
>>>>  src/compiler/glsl/glcpp/glcpp.c          |   2 +-
>>>>  src/compiler/glsl/glcpp/glcpp.h          |  19 ++-
>>>>  src/compiler/glsl/glcpp/pp.c             |   6 +-
>>>>  src/compiler/glsl/glsl_parser_extras.cpp | 283 +++++++++++++++++--------------
>>>>  src/compiler/glsl/glsl_parser_extras.h   |  17 +-
>>>>  src/compiler/glsl/test_optpass.cpp       |   2 +-
>>>>  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 ++++++
>>>>  14 files changed, 269 insertions(+), 355 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/glcpp/glcpp-parse.y b/src/compiler/glsl/glcpp/glcpp-parse.y
>>>> index b9d690d..ca376d9 100644
>>>> --- a/src/compiler/glsl/glcpp/glcpp-parse.y
>>>> +++ b/src/compiler/glsl/glcpp/glcpp-parse.y
>>>> @@ -1311,7 +1311,7 @@ add_builtin_define(glcpp_parser_t *parser, const char *name, int value)
>>>>  }
>>>>
>>>>  glcpp_parser_t *
>>>> -glcpp_parser_create(const struct gl_extensions *extensions, gl_api api)
>>>> +glcpp_parser_create(glcpp_extension_iterator extensions, void *state, gl_api api)
>>>>  {
>>>>     glcpp_parser_t *parser;
>>>>
>>>> @@ -1344,6 +1344,7 @@ glcpp_parser_create(const struct gl_extensions *extensions, gl_api api)
>>>>     parser->error = 0;
>>>>
>>>>     parser->extensions = extensions;
>>>> +   parser->state = state;
>>>>     parser->api = api;
>>>>     parser->version_resolved = false;
>>>>
>>>> @@ -2279,8 +2280,6 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio
>>>>                                           const char *es_identifier,
>>>>                                           bool explicitly_set)
>>>>  {
>>>> -   const struct gl_extensions *extensions = parser->extensions;
>>>> -
>>>>     if (parser->version_resolved)
>>>>        return;
>>>>
>>>> @@ -2292,199 +2291,9 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio
>>>>                       (es_identifier && (strcmp(es_identifier, "es") == 0));
>>>>
>>>>     /* Add pre-defined macros. */
>>>> -   if (parser->is_gles) {
>>>> +   if (parser->is_gles)
>>>>        add_builtin_define(parser, "GL_ES", 1);
>>>> -      add_builtin_define(parser, "GL_EXT_separate_shader_objects", 1);
>>>> -      add_builtin_define(parser, "GL_EXT_draw_buffers", 1);
>>>> -
>>>> -      if (extensions != NULL) {
>>>> -         if (extensions->OES_EGL_image_external)
>>>> -            add_builtin_define(parser, "GL_OES_EGL_image_external", 1);
>>>> -         if (extensions->OES_sample_variables) {
>>>> -            add_builtin_define(parser, "GL_OES_sample_variables", 1);
>>>> -            add_builtin_define(parser, "GL_OES_shader_multisample_interpolation", 1);
>>>> -         }
>>>> -         if (extensions->OES_standard_derivatives)
>>>> -            add_builtin_define(parser, "GL_OES_standard_derivatives", 1);
>>>> -         if (extensions->ARB_texture_multisample)
>>>> -            add_builtin_define(parser, "GL_OES_texture_storage_multisample_2d_array", 1);
>>>> -         if (extensions->ARB_blend_func_extended)
>>>> -            add_builtin_define(parser, "GL_EXT_blend_func_extended", 1);
>>>> -         if (extensions->ARB_cull_distance)
>>>> -            add_builtin_define(parser, "GL_EXT_clip_cull_distance", 1);
>>>> -
>>>> -         if (version >= 310) {
>>>> -            if (extensions->ARB_shader_image_load_store)
>>>> -               add_builtin_define(parser, "GL_OES_shader_image_atomic", 1);
>>>> -
>>>> -            if (extensions->OES_geometry_shader) {
>>>> -               add_builtin_define(parser, "GL_OES_geometry_point_size", 1);
>>>> -               add_builtin_define(parser, "GL_OES_geometry_shader", 1);
>>>> -            }
>>>> -            if (extensions->ARB_gpu_shader5) {
>>>> -               add_builtin_define(parser, "GL_EXT_gpu_shader5", 1);
>>>> -               add_builtin_define(parser, "GL_OES_gpu_shader5", 1);
>>>> -            }
>>>> -            if (extensions->OES_texture_buffer) {
>>>> -               add_builtin_define(parser, "GL_EXT_texture_buffer", 1);
>>>> -               add_builtin_define(parser, "GL_OES_texture_buffer", 1);
>>>> -            }
>>>> -            if (extensions->OES_shader_io_blocks) {
>>>> -               add_builtin_define(parser, "GL_EXT_shader_io_blocks", 1);
>>>> -               add_builtin_define(parser, "GL_OES_shader_io_blocks", 1);
>>>> -            }
>>>> -            if (extensions->OES_primitive_bounding_box) {
>>>> -               add_builtin_define(parser, "GL_EXT_primitive_bounding_box", 1);
>>>> -               add_builtin_define(parser, "GL_OES_primitive_bounding_box", 1);
>>>> -            }
>>>> -         }
>>>> -      }
>>>> -   } else {
>>>> -      add_builtin_define(parser, "GL_ARB_draw_buffers", 1);
>>>> -      add_builtin_define(parser, "GL_ARB_enhanced_layouts", 1);
>>>> -      add_builtin_define(parser, "GL_ARB_separate_shader_objects", 1);
>>>> -      add_builtin_define(parser, "GL_ARB_texture_rectangle", 1);
>>>> -      add_builtin_define(parser, "GL_AMD_shader_trinary_minmax", 1);
>>>> -
>>>> -      if (extensions != NULL) {
>>>> -         if (extensions->EXT_texture_array)
>>>> -            add_builtin_define(parser, "GL_EXT_texture_array", 1);
>>>> -
>>>> -         if (extensions->ARB_ES3_1_compatibility)
>>>> -            add_builtin_define(parser, "GL_ARB_ES3_1_compatibility", 1);
>>>> -
>>>> -         if (extensions->ARB_arrays_of_arrays)
>>>> -             add_builtin_define(parser, "GL_ARB_arrays_of_arrays", 1);
>>>> -
>>>> -         if (extensions->ARB_fragment_coord_conventions) {
>>>> -            add_builtin_define(parser, "GL_ARB_fragment_coord_conventions",
>>>> -                               1);
>>>> -         }
>>>> -
>>>> -         if (extensions->ARB_fragment_layer_viewport)
>>>> -            add_builtin_define(parser, "GL_ARB_fragment_layer_viewport", 1);
>>>> -
>>>> -         if (extensions->ARB_explicit_attrib_location)
>>>> -            add_builtin_define(parser, "GL_ARB_explicit_attrib_location", 1);
>>>> -
>>>> -         if (extensions->ARB_explicit_uniform_location)
>>>> -            add_builtin_define(parser, "GL_ARB_explicit_uniform_location", 1);
>>>> -
>>>> -         if (extensions->ARB_shader_texture_lod)
>>>> -            add_builtin_define(parser, "GL_ARB_shader_texture_lod", 1);
>>>> -
>>>> -         if (extensions->ARB_draw_instanced)
>>>> -            add_builtin_define(parser, "GL_ARB_draw_instanced", 1);
>>>> -
>>>> -         if (extensions->ARB_conservative_depth) {
>>>> -            add_builtin_define(parser, "GL_AMD_conservative_depth", 1);
>>>> -            add_builtin_define(parser, "GL_ARB_conservative_depth", 1);
>>>> -         }
>>>> -
>>>> -         if (extensions->ARB_shader_bit_encoding)
>>>> -            add_builtin_define(parser, "GL_ARB_shader_bit_encoding", 1);
>>>> -
>>>> -         if (extensions->ARB_shader_clock)
>>>> -            add_builtin_define(parser, "GL_ARB_shader_clock", 1);
>>>> -
>>>> -         if (extensions->ARB_uniform_buffer_object)
>>>> -            add_builtin_define(parser, "GL_ARB_uniform_buffer_object", 1);
>>>> -
>>>> -         if (extensions->ARB_texture_cube_map_array)
>>>> -            add_builtin_define(parser, "GL_ARB_texture_cube_map_array", 1);
>>>> -
>>>> -         if (extensions->ARB_shading_language_packing)
>>>> -            add_builtin_define(parser, "GL_ARB_shading_language_packing", 1);
>>>> -
>>>> -         if (extensions->ARB_texture_multisample)
>>>> -            add_builtin_define(parser, "GL_ARB_texture_multisample", 1);
>>>> -
>>>> -         if (extensions->ARB_texture_query_levels)
>>>> -            add_builtin_define(parser, "GL_ARB_texture_query_levels", 1);
>>>> -
>>>> -         if (extensions->ARB_texture_query_lod)
>>>> -            add_builtin_define(parser, "GL_ARB_texture_query_lod", 1);
>>>> -
>>>> -         if (extensions->ARB_gpu_shader5)
>>>> -            add_builtin_define(parser, "GL_ARB_gpu_shader5", 1);
>>>> -
>>>> -         if (extensions->ARB_gpu_shader_fp64)
>>>> -            add_builtin_define(parser, "GL_ARB_gpu_shader_fp64", 1);
>>>> -
>>>> -         if (extensions->ARB_vertex_attrib_64bit)
>>>> -            add_builtin_define(parser, "GL_ARB_vertex_attrib_64bit", 1);
>>>> -
>>>> -         if (extensions->AMD_vertex_shader_layer)
>>>> -            add_builtin_define(parser, "GL_AMD_vertex_shader_layer", 1);
>>>> -
>>>> -         if (extensions->AMD_vertex_shader_viewport_index)
>>>> -            add_builtin_define(parser, "GL_AMD_vertex_shader_viewport_index", 1);
>>>> -
>>>> -         if (extensions->ARB_shading_language_420pack)
>>>> -            add_builtin_define(parser, "GL_ARB_shading_language_420pack", 1);
>>>> -
>>>> -         if (extensions->ARB_sample_shading)
>>>> -            add_builtin_define(parser, "GL_ARB_sample_shading", 1);
>>>> -
>>>> -         if (extensions->ARB_texture_gather)
>>>> -            add_builtin_define(parser, "GL_ARB_texture_gather", 1);
>>>> -
>>>> -         if (extensions->ARB_shader_atomic_counters)
>>>> -            add_builtin_define(parser, "GL_ARB_shader_atomic_counters", 1);
>>>> -
>>>> -         if (extensions->ARB_shader_atomic_counter_ops)
>>>> -            add_builtin_define(parser, "GL_ARB_shader_atomic_counter_ops", 1);
>>>> -
>>>> -         if (extensions->ARB_viewport_array)
>>>> -            add_builtin_define(parser, "GL_ARB_viewport_array", 1);
>>>> -
>>>> -         if (extensions->ARB_compute_shader)
>>>> -            add_builtin_define(parser, "GL_ARB_compute_shader", 1);
>>>> -
>>>> -         if (extensions->ARB_shader_image_load_store)
>>>> -            add_builtin_define(parser, "GL_ARB_shader_image_load_store", 1);
>>>> -
>>>> -         if (extensions->ARB_shader_image_size)
>>>> -            add_builtin_define(parser, "GL_ARB_shader_image_size", 1);
>>>> -
>>>> -         if (extensions->ARB_shader_texture_image_samples)
>>>> -            add_builtin_define(parser, "GL_ARB_shader_texture_image_samples", 1);
>>>> -
>>>> -         if (extensions->ARB_derivative_control)
>>>> -            add_builtin_define(parser, "GL_ARB_derivative_control", 1);
>>>> -
>>>> -         if (extensions->ARB_shader_precision)
>>>> -            add_builtin_define(parser, "GL_ARB_shader_precision", 1);
>>>> -
>>>> -         if (extensions->ARB_shader_storage_buffer_object)
>>>> -            add_builtin_define(parser, "GL_ARB_shader_storage_buffer_object", 1);
>>>> -
>>>> -         if (extensions->ARB_tessellation_shader)
>>>> -            add_builtin_define(parser, "GL_ARB_tessellation_shader", 1);
>>>> -
>>>> -         if (extensions->ARB_shader_subroutine)
>>>> -            add_builtin_define(parser, "GL_ARB_shader_subroutine", 1);
>>>> -
>>>> -         if (extensions->ARB_shader_draw_parameters)
>>>> -            add_builtin_define(parser, "GL_ARB_shader_draw_parameters", 1);
>>>> -
>>>> -         if (extensions->ARB_cull_distance)
>>>> -            add_builtin_define(parser, "GL_ARB_cull_distance", 1);
>>>> -
>>>> -         if (extensions->ARB_shader_group_vote)
>>>> -            add_builtin_define(parser, "GL_ARB_shader_group_vote", 1);
>>>> -      }
>>>> -   }
>>>> -
>>>> -   if (extensions != NULL) {
>>>> -      if (extensions->EXT_shader_integer_mix)
>>>> -         add_builtin_define(parser, "GL_EXT_shader_integer_mix", 1);
>>>> -
>>>> -      if (extensions->EXT_shader_samples_identical)
>>>> -         add_builtin_define(parser, "GL_EXT_shader_samples_identical", 1);
>>>> -   }
>>>> -
>>>> -   if (version >= 150)
>>>> +   else if (version >= 150)
>>>>        add_builtin_define(parser, "GL_core_profile", 1);
>>>>
>>>>     /* Currently, all ES2/ES3 implementations support highp in the
>>>> @@ -2495,6 +2304,11 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio
>>>>     if (version >= 130 || parser->is_gles)
>>>>        add_builtin_define (parser, "GL_FRAGMENT_PRECISION_HIGH", 1);
>>>>
>>>> +   /* Add all the extension macros available in this context */
>>>> +   if (parser->extensions)
>>>> +      parser->extensions(parser->state, add_builtin_define, parser,
>>>> +                         version, parser->is_gles);
>>>> +
>>>>     if (explicitly_set) {
>>>>        ralloc_asprintf_rewrite_tail(&parser->output, &parser->output_length,
>>>>                                     "#version %" PRIiMAX "%s%s", version,
>>>> diff --git a/src/compiler/glsl/glcpp/glcpp.c b/src/compiler/glsl/glcpp/glcpp.c
>>>> index c62f4ef..f08b144 100644
>>>> --- a/src/compiler/glsl/glcpp/glcpp.c
>>>> +++ b/src/compiler/glsl/glcpp/glcpp.c
>>>> @@ -171,7 +171,7 @@ main (int argc, char *argv[])
>>>>
>>>>         _mesa_locale_init();
>>>>
>>>> -       ret = glcpp_preprocess(ctx, &shader, &info_log, NULL, &gl_ctx);
>>>> +       ret = glcpp_preprocess(ctx, &shader, &info_log, NULL, NULL, &gl_ctx);
>>>>
>>>>         printf("%s", shader);
>>>>         fprintf(stderr, "%s", info_log);
>>>> diff --git a/src/compiler/glsl/glcpp/glcpp.h b/src/compiler/glsl/glcpp/glcpp.h
>>>> index d87e6b7..07eaf68 100644
>>>> --- a/src/compiler/glsl/glcpp/glcpp.h
>>>> +++ b/src/compiler/glsl/glcpp/glcpp.h
>>>> @@ -171,6 +171,15 @@ typedef struct active_list {
>>>>         struct active_list *next;
>>>>  } active_list_t;
>>>>
>>>> +struct _mesa_glsl_parse_state;
>>>> +
>>>> +typedef void (*glcpp_extension_iterator)(
>>>> +               struct _mesa_glsl_parse_state *state,
>>>> +               void (*add_builtin_define)(glcpp_parser_t *, const char *, int),
>>>> +               glcpp_parser_t *data,
>>>> +               unsigned version,
>>>> +               bool es);
>>>> +
>>>>  struct glcpp_parser {
>>>>         yyscan_t scanner;
>>>>         struct hash_table *defines;
>>>> @@ -194,7 +203,8 @@ struct glcpp_parser {
>>>>         size_t output_length;
>>>>         size_t info_log_length;
>>>>         int error;
>>>> -       const struct gl_extensions *extensions;
>>>> +       glcpp_extension_iterator extensions;
>>>> +       void *state;
>>>>         gl_api api;
>>>>         bool version_resolved;
>>>>         bool has_new_line_number;
>>>> @@ -204,10 +214,8 @@ struct glcpp_parser {
>>>>         bool is_gles;
>>>>  };
>>>>
>>>> -struct gl_extensions;
>>>> -
>>>>  glcpp_parser_t *
>>>> -glcpp_parser_create (const struct gl_extensions *extensions, gl_api api);
>>>> +glcpp_parser_create (glcpp_extension_iterator extensions, void *state, gl_api api);
>>>>
>>>>  int
>>>>  glcpp_parser_parse (glcpp_parser_t *parser);
>>>> @@ -220,7 +228,8 @@ glcpp_parser_resolve_implicit_version(glcpp_parser_t *parser);
>>>>
>>>>  int
>>>>  glcpp_preprocess(void *ralloc_ctx, const char **shader, char **info_log,
>>>> -          const struct gl_extensions *extensions, struct gl_context *g_ctx);
>>>> +                glcpp_extension_iterator extensions, void *state,
>>>> +                struct gl_context *g_ctx);
>>>>
>>>>  /* Functions for writing to the info log */
>>>>
>>>> diff --git a/src/compiler/glsl/glcpp/pp.c b/src/compiler/glsl/glcpp/pp.c
>>>> index 160c666..b591279 100644
>>>> --- a/src/compiler/glsl/glcpp/pp.c
>>>> +++ b/src/compiler/glsl/glcpp/pp.c
>>>> @@ -213,10 +213,12 @@ remove_line_continuations(glcpp_parser_t *ctx, const char *shader)
>>>>
>>>>  int
>>>>  glcpp_preprocess(void *ralloc_ctx, const char **shader, char **info_log,
>>>> -          const struct gl_extensions *extensions, struct gl_context *gl_ctx)
>>>> +                 glcpp_extension_iterator extensions, void *state,
>>>> +                 struct gl_context *gl_ctx)
>>>>  {
>>>>         int errors;
>>>> -       glcpp_parser_t *parser = glcpp_parser_create (extensions, gl_ctx->API);
>>>> +       glcpp_parser_t *parser =
>>>> +               glcpp_parser_create(extensions, state, gl_ctx->API);
>>>>
>>>>         if (! gl_ctx->Const.DisableGLSLLineContinuations)
>>>>                 *shader = remove_line_continuations(parser, *shader);
>>>> diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp
>>>> index ce2c3e8..be6886d 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";
>>>> @@ -1789,6 +1789,43 @@ assign_subroutine_indexes(struct gl_shader *sh,
>>>>     }
>>>>  }
>>>>
>>>> +static void
>>>> +add_builtin_defines(struct _mesa_glsl_parse_state *state,
>>>> +                    void (*add_builtin_define)(struct glcpp_parser *, const char *, int),
>>>> +                    struct glcpp_parser *data,
>>>> +                    unsigned version,
>>>> +                    bool es)
>>>> +{
>>>> +   unsigned gl_version = state->ctx->Extensions.Version;
>>>> +   gl_api api = state->ctx->API;
>>>> +
>>>> +   if (gl_version != 0xff) {
>>>> +      unsigned i;
>>>> +      for (i = 0; i < state->num_supported_versions; i++) {
>>>> +         if (state->supported_versions[i].ver == version &&
>>>> +             state->supported_versions[i].es == es) {
>>>> +            gl_version = state->supported_versions[i].gl_ver;
>>>> +            break;
>>>> +         }
>>>> +      }
>>>> +
>>>> +      if (i == state->num_supported_versions)
>>>> +         return;
>>>> +   }
>>>> +
>>>> +   if (es)
>>>> +      api = API_OPENGLES2;
>>>> +
>>>> +   for (unsigned i = 0;
>>>> +        i < ARRAY_SIZE(_mesa_glsl_supported_extensions); ++i) {
>>>> +      const _mesa_glsl_extension *extension
>>>> +         = &_mesa_glsl_supported_extensions[i];
>>>> +      if (extension->compatible_with_state(state, api, gl_version)) {
>>>> +         add_builtin_define(data, extension->name, 1);
>>>> +      }
>>>> +   }
>>>> +}
>>>> +
>>>>  void
>>>>  _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
>>>>                            bool dump_ast, bool dump_hir)
>>>> @@ -1802,7 +1839,7 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
>>>>                                false, true);
>>>>
>>>>     state->error = glcpp_preprocess(state, &source, &state->info_log,
>>>> -                             &ctx->Extensions, ctx);
>>>> +                             add_builtin_defines, state, ctx);
>>>>
>>>>     if (!state->error) {
>>>>       _mesa_glsl_lexer_ctor(state, source);
>>>> diff --git a/src/compiler/glsl/glsl_parser_extras.h b/src/compiler/glsl/glsl_parser_extras.h
>>>> index 622a809..59a08f5 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;
>>>>
>>>>     /**
>>>> @@ -804,8 +806,19 @@ extern bool _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
>>>>  extern "C" {
>>>>  #endif
>>>>
>>>> +struct glcpp_parser;
>>>> +
>>>> +typedef void (*glcpp_extension_iterator)(
>>>> +               struct _mesa_glsl_parse_state *state,
>>>> +               void (*add_builtin_define)(struct glcpp_parser *, const char *, int),
>>>> +               struct glcpp_parser *data,
>>>> +               unsigned version,
>>>> +               bool es);
>>>> +
>>>>  extern int glcpp_preprocess(void *ctx, const char **shader, char **info_log,
>>>> -                      const struct gl_extensions *extensions, struct gl_context *gl_ctx);
>>>> +                            glcpp_extension_iterator extensions,
>>>> +                            struct _mesa_glsl_parse_state *state,
>>>> +                            struct gl_context *gl_ctx);
>>>>
>>>>  extern void _mesa_destroy_shader_compiler(void);
>>>>  extern void _mesa_destroy_shader_compiler_caches(void);
>>>> diff --git a/src/compiler/glsl/test_optpass.cpp b/src/compiler/glsl/test_optpass.cpp
>>>> index fed1fab..f562cad 100644
>>>> --- a/src/compiler/glsl/test_optpass.cpp
>>>> +++ b/src/compiler/glsl/test_optpass.cpp
>>>> @@ -220,7 +220,7 @@ int test_optpass(int argc, char **argv)
>>>>        shader->Source = input.c_str();
>>>>        const char *source = shader->Source;
>>>>        state->error = glcpp_preprocess(state, &source, &state->info_log,
>>>> -                                state->extensions, ctx) != 0;
>>>> +                                      NULL, NULL, ctx) != 0;
>>>>
>>>>        if (!state->error) {
>>>>           _mesa_glsl_lexer_ctor(state, source);
>>>> 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