]> git.tdb.fi Git - libs/gl.git/commitdiff
Always use member access for interface blocks, even anonymous ones
authorMikko Rasa <tdb@tdb.fi>
Mon, 5 Apr 2021 11:49:41 +0000 (14:49 +0300)
committerMikko Rasa <tdb@tdb.fi>
Mon, 5 Apr 2021 11:58:53 +0000 (14:58 +0300)
Having variable references magically refer to variables inside interface
blocks causes trouble when generating SPIR-V.

This currently breaks one test case because UnusedVariableRemover can't
track access chains.

source/glsl/optimize.cpp
source/glsl/output.cpp
source/glsl/output.h
source/glsl/resolve.cpp

index d7558ebde6c095b240943d4b317840425b46282a..475e8b646de280261b0b1347bf1339a84de578b8 100644 (file)
@@ -997,10 +997,6 @@ bool UnusedVariableRemover::apply(Stage &s)
                if(i->used_by.empty())
                        unused_nodes.insert(i->node);
 
-       for(map<string, InterfaceBlock *>::const_iterator i=s.interface_blocks.begin(); i!=s.interface_blocks.end(); ++i)
-               if(i->second->instance_name.empty())
-                       unused_nodes.insert(i->second);
-
        for(BlockVariableMap::const_iterator i=variables.begin(); i!=variables.end(); ++i)
        {
                if(i->second.output)
@@ -1153,16 +1149,8 @@ void UnusedVariableRemover::visit(VariableDeclaration &var)
 
 void UnusedVariableRemover::visit(InterfaceBlock &iface)
 {
-       if(iface.instance_name.empty())
-       {
-               SetForScope<InterfaceBlock *> set_block(interface_block, &iface);
-               iface.struct_declaration->members.visit(*this);
-       }
-       else
-       {
-               VariableInfo &var_info = variables[&iface];
-               var_info.output = (iface.interface=="out" && (iface.linked_block || !iface.block_name.compare(0, 3, "gl_")));
-       }
+       VariableInfo &var_info = variables[&iface];
+       var_info.output = (iface.interface=="out" && (iface.linked_block || !iface.block_name.compare(0, 3, "gl_")));
 }
 
 void UnusedVariableRemover::merge_variables(const BlockVariableMap &other_vars)
index 1d82cae6a9ed95f20debbcf500a6a242c929c54a..38adb5bd6b799f54f165299657b90f09830293de 100644 (file)
@@ -14,7 +14,8 @@ Formatter::Formatter():
        source_line(1),
        indent(0),
        parameter_list(false),
-       omit_builtin(false)
+       omit_builtin(false),
+       r_empty_name(false)
 { }
 
 const string &Formatter::apply(Stage &s)
@@ -154,17 +155,22 @@ void Formatter::visit(Literal &literal)
 void Formatter::visit(VariableReference &var)
 {
        append(var.name);
+       r_empty_name = false;
 }
 
 void Formatter::visit(InterfaceBlockReference &iface)
 {
-       append(iface.name);
+       r_empty_name = iface.declaration->instance_name.empty();
+       if(!r_empty_name)
+               append(iface.declaration->instance_name);
 }
 
 void Formatter::visit(MemberAccess &memacc)
 {
        visit_expression(*memacc.left, memacc.oper, false);
-       append(format(".%s", memacc.member));
+       if(!r_empty_name)
+               append('.');
+       append(memacc.member);
 }
 
 void Formatter::visit(Swizzle &swizzle)
index 6bdb1ab76d054ce64d7fd250590ebc44c762f41b..ef9369876b46c00221ad6e33093c6e76153fee93 100644 (file)
@@ -20,6 +20,7 @@ private:
        unsigned indent;
        bool parameter_list;
        bool omit_builtin;
+       bool r_empty_name;
 
 public:
        Formatter();
index 8bfe635ee73b8d2f3c0dd1bd9dd7414313117263..c5a507a222a96558a7582d72b8725216889d9fa7 100644 (file)
@@ -226,28 +226,42 @@ void VariableResolver::visit(VariableReference &var)
        {
                const map<string, InterfaceBlock *> &blocks = stage->interface_blocks;
                map<string, InterfaceBlock *>::const_iterator i = blocks.find(var.name);
+               if(i==blocks.end())
+               {
+                       // Look for the variable in anonymous interface blocks.
+                       for(i=blocks.begin(); i!=blocks.end(); ++i)
+                               if(i->second->instance_name.empty() && i->second->struct_declaration)
+                                       if(i->second->struct_declaration->members.variables.count(var.name))
+                                               break;
+               }
+
                if(i!=blocks.end())
                {
-                       /* The name refers to an interface block with an instance name rather
-                       than a variable.  Prepare a new syntax tree node accordingly. */
+                       /* The name refers to either an interface block with an instance name
+                       or a variable declared inside an anonymous interface block.  Prepare
+                       new syntax tree nodes accordingly. */
                        InterfaceBlockReference *iface_ref = new InterfaceBlockReference;
                        iface_ref->source = var.source;
                        iface_ref->line = var.line;
-                       iface_ref->name = var.name;
                        iface_ref->declaration = i->second;
-                       r_replacement_expr = iface_ref;
-               }
-               else
-               {
-                       // Look for the variable in anonymous interface blocks.
-                       for(i=blocks.begin(); (!declaration && i!=blocks.end()); ++i)
-                               if(i->second->instance_name.empty() && i->second->struct_declaration)
-                               {
-                                       const map<string, VariableDeclaration *> &iface_vars = i->second->struct_declaration->members.variables;
-                                       map<string, VariableDeclaration *>::const_iterator j = iface_vars.find(var.name);
-                                       if(j!=iface_vars.end())
-                                               declaration = j->second;
-                               }
+
+                       if(i->second->instance_name.empty())
+                       {
+                               iface_ref->name = format("%s %s", i->second->interface, i->second->block_name);
+
+                               MemberAccess *memacc = new MemberAccess;
+                               memacc->source = var.source;
+                               memacc->line = var.line;
+                               memacc->left = iface_ref;
+                               memacc->member = var.name;
+
+                               r_replacement_expr = memacc;
+                       }
+                       else
+                       {
+                               iface_ref->name = var.name;
+                               r_replacement_expr = iface_ref;
+                       }
                }
        }