From: Mikko Rasa Date: Fri, 2 Dec 2016 10:26:12 +0000 (+0200) Subject: Reorder declarations in shaders X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=00be85f53c5bec0be00a7ed6271e1f5a38e0b534;hp=ed06ec666e4b3dac21c4482c56e99bf7fd19b042 Reorder declarations in shaders So that structs appear before variables and variables appear before functions. This ensures that the declarations stay visible if an expression is moved to an earlier point while inlining functions. --- diff --git a/source/programcompiler.cpp b/source/programcompiler.cpp index fdb2576e..7224df1e 100644 --- a/source/programcompiler.cpp +++ b/source/programcompiler.cpp @@ -165,6 +165,7 @@ void ProgramCompiler::generate(Stage &stage) apply(stage); apply(stage); apply(stage); + apply(stage); apply(stage); } @@ -917,6 +918,45 @@ void ProgramCompiler::VariableRenamer::visit(VariableDeclaration &var) } +ProgramCompiler::DeclarationReorderer::DeclarationReorderer(): + kind(NO_DECLARATION) +{ } + +void ProgramCompiler::DeclarationReorderer::visit(Block &block) +{ + list >::iterator struct_insert_point = block.body.end(); + list >::iterator variable_insert_point = block.body.end(); + + for(list >::iterator i=block.body.begin(); i!=block.body.end(); ) + { + kind = NO_DECLARATION; + (*i)->visit(*this); + + bool moved = false; + if(kind==STRUCT && struct_insert_point!=block.body.end()) + { + block.body.insert(struct_insert_point, *i); + moved = true; + } + else if(kind>STRUCT && struct_insert_point==block.body.end()) + struct_insert_point = i; + + if(kind==VARIABLE && variable_insert_point!=block.body.end()) + { + block.body.insert(variable_insert_point, *i); + moved = true; + } + else if(kind>VARIABLE && variable_insert_point==block.body.end()) + variable_insert_point = i; + + if(moved) + block.body.erase(i++); + else + ++i; + } +} + + ProgramCompiler::ExpressionEvaluator::ExpressionEvaluator(): variable_values(0), result(0.0f), diff --git a/source/programcompiler.h b/source/programcompiler.h index 398bb214..8c4034d4 100644 --- a/source/programcompiler.h +++ b/source/programcompiler.h @@ -156,6 +156,29 @@ private: virtual void visit(ProgramSyntax::VariableDeclaration &); }; + struct DeclarationReorderer: Visitor + { + enum DeclarationKind + { + NO_DECLARATION, + LAYOUT, + STRUCT, + VARIABLE, + FUNCTION + }; + + DeclarationKind kind; + + DeclarationReorderer(); + + virtual void visit(ProgramSyntax::Block &); + virtual void visit(ProgramSyntax::InterfaceLayout &) { kind = LAYOUT; } + virtual void visit(ProgramSyntax::StructDeclaration &) { kind = STRUCT; } + virtual void visit(ProgramSyntax::VariableDeclaration &) { kind = VARIABLE; } + virtual void visit(ProgramSyntax::InterfaceBlock &) { kind = VARIABLE; } + virtual void visit(ProgramSyntax::FunctionDeclaration &) { kind = FUNCTION; } + }; + struct ExpressionEvaluator: ProgramSyntax::NodeVisitor { typedef std::map ValueMap;