From ea844415db7fb7705ecbfea9cf27df2a8f00b802 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 11 Nov 2021 01:31:47 +0200 Subject: [PATCH] Add a utility function for following a chain of base types --- source/glsl/finalize.cpp | 11 +++-------- source/glsl/syntax.cpp | 13 +++++++++++++ source/glsl/syntax.h | 2 +- source/glsl/validate.cpp | 11 +++-------- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/source/glsl/finalize.cpp b/source/glsl/finalize.cpp index 864a128b..3bdca5cb 100644 --- a/source/glsl/finalize.cpp +++ b/source/glsl/finalize.cpp @@ -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(type)) - type = basic->base_type; - if(dynamic_cast(type) && !visit_uniform(var.name, var.layout)) + const TypeDeclaration *base_type = get_ultimate_base_type(var.type_declaration); + if(dynamic_cast(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(type)) - type = basic->base_type; - if(dynamic_cast(type)) + if(dynamic_cast(get_ultimate_base_type(var.type_declaration))) stage->texture_bindings[var.name] = i->value; i = var.layout->qualifiers.erase(i); diff --git a/source/glsl/syntax.cpp b/source/glsl/syntax.cpp index 1489eb9e..40f6d4f6 100644 --- a/source/glsl/syntax.cpp +++ b/source/glsl/syntax.cpp @@ -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(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); diff --git a/source/glsl/syntax.h b/source/glsl/syntax.h index 95c15ac0..499779d9 100644 --- a/source/glsl/syntax.h +++ b/source/glsl/syntax.h @@ -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 &); diff --git a/source/glsl/validate.cpp b/source/glsl/validate.cpp index e11f181e..df3312e1 100644 --- a/source/glsl/validate.cpp +++ b/source/glsl/validate.cpp @@ -77,11 +77,9 @@ void DeclarationValidator::visit(Layout &layout) if(variable) { - TypeDeclaration *type = variable->type_declaration; - while(BasicTypeDeclaration *basic = dynamic_cast(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(type)); + allowed = (scope==GLOBAL && uniform && dynamic_cast(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(type)) - type = basic->base_type; - if(!dynamic_cast(type)) + if(!dynamic_cast(get_ultimate_base_type(variable->type_declaration))) error(var, "Interface qualifier 'uniform' not allowed on non-opaque variable in global scope"); } } -- 2.45.2