]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/finalize.cpp
Fix a name conflict in certain inlining scenarios
[libs/gl.git] / source / glsl / finalize.cpp
index e89aa4942ad768bb32318dad10cde682de7c78f8..60312be8adf8fc09cdb6a55ed76de342b9f3da46 100644 (file)
@@ -46,12 +46,7 @@ void StructOrganizer::visit(VariableDeclaration &var)
                if(layout_offset)
                        *layout_offset = offset;
                else
-               {
-                       if(!var.layout)
-                               var.layout = new Layout;
-
-                       var.layout->qualifiers.push_back(Layout::Qualifier("offset", offset));
-               }
+                       add_layout_qualifier(var.layout, Layout::Qualifier("offset", offset));
 
                if(!has_matrix_order)
                {
@@ -59,7 +54,7 @@ void StructOrganizer::visit(VariableDeclaration &var)
                        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"));
+                               add_layout_qualifier(var.layout, Layout::Qualifier("column_major"));
                }
 
                offset += mem_reqs.size;
@@ -67,8 +62,10 @@ void StructOrganizer::visit(VariableDeclaration &var)
 }
 
 
-void LocationAllocator::apply(Module &module, const Features &features)
+void LocationAllocator::apply(Module &module, const Features &f, bool a)
 {
+       features = f;
+       alloc_new = a;
        for(Stage &s: module.stages)
                apply(s);
 
@@ -111,11 +108,14 @@ void LocationAllocator::allocate_locations(const string &iface)
                        auto j = uniforms.find((*i)->name);
                        if(j!=uniforms.end() && j->second.location>=0)
                        {
-                               add_layout_value((*i)->layout, "location", j->second.location);
+                               add_layout_qualifier((*i)->layout, Layout::Qualifier("location", j->second.location));
                                continue;
                        }
                }
 
+               if(!alloc_new)
+                       continue;
+
                set<unsigned> &used = used_locations[(*i)->interface];
 
                unsigned size = LocationCounter().apply(**i);
@@ -130,7 +130,7 @@ void LocationAllocator::allocate_locations(const string &iface)
                        next = blocking+1;
                }
 
-               add_layout_value((*i)->layout, "location", next);
+               add_layout_qualifier((*i)->layout, Layout::Qualifier("location", next));
                if((*i)->interface=="uniform")
                        uniforms[(*i)->name].location = next;
 
@@ -145,28 +145,52 @@ void LocationAllocator::allocate_locations(const string &iface)
 void LocationAllocator::bind_uniform(RefPtr<Layout> &layout, const string &name, unsigned range)
 {
        auto i = uniforms.find(name);
+
+       int desc_set = (i!=uniforms.end() ? i->second.desc_set : 0);
+       if(features.target_api==VULKAN && get_layout_value(layout.get(), "set")<0)
+               add_layout_qualifier(layout, Layout::Qualifier("set", desc_set));
+
        if(i!=uniforms.end() && i->second.bind_point>=0)
-               add_layout_value(layout, "binding", i->second.bind_point);
-       else
+               add_layout_qualifier(layout, Layout::Qualifier("binding", i->second.bind_point));
+       else if(alloc_new)
        {
-               set<unsigned> &used = used_bindings[0];
+               set<unsigned> &used = used_bindings[desc_set];
 
                unsigned bind_point = fold32(hash64(name))%range;
                while(used.count(bind_point))
                        bind_point = (bind_point+1)%range;
 
-               add_layout_value(layout, "binding", bind_point);
+               add_layout_qualifier(layout, Layout::Qualifier("binding", bind_point));
                uniforms[name].bind_point = bind_point;
                used.insert(bind_point);
        }
 }
 
-void LocationAllocator::add_layout_value(RefPtr<Layout> &layout, const string &name, unsigned value)
+bool LocationAllocator::visit_uniform(const string &name, RefPtr<Layout> &layout)
 {
-       if(!layout)
-               layout = new Layout;
+       int desc_set = 0;
+       int bind_point = get_layout_value(layout.get(), "binding");
+
+       if(features.target_api==VULKAN)
+       {
+               desc_set = get_layout_value(layout.get(), "set");
+               if(desc_set<0 && bind_point>=0)
+               {
+                       desc_set = 0;
+                       add_layout_qualifier(layout, Layout::Qualifier("set", desc_set));
+               }
+
+               if(desc_set>=0)
+                       uniforms[name].desc_set = desc_set;
+       }
 
-       layout->qualifiers.push_back(Layout::Qualifier(name, value));
+       if(bind_point>=0)
+       {
+               used_bindings[desc_set].insert(bind_point);
+               uniforms[name].bind_point = bind_point;
+       }
+
+       return bind_point>=0;
 }
 
 void LocationAllocator::visit(VariableDeclaration &var)
@@ -176,13 +200,13 @@ void LocationAllocator::visit(VariableDeclaration &var)
 
        if(!var.interface.empty())
        {
-               int location = (var.layout ? get_layout_value(*var.layout, "location") : -1);
+               int location = get_layout_value(var.layout.get(), "location");
 
                if(location<0 && var.linked_declaration && var.linked_declaration->layout)
                {
-                       location = get_layout_value(*var.linked_declaration->layout, "location");
+                       location = get_layout_value(var.linked_declaration->layout.get(), "location");
                        if(location>=0)
-                               add_layout_value(var.layout, "location", location);
+                               add_layout_qualifier(var.layout, Layout::Qualifier("location", location));
                }
 
                if(location>=0)
@@ -199,20 +223,9 @@ void LocationAllocator::visit(VariableDeclaration &var)
 
        if(var.interface=="uniform")
        {
-               const TypeDeclaration *type = var.type_declaration;
-               while(const BasicTypeDeclaration *basic = dynamic_cast<const BasicTypeDeclaration *>(type))
-                       type = basic->base_type;
-               if(dynamic_cast<const ImageTypeDeclaration *>(type))
-               {
-                       int bind_point = (var.layout ? get_layout_value(*var.layout, "binding") : -1);
-                       if(bind_point>=0)
-                       {
-                               used_bindings[0].insert(bind_point);
-                               uniforms[var.name].bind_point = bind_point;
-                       }
-                       else
-                               unbound_textures.push_back(&var);
-               }
+               const TypeDeclaration *base_type = get_ultimate_base_type(var.type_declaration);
+               if(dynamic_cast<const ImageTypeDeclaration *>(base_type) && !visit_uniform(var.name, var.layout))
+                       unbound_textures.push_back(&var);
        }
 }
 
@@ -223,25 +236,9 @@ void LocationAllocator::visit(InterfaceBlock &iface)
 
        if(iface.interface=="uniform")
        {
-               bool push_constant = false;
-               if(iface.layout)
-               {
-                       auto i = find_member(iface.layout->qualifiers, string("push_constant"), &Layout::Qualifier::name);
-                       push_constant = (i!=iface.layout->qualifiers.end());
-               }
-
-               if(!push_constant)
-               {
-                       int bind_point = (iface.layout ? get_layout_value(*iface.layout, "binding") : -1);
-
-                       if(bind_point>=0)
-                       {
-                               used_bindings[0].insert(bind_point);
-                               uniforms[iface.block_name].bind_point = bind_point;
-                       }
-                       else
-                               unbound_blocks.push_back(&iface);
-               }
+               bool push_constant = has_layout_qualifier(iface.layout.get(), "push_constant");
+               if(!push_constant && !visit_uniform(iface.block_name, iface.layout))
+                       unbound_blocks.push_back(&iface);
        }
 }
 
@@ -522,13 +519,7 @@ bool StructuralFeatureConverter::supports_interface_blocks(const string &iface)
 
 void StructuralFeatureConverter::visit(InterfaceBlock &iface)
 {
-       bool push_constant = false;
-       if(iface.layout)
-       {
-               auto i = find_member(iface.layout->qualifiers, string("push_constant"), &Layout::Qualifier::name);
-               push_constant = (i!=iface.layout->qualifiers.end());
-       }
-
+       bool push_constant = has_layout_qualifier(iface.layout.get(), "push_constant");
        if((!supports_interface_blocks(iface.interface) || (push_constant && features.target_api!=VULKAN)) && iface.type_declaration)
        {
                if(!iface.instance_name.empty())
@@ -667,10 +658,7 @@ void QualifierConverter::visit(VariableDeclaration &var)
                        }
                        else if(i->name=="binding" && !supports_binding())
                        {
-                               const TypeDeclaration *type = var.type_declaration;
-                               while(const BasicTypeDeclaration *basic = dynamic_cast<const BasicTypeDeclaration *>(type))
-                                       type = basic->base_type;
-                               if(dynamic_cast<const ImageTypeDeclaration *>(type))
+                               if(dynamic_cast<const ImageTypeDeclaration *>(get_ultimate_base_type(var.type_declaration)))
                                        stage->texture_bindings[var.name] = i->value;
 
                                i = var.layout->qualifiers.erase(i);