X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Ffinalize.cpp;h=eee8a5198efa8b2037848bcc7a34bd8cd0d333ff;hb=c4aeeced7b397d46772577775bd3a0d6c4706cba;hp=2d1a46fb0862639457a1137a2de94036c6a1f7da;hpb=8f2713a3f1501e90016bb8069ecd08dde2f90e56;p=libs%2Fgl.git diff --git a/source/glsl/finalize.cpp b/source/glsl/finalize.cpp index 2d1a46fb..eee8a519 100644 --- a/source/glsl/finalize.cpp +++ b/source/glsl/finalize.cpp @@ -12,16 +12,75 @@ namespace Msp { namespace GL { namespace SL { +StructOrganizer::StructOrganizer(): + offset(-1) +{ } + +void StructOrganizer::visit(StructDeclaration &strct) +{ + SetForScope set_offset(offset, 0); + TraversingVisitor::visit(strct); +} + +void StructOrganizer::visit(VariableDeclaration &var) +{ + if(offset>=0) + { + int *layout_offset = 0; + bool has_matrix_order = false; + if(var.layout) + { + for(Layout::Qualifier &q: var.layout->qualifiers) + { + if(q.name=="offset" && q.has_value) + { + layout_offset = &q.value; + if(q.value>=offset) + offset = q.value; + } + else if(q.name=="column_major" || q.name=="row_major") + has_matrix_order = true; + } + } + + MemoryRequirementsCalculator::Result mem_reqs = MemoryRequirementsCalculator().apply(var); + offset += mem_reqs.alignment-1; + offset -= offset%mem_reqs.alignment; + + if(layout_offset) + *layout_offset = offset; + else + { + if(!var.layout) + var.layout = new Layout; + + var.layout->qualifiers.push_back(Layout::Qualifier("offset", offset)); + } + + if(!has_matrix_order) + { + const BasicTypeDeclaration *basic = dynamic_cast(var.type_declaration); + while(basic && basic->kind==BasicTypeDeclaration::ARRAY) + basic = dynamic_cast(basic->base_type); + if(basic && basic->kind==BasicTypeDeclaration::MATRIX) + var.layout->qualifiers.push_back(Layout::Qualifier("column_major")); + } + + offset += mem_reqs.size; + } +} + + void LocationAllocator::apply(Module &module, const Features &features) { - for(list::iterator i=module.stages.begin(); i!=module.stages.end(); ++i) - apply(*i); + for(Stage &s: module.stages) + apply(s); allocate_locations("uniform"); - for(vector::const_iterator i=unbound_blocks.begin(); i!=unbound_blocks.end(); ++i) - bind_uniform((*i)->layout, (*i)->block_name, features.uniform_binding_range); - for(vector::const_iterator i=unbound_textures.begin(); i!=unbound_textures.end(); ++i) - bind_uniform((*i)->layout, (*i)->name, features.texture_binding_range); + for(InterfaceBlock *b: unbound_blocks) + bind_uniform(b->layout, b->block_name, features.uniform_binding_range); + for(VariableDeclaration *t: unbound_textures) + bind_uniform(t->layout, t->name, features.texture_binding_range); } void LocationAllocator::apply(Stage &stage) @@ -37,9 +96,9 @@ void LocationAllocator::apply(Stage &stage) void LocationAllocator::allocate_locations(const string &iface) { - vector::iterator write = unplaced_variables.begin(); + auto write = unplaced_variables.begin(); unsigned next = 0; - for(vector::const_iterator i=unplaced_variables.begin(); i!=unplaced_variables.end(); ++i) + for(auto i=unplaced_variables.begin(); i!=unplaced_variables.end(); ++i) { if((*i)->interface!=iface) { @@ -51,7 +110,7 @@ void LocationAllocator::allocate_locations(const string &iface) if((*i)->interface=="uniform") { - map::const_iterator j = uniforms.find((*i)->name); + auto j = uniforms.find((*i)->name); if(j!=uniforms.end() && j->second.location>=0) { add_layout_value((*i)->layout, "location", j->second.location); @@ -87,7 +146,7 @@ void LocationAllocator::allocate_locations(const string &iface) void LocationAllocator::bind_uniform(RefPtr &layout, const string &name, unsigned range) { - map::const_iterator i = uniforms.find(name); + auto i = uniforms.find(name); if(i!=uniforms.end() && i->second.bind_point>=0) add_layout_value(layout, "binding", i->second.bind_point); else @@ -109,11 +168,7 @@ void LocationAllocator::add_layout_value(RefPtr &layout, const string &n if(!layout) layout = new Layout; - Layout::Qualifier qual; - qual.name = name; - qual.has_value = true; - qual.value = value; - layout->qualifiers.push_back(qual); + layout->qualifiers.push_back(Layout::Qualifier(name, value)); } void LocationAllocator::visit(VariableDeclaration &var) @@ -196,7 +251,7 @@ void PrecisionConverter::apply(Stage &s) void PrecisionConverter::visit(Block &block) { - for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ++i) + for(auto i=block.body.begin(); i!=block.body.end(); ++i) { if(&block==&stage->content) insert_point = i; @@ -285,7 +340,7 @@ void LegacyConverter::unsupported(const string &reason) void LegacyConverter::visit(Block &block) { - for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ++i) + for(auto i=block.body.begin(); i!=block.body.end(); ++i) { if(&block==&stage->content) uniform_insert_point = i; @@ -459,7 +514,7 @@ void LegacyConverter::visit(VariableDeclaration &var) { if(var.layout) { - for(vector::const_iterator i=var.layout->qualifiers.begin(); i!=var.layout->qualifiers.end(); ) + for(auto i=var.layout->qualifiers.begin(); i!=var.layout->qualifiers.end(); ) { if(i->name=="location") { @@ -565,7 +620,7 @@ void LegacyConverter::visit(InterfaceBlock &iface) { if(iface.layout) { - for(vector::const_iterator i=iface.layout->qualifiers.begin(); i!=iface.layout->qualifiers.end(); ) + for(auto i=iface.layout->qualifiers.begin(); i!=iface.layout->qualifiers.end(); ) { if(i->name=="location" && !supports_interface_block_location()) i = iface.layout->qualifiers.erase(i);