X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Fgenerate.cpp;h=ac16c31f889dce86ae02541121802d84b59a496e;hb=ab5f2e6;hp=379a6871ae754aef88ec7b589997493e025733e1;hpb=947bb7477205c038aa1804b84452cddd2108550a;p=libs%2Fgl.git diff --git a/source/glsl/generate.cpp b/source/glsl/generate.cpp index 379a6871..ac16c31f 100644 --- a/source/glsl/generate.cpp +++ b/source/glsl/generate.cpp @@ -12,13 +12,19 @@ DeclarationCombiner::DeclarationCombiner(): toplevel(true) { } +void DeclarationCombiner::apply(Stage &stage) +{ + visit(stage.content); + NodeRemover().apply(stage, nodes_to_remove); +} + void DeclarationCombiner::visit(Block &block) { if(!toplevel) return; SetForScope set(toplevel, false); - BlockModifier::visit(block); + TraversingVisitor::visit(block); } void DeclarationCombiner::visit(FunctionDeclaration &func) @@ -64,7 +70,7 @@ void DeclarationCombiner::visit(VariableDeclaration &var) else ptr->layout = var.layout; } - remove_node = true; + nodes_to_remove.insert(&var); } else ptr = &var; @@ -240,7 +246,8 @@ void FunctionResolver::visit(FunctionDeclaration &func) InterfaceGenerator::InterfaceGenerator(): stage(0), - scope_level(0) + scope_level(0), + current_block(0) { } string InterfaceGenerator::get_out_prefix(Stage::Type type) @@ -260,26 +267,20 @@ void InterfaceGenerator::apply(Stage &s) in_prefix = get_out_prefix(stage->previous->type); out_prefix = get_out_prefix(stage->type); visit(s.content); + NodeRemover().apply(s, nodes_to_remove); } void InterfaceGenerator::visit(Block &block) { SetForScope set(scope_level, scope_level+1); - for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ) + SetForScope set_block(current_block, &block); + for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ++i) { - (*i)->visit(*this); - + assignment_insert_point = i; if(scope_level==1) - { - for(map >::iterator j=iface_declarations.begin(); j!=iface_declarations.end(); ++j) - { - NodeList::iterator k = block.body.insert(i, j->second); - (*k)->visit(*this); - } - iface_declarations.clear(); - } + iface_insert_point = i; - apply_and_increment(block, i); + (*i)->visit(*this); } } @@ -292,7 +293,7 @@ string InterfaceGenerator::change_prefix(const string &name, const string &prefi bool 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)) + if(stage_vars.count(name)) return false; VariableDeclaration* iface_var = new VariableDeclaration; @@ -309,7 +310,12 @@ bool InterfaceGenerator::generate_interface(VariableDeclaration &var, const stri iface_var->array_size = var.array_size; if(iface=="in") iface_var->linked_declaration = &var; - iface_declarations[name] = iface_var; + stage->content.body.insert(iface_insert_point, iface_var); + { + SetForScope set_level(scope_level, 1); + SetForScope set_block(current_block, &stage->content); + iface_var->visit(*this); + } return true; } @@ -325,8 +331,8 @@ ExpressionStatement &InterfaceGenerator::insert_assignment(const string &left, E ExpressionStatement *stmt = new ExpressionStatement; stmt->expression = assign; + current_block->body.insert(assignment_insert_point, stmt); stmt->visit(*this); - insert_nodes.push_back(stmt); return *stmt; } @@ -335,8 +341,6 @@ void InterfaceGenerator::visit(VariableReference &var) { if(var.declaration || !stage->previous) return; - if(iface_declarations.count(var.name)) - return; const map &prev_out = stage->previous->out_variables; map::const_iterator i = prev_out.find(var.name); @@ -357,7 +361,7 @@ void InterfaceGenerator::visit(VariableDeclaration &var) stage->out_variables[var.name] = &var; else if(generate_interface(var, "out", change_prefix(var.name, string()))) { - remove_node = true; + nodes_to_remove.insert(&var); if(var.init_expression) { ExpressionStatement &stmt = insert_assignment(var.name, var.init_expression->clone()); @@ -393,9 +397,6 @@ void InterfaceGenerator::visit(Passthrough &pass) 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.get()); if(stage->previous) { @@ -449,7 +450,7 @@ void InterfaceGenerator::visit(Passthrough &pass) insert_assignment(out_name, ref); } - remove_node = true; + nodes_to_remove.insert(&pass); }