From b3e71de19f35773c22391151ebb02062d6894bc9 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 12 Nov 2016 02:00:09 +0200 Subject: [PATCH] Process existing inputs in passthrough Vertex shader inputs are not linked to any outputs so they weren't being recognized for passthrough. Also, some inputs might have already been declared either explicitly or implicitly so those declarations should be preferred over creating new ones. --- source/programcompiler.cpp | 65 ++++++++++++++++++++++++-------------- source/programcompiler.h | 2 +- 2 files changed, 42 insertions(+), 25 deletions(-) diff --git a/source/programcompiler.cpp b/source/programcompiler.cpp index d518ef3a..79031e41 100644 --- a/source/programcompiler.cpp +++ b/source/programcompiler.cpp @@ -452,7 +452,7 @@ void ProgramCompiler::InterfaceGenerator::visit(Block &block) if(scope_level==1) { - for(map::iterator j=iface_declarations.begin(); j!=iface_declarations.end(); ++j) + for(map::iterator j=iface_declarations.begin(); j!=iface_declarations.end(); ++j) { list >::iterator k = block.body.insert(i, j->second); (*k)->visit(*this); @@ -478,22 +478,22 @@ string ProgramCompiler::InterfaceGenerator::change_prefix(const string &name, co return prefix+name.substr(offset); } -bool ProgramCompiler::InterfaceGenerator::generate_interface(VariableDeclaration &out, const string &iface, const string &name) +bool ProgramCompiler::InterfaceGenerator::generate_interface(VariableDeclaration &var, const string &iface, const string &name) { const map &stage_vars = (iface=="in" ? stage->in_variables : stage->out_variables); if(stage_vars.count(name) || iface_declarations.count(name)) return false; VariableDeclaration* iface_var = new VariableDeclaration; - iface_var->sampling = out.sampling; + iface_var->sampling = var.sampling; iface_var->interface = iface; - iface_var->type = out.type; - iface_var->type_declaration = out.type_declaration; + iface_var->type = var.type; + iface_var->type_declaration = var.type_declaration; iface_var->name = name; - iface_var->array = (out.array || (stage->type==GEOMETRY && iface=="in")); - iface_var->array_size = out.array_size; + iface_var->array = (var.array || (stage->type==GEOMETRY && iface=="in")); + iface_var->array_size = var.array_size; if(iface=="in") - iface_var->linked_declaration = &out; + iface_var->linked_declaration = &var; iface_declarations[name] = iface_var; return true; @@ -564,31 +564,48 @@ void ProgramCompiler::InterfaceGenerator::visit(VariableDeclaration &var) void ProgramCompiler::InterfaceGenerator::visit(Passthrough &pass) { + vector pass_vars; + + for(map::const_iterator i=stage->in_variables.begin(); i!=stage->in_variables.end(); ++i) + pass_vars.push_back(i->second); + for(map::const_iterator i=iface_declarations.begin(); i!=iface_declarations.end(); ++i) + if(i->second->interface=="in") + pass_vars.push_back(i->second); + if(stage->previous) { const map &prev_out = stage->previous->out_variables; for(map::const_iterator i=prev_out.begin(); i!=prev_out.end(); ++i) { - string out_name = change_prefix(i->second->name, out_prefix); - generate_interface(*i->second, "in", i->second->name); - generate_interface(*i->second, "out", out_name); + bool linked = false; + for(vector::const_iterator j=pass_vars.begin(); (!linked && j!=pass_vars.end()); ++j) + linked = ((*j)->linked_declaration==i->second); - VariableReference *ref = new VariableReference; - ref->name = i->first; - if(pass.subscript) - { - BinaryExpression *subscript = new BinaryExpression; - subscript->left = ref; - subscript->oper = "["; - subscript->right = pass.subscript; - subscript->after = "]"; - insert_assignment(out_name, subscript); - } - else - insert_assignment(out_name, ref); + if(!linked && generate_interface(*i->second, "in", i->second->name)) + pass_vars.push_back(i->second); } } + for(vector::const_iterator i=pass_vars.begin(); i!=pass_vars.end(); ++i) + { + string out_name = change_prefix((*i)->name, out_prefix); + generate_interface(**i, "out", out_name); + + VariableReference *ref = new VariableReference; + ref->name = (*i)->name; + if(pass.subscript) + { + BinaryExpression *subscript = new BinaryExpression; + subscript->left = ref; + subscript->oper = "["; + subscript->right = pass.subscript; + subscript->after = "]"; + insert_assignment(out_name, subscript); + } + else + insert_assignment(out_name, ref); + } + remove_node = true; } diff --git a/source/programcompiler.h b/source/programcompiler.h index db7aefe9..3b63c5e9 100644 --- a/source/programcompiler.h +++ b/source/programcompiler.h @@ -72,7 +72,7 @@ private: std::string in_prefix; std::string out_prefix; unsigned scope_level; - std::map iface_declarations; + std::map iface_declarations; bool remove_node; std::list insert_nodes; -- 2.43.0