X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Foptimize.cpp;h=596d7e20b071365850cb8d3e894b6eb0db910c1b;hb=c1b42fd479c5ca4cbab258ee0fa5c7cac319f928;hp=d57002552540c6c375cb7446f8465a9538a0a42d;hpb=22d5405729048ee2677a1e45e309e6328de64a26;p=libs%2Fgl.git diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index d5700255..596d7e20 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -8,6 +8,55 @@ namespace Msp { namespace GL { namespace SL { +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(); (!specializable && i!=qualifiers.end()); ++i) + if(i->name=="constant_id") + { + specializable = true; + qualifiers.erase(i); + } + + if(qualifiers.empty()) + var.layout = 0; + } + + if(specializable) + { + 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"); + literal->value = static_cast(i->second); + } + else if(var.type=="int") + { + literal->token = lexical_cast(i->second); + literal->value = i->second; + } + var.init_expression = literal; + } + } +} + + InlineableFunctionLocator::InlineableFunctionLocator(): current_function(0), return_count(0) @@ -102,8 +151,7 @@ const string &InlineContentInjector::apply(Stage &stage, FunctionDeclaration &ta SetForScope set_pass(pass, RENAME); var->visit(*this); - staging_block.body.push_back(0); - staging_block.body.back() = var; + staging_block.body.push_back_nocopy(var); params.push_back(var); } @@ -117,8 +165,7 @@ const string &InlineContentInjector::apply(Stage &stage, FunctionDeclaration &ta SetForScope set_pass(pass, RENAME); r_inlined_statement->visit(*this); - staging_block.body.push_back(0); - staging_block.body.back() = r_inlined_statement; + staging_block.body.push_back_nocopy(r_inlined_statement); } /* Now collect names from the staging block. Local variables that would @@ -188,8 +235,11 @@ void InlineContentInjector::visit(VariableDeclaration &var) if(pass==RENAME) { + /* Check against conflicts with the other context as well as variables + already renamed here. */ + bool conflict = (staging_block.variables.count(var.name) || referenced_names.count(var.name)); staging_block.variables[var.name] = &var; - if(referenced_names.count(var.name)) + if(conflict) { string mapped_name = get_unused_variable_name(staging_block, var.name); if(mapped_name!=var.name) @@ -267,12 +317,12 @@ void FunctionInliner::visit(Block &block) void FunctionInliner::visit(FunctionCall &call) { + for(NodeArray::iterator i=call.arguments.begin(); (!r_inlined_here && i!=call.arguments.end()); ++i) + visit(*i); + if(r_inlined_here) return; - for(NodeArray::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i) - visit(*i); - FunctionDeclaration *def = call.declaration; if(def) def = def->definition; @@ -1118,7 +1168,7 @@ void UnusedVariableRemover::visit(VariableDeclaration &var) /* Mark variables as output if they're used by the next stage or the graphics API. */ if(interface_block) - var_info.output = (interface_block->interface=="out" && (interface_block->linked_block || !interface_block->name.compare(0, 3, "gl_"))); + var_info.output = (interface_block->interface=="out" && (interface_block->linked_block || !interface_block->block_name.compare(0, 3, "gl_"))); else var_info.output = (var.interface=="out" && (stage->type==Stage::FRAGMENT || var.linked_declaration || !var.name.compare(0, 3, "gl_"))); @@ -1140,7 +1190,7 @@ void UnusedVariableRemover::visit(InterfaceBlock &iface) else { VariableInfo &var_info = variables[&iface]; - var_info.output = (iface.interface=="out" && (iface.linked_block || !iface.name.compare(0, 3, "gl_"))); + var_info.output = (iface.interface=="out" && (iface.linked_block || !iface.block_name.compare(0, 3, "gl_"))); } }