X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Foptimize.cpp;h=c9d3c33a543830f3618a6d2e337d92519026de6c;hb=9978e2f62777795bf478b301aadffdd0ee8cbd41;hp=0d6f753768ad2bd5fdbf7ff4d3a8f44ff75f1cb9;hpb=57ff0b07aca38aee593a85831ba600b77e3b7a7b;p=libs%2Fgl.git diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index 0d6f7537..c9d3c33a 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -356,7 +356,7 @@ void ExpressionInliner::visit(RefPtr &expr) ExpressionUse use; use.reference = &expr; use.ref_scope = current_block; - use.blocked = access_write; + use.blocked = access_write || r_ref_info->blocked; if(iteration_body && !r_ref_info->trivial) { @@ -428,10 +428,10 @@ void ExpressionInliner::visit(Assignment &assign) r_trivial = true; visit(assign.right); - auto i = assignments.find(assign.target); + auto i = assignments.find(assign.target.declaration); if(i!=assignments.end()) { - if(iteration_body && i->second->expression) + if(iteration_body && i->second && i->second->expression) { /* Block inlining into previous references within the iteration statement. On iterations after the first they would refer to the @@ -441,6 +441,10 @@ void ExpressionInliner::visit(Assignment &assign) u.blocked = (k==iteration_body); } + for(; (i!=assignments.end() && i->first.declaration==assign.target.declaration); ++i) + if(targets_overlap(i->first, assign.target)) + i->second->blocked = true; + expressions.push_back(ExpressionInfo()); ExpressionInfo &info = expressions.back(); info.target = assign.target; @@ -450,7 +454,7 @@ void ExpressionInliner::visit(Assignment &assign) info.assign_scope = current_block; info.trivial = r_trivial; - i->second = &info; + assignments[assign.target] = &info; } r_trivial = false; @@ -1260,23 +1264,15 @@ bool UnusedVariableRemover::apply(Stage &s) for(const auto &kvp: variables) { - if(kvp.second.output) + if(!kvp.second.referenced) + unused_nodes.insert(kvp.first); + else if(kvp.second.output) { /* The last visible assignments of output variables are used by the next stage or the API. */ for(AssignmentInfo *a: kvp.second.assignments) unused_nodes.erase(a->node); } - - if(!kvp.second.output && !kvp.second.referenced) - { - // Don't remove variables from inside interface blocks. - if(!kvp.second.interface_block) - unused_nodes.insert(kvp.first); - } - else if(kvp.second.interface_block) - // Interface blocks are kept if even one member is used. - unused_nodes.erase(kvp.second.interface_block); } NodeRemover().apply(s, unused_nodes); @@ -1292,36 +1288,12 @@ void UnusedVariableRemover::referenced(const Assignment::Target &target, Node &n { bool loop_external = false; for(AssignmentInfo *a: var_info.assignments) - { - bool covered = true; - for(unsigned j=0; (covered && jtarget.chain_len && j(a->target.chain[j]&0xC0); - Assignment::Target::ChainType type2 = static_cast(target.chain[j]&0xC0); - unsigned index1 = a->target.chain[j]&0x3F; - unsigned index2 = target.chain[j]&0x3F; - if(type1==Assignment::Target::SWIZZLE || type2==Assignment::Target::SWIZZLE) - { - if(type1==Assignment::Target::SWIZZLE && type2==Assignment::Target::SWIZZLE) - covered = index1&index2; - else if(type1==Assignment::Target::ARRAY && index1<4) - covered = index2&(1<target, target)) { a->used_by.push_back(&node); if(a->in_loop clear_reference(r_reference, Assignment::Target()); binary.right->visit(*this); } @@ -1493,14 +1466,14 @@ void UnusedVariableRemover::visit(VariableDeclaration &var) return; VariableInfo &var_info = variables[&var]; - var_info.interface_block = interface_block; /* 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->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_"))); + var_info.output = (var.interface=="out" && (stage->type==Stage::FRAGMENT || var.linked_declaration || !var.name.compare(0, 3, "gl_"))); + + // Linked outputs are automatically referenced. + if(var_info.output && var.linked_declaration) + var_info.referenced = true; if(var.init_expression) { @@ -1581,8 +1554,14 @@ void UnusedVariableRemover::visit(Iteration &iter) vector saved_refs; swap(loop_ext_refs, saved_refs); { + if(iter.init_statement) + iter.init_statement->visit(*this); SetForScope set_loop(in_loop, in_loop+1); - TraversingVisitor::visit(iter); + if(iter.condition) + iter.condition->visit(*this); + iter.body.visit(*this); + if(iter.loop_expression) + iter.loop_expression->visit(*this); } swap(loop_ext_refs, saved_refs);