[Mesa-dev] [PATCH] glsl: Fix unsupported version error for GLSL ES 3.00, future proof for 3.30.

Ian Romanick idr at freedesktop.org
Mon Feb 11 14:35:39 PST 2013


On 02/05/2013 04:50 PM, Paul Berry wrote:
> When the user specifies an unsupported GLSL version,
> _mesa_glsl_parse_state::process_version_directive() nicely gives them
> an error message telling them which GLSL versions are supported.
> Previous to this patch, the logic for determining whether a given
> language version was supported was independent from the logic to
> generate this error message string; as a result, we had a bug where
> GLSL 3.00 would never be listed in the error message as an available
> language version, even if it was really available.
>
> To make matters worse, the code for generating the error message
> string assumed that desktop GL versions were always separated by 0.10,
> an assumption that will be wrong as soon as we support GLSL 3.30.
>
> This patch fixes both problems by adding a table of supported GLSL
> versions to _mesa_glsl_parse_state; this table is used both to
> generate the error message and to check whether a given version is
> supported.

Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

> ---
>   src/glsl/glsl_parser_extras.cpp | 112 +++++++++++++++++++++-------------------
>   src/glsl/glsl_parser_extras.h   |   8 +++
>   2 files changed, 66 insertions(+), 54 deletions(-)
>
> diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
> index c8dbc89..db35f44 100644
> --- a/src/glsl/glsl_parser_extras.cpp
> +++ b/src/glsl/glsl_parser_extras.cpp
> @@ -47,6 +47,11 @@ glsl_compute_version_string(void *mem_ctx, bool is_es, unsigned version)
>                             version / 100, version % 100);
>   }
>
> +
> +static unsigned known_desktop_glsl_versions[] =
> +   { 110, 120, 130, 140, 150, 330, 400, 410, 420, 430 };
> +
> +
>   _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
>   					       GLenum target, void *mem_ctx)
>    : ctx(_ctx)
> @@ -97,22 +102,51 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
>
>      this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
>
> -   const unsigned lowest_version =
> -      (ctx->API == API_OPENGLES2) || ctx->Extensions.ARB_ES2_compatibility
> -      ? 100 : 110;
> -   const unsigned highest_version =
> -      _mesa_is_desktop_gl(ctx) ? ctx->Const.GLSLVersion : 100;
> -   char *supported = ralloc_strdup(this, "");
> +   /* Populate the list of supported GLSL versions */
> +   /* 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.
> +    */
> +   this->num_supported_versions = 0;
> +   if (_mesa_is_desktop_gl(ctx)) {
> +      for (unsigned i = 0; i < ARRAY_SIZE(known_desktop_glsl_versions); i++) {
> +         if (known_desktop_glsl_versions[i] <= ctx->Const.GLSLVersion) {
> +            this->supported_versions[this->num_supported_versions].ver
> +               = known_desktop_glsl_versions[i];
> +            this->supported_versions[this->num_supported_versions].es = false;
> +            this->num_supported_versions++;
> +         }
> +      }
> +   }
> +   if (ctx->API == API_OPENGLES2 || ctx->Extensions.ARB_ES2_compatibility) {
> +      this->supported_versions[this->num_supported_versions].ver = 100;
> +      this->supported_versions[this->num_supported_versions].es = true;
> +      this->num_supported_versions++;
> +   }
> +   if (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility) {
> +      this->supported_versions[this->num_supported_versions].ver = 300;
> +      this->supported_versions[this->num_supported_versions].es = true;
> +      this->num_supported_versions++;
> +   }
> +   assert(this->num_supported_versions
> +          <= ARRAY_SIZE(this->supported_versions));
>
> -   for (unsigned ver = lowest_version; ver <= highest_version; ver += 10) {
> -      const char *const prefix = (ver == lowest_version)
> +   /* Create a string for use in error messages to tell the user which GLSL
> +    * versions are supported.
> +    */
> +   char *supported = ralloc_strdup(this, "");
> +   for (unsigned i = 0; i < this->num_supported_versions; i++) {
> +      unsigned ver = this->supported_versions[i].ver;
> +      const char *const prefix = (i == 0)
>   	 ? ""
> -	 : ((ver == highest_version) ? ", and " : ", ");
> +	 : ((i == this->num_supported_versions - 1) ? ", and " : ", ");
> +      const char *const suffix = (this->supported_versions[i].es) ? " ES" : "";
>
> -      ralloc_asprintf_append(& supported, "%s%d.%02d%s",
> +      ralloc_asprintf_append(& supported, "%s%u.%02u%s",
>   			     prefix,
>   			     ver / 100, ver % 100,
> -			     (ver == 100) ? " ES" : "");
> +			     suffix);
>      }
>
>      this->supported_version_string = supported;
> @@ -198,58 +232,28 @@ _mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version,
>         }
>      }
>
> -   bool supported = false;
> -
> -   if (es_token_present) {
> -      this->es_shader = true;
> -      switch (version) {
> -      case 100:
> +   this->es_shader = es_token_present;
> +   if (version == 100) {
> +      if (es_token_present) {
>            _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:
> +      } else {
>            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;
>
> +   bool supported = false;
> +   for (unsigned i = 0; i < this->num_supported_versions; i++) {
> +      if (this->supported_versions[i].ver == (unsigned) version
> +          && this->supported_versions[i].es == this->es_shader) {
> +         supported = true;
> +         break;
> +      }
> +   }
> +
>      if (!supported) {
>         _mesa_glsl_error(locp, this, "%s is not supported. "
>                          "Supported versions are: %s\n",
> diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
> index 53df149..ed123be 100644
> --- a/src/glsl/glsl_parser_extras.h
> +++ b/src/glsl/glsl_parser_extras.h
> @@ -25,6 +25,8 @@
>   #ifndef GLSL_PARSER_EXTRAS_H
>   #define GLSL_PARSER_EXTRAS_H
>
> +#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
> +
>   /*
>    * Most of the definitions here only apply to C++
>    */
> @@ -148,6 +150,12 @@ struct _mesa_glsl_parse_state {
>      unsigned uniform_block_array_size;
>      struct gl_uniform_block *uniform_blocks;
>
> +   unsigned num_supported_versions;
> +   struct {
> +      unsigned ver;
> +      bool es;
> +   } supported_versions[12];
> +
>      bool es_shader;
>      unsigned language_version;
>      enum _mesa_glsl_parser_targets target;
>



More information about the mesa-dev mailing list