X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fglsl%2Ffinalize.cpp;h=5307cff93ed1461d1da9c5eab9de770fd6fcd8b0;hp=52cf95804245767ec1e487619313e87d66ee17dc;hb=03b2ea5c9c611cfa5f02afb49ed7e05743e691b4;hpb=4ecc965177df174ed2d26cfedf24665c8879acda diff --git a/source/glsl/finalize.cpp b/source/glsl/finalize.cpp index 52cf9580..5307cff9 100644 --- a/source/glsl/finalize.cpp +++ b/source/glsl/finalize.cpp @@ -72,8 +72,8 @@ void LocationAllocator::apply(Module &module, const Features &f, bool a) if(features.target_api!=VULKAN) allocate_locations("uniform"); - for(InterfaceBlock *b: unbound_blocks) - bind_uniform(b->layout, b->block_name, features.uniform_binding_range); + for(VariableDeclaration *b: unbound_blocks) + bind_uniform(b->layout, b->block_declaration->block_name, features.uniform_binding_range); for(VariableDeclaration *t: unbound_textures) bind_uniform(t->layout, t->name, features.texture_binding_range); } @@ -198,7 +198,7 @@ void LocationAllocator::visit(VariableDeclaration &var) if(!var.name.compare(0, 3, "gl_")) return; - if(!var.interface.empty()) + if(!var.interface.empty() && !var.block_declaration) { int location = get_layout_value(var.layout.get(), "location"); @@ -223,22 +223,18 @@ void LocationAllocator::visit(VariableDeclaration &var) if(var.interface=="uniform") { - 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); - } -} - -void LocationAllocator::visit(InterfaceBlock &iface) -{ - if(!iface.instance_name.compare(0, 3, "gl_")) - return; - - if(iface.interface=="uniform") - { - 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); + if(var.block_declaration) + { + bool push_constant = has_layout_qualifier(var.layout.get(), "push_constant"); + if(!push_constant && !visit_uniform(var.block_declaration->block_name, var.layout)) + unbound_blocks.push_back(&var); + } + else + { + 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); + } } } @@ -413,11 +409,8 @@ void StructuralFeatureConverter::visit(VariableReference &var) var.name = "gl_FragColor"; var.declaration = 0; } -} -void StructuralFeatureConverter::visit(InterfaceBlockReference &iface) -{ - r_flattened_interface = nodes_to_remove.count(iface.declaration); + r_flattened_interface = nodes_to_remove.count(var.declaration); } void StructuralFeatureConverter::visit(MemberAccess &memacc) @@ -486,18 +479,6 @@ void StructuralFeatureConverter::visit(FunctionCall &call) TraversingVisitor::visit(call); } -void StructuralFeatureConverter::visit(VariableDeclaration &var) -{ - if((var.interface=="in" || var.interface=="out") && !supports_unified_interface_syntax()) - if(stage->type==Stage::FRAGMENT && var.interface=="out") - { - frag_out = &var; - nodes_to_remove.insert(&var); - } - - TraversingVisitor::visit(var); -} - bool StructuralFeatureConverter::supports_interface_blocks(const string &iface) const { if(features.target_api==VULKAN) @@ -517,27 +498,35 @@ bool StructuralFeatureConverter::supports_interface_blocks(const string &iface) return false; } -void StructuralFeatureConverter::visit(InterfaceBlock &iface) +void StructuralFeatureConverter::visit(VariableDeclaration &var) { - 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(var.block_declaration) { - if(!iface.instance_name.empty()) - unsupported("ARB_uniform_buffer_object required for interface block instances"); - else if(iface.struct_declaration) + bool push_constant = has_layout_qualifier(var.layout.get(), "push_constant"); + if(!supports_interface_blocks(var.interface) || (push_constant && features.target_api!=VULKAN)) { - for(const RefPtr &s: iface.struct_declaration->members.body) - if(VariableDeclaration *var = dynamic_cast(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); + if(var.name.find(' ')==string::npos) + unsupported("ARB_uniform_buffer_object required for interface block instances"); + else + { + for(const RefPtr &s: var.block_declaration->members.body) + if(VariableDeclaration *mem = dynamic_cast(s.get())) + mem->interface = var.interface; + stage->content.body.splice(uniform_insert_point, var.block_declaration->members.body); + nodes_to_remove.insert(&var); + nodes_to_remove.insert(var.block_declaration); + } } - else - /* If the interface block is an array, it should have an instance - name too, so this should never be reached */ - throw logic_error("Unexpected interface block configuration"); } + + if((var.interface=="in" || var.interface=="out") && !supports_unified_interface_syntax()) + if(stage->type==Stage::FRAGMENT && var.interface=="out") + { + frag_out = &var; + nodes_to_remove.insert(&var); + } + + TraversingVisitor::visit(var); } @@ -618,6 +607,18 @@ bool QualifierConverter::supports_binding() const return check_version(Version(4, 20)); } +bool QualifierConverter::supports_interface_block_location() const +{ + if(features.target_api==VULKAN) + return true; + else if(features.target_api==OPENGL_ES) + return check_version(Version(3, 20)); + else if(check_version(Version(4, 40))) + return true; + else + return check_extension(&Features::arb_enhanced_layouts); +} + void QualifierConverter::visit(VariableDeclaration &var) { if(var.layout) @@ -628,7 +629,9 @@ void QualifierConverter::visit(VariableDeclaration &var) { bool supported = true; bool external = false; - if(var.interface=="in") + if(var.block_declaration) + supported = supports_interface_block_location(); + else if(var.interface=="in") { external = (stage->type==Stage::VERTEX); supported = (external ? supports_interface_layouts() : supports_stage_interface_layouts()); @@ -658,7 +661,9 @@ void QualifierConverter::visit(VariableDeclaration &var) } else if(i->name=="binding" && !supports_binding()) { - if(dynamic_cast(get_ultimate_base_type(var.type_declaration))) + if(var.block_declaration) + stage->uniform_block_bindings[var.block_declaration->block_name] = i->value; + else if(dynamic_cast(get_ultimate_base_type(var.type_declaration))) stage->texture_bindings[var.name] = i->value; i = var.layout->qualifiers.erase(i); @@ -689,40 +694,6 @@ void QualifierConverter::visit(VariableDeclaration &var) TraversingVisitor::visit(var); } -bool QualifierConverter::supports_interface_block_location() const -{ - if(features.target_api==VULKAN) - return true; - else if(features.target_api==OPENGL_ES) - return check_version(Version(3, 20)); - else if(check_version(Version(4, 40))) - return true; - else - return check_extension(&Features::arb_enhanced_layouts); -} - -void QualifierConverter::visit(InterfaceBlock &iface) -{ - if(iface.layout) - { - for(auto i=iface.layout->qualifiers.begin(); i!=iface.layout->qualifiers.end(); ) - { - if(i->name=="location" && !supports_interface_block_location()) - i = iface.layout->qualifiers.erase(i); - else if(i->name=="binding" && !supports_binding()) - { - stage->uniform_block_bindings[iface.block_name] = i->value; - i = iface.layout->qualifiers.erase(i); - } - else - ++i; - } - - if(iface.layout->qualifiers.empty()) - iface.layout = 0; - } -} - } // namespace SL } // namespace GL } // namespace Msp