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
This commit is contained in:
Ian Romanick 2011-01-31 15:02:24 -08:00
parent e5e34ab18e
commit 14880a510a
3 changed files with 82 additions and 9 deletions

View File

@ -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);
}
}
;

View File

@ -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 *

View File

@ -72,6 +72,16 @@ struct _mesa_glsl_parse_state {
const char *version_string;
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.
*
@ -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;
/**