X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Fgenerate.cpp;h=fe053ade254c3105d80771a72d575b264583946a;hb=3f899b1fc2e04f4fe74c99ad3e8ebb900c257214;hp=c073d870ac4d779591fa2c896724737a5de278ca;hpb=7daccf2582084283a9e5064995f674eef835996e;p=libs%2Fgl.git diff --git a/source/glsl/generate.cpp b/source/glsl/generate.cpp index c073d870..fe053ade 100644 --- a/source/glsl/generate.cpp +++ b/source/glsl/generate.cpp @@ -1,4 +1,6 @@ +#include #include +#include #include "builtin.h" #include "generate.h" @@ -22,20 +24,6 @@ void DeclarationCombiner::visit(Block &block) TraversingVisitor::visit(block); } -void DeclarationCombiner::visit(FunctionDeclaration &func) -{ - vector &decls = functions[func.name]; - if(func.definition) - { - for(vector::iterator i=decls.begin(); i!=decls.end(); ++i) - { - (*i)->definition = func.definition; - (*i)->body.body.clear(); - } - } - decls.push_back(&func); -} - void DeclarationCombiner::visit(VariableDeclaration &var) { VariableDeclaration *&ptr = variables[var.name]; @@ -73,7 +61,54 @@ void DeclarationCombiner::visit(VariableDeclaration &var) } -void BlockResolver::enter(Block &block) +ConstantSpecializer::ConstantSpecializer(): + values(0) +{ } + +void ConstantSpecializer::apply(Stage &stage, const map *v) +{ + values = v; + stage.content.visit(*this); +} + +void ConstantSpecializer::visit(VariableDeclaration &var) +{ + bool specializable = false; + if(var.layout) + { + vector &qualifiers = var.layout->qualifiers; + for(vector::iterator i=qualifiers.begin(); i!=qualifiers.end(); ++i) + if(i->name=="constant_id") + { + specializable = true; + if(values) + qualifiers.erase(i); + else if(i->value==-1) + i->value = hash32(var.name)&0x7FFFFFFF; + break; + } + + if(qualifiers.empty()) + var.layout = 0; + } + + if(specializable && values) + { + map::const_iterator i = values->find(var.name); + if(i!=values->end()) + { + RefPtr literal = new Literal; + if(var.type=="bool") + literal->token = (i->second ? "true" : "false"); + else if(var.type=="int") + literal->token = lexical_cast(i->second); + var.init_expression = literal; + } + } +} + + +void BlockHierarchyResolver::enter(Block &block) { block.parent = current_block; } @@ -91,6 +126,8 @@ VariableResolver::VariableResolver(): void VariableResolver::apply(Stage &s) { stage = &s; + s.types.clear(); + s.interface_blocks.clear(); Stage *builtin_stage = get_builtins(s.type); builtins = (builtin_stage ? &builtin_stage->content : 0); s.content.visit(*this); @@ -268,29 +305,44 @@ void VariableResolver::visit(InterfaceBlock &iface) } +void FunctionResolver::apply(Stage &s) +{ + stage = &s; + s.functions.clear(); + s.content.visit(*this); +} + void FunctionResolver::visit(FunctionCall &call) { - map >::iterator i = functions.find(call.name); - if(i!=functions.end()) - call.declaration = i->second.back(); + map::iterator i = stage->functions.find(call.name); + if(i!=stage->functions.end()) + call.declaration = i->second; TraversingVisitor::visit(call); } void FunctionResolver::visit(FunctionDeclaration &func) { - vector &decls = functions[func.name]; - if(func.definition) + FunctionDeclaration *&stage_decl = stage->functions[func.name]; + vector &decls = declarations[func.name]; + if(func.definition==&func) { + stage_decl = &func; + for(vector::iterator i=decls.begin(); i!=decls.end(); ++i) + { (*i)->definition = func.definition; - decls.clear(); - decls.push_back(&func); + (*i)->body.body.clear(); + } } - else if(!decls.empty() && decls.back()->definition) - func.definition = decls.back()->definition; else - decls.push_back(&func); + { + if(!stage_decl) + stage_decl = &func; + + func.definition = stage_decl->definition; + } + decls.push_back(&func); TraversingVisitor::visit(func); } @@ -363,6 +415,7 @@ bool InterfaceGenerator::generate_interface(VariableDeclaration &var, const stri iface_var->array_size = var.array_size; if(iface=="in") { + iface_var->layout = var.layout; iface_var->linked_declaration = &var; var.linked_declaration = iface_var; }