diff options
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/compiler/SConscript.glsl | 2 | ||||
-rw-r--r-- | src/compiler/glsl/glcpp/glcpp-parse.y | 204 | ||||
-rw-r--r-- | src/compiler/glsl/glcpp/glcpp.c | 2 | ||||
-rw-r--r-- | src/compiler/glsl/glcpp/glcpp.h | 19 | ||||
-rw-r--r-- | src/compiler/glsl/glcpp/pp.c | 6 | ||||
-rw-r--r-- | src/compiler/glsl/glsl_parser_extras.cpp | 281 | ||||
-rw-r--r-- | src/compiler/glsl/glsl_parser_extras.h | 17 | ||||
-rw-r--r-- | src/compiler/glsl/test_optpass.cpp | 2 | ||||
-rw-r--r-- | src/mesa/Android.libmesa_glsl_utils.mk | 2 | ||||
-rw-r--r-- | src/mesa/Makefile.sources | 1 | ||||
-rw-r--r-- | src/mesa/main/extensions.c | 33 | ||||
-rw-r--r-- | src/mesa/main/extensions.h | 1 | ||||
-rw-r--r-- | src/mesa/main/extensions_table.c | 51 |
14 files changed, 268 insertions, 354 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index b130f5b7ced..d4e34b47bee 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -107,6 +107,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 4252ce15771..31d8f6debf4 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 a1597611144..ca376d983ff 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); - } - } - } - } 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 (extensions->MESA_shader_integer_functions) - add_builtin_define(parser, "GL_MESA_shader_integer_functions", 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 c62f4efec9d..f08b14427f4 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 d87e6b77dc5..07eaf684bee 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 160c6662ff6..b5912799371 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 007743497d4..ff638fd8013 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, @@ -75,6 +77,7 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx, this->language_version = 110; this->forced_language_version = ctx->Const.ForceGLSLVersion; this->zero_init = ctx->Const.GLSLZeroInit; + this->gl_version = 20; this->es_shader = false; this->ARB_texture_rectangle_enable = true; @@ -195,9 +198,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 */ @@ -212,6 +215,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++; } @@ -219,22 +224,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++; } @@ -399,6 +408,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; } @@ -511,28 +521,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 @@ -553,12 +547,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 } @@ -567,92 +573,89 @@ 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_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_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_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(MESA_shader_integer_functions, true, true, MESA_shader_integer_functions), + 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_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), + EXT(MESA_shader_integer_functions), }; #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"; @@ -1790,6 +1790,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) @@ -1803,7 +1840,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 9548e62532f..cca7fa8e0ee 100644 --- a/src/compiler/glsl/glsl_parser_extras.h +++ b/src/compiler/glsl/glsl_parser_extras.h @@ -300,13 +300,15 @@ 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; bool zero_init; + unsigned gl_version; gl_shader_stage stage; /** @@ -803,8 +805,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 f19d7e6e6d5..852af1919bc 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 5a80f221c8f..dfea801b057 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 aa06860a73e..a16968d7e87 100644 --- a/src/mesa/Makefile.sources +++ b/src/mesa/Makefile.sources @@ -79,6 +79,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 fa50cb68cca..62a731675d7 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 43ef6aa6451..efef1be4751 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 00000000000..1e37fbcc462 --- /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 +}; |