summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Berry <[email protected]>2012-08-02 11:17:30 -0700
committerIan Romanick <[email protected]>2012-12-06 12:13:22 -0800
commit2b4aeddfb3cdae95d69e7f46eac87514f372f531 (patch)
treecb5a3d84c80f18014fb6a0384b25afac078cf5da
parent629b9edc99a0b662cf907b9e068be2fd6ac5ae26 (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.yy6
-rw-r--r--src/glsl/glsl_parser_extras.cpp105
-rw-r--r--src/glsl/glsl_parser_extras.h3
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;