summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl/glsl_parser_extras.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/glsl/glsl_parser_extras.cpp')
-rw-r--r--src/compiler/glsl/glsl_parser_extras.cpp281
1 files changed, 159 insertions, 122 deletions
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);