]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/finalize.cpp
Fix opcode for matrix inverse
[libs/gl.git] / source / glsl / finalize.cpp
index 2d1a46fb0862639457a1137a2de94036c6a1f7da..192baec550e111313c76a5cde659e37c6604fba8 100644 (file)
@@ -12,6 +12,66 @@ 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;
+               bool has_matrix_order = false;
+               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;
+                               }
+                               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;
+
+                       var.layout->qualifiers.push_back(Layout::Qualifier("offset", offset));
+               }
+
+               if(!has_matrix_order)
+               {
+                       const BasicTypeDeclaration *basic = dynamic_cast<const BasicTypeDeclaration *>(var.type_declaration);
+                       while(basic && basic->kind==BasicTypeDeclaration::ARRAY)
+                               basic = dynamic_cast<const BasicTypeDeclaration *>(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<Stage>::iterator i=module.stages.begin(); i!=module.stages.end(); ++i)
@@ -109,11 +169,7 @@ void LocationAllocator::add_layout_value(RefPtr<Layout> &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)