From 9229a3e70dace406d897148857ed6567986c3bcd Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 12 Mar 2021 11:53:11 +0200 Subject: [PATCH] Limit GLSL passthrough statement to variables declared by that point This fixes an issue where a base module's passthrough statement would generate references to inputs declared in an importing module, resulting in a compile error. --- source/glsl/generate.cpp | 16 ++++---- source/glsl/generate.h | 1 + tests/glsl/passthrough_declaration_order.glsl | 41 +++++++++++++++++++ 3 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 tests/glsl/passthrough_declaration_order.glsl diff --git a/source/glsl/generate.cpp b/source/glsl/generate.cpp index 01d34c63..ab487a44 100644 --- a/source/glsl/generate.cpp +++ b/source/glsl/generate.cpp @@ -1065,6 +1065,8 @@ VariableDeclaration *InterfaceGenerator::generate_interface(VariableDeclaration iface_target_block->body.insert(iface_insert_point, iface_var); iface_target_block->variables.insert(make_pair(name, iface_var)); + if(iface_target_block==&stage->content && iface=="in") + declared_inputs.push_back(iface_var); return iface_var; } @@ -1197,11 +1199,13 @@ void InterfaceGenerator::visit(VariableDeclaration &var) } } } - else if(var.interface=="in") + else if(var.interface=="in" && current_block==&stage->content) { + declared_inputs.push_back(&var); + /* Try to link input variables in global scope with output variables from previous stage. */ - if(current_block==&stage->content && !var.linked_declaration && stage->previous) + if(!var.linked_declaration && stage->previous) { const map &prev_vars = stage->previous->content.variables; map::const_iterator i = prev_vars.find(var.name); @@ -1246,12 +1250,8 @@ void InterfaceGenerator::visit(FunctionDeclaration &func) void InterfaceGenerator::visit(Passthrough &pass) { - vector pass_vars; - - // Pass through all input variables of this stage. - for(map::const_iterator i=stage->content.variables.begin(); i!=stage->content.variables.end(); ++i) - if(i->second->interface=="in") - pass_vars.push_back(i->second); + // Pass through all input variables declared so far. + vector pass_vars = declared_inputs; if(stage->previous) { diff --git a/source/glsl/generate.h b/source/glsl/generate.h index 4e66ef68..c7a162e5 100644 --- a/source/glsl/generate.h +++ b/source/glsl/generate.h @@ -200,6 +200,7 @@ private: std::string out_prefix; bool function_scope; bool copy_block; + std::vector declared_inputs; Block *iface_target_block; NodeList::iterator iface_insert_point; NodeList::iterator assignment_insert_point; diff --git a/tests/glsl/passthrough_declaration_order.glsl b/tests/glsl/passthrough_declaration_order.glsl new file mode 100644 index 00000000..52712d85 --- /dev/null +++ b/tests/glsl/passthrough_declaration_order.glsl @@ -0,0 +1,41 @@ +#pragma MSP stage(vertex) +layout(location=0) in vec4 position; +void process(); +void main() +{ + gl_Position = position; + passthrough; + process(); +} +layout(location=1) in vec4 color; +void process() +{ + passthrough; +} + +#pragma MSP stage(fragment) +layout(location=0) out vec4 frag_color; +void main() +{ + frag_color = color; +} + +/* Expected output: vertex +layout(location=0) in vec4 position; +layout(location=1) in vec4 color; +out vec4 _vs_out_color; +void main() +{ + gl_Position = position; + _vs_out_color = color; +} +*/ + +/* Expected output: fragment +layout(location=0) out vec4 frag_color; +in vec4 _vs_out_color; +void main() +{ + frag_color = _vs_out_color; +} +*/ -- 2.43.0