diff options
author | Paul Berry <[email protected]> | 2012-08-02 11:17:30 -0700 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2012-12-06 12:13:22 -0800 |
commit | 2b4aeddfb3cdae95d69e7f46eac87514f372f531 (patch) | |
tree | cb5a3d84c80f18014fb6a0384b25afac078cf5da | |
parent | 629b9edc99a0b662cf907b9e068be2fd6ac5ae26 (diff) |
glsl/parser: Handle "#version 300 es" directive.
Note that GLSL 1.00 is selected using "#version 100", so "#version 100
es" is prohibited.
v2: Check for GLES3 before allowing '#version 300 es'
v3: Make sure a correct language_version is set in
_mesa_glsl_parse_state::process_version_directive.
Signed-off-by: Paul Berry <[email protected]>
Signed-off-by: Ian Romanick <[email protected]>
Reviewed-by: Kenneth Graunke <[email protected]>
Acked-by: Carl Worth <[email protected]>
-rw-r--r-- | src/glsl/glsl_parser.yy | 6 | ||||
-rw-r--r-- | src/glsl/glsl_parser_extras.cpp | 105 | ||||
-rw-r--r-- | src/glsl/glsl_parser_extras.h | 3 |
3 files changed, 86 insertions, 28 deletions
diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy index b15e1d1f548..d938765d750 100644 --- a/src/glsl/glsl_parser.yy +++ b/src/glsl/glsl_parser.yy @@ -261,8 +261,12 @@ version_statement: /* blank - no #version specified: defaults are already set */ | VERSION_TOK INTCONSTANT EOL { - state->process_version_directive(&@2, $2); + state->process_version_directive(&@2, $2, NULL); } + | VERSION_TOK INTCONSTANT any_identifier EOL + { + state->process_version_directive(&@2, $2, $3); + } ; pragma_statement: diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index cc33a0724e1..19518f166d4 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -178,38 +178,72 @@ _mesa_glsl_parse_state::check_version(unsigned required_glsl_version, * Process a GLSL #version directive. * * \param version is the integer that follows the #version token. + * + * \param ident is a string identifier that follows the integer, if any is + * present. Otherwise NULL. */ void -_mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version) +_mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version, + const char *ident) { + bool es_token_present = false; + if (ident) { + if (strcmp(ident, "es") == 0) { + es_token_present = true; + } else { + _mesa_glsl_error(locp, this, + "Illegal text following version number\n"); + } + } + bool supported = false; - switch (version) { - case 100: + if (es_token_present) { this->es_shader = true; - supported = this->ctx->API == API_OPENGLES2 || - this->ctx->Extensions.ARB_ES2_compatibility; - break; - case 110: - case 120: - /* FINISHME: Once the OpenGL 3.0 'forward compatible' context or - * the OpenGL 3.2 Core context is supported, this logic will need - * change. Older versions of GLSL are no longer supported - * outside the compatibility contexts of 3.x. - */ - case 130: - case 140: - case 150: - case 330: - case 400: - case 410: - case 420: - supported = _mesa_is_desktop_gl(this->ctx) && - ((unsigned) version) <= this->ctx->Const.GLSLVersion; - break; - default: - supported = false; - break; + switch (version) { + case 100: + _mesa_glsl_error(locp, this, + "GLSL 1.00 ES should be selected using " + "`#version 100'\n"); + supported = this->ctx->API == API_OPENGLES2 || + this->ctx->Extensions.ARB_ES2_compatibility; + break; + case 300: + supported = _mesa_is_gles3(this->ctx) || + this->ctx->Extensions.ARB_ES3_compatibility; + break; + default: + supported = false; + break; + } + } else { + switch (version) { + case 100: + this->es_shader = true; + supported = this->ctx->API == API_OPENGLES2 || + this->ctx->Extensions.ARB_ES2_compatibility; + break; + case 110: + case 120: + /* FINISHME: Once the OpenGL 3.0 'forward compatible' context or + * the OpenGL 3.2 Core context is supported, this logic will need + * change. Older versions of GLSL are no longer supported + * outside the compatibility contexts of 3.x. + */ + case 130: + case 140: + case 150: + case 330: + case 400: + case 410: + case 420: + supported = _mesa_is_desktop_gl(this->ctx) && + ((unsigned) version) <= this->ctx->Const.GLSLVersion; + break; + default: + supported = false; + break; + } } this->language_version = version; @@ -219,6 +253,25 @@ _mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version) "Supported versions are: %s\n", this->get_version_string(), this->supported_version_string); + + /* On exit, the language_version must be set to a valid value. + * Later calls to _mesa_glsl_initialize_types will misbehave if + * the version is invalid. + */ + switch (this->ctx->API) { + case API_OPENGL_COMPAT: + case API_OPENGL_CORE: + this->language_version = this->ctx->Const.GLSLVersion; + break; + + case API_OPENGLES: + assert(!"Should not get here."); + /* FALLTHROUGH */ + + case API_OPENGLES2: + this->language_version = 100; + break; + } } if (this->language_version >= 140) { diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h index 59c4b24dcd3..8cda9278415 100644 --- a/src/glsl/glsl_parser_extras.h +++ b/src/glsl/glsl_parser_extras.h @@ -136,7 +136,8 @@ struct _mesa_glsl_parse_state { return check_version(130, 300, locp, "bit-wise operations are forbidden"); } - void process_version_directive(YYLTYPE *locp, int version); + void process_version_directive(YYLTYPE *locp, int version, + const char *ident); struct gl_context *const ctx; void *scanner; |