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

Ian Romanick idr at kemper.freedesktop.org
Mon Jan 31 23:33:18 UTC 2011


Module: Mesa
Branch: master
Commit: 14880a510a1a288df0778395097d5a52806abfb0
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=14880a510a1a288df0778395097d5a52806abfb0

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

---

 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 7336b18..d0bebc7 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 5a8a524..2ed8b84 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 970275c..8d4fca7 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;
 
    /**




More information about the mesa-commit mailing list