From 966a797e433120094e1e39693f1f17be8678d03e Mon Sep 17 00:00:00 2001 From: "vadym.shovkoplias" Date: Tue, 28 Aug 2018 10:32:18 +0300 Subject: [PATCH] glsl/linker: Link all out vars from a shader objects on a single stage During intra stage linking some out variables can be dropped because it is not used in a shader with the main function. But these out vars can be referenced on later stages which can lead to further linking errors. Signed-off-by: Vadym Shovkoplias Reviewed-by: Timothy Arceri Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105731 --- src/compiler/glsl/linker.cpp | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index 3ce78fe6428..f08971d7803 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -2187,6 +2187,40 @@ link_cs_input_layout_qualifiers(struct gl_shader_program *prog, } } +/** + * Link all out variables on a single stage which are not + * directly used in a shader with the main function. + */ +static void +link_output_variables(struct gl_linked_shader *linked_shader, + struct gl_shader **shader_list, + unsigned num_shaders) +{ + struct glsl_symbol_table *symbols = linked_shader->symbols; + + for (unsigned i = 0; i < num_shaders; i++) { + + /* Skip shader object with main function */ + if (shader_list[i]->symbols->get_function("main")) + continue; + + foreach_in_list(ir_instruction, ir, shader_list[i]->ir) { + if (ir->ir_type != ir_type_variable) + continue; + + ir_variable *const var = (ir_variable *) ir; + + if (var->data.mode == ir_var_shader_out && + !symbols->get_variable(var->name)) { + symbols->add_variable(var); + linked_shader->ir->push_head(var); + } + } + } + + return; +} + /** * Combine a group of shaders for a single stage to generate a linked shader @@ -2352,6 +2386,9 @@ link_intrastage_shaders(void *mem_ctx, return NULL; } + if (linked->Stage != MESA_SHADER_FRAGMENT) + link_output_variables(linked, shader_list, num_shaders); + /* Make a pass over all variable declarations to ensure that arrays with * unspecified sizes have a size specified. The size is inferred from the * max_array_access field. -- 2.30.2