]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/finalize.cpp
Allow a push constant block to be specified, but flatten it for now
[libs/gl.git] / source / glsl / finalize.cpp
index 4068037e919e81b5cc514d12584bec7df8088360..2fff7549cab5b3c150feb3f7c223d314da324999 100644 (file)
@@ -221,15 +221,25 @@ void LocationAllocator::visit(InterfaceBlock &iface)
 
        if(iface.interface=="uniform")
        {
-               int bind_point = (iface.layout ? get_layout_value(*iface.layout, "binding") : -1);
+               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(bind_point>=0)
+               if(!push_constant)
                {
-                       used_bindings[0].insert(bind_point);
-                       uniforms[iface.block_name].bind_point = bind_point;
+                       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);
                }
-               else
-                       unbound_blocks.push_back(&iface);
        }
 }
 
@@ -336,6 +346,15 @@ void LegacyConverter::visit(Block &block)
        }
 }
 
+void LegacyConverter::visit(RefPtr<Expression> &expr)
+{
+       r_replaced_reference = 0;
+       expr->visit(*this);
+       if(r_replaced_reference)
+               expr = r_replaced_reference;
+       r_replaced_reference = 0;
+}
+
 bool LegacyConverter::check_version(const Version &feature_version) const
 {
        if(features.glsl_version<feature_version)
@@ -386,6 +405,23 @@ void LegacyConverter::visit(VariableReference &var)
        }
 }
 
+void LegacyConverter::visit(InterfaceBlockReference &iface)
+{
+       r_flattened_interface = nodes_to_remove.count(iface.declaration);
+}
+
+void LegacyConverter::visit(MemberAccess &memacc)
+{
+       r_flattened_interface = false;
+       visit(memacc.left);
+       if(r_flattened_interface)
+       {
+               VariableReference *var = new VariableReference;
+               var->name = memacc.member;
+               r_replaced_reference = var;
+       }
+}
+
 void LegacyConverter::visit(Assignment &assign)
 {
        TraversingVisitor::visit(assign);
@@ -574,6 +610,10 @@ void LegacyConverter::visit(VariableDeclaration &var)
                }
        }
 
+       if(var.name=="gl_ClipDistance")
+               if(const Literal *literal_size = dynamic_cast<const Literal *>(var.array_size.get()))
+                       stage->n_clip_distances = literal_size->value.value<int>();
+
        TraversingVisitor::visit(var);
 }
 
@@ -606,6 +646,7 @@ bool LegacyConverter::supports_interface_block_location() const
 
 void LegacyConverter::visit(InterfaceBlock &iface)
 {
+       bool push_constant = false;
        if(iface.layout)
        {
                for(auto i=iface.layout->qualifiers.begin(); i!=iface.layout->qualifiers.end(); )
@@ -618,19 +659,26 @@ void LegacyConverter::visit(InterfaceBlock &iface)
                                i = iface.layout->qualifiers.erase(i);
                        }
                        else
+                       {
+                               if(i->name=="push_constant")
+                                       push_constant = true;
                                ++i;
+                       }
                }
 
                if(iface.layout->qualifiers.empty())
                        iface.layout = 0;
        }
 
-       if(!supports_interface_blocks(iface.interface) && iface.type_declaration)
+       if((!supports_interface_blocks(iface.interface) || push_constant) && iface.type_declaration)
        {
                if(!iface.instance_name.empty())
                        unsupported("ARB_uniform_buffer_object required for interface block instances");
                else if(iface.struct_declaration)
                {
+                       for(const RefPtr<Statement> &s: iface.struct_declaration->members.body)
+                               if(VariableDeclaration *var = dynamic_cast<VariableDeclaration *>(s.get()))
+                                       var->interface = iface.interface;
                        stage->content.body.splice(uniform_insert_point, iface.struct_declaration->members.body);
                        nodes_to_remove.insert(&iface);
                        nodes_to_remove.insert(iface.struct_declaration);