X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Ffinalize.cpp;h=94007b8fc3eda25f24b91deff5425549de70ce15;hb=180698dbb41d312128c496721f1207c6688fe350;hp=2d1a46fb0862639457a1137a2de94036c6a1f7da;hpb=8f2713a3f1501e90016bb8069ecd08dde2f90e56;p=libs%2Fgl.git diff --git a/source/glsl/finalize.cpp b/source/glsl/finalize.cpp index 2d1a46fb..94007b8f 100644 --- a/source/glsl/finalize.cpp +++ b/source/glsl/finalize.cpp @@ -12,6 +12,74 @@ 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) + { + vector &qualifiers = var.layout->qualifiers; + for(vector::iterator i=qualifiers.begin(); i!=qualifiers.end(); ++i) + { + if(i->name=="offset" && i->has_value) + { + layout_offset = &i->value; + if(i->value>=offset) + offset = i->value; + } + else if(i->name=="column_major" || i->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; + + Layout::Qualifier qual; + qual.name = "offset"; + qual.has_value = true; + qual.value = offset; + var.layout->qualifiers.push_back(qual); + } + + 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) + { + Layout::Qualifier qual; + qual.name = "column_major"; + var.layout->qualifiers.push_back(qual); + } + } + + offset += mem_reqs.size; + } +} + + void LocationAllocator::apply(Module &module, const Features &features) { for(list::iterator i=module.stages.begin(); i!=module.stages.end(); ++i)