]> git.tdb.fi Git - libs/gl.git/commitdiff
Add a utility function for following a chain of base types
authorMikko Rasa <tdb@tdb.fi>
Wed, 10 Nov 2021 23:31:47 +0000 (01:31 +0200)
committerMikko Rasa <tdb@tdb.fi>
Wed, 10 Nov 2021 23:39:41 +0000 (01:39 +0200)
source/glsl/finalize.cpp
source/glsl/syntax.cpp
source/glsl/syntax.h
source/glsl/validate.cpp

index 864a128b9230543913a629ff25e4b031af4981aa..3bdca5cb7d02dcbf786e69dd60d9f0b3b394d554 100644 (file)
@@ -210,10 +210,8 @@ 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) && !visit_uniform(var.name, var.layout))
+               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);
        }
 }
@@ -659,10 +657,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);
index 1489eb9e2af7e04ec542deb1c740efa6d8fc4d7f..40f6d4f660b24c84dff02a910951c71c87ad6c4e 100644 (file)
@@ -402,6 +402,19 @@ string get_unused_variable_name(const Block &block, const string &base)
        }
 }
 
+const TypeDeclaration *get_ultimate_base_type(const TypeDeclaration *type)
+{
+       if(!type)
+               return 0;
+       while(const BasicTypeDeclaration *basic = dynamic_cast<const BasicTypeDeclaration *>(type))
+       {
+               if(!basic->base_type)
+                       break;
+               type = basic->base_type;
+       }
+       return type;
+}
+
 int get_layout_value(const Layout &layout, const string &name, int def_value)
 {
        auto i = find_member(layout.qualifiers, name, &Layout::Qualifier::name);
index 95c15ac069046644e92df976f3e38c5a596d0edb..499779d91faf2e162a2b47ef0b48ca8ab88fed84 100644 (file)
@@ -552,7 +552,7 @@ struct Module
 };
 
 std::string get_unused_variable_name(const Block &, const std::string &);
-
+const TypeDeclaration *get_ultimate_base_type(const TypeDeclaration *);
 int get_layout_value(const Layout &, const std::string &, int = -1);
 void add_to_chain(Assignment::Target &, Assignment::Target::ChainType, unsigned);
 bool targets_overlap(const Assignment::Target &, const Assignment::Target &);
index e11f181e0b42d1140b67b313cfe449ff8bad52d7..df3312e1fa9f6b46f3fdc52f7e305ded14059bab 100644 (file)
@@ -77,11 +77,9 @@ void DeclarationValidator::visit(Layout &layout)
 
                        if(variable)
                        {
-                               TypeDeclaration *type = variable->type_declaration;
-                               while(BasicTypeDeclaration *basic = dynamic_cast<BasicTypeDeclaration *>(type))
-                                       type = basic->base_type;
+                               const TypeDeclaration *base_type = get_ultimate_base_type(variable->type_declaration);
                                bool uniform = (variable->interface=="uniform");
-                               allowed = (scope==GLOBAL && uniform && dynamic_cast<ImageTypeDeclaration *>(type));
+                               allowed = (scope==GLOBAL && uniform && dynamic_cast<const ImageTypeDeclaration *>(base_type));
                                err_descr = (uniform ? "variable of non-opaque type" : "non-uniform variable");
                        }
                        else if(iface_block)
@@ -258,10 +256,7 @@ void DeclarationValidator::visit(VariableDeclaration &var)
                        error(var, format("Interface qualifier not allowed on %s", descr));
                else if(scope==GLOBAL && variable->interface=="uniform" && features.target_api==VULKAN)
                {
-                       TypeDeclaration *type = variable->type_declaration;
-                       while(BasicTypeDeclaration *basic = dynamic_cast<BasicTypeDeclaration *>(type))
-                               type = basic->base_type;
-                       if(!dynamic_cast<ImageTypeDeclaration *>(type))
+                       if(!dynamic_cast<const ImageTypeDeclaration *>(get_ultimate_base_type(variable->type_declaration)))
                                error(var, "Interface qualifier 'uniform' not allowed on non-opaque variable in global scope");
                }
        }