summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2011-01-31 15:02:24 -0800
committerIan Romanick <[email protected]>2011-01-31 15:32:56 -0800
commit14880a510a1a288df0778395097d5a52806abfb0 (patch)
tree275eb4aa6bd212329277fb36838408a61a3d28f8
parente5e34ab18eeaffa465094f6281dfe293b84376db (diff)
glsl: Reject shader versions not supported by the implementation
Previously we'd happily compile GLSL 1.30 shaders on any driver. We'd also happily compile GLSL 1.10 and 1.20 shaders in an ES2 context. This has been a long standing FINISHME in the compiler. NOTE: This is a candidate for the 7.9 and 7.10 branches
-rw-r--r--src/glsl/glsl_parser.ypp33
-rw-r--r--src/glsl/glsl_parser_extras.cpp32
-rw-r--r--src/glsl/glsl_parser_extras.h26
3 files changed, 82 insertions, 9 deletions
diff --git a/src/glsl/glsl_parser.ypp b/src/glsl/glsl_parser.ypp
index 7336b18cdcc..d0bebc7fec9 100644
--- a/src/glsl/glsl_parser.ypp
+++ b/src/glsl/glsl_parser.ypp
@@ -220,25 +220,40 @@ version_statement:
/* blank - no #version specified: defaults are already set */
| VERSION INTCONSTANT EOL
{
+ bool supported = false;
+
switch ($2) {
case 100:
state->es_shader = true;
+ supported = state->Const.GLSL_100ES;
+ break;
case 110:
+ supported = state->Const.GLSL_110;
+ break;
case 120:
+ supported = state->Const.GLSL_120;
+ break;
case 130:
- /* FINISHME: Check against implementation support versions. */
- state->language_version = $2;
- state->version_string =
- ralloc_asprintf(state, "GLSL%s %d.%02d",
- state->es_shader ? " ES" : "",
- state->language_version / 100,
- state->language_version % 100);
+ supported = state->Const.GLSL_130;
break;
default:
- _mesa_glsl_error(& @2, state, "Shading language version"
- "%u is not supported\n", $2);
+ supported = false;
break;
}
+
+ state->language_version = $2;
+ state->version_string =
+ ralloc_asprintf(state, "GLSL%s %d.%02d",
+ state->es_shader ? " ES" : "",
+ state->language_version / 100,
+ state->language_version % 100);
+
+ if (!supported) {
+ _mesa_glsl_error(& @2, state, "%s is not supported. "
+ "Supported versions are: %s\n",
+ state->version_string,
+ state->supported_version_string);
+ }
}
;
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index 5a8a5248c03..2ed8b843a24 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -79,6 +79,38 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *ctx,
this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents;
this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
+
+ /* Note: 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.
+ */
+ this->Const.GLSL_100ES = (ctx->API == API_OPENGLES2)
+ || ctx->Extensions.ARB_ES2_compatibility;
+ this->Const.GLSL_110 = (ctx->API == API_OPENGL);
+ this->Const.GLSL_120 = (ctx->API == API_OPENGL)
+ && (ctx->Const.GLSLVersion >= 120);
+ this->Const.GLSL_130 = (ctx->API == API_OPENGL)
+ && (ctx->Const.GLSLVersion >= 130);
+
+ const unsigned lowest_version =
+ (ctx->API == API_OPENGLES2) || ctx->Extensions.ARB_ES2_compatibility
+ ? 100 : 110;
+ const unsigned highest_version =
+ (ctx->API == API_OPENGL) ? ctx->Const.GLSLVersion : 100;
+ char *supported = (char *) ralloc_context(this);
+
+ for (unsigned ver = lowest_version; ver <= highest_version; ver += 10) {
+ const char *const prefix = (ver == lowest_version)
+ ? ""
+ : ((ver == highest_version) ? ", and " : ", ");
+
+ ralloc_asprintf_append(& supported, "%s%d.%02d%s",
+ prefix,
+ ver / 100, ver % 100,
+ (ver == 100) ? " ES" : "");
+ }
+
+ this->supported_version_string = supported;
}
const char *
diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
index 970275c0d19..8d4fca78773 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -73,6 +73,16 @@ struct _mesa_glsl_parse_state {
enum _mesa_glsl_parser_targets target;
/**
+ * Printable list of GLSL versions supported by the current context
+ *
+ * \note
+ * This string should probably be generated per-context instead of per
+ * invokation of the compiler. This should be changed when the method of
+ * tracking supported GLSL versions changes.
+ */
+ const char *supported_version_string;
+
+ /**
* Implementation defined limits that affect built-in variables, etc.
*
* \sa struct gl_constants (in mtypes.h)
@@ -93,6 +103,22 @@ struct _mesa_glsl_parse_state {
/* ARB_draw_buffers */
unsigned MaxDrawBuffers;
+
+ /**
+ * Set of GLSL versions supported by the current context
+ *
+ * Knowing that version X is supported doesn't mean that versions before
+ * X are also supported. Version 1.00 is only supported in an ES2
+ * context or when GL_ARB_ES2_compatibility is supported. In an OpenGL
+ * 3.0 "forward compatible" context, GLSL 1.10 and 1.20 are \b not
+ * supported.
+ */
+ /*@{*/
+ unsigned GLSL_100ES:1;
+ unsigned GLSL_110:1;
+ unsigned GLSL_120:1;
+ unsigned GLSL_130:1;
+ /*@}*/
} Const;
/**