summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/glsl/linker.cpp40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
index 3fde7e78d31..2f4c8860547 100644
--- a/src/compiler/glsl/linker.cpp
+++ b/src/compiler/glsl/linker.cpp
@@ -4640,6 +4640,45 @@ link_assign_subroutine_types(struct gl_shader_program *prog)
}
static void
+verify_subroutine_associated_funcs(struct gl_shader_program *prog)
+{
+ unsigned mask = prog->data->linked_stages;
+ while (mask) {
+ const int i = u_bit_scan(&mask);
+ gl_program *p = prog->_LinkedShaders[i]->Program;
+ glsl_symbol_table *symbols = prog->_LinkedShaders[i]->symbols;
+
+ /*
+ * From OpenGL ES Shading Language 4.00 specification
+ * (6.1.2 Subroutines):
+ * "A program will fail to compile or link if any shader
+ * or stage contains two or more functions with the same
+ * name if the name is associated with a subroutine type."
+ */
+ for (unsigned j = 0; j < p->sh.NumSubroutineFunctions; j++) {
+ unsigned definitions = 0;
+ char *name = p->sh.SubroutineFunctions[j].name;
+ ir_function *fn = symbols->get_function(name);
+
+ /* Calculate number of function definitions with the same name */
+ foreach_in_list(ir_function_signature, sig, &fn->signatures) {
+ if (sig->is_defined) {
+ if (++definitions > 1) {
+ linker_error(prog, "%s shader contains two or more function "
+ "definitions with name `%s', which is "
+ "associated with a subroutine type.\n",
+ _mesa_shader_stage_to_string(i),
+ fn->name);
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+static void
set_always_active_io(exec_list *ir, ir_variable_mode io_mode)
{
assert(io_mode == ir_var_shader_in || io_mode == ir_var_shader_out);
@@ -5024,6 +5063,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
check_explicit_uniform_locations(ctx, prog);
link_assign_subroutine_types(prog);
+ verify_subroutine_associated_funcs(prog);
if (!prog->data->LinkStatus)
goto done;