Mesa (7.9): glsl: Reject shader versions not supported by the implementation

Ian Romanick idr at kemper.freedesktop.org
Tue Mar 1 00:04:39 UTC 2011


Module: Mesa
Branch: 7.9
Commit: 8cf57be87829146c029d7be059adbc2500c09285
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8cf57be87829146c029d7be059adbc2500c09285

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Mon Jan 31 15:02:24 2011 -0800

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
(cherry picked from commit 14880a510a1a288df0778395097d5a52806abfb0)

---

 src/glsl/glsl_parser.ypp        |   33 ++++++++++++++++++++++++---------
 src/glsl/glsl_parser_extras.cpp |   32 ++++++++++++++++++++++++++++++++
 src/glsl/glsl_parser_extras.h   |   26 ++++++++++++++++++++++++++
 3 files changed, 82 insertions(+), 9 deletions(-)

diff --git a/src/glsl/glsl_parser.ypp b/src/glsl/glsl_parser.ypp
index ded1ea8..763295c 100644
--- a/src/glsl/glsl_parser.ypp
+++ b/src/glsl/glsl_parser.ypp
@@ -222,25 +222,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 dcd5bae..7a3c101 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 __GLcontextRec *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 af6c6b6..1e3556f 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -74,6 +74,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)
@@ -94,6 +104,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;
 
    /**




More information about the mesa-commit mailing list