]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/finalize.cpp
Add visitors to calculate offsets of struct members
[libs/gl.git] / source / glsl / finalize.cpp
index 2d1a46fb0862639457a1137a2de94036c6a1f7da..6e9a478012e0dad898065da952868d8bf03eff46 100644 (file)
@@ -12,6 +12,57 @@ namespace Msp {
 namespace GL {
 namespace SL {
 
+StructOrganizer::StructOrganizer():
+       offset(-1)
+{ }
+
+void StructOrganizer::visit(StructDeclaration &strct)
+{
+       SetForScope<int> set_offset(offset, 0);
+       TraversingVisitor::visit(strct);
+}
+
+void StructOrganizer::visit(VariableDeclaration &var)
+{
+       if(offset>=0)
+       {
+               int *layout_offset = 0;
+               if(var.layout)
+               {
+                       vector<Layout::Qualifier> &qualifiers = var.layout->qualifiers;
+                       for(vector<Layout::Qualifier>::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;
+                                       break;
+                               }
+               }
+
+               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);
+               }
+
+               offset += mem_reqs.size;
+       }
+}
+
+
 void LocationAllocator::apply(Module &module, const Features &features)
 {
        for(list<Stage>::iterator i=module.stages.begin(); i!=module.stages.end(); ++i)