diff options
-rw-r--r-- | src/glsl/glsl_parser_extras.cpp | 51 | ||||
-rw-r--r-- | src/glsl/glsl_parser_extras.h | 45 |
2 files changed, 86 insertions, 10 deletions
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index 3e192037e0d..14589b02005 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -123,6 +123,57 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx, this->default_uniform_qualifier->flags.q.column_major = 1; } +/** + * Determine whether the current GLSL version is sufficiently high to support + * a certain feature, and generate an error message if it isn't. + * + * \param required_glsl_version and \c required_glsl_es_version are + * interpreted as they are in _mesa_glsl_parse_state::is_version(). + * + * \param locp is the parser location where the error should be reported. + * + * \param fmt (and additional arguments) constitute a printf-style error + * message to report if the version check fails. Information about the + * current and required GLSL versions will be appended. So, for example, if + * the GLSL version being compiled is 1.20, and check_version(130, 300, locp, + * "foo unsupported") is called, the error message will be "foo unsupported in + * GLSL 1.20 (GLSL 1.30 or GLSL 3.00 ES required)". + */ +bool +_mesa_glsl_parse_state::check_version(unsigned required_glsl_version, + unsigned required_glsl_es_version, + YYLTYPE *locp, const char *fmt, ...) +{ + if (this->is_version(required_glsl_version, required_glsl_es_version)) + return true; + + va_list args; + va_start(args, fmt); + char *problem = ralloc_vasprintf(ctx, fmt, args); + va_end(args); + const char *glsl_version_string + = glsl_compute_version_string(ctx, false, required_glsl_version); + const char *glsl_es_version_string + = glsl_compute_version_string(ctx, true, required_glsl_es_version); + const char *requirement_string = ""; + if (required_glsl_version && required_glsl_es_version) { + requirement_string = ralloc_asprintf(ctx, " (%s or %s required)", + glsl_version_string, + glsl_es_version_string); + } else if (required_glsl_version) { + requirement_string = ralloc_asprintf(ctx, " (%s required)", + glsl_version_string); + } else if (required_glsl_es_version) { + requirement_string = ralloc_asprintf(ctx, " (%s required)", + glsl_es_version_string); + } + _mesa_glsl_error(locp, this, "%s in %s%s.", + problem, this->get_version_string(), + requirement_string); + + return false; +} + const char * _mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target) { diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h index 26fdee1c14d..597b49ef19d 100644 --- a/src/glsl/glsl_parser_extras.h +++ b/src/glsl/glsl_parser_extras.h @@ -59,6 +59,16 @@ struct glsl_switch_state { const char * glsl_compute_version_string(void *mem_ctx, bool is_es, unsigned version); +typedef struct YYLTYPE { + int first_line; + int first_column; + int last_line; + int last_column; + unsigned source; +} YYLTYPE; +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 + struct _mesa_glsl_parse_state { _mesa_glsl_parse_state(struct gl_context *_ctx, GLenum target, void *mem_ctx); @@ -90,6 +100,31 @@ struct _mesa_glsl_parse_state { this->language_version); } + /** + * Determine whether the current GLSL version is sufficiently high to + * support a certain feature. + * + * \param required_glsl_version is the desktop GLSL version that is + * required to support the feature, or 0 if no version of desktop GLSL + * supports the feature. + * + * \param required_glsl_es_version is the GLSL ES version that is required + * to support the feature, or 0 if no version of GLSL ES suports the + * feature. + */ + bool is_version(unsigned required_glsl_version, + unsigned required_glsl_es_version) + { + unsigned required_version = this->es_shader ? + required_glsl_es_version : required_glsl_version; + return required_version != 0 + && this->language_version >= required_version; + } + + bool check_version(unsigned required_glsl_version, + unsigned required_glsl_es_version, + YYLTYPE *locp, const char *fmt, ...) PRINTFLIKE(5, 6); + struct gl_context *const ctx; void *scanner; exec_list translation_unit; @@ -229,16 +264,6 @@ struct _mesa_glsl_parse_state { unsigned num_builtins_to_link; }; -typedef struct YYLTYPE { - int first_line; - int first_column; - int last_line; - int last_column; - unsigned source; -} YYLTYPE; -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 - # define YYLLOC_DEFAULT(Current, Rhs, N) \ do { \ if (N) \ |