aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r--mesalib/src/glsl/glsl_lexer.ll2
-rw-r--r--mesalib/src/glsl/glsl_parser.yy10
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp92
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.h4
-rw-r--r--mesalib/src/glsl/ir_function_detect_recursion.cpp1
-rw-r--r--mesalib/src/glsl/link_interface_blocks.cpp25
-rw-r--r--mesalib/src/glsl/link_uniform_blocks.cpp2
-rw-r--r--mesalib/src/glsl/link_varyings.cpp12
-rw-r--r--mesalib/src/glsl/link_varyings.h2
-rw-r--r--mesalib/src/glsl/linker.cpp122
-rw-r--r--mesalib/src/glsl/linker.h12
11 files changed, 126 insertions, 158 deletions
diff --git a/mesalib/src/glsl/glsl_lexer.ll b/mesalib/src/glsl/glsl_lexer.ll
index 93752307d..e24df8096 100644
--- a/mesalib/src/glsl/glsl_lexer.ll
+++ b/mesalib/src/glsl/glsl_lexer.ll
@@ -149,7 +149,7 @@ literal_integer(char *text, int len, struct _mesa_glsl_parse_state *state,
%option bison-bridge bison-locations reentrant noyywrap
%option nounput noyy_top_state
%option never-interactive
-%option prefix="_mesa_glsl_"
+%option prefix="_mesa_glsl_lexer_"
%option extra-type="struct _mesa_glsl_parse_state *"
%x PP PRAGMA
diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy
index bf312366b..fcc5620cd 100644
--- a/mesalib/src/glsl/glsl_parser.yy
+++ b/mesalib/src/glsl/glsl_parser.yy
@@ -31,14 +31,18 @@
#include "glsl_types.h"
#include "main/context.h"
-#define YYLEX_PARAM state->scanner
-
#undef yyerror
static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg)
{
_mesa_glsl_error(loc, st, "%s", msg);
}
+
+static int
+_mesa_glsl_lex(YYSTYPE *val, YYLTYPE *loc, _mesa_glsl_parse_state *state)
+{
+ return _mesa_glsl_lexer_lex(val, loc, state->scanner);
+}
%}
%expect 0
@@ -55,7 +59,7 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg)
@$.source = 0;
}
-%lex-param {void *scanner}
+%lex-param {struct _mesa_glsl_parse_state *state}
%parse-param {struct _mesa_glsl_parse_state *state}
%union {
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index e36ba584a..a5bc20c23 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -74,7 +74,8 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
this->num_builtins_to_link = 0;
/* Set default language version and extensions */
- this->language_version = 110;
+ this->language_version = ctx->Const.ForceGLSLVersion ?
+ ctx->Const.ForceGLSLVersion : 110;
this->es_shader = false;
this->ARB_texture_rectangle_enable = true;
@@ -430,15 +431,6 @@ struct _mesa_glsl_extension {
*/
const char *name;
- /** True if this extension is available to vertex shaders */
- bool avail_in_VS;
-
- /** True if this extension is available to geometry shaders */
- bool avail_in_GS;
-
- /** True if this extension is available to fragment shaders */
- bool avail_in_FS;
-
/** True if this extension is available to desktop GL shaders */
bool avail_in_GL;
@@ -485,9 +477,9 @@ struct _mesa_glsl_extension {
void set_flags(_mesa_glsl_parse_state *state, ext_behavior behavior) const;
};
-#define EXT(NAME, VS, GS, FS, GL, ES, SUPPORTED_FLAG) \
- { "GL_" #NAME, VS, GS, FS, GL, ES, &gl_extensions::SUPPORTED_FLAG, \
- &_mesa_glsl_parse_state::NAME##_enable, \
+#define EXT(NAME, GL, ES, SUPPORTED_FLAG) \
+ { "GL_" #NAME, GL, ES, &gl_extensions::SUPPORTED_FLAG, \
+ &_mesa_glsl_parse_state::NAME##_enable, \
&_mesa_glsl_parse_state::NAME##_warn }
/**
@@ -495,31 +487,31 @@ struct _mesa_glsl_extension {
* and the conditions under which they are supported.
*/
static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
- /* target availability API availability */
- /* name VS GS FS GL ES supported flag */
- EXT(ARB_conservative_depth, false, false, true, true, false, ARB_conservative_depth),
- EXT(ARB_draw_buffers, false, false, true, true, false, dummy_true),
- EXT(ARB_draw_instanced, true, false, false, true, false, ARB_draw_instanced),
- EXT(ARB_explicit_attrib_location, true, false, true, true, false, ARB_explicit_attrib_location),
- EXT(ARB_fragment_coord_conventions, true, false, true, true, false, ARB_fragment_coord_conventions),
- EXT(ARB_texture_rectangle, true, false, true, true, false, dummy_true),
- EXT(EXT_texture_array, true, false, true, true, false, EXT_texture_array),
- EXT(ARB_shader_texture_lod, true, false, true, true, false, ARB_shader_texture_lod),
- EXT(ARB_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export),
- EXT(AMD_conservative_depth, false, false, true, true, false, ARB_conservative_depth),
- EXT(AMD_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export),
- EXT(OES_texture_3D, true, false, true, false, true, EXT_texture3D),
- EXT(OES_EGL_image_external, true, false, true, false, true, OES_EGL_image_external),
- EXT(ARB_shader_bit_encoding, true, true, true, true, false, ARB_shader_bit_encoding),
- EXT(ARB_uniform_buffer_object, true, false, true, true, false, ARB_uniform_buffer_object),
- EXT(OES_standard_derivatives, false, false, true, false, true, OES_standard_derivatives),
- EXT(ARB_texture_cube_map_array, true, false, true, true, false, ARB_texture_cube_map_array),
- EXT(ARB_shading_language_packing, true, false, true, true, false, ARB_shading_language_packing),
- EXT(ARB_shading_language_420pack, true, true, true, true, false, ARB_shading_language_420pack),
- EXT(ARB_texture_multisample, true, false, true, true, false, ARB_texture_multisample),
- EXT(ARB_texture_query_lod, false, false, true, true, false, ARB_texture_query_lod),
- EXT(ARB_gpu_shader5, true, true, true, true, false, ARB_gpu_shader5),
- EXT(AMD_vertex_shader_layer, true, false, false, true, false, AMD_vertex_shader_layer),
+ /* API availability */
+ /* name GL ES supported flag */
+ EXT(ARB_conservative_depth, true, false, ARB_conservative_depth),
+ EXT(ARB_draw_buffers, true, false, dummy_true),
+ EXT(ARB_draw_instanced, true, false, ARB_draw_instanced),
+ EXT(ARB_explicit_attrib_location, true, false, ARB_explicit_attrib_location),
+ EXT(ARB_fragment_coord_conventions, true, false, ARB_fragment_coord_conventions),
+ EXT(ARB_texture_rectangle, true, false, dummy_true),
+ EXT(EXT_texture_array, true, false, EXT_texture_array),
+ EXT(ARB_shader_texture_lod, true, false, ARB_shader_texture_lod),
+ EXT(ARB_shader_stencil_export, true, false, ARB_shader_stencil_export),
+ EXT(AMD_conservative_depth, true, false, ARB_conservative_depth),
+ EXT(AMD_shader_stencil_export, true, false, ARB_shader_stencil_export),
+ EXT(OES_texture_3D, false, true, EXT_texture3D),
+ EXT(OES_EGL_image_external, false, true, OES_EGL_image_external),
+ EXT(ARB_shader_bit_encoding, true, false, ARB_shader_bit_encoding),
+ EXT(ARB_uniform_buffer_object, true, false, ARB_uniform_buffer_object),
+ EXT(OES_standard_derivatives, false, true, OES_standard_derivatives),
+ EXT(ARB_texture_cube_map_array, true, false, ARB_texture_cube_map_array),
+ EXT(ARB_shading_language_packing, true, false, ARB_shading_language_packing),
+ EXT(ARB_shading_language_420pack, true, false, ARB_shading_language_420pack),
+ EXT(ARB_texture_multisample, true, false, ARB_texture_multisample),
+ EXT(ARB_texture_query_lod, true, false, ARB_texture_query_lod),
+ EXT(ARB_gpu_shader5, true, false, ARB_gpu_shader5),
+ EXT(AMD_vertex_shader_layer, true, false, AMD_vertex_shader_layer),
};
#undef EXT
@@ -532,30 +524,6 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
bool _mesa_glsl_extension::compatible_with_state(const _mesa_glsl_parse_state *
state) const
{
- /* Check that this extension matches the type of shader we are
- * compiling to.
- */
- switch (state->target) {
- case vertex_shader:
- if (!this->avail_in_VS) {
- return false;
- }
- break;
- case geometry_shader:
- if (!this->avail_in_GS) {
- return false;
- }
- break;
- case fragment_shader:
- if (!this->avail_in_FS) {
- return false;
- }
- break;
- default:
- assert (!"Unrecognized shader target");
- return false;
- }
-
/* Check that this extension matches whether we are compiling
* for desktop GL or GLES.
*/
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h
index 7f478df80..1e386dd31 100644
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -337,8 +337,8 @@ extern void _mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state,
extern void _mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state);
union YYSTYPE;
-extern int _mesa_glsl_lex(union YYSTYPE *yylval, YYLTYPE *yylloc,
- void *scanner);
+extern int _mesa_glsl_lexer_lex(union YYSTYPE *yylval, YYLTYPE *yylloc,
+ void *scanner);
extern int _mesa_glsl_parse(struct _mesa_glsl_parse_state *);
diff --git a/mesalib/src/glsl/ir_function_detect_recursion.cpp b/mesalib/src/glsl/ir_function_detect_recursion.cpp
index 5df3ac518..280c4734a 100644
--- a/mesalib/src/glsl/ir_function_detect_recursion.cpp
+++ b/mesalib/src/glsl/ir_function_detect_recursion.cpp
@@ -319,7 +319,6 @@ emit_errors_linked(const void *key, void *data, void *closure)
linker_error(prog, "function `%s' has static recursion.\n", proto);
ralloc_free(proto);
- prog->LinkStatus = false;
}
diff --git a/mesalib/src/glsl/link_interface_blocks.cpp b/mesalib/src/glsl/link_interface_blocks.cpp
index b91860d03..928a88ee2 100644
--- a/mesalib/src/glsl/link_interface_blocks.cpp
+++ b/mesalib/src/glsl/link_interface_blocks.cpp
@@ -31,8 +31,9 @@
#include "linker.h"
#include "main/macros.h"
-bool
-validate_intrastage_interface_blocks(const gl_shader **shader_list,
+void
+validate_intrastage_interface_blocks(struct gl_shader_program *prog,
+ const gl_shader **shader_list,
unsigned num_shaders)
{
glsl_symbol_table interfaces;
@@ -62,16 +63,17 @@ validate_intrastage_interface_blocks(const gl_shader **shader_list,
interfaces.add_interface(iface_type->name, iface_type,
(enum ir_variable_mode) var->mode);
} else if (old_iface_type != iface_type) {
- return false;
+ linker_error(prog, "definitions of interface block `%s' do not"
+ " match\n", iface_type->name);
+ return;
}
}
}
-
- return true;
}
-bool
-validate_interstage_interface_blocks(const gl_shader *producer,
+void
+validate_interstage_interface_blocks(struct gl_shader_program *prog,
+ const gl_shader *producer,
const gl_shader *consumer)
{
glsl_symbol_table interfaces;
@@ -102,9 +104,10 @@ validate_interstage_interface_blocks(const gl_shader *producer,
if (expected_type == NULL)
continue;
- if (var->interface_type != expected_type)
- return false;
+ if (var->interface_type != expected_type) {
+ linker_error(prog, "definitions of interface block `%s' do not "
+ "match\n", var->interface_type->name);
+ return;
+ }
}
-
- return true;
}
diff --git a/mesalib/src/glsl/link_uniform_blocks.cpp b/mesalib/src/glsl/link_uniform_blocks.cpp
index c72d1d8f1..1083653c7 100644
--- a/mesalib/src/glsl/link_uniform_blocks.cpp
+++ b/mesalib/src/glsl/link_uniform_blocks.cpp
@@ -137,7 +137,7 @@ struct block {
bool has_instance_name;
};
-int
+unsigned
link_uniform_blocks(void *mem_ctx,
struct gl_shader_program *prog,
struct gl_shader **shader_list,
diff --git a/mesalib/src/glsl/link_varyings.cpp b/mesalib/src/glsl/link_varyings.cpp
index 51cbdaa0e..2c7e4514e 100644
--- a/mesalib/src/glsl/link_varyings.cpp
+++ b/mesalib/src/glsl/link_varyings.cpp
@@ -43,7 +43,7 @@
/**
* Validate that outputs from one stage match inputs of another
*/
-bool
+void
cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
gl_shader *producer, gl_shader *consumer)
{
@@ -106,7 +106,7 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
producer_stage, output->name,
output->type->name,
consumer_stage, input->type->name);
- return false;
+ return;
}
}
@@ -121,7 +121,7 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
(output->centroid) ? "has" : "lacks",
consumer_stage,
(input->centroid) ? "has" : "lacks");
- return false;
+ return;
}
if (input->invariant != output->invariant) {
@@ -133,7 +133,7 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
(output->invariant) ? "has" : "lacks",
consumer_stage,
(input->invariant) ? "has" : "lacks");
- return false;
+ return;
}
if (input->interpolation != output->interpolation) {
@@ -147,12 +147,10 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
output->interpolation_string(),
consumer_stage,
input->interpolation_string());
- return false;
+ return;
}
}
}
-
- return true;
}
diff --git a/mesalib/src/glsl/link_varyings.h b/mesalib/src/glsl/link_varyings.h
index 7f7be353b..cfc6e474f 100644
--- a/mesalib/src/glsl/link_varyings.h
+++ b/mesalib/src/glsl/link_varyings.h
@@ -214,7 +214,7 @@ private:
};
-bool
+void
cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
gl_shader *producer, gl_shader *consumer);
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index ac010cfbb..942f90615 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -340,12 +340,12 @@ count_attribute_slots(const glsl_type *t)
*
* \param shader Vertex shader executable to be verified
*/
-bool
+void
validate_vertex_shader_executable(struct gl_shader_program *prog,
struct gl_shader *shader)
{
if (shader == NULL)
- return true;
+ return;
/* From the GLSL 1.10 spec, page 48:
*
@@ -378,7 +378,7 @@ validate_vertex_shader_executable(struct gl_shader_program *prog,
find.run(shader->ir);
if (!find.variable_found()) {
linker_error(prog, "vertex shader does not write to `gl_Position'\n");
- return false;
+ return;
}
}
@@ -402,7 +402,7 @@ validate_vertex_shader_executable(struct gl_shader_program *prog,
if (clip_vertex.variable_found() && clip_distance.variable_found()) {
linker_error(prog, "vertex shader writes to both `gl_ClipVertex' "
"and `gl_ClipDistance'\n");
- return false;
+ return;
}
prog->Vert.UsesClipDistance = clip_distance.variable_found();
ir_variable *clip_distance_var =
@@ -410,8 +410,6 @@ validate_vertex_shader_executable(struct gl_shader_program *prog,
if (clip_distance_var)
prog->Vert.ClipDistanceArraySize = clip_distance_var->type->length;
}
-
- return true;
}
@@ -420,12 +418,12 @@ validate_vertex_shader_executable(struct gl_shader_program *prog,
*
* \param shader Fragment shader executable to be verified
*/
-bool
+void
validate_fragment_shader_executable(struct gl_shader_program *prog,
struct gl_shader *shader)
{
if (shader == NULL)
- return true;
+ return;
find_assignment_visitor frag_color("gl_FragColor");
find_assignment_visitor frag_data("gl_FragData");
@@ -436,10 +434,7 @@ validate_fragment_shader_executable(struct gl_shader_program *prog,
if (frag_color.variable_found() && frag_data.variable_found()) {
linker_error(prog, "fragment shader writes to both "
"`gl_FragColor' and `gl_FragData'\n");
- return false;
}
-
- return true;
}
@@ -469,7 +464,7 @@ mode_string(const ir_variable *var)
/**
* Perform validation of global variables used across multiple shaders
*/
-bool
+void
cross_validate_globals(struct gl_shader_program *prog,
struct gl_shader **shader_list,
unsigned num_shaders,
@@ -524,7 +519,7 @@ cross_validate_globals(struct gl_shader_program *prog,
mode_string(var),
var->name, var->type->name,
existing->type->name);
- return false;
+ return;
}
}
@@ -534,7 +529,7 @@ cross_validate_globals(struct gl_shader_program *prog,
linker_error(prog, "explicit locations for %s "
"`%s' have differing values\n",
mode_string(var), var->name);
- return false;
+ return;
}
existing->location = var->location;
@@ -553,7 +548,7 @@ cross_validate_globals(struct gl_shader_program *prog,
linker_error(prog, "explicit bindings for %s "
"`%s' have differing values\n",
mode_string(var), var->name);
- return false;
+ return;
}
existing->binding = var->binding;
@@ -614,7 +609,7 @@ cross_validate_globals(struct gl_shader_program *prog,
linker_error(prog, "initializers for %s "
"`%s' have differing values\n",
mode_string(var), var->name);
- return false;
+ return;
}
} else {
/* If the first-seen instance of a particular uniform did not
@@ -643,7 +638,7 @@ cross_validate_globals(struct gl_shader_program *prog,
"shared global variable `%s' has multiple "
"non-constant initializers.\n",
var->name);
- return false;
+ return;
}
/* Some instance had an initializer, so keep track of that. In
@@ -658,31 +653,29 @@ cross_validate_globals(struct gl_shader_program *prog,
linker_error(prog, "declarations for %s `%s' have "
"mismatching invariant qualifiers\n",
mode_string(var), var->name);
- return false;
+ return;
}
if (existing->centroid != var->centroid) {
linker_error(prog, "declarations for %s `%s' have "
"mismatching centroid qualifiers\n",
mode_string(var), var->name);
- return false;
+ return;
}
} else
variables.add_variable(var);
}
}
-
- return true;
}
/**
* Perform validation of uniforms used across multiple shader stages
*/
-bool
+void
cross_validate_uniforms(struct gl_shader_program *prog)
{
- return cross_validate_globals(prog, prog->_LinkedShaders,
- MESA_SHADER_TYPES, true);
+ cross_validate_globals(prog, prog->_LinkedShaders,
+ MESA_SHADER_TYPES, true);
}
/**
@@ -955,21 +948,21 @@ link_intrastage_shaders(void *mem_ctx,
/* Check that global variables defined in multiple shaders are consistent.
*/
- if (!cross_validate_globals(prog, shader_list, num_shaders, false))
+ cross_validate_globals(prog, shader_list, num_shaders, false);
+ if (!prog->LinkStatus)
return NULL;
/* Check that interface blocks defined in multiple shaders are consistent.
*/
- if (!validate_intrastage_interface_blocks((const gl_shader **)shader_list,
- num_shaders))
+ validate_intrastage_interface_blocks(prog, (const gl_shader **)shader_list,
+ num_shaders);
+ if (!prog->LinkStatus)
return NULL;
- /* Check that uniform blocks between shaders for a stage agree. */
- const int num_uniform_blocks =
+ /* Link up uniform blocks defined within this stage. */
+ const unsigned num_uniform_blocks =
link_uniform_blocks(mem_ctx, prog, shader_list, num_shaders,
&uniform_blocks);
- if (num_uniform_blocks < 0)
- return NULL;
/* Check that there is only a single definition of each function signature
* across all shaders.
@@ -1529,7 +1522,7 @@ store_fragdepth_layout(struct gl_shader_program *prog)
/**
* Validate the resources used by a program versus the implementation limits
*/
-static bool
+static void
check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
{
static const char *const shader_names[MESA_SHADER_TYPES] = {
@@ -1626,8 +1619,6 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
}
}
}
-
- return prog->LinkStatus;
}
void
@@ -1638,7 +1629,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
void *mem_ctx = ralloc_context(NULL); // temporary linker context
- prog->LinkStatus = false;
+ prog->LinkStatus = true; /* All error paths will set this to false */
prog->Validated = false;
prog->_Used = false;
@@ -1724,10 +1715,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
link_intrastage_shaders(mem_ctx, ctx, prog, vert_shader_list,
num_vert_shaders);
- if (sh == NULL)
+ if (!prog->LinkStatus)
goto done;
- if (!validate_vertex_shader_executable(prog, sh))
+ validate_vertex_shader_executable(prog, sh);
+ if (!prog->LinkStatus)
goto done;
_mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_VERTEX],
@@ -1739,10 +1731,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
link_intrastage_shaders(mem_ctx, ctx, prog, frag_shader_list,
num_frag_shaders);
- if (sh == NULL)
+ if (!prog->LinkStatus)
goto done;
- if (!validate_fragment_shader_executable(prog, sh))
+ validate_fragment_shader_executable(prog, sh);
+ if (!prog->LinkStatus)
goto done;
_mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_FRAGMENT],
@@ -1753,36 +1746,36 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
* performed, then locations are assigned for uniforms, attributes, and
* varyings.
*/
- if (cross_validate_uniforms(prog)) {
- unsigned prev;
+ cross_validate_uniforms(prog);
+ if (!prog->LinkStatus)
+ goto done;
- for (prev = 0; prev < MESA_SHADER_TYPES; prev++) {
- if (prog->_LinkedShaders[prev] != NULL)
- break;
- }
+ unsigned prev;
- /* Validate the inputs of each stage with the output of the preceding
- * stage.
- */
- for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) {
- if (prog->_LinkedShaders[i] == NULL)
- continue;
+ for (prev = 0; prev < MESA_SHADER_TYPES; prev++) {
+ if (prog->_LinkedShaders[prev] != NULL)
+ break;
+ }
- if (!validate_interstage_interface_blocks(prog->_LinkedShaders[prev],
- prog->_LinkedShaders[i])) {
- linker_error(prog, "interface block mismatch between shader stages\n");
- goto done;
- }
+ /* Validate the inputs of each stage with the output of the preceding
+ * stage.
+ */
+ for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) {
+ if (prog->_LinkedShaders[i] == NULL)
+ continue;
- if (!cross_validate_outputs_to_inputs(prog,
- prog->_LinkedShaders[prev],
- prog->_LinkedShaders[i]))
- goto done;
+ validate_interstage_interface_blocks(prog, prog->_LinkedShaders[prev],
+ prog->_LinkedShaders[i]);
+ if (!prog->LinkStatus)
+ goto done;
- prev = i;
- }
+ cross_validate_outputs_to_inputs(prog,
+ prog->_LinkedShaders[prev],
+ prog->_LinkedShaders[i]);
+ if (!prog->LinkStatus)
+ goto done;
- prog->LinkStatus = true;
+ prev = i;
}
@@ -1971,7 +1964,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
link_assign_uniform_locations(prog);
store_fragdepth_layout(prog);
- if (!check_resources(ctx, prog))
+ check_resources(ctx, prog);
+ if (!prog->LinkStatus)
goto done;
/* OpenGL ES requires that a vertex shader and a fragment shader both be
diff --git a/mesalib/src/glsl/linker.h b/mesalib/src/glsl/linker.h
index 2fe2410c2..0ce747d6c 100644
--- a/mesalib/src/glsl/linker.h
+++ b/mesalib/src/glsl/linker.h
@@ -53,19 +53,21 @@ extern bool
link_uniform_blocks_are_compatible(const gl_uniform_block *a,
const gl_uniform_block *b);
-extern int
+extern unsigned
link_uniform_blocks(void *mem_ctx,
struct gl_shader_program *prog,
struct gl_shader **shader_list,
unsigned num_shaders,
struct gl_uniform_block **blocks_ret);
-bool
-validate_intrastage_interface_blocks(const gl_shader **shader_list,
+void
+validate_intrastage_interface_blocks(struct gl_shader_program *prog,
+ const gl_shader **shader_list,
unsigned num_shaders);
-bool
-validate_interstage_interface_blocks(const gl_shader *producer,
+void
+validate_interstage_interface_blocks(struct gl_shader_program *prog,
+ const gl_shader *producer,
const gl_shader *consumer);
/**