[Mesa-dev] [PATCH v3] glsl: reuse main extension table to appropriately restrict extensions
Ilia Mirkin
imirkin at alum.mit.edu
Mon Jul 18 21:03:51 UTC 2016
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