X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Ffinalize.cpp;h=4068037e919e81b5cc514d12584bec7df8088360;hb=6f06479b765946bdd3174b2c05e7a1dda24c31c2;hp=1b300e72a872cd55aa19727cf284efba5607b26f;hpb=c6b29fbf9927467b21dca65539a1fa2c98f96e0e;p=libs%2Fgl.git diff --git a/source/glsl/finalize.cpp b/source/glsl/finalize.cpp index 1b300e72..4068037e 100644 --- a/source/glsl/finalize.cpp +++ b/source/glsl/finalize.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include "finalize.h" @@ -11,11 +12,71 @@ namespace Msp { namespace GL { namespace SL { -void LocationAllocator::apply(Module &module) +void StructOrganizer::visit(StructDeclaration &strct) { - for(list::iterator i=module.stages.begin(); i!=module.stages.end(); ++i) - apply(*i); + SetForScope set_offset(offset, 0); + TraversingVisitor::visit(strct); +} + +void StructOrganizer::visit(VariableDeclaration &var) +{ + if(offset>=0) + { + int *layout_offset = 0; + bool has_matrix_order = false; + if(var.layout) + { + for(Layout::Qualifier &q: var.layout->qualifiers) + { + if(q.name=="offset" && q.has_value) + { + layout_offset = &q.value; + if(q.value>=offset) + offset = q.value; + } + else if(q.name=="column_major" || q.name=="row_major") + has_matrix_order = true; + } + } + + MemoryRequirementsCalculator::Result mem_reqs = MemoryRequirementsCalculator().apply(var); + offset += mem_reqs.alignment-1; + offset -= offset%mem_reqs.alignment; + + if(layout_offset) + *layout_offset = offset; + else + { + if(!var.layout) + var.layout = new Layout; + + var.layout->qualifiers.push_back(Layout::Qualifier("offset", offset)); + } + + if(!has_matrix_order) + { + const BasicTypeDeclaration *basic = dynamic_cast(var.type_declaration); + while(basic && basic->kind==BasicTypeDeclaration::ARRAY) + basic = dynamic_cast(basic->base_type); + if(basic && basic->kind==BasicTypeDeclaration::MATRIX) + var.layout->qualifiers.push_back(Layout::Qualifier("column_major")); + } + + offset += mem_reqs.size; + } +} + + +void LocationAllocator::apply(Module &module, const Features &features) +{ + for(Stage &s: module.stages) + apply(s); allocate_locations("uniform"); + + for(InterfaceBlock *b: unbound_blocks) + bind_uniform(b->layout, b->block_name, features.uniform_binding_range); + for(VariableDeclaration *t: unbound_textures) + bind_uniform(t->layout, t->name, features.texture_binding_range); } void LocationAllocator::apply(Stage &stage) @@ -31,9 +92,9 @@ void LocationAllocator::apply(Stage &stage) void LocationAllocator::allocate_locations(const string &iface) { - vector::iterator write = unplaced_variables.begin(); + auto write = unplaced_variables.begin(); unsigned next = 0; - for(vector::const_iterator i=unplaced_variables.begin(); i!=unplaced_variables.end(); ++i) + for(auto i=unplaced_variables.begin(); i!=unplaced_variables.end(); ++i) { if((*i)->interface!=iface) { @@ -45,10 +106,10 @@ void LocationAllocator::allocate_locations(const string &iface) if((*i)->interface=="uniform") { - map::const_iterator j = uniform_locations.find((*i)->name); - if(j!=uniform_locations.end()) + auto j = uniforms.find((*i)->name); + if(j!=uniforms.end() && j->second.location>=0) { - add_location((*i)->layout, j->second); + add_layout_value((*i)->layout, "location", j->second.location); continue; } } @@ -67,9 +128,9 @@ void LocationAllocator::allocate_locations(const string &iface) next = blocking+1; } - add_location((*i)->layout, next); + add_layout_value((*i)->layout, "location", next); if((*i)->interface=="uniform") - uniform_locations[(*i)->name] = next; + uniforms[(*i)->name].location = next; for(unsigned j=0; j &layout, unsigned location) +void LocationAllocator::bind_uniform(RefPtr &layout, const string &name, unsigned range) +{ + auto i = uniforms.find(name); + if(i!=uniforms.end() && i->second.bind_point>=0) + add_layout_value(layout, "binding", i->second.bind_point); + else + { + set &used = used_bindings[0]; + + unsigned bind_point = fold32(hash64(name))%range; + while(used.count(bind_point)) + bind_point = (bind_point+1)%range; + + add_layout_value(layout, "binding", bind_point); + uniforms[name].bind_point = bind_point; + used.insert(bind_point); + } +} + +void LocationAllocator::add_layout_value(RefPtr &layout, const string &name, unsigned value) { if(!layout) layout = new Layout; - Layout::Qualifier qual; - qual.name = "location"; - qual.has_value = true; - qual.value = location; - layout->qualifiers.push_back(qual); + layout->qualifiers.push_back(Layout::Qualifier(name, value)); } void LocationAllocator::visit(VariableDeclaration &var) { - if(!var.interface.empty() && var.name.compare(0, 3, "gl_")) + if(!var.name.compare(0, 3, "gl_")) + return; + + if(!var.interface.empty()) { int location = (var.layout ? get_layout_value(*var.layout, "location") : -1); @@ -101,7 +180,7 @@ void LocationAllocator::visit(VariableDeclaration &var) { location = get_layout_value(*var.linked_declaration->layout, "location"); if(location>=0) - add_location(var.layout, location); + add_layout_value(var.layout, "location", location); } if(location>=0) @@ -110,17 +189,50 @@ void LocationAllocator::visit(VariableDeclaration &var) for(unsigned i=0; i(type)) + type = basic->base_type; + if(dynamic_cast(type)) + { + int bind_point = (var.layout ? get_layout_value(*var.layout, "binding") : -1); + if(bind_point>=0) + { + used_bindings[0].insert(bind_point); + uniforms[var.name].bind_point = bind_point; + } + else + unbound_textures.push_back(&var); + } + } } +void LocationAllocator::visit(InterfaceBlock &iface) +{ + if(!iface.instance_name.compare(0, 3, "gl_")) + return; + + if(iface.interface=="uniform") + { + 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); + } +} -PrecisionConverter::PrecisionConverter(): - stage(0) -{ } void PrecisionConverter::apply(Stage &s) { @@ -131,7 +243,7 @@ void PrecisionConverter::apply(Stage &s) void PrecisionConverter::visit(Block &block) { - for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ++i) + for(auto i=block.body.begin(); i!=block.body.end(); ++i) { if(&block==&stage->content) insert_point = i; @@ -141,7 +253,7 @@ void PrecisionConverter::visit(Block &block) void PrecisionConverter::visit(Precision &prec) { - if(stage->required_features.gl_api==OPENGL_ES2) + if(stage->required_features.target_api==OPENGL_ES) have_default.insert(prec.type); else nodes_to_remove.insert(&prec); @@ -149,7 +261,7 @@ void PrecisionConverter::visit(Precision &prec) void PrecisionConverter::visit(VariableDeclaration &var) { - if(stage->required_features.gl_api!=OPENGL_ES2) + if(stage->required_features.target_api!=OPENGL_ES) { var.precision.clear(); return; @@ -188,10 +300,6 @@ void PrecisionConverter::visit(VariableDeclaration &var) } -LegacyConverter::LegacyConverter(): - frag_out(0) -{ } - void LegacyConverter::apply(Stage &s, const Features &feat) { stage = &s; @@ -202,7 +310,7 @@ void LegacyConverter::apply(Stage &s, const Features &feat) NodeRemover().apply(s, nodes_to_remove); if(!stage->required_features.glsl_version) - stage->required_features.glsl_version = Version(1, (stage->required_features.gl_api==OPENGL_ES2 ? 0 : 10)); + stage->required_features.glsl_version = Version(1, (stage->required_features.target_api==OPENGL_ES ? 0 : 10)); } else unsupported(format("Stage %s is not supported", Stage::get_stage_name(s.type))); @@ -220,7 +328,7 @@ void LegacyConverter::unsupported(const string &reason) void LegacyConverter::visit(Block &block) { - for(NodeList::iterator i=block.body.begin(); i!=block.body.end(); ++i) + for(auto i=block.body.begin(); i!=block.body.end(); ++i) { if(&block==&stage->content) uniform_insert_point = i; @@ -252,7 +360,7 @@ bool LegacyConverter::supports_stage(Stage::Type st) const { if(st==Stage::GEOMETRY) { - if(features.gl_api==OPENGL_ES2) + if(features.target_api==OPENGL_ES) return check_version(Version(3, 20)); else return check_version(Version(1, 50)); @@ -263,7 +371,7 @@ bool LegacyConverter::supports_stage(Stage::Type st) const bool LegacyConverter::supports_unified_interface_syntax() const { - if(features.gl_api==OPENGL_ES2) + if(features.target_api==OPENGL_ES) return check_version(Version(3, 0)); else return check_version(Version(1, 30)); @@ -287,7 +395,7 @@ void LegacyConverter::visit(Assignment &assign) bool LegacyConverter::supports_unified_sampling_functions() const { - if(features.gl_api==OPENGL_ES2) + if(features.target_api==OPENGL_ES) return check_version(Version(3, 0)); else return check_version(Version(1, 30)); @@ -332,7 +440,7 @@ void LegacyConverter::visit(FunctionCall &call) bool LegacyConverter::supports_interface_layouts() const { - if(features.gl_api==OPENGL_ES2) + if(features.target_api==OPENGL_ES) return check_version(Version(3, 0)); else if(check_version(Version(3, 30))) return true; @@ -344,7 +452,7 @@ bool LegacyConverter::supports_interface_layouts() const bool LegacyConverter::supports_stage_interface_layouts() const { - if(features.gl_api==OPENGL_ES2) + if(features.target_api==OPENGL_ES) return check_version(Version(3, 10)); else if(check_version(Version(4, 10))) return true; @@ -354,7 +462,7 @@ bool LegacyConverter::supports_stage_interface_layouts() const bool LegacyConverter::supports_centroid_sampling() const { - if(features.gl_api==OPENGL_ES2) + if(features.target_api==OPENGL_ES) return check_version(Version(3, 0)); else if(check_version(Version(1, 20))) return true; @@ -364,7 +472,7 @@ bool LegacyConverter::supports_centroid_sampling() const bool LegacyConverter::supports_sample_sampling() const { - if(features.gl_api==OPENGL_ES2) + if(features.target_api==OPENGL_ES) return check_version(Version(3, 20)); else if(check_version(Version(4, 0))) return true; @@ -374,7 +482,7 @@ bool LegacyConverter::supports_sample_sampling() const bool LegacyConverter::supports_uniform_location() const { - if(features.gl_api==OPENGL_ES2) + if(features.target_api==OPENGL_ES) return check_version(Version(3, 10)); else if(check_version(Version(4, 30))) return true; @@ -384,7 +492,7 @@ bool LegacyConverter::supports_uniform_location() const bool LegacyConverter::supports_binding() const { - if(features.gl_api==OPENGL_ES2) + if(features.target_api==OPENGL_ES) return check_version(Version(3, 10)); else return check_version(Version(4, 20)); @@ -394,7 +502,7 @@ void LegacyConverter::visit(VariableDeclaration &var) { if(var.layout) { - for(vector::const_iterator i=var.layout->qualifiers.begin(); i!=var.layout->qualifiers.end(); ) + for(auto i=var.layout->qualifiers.begin(); i!=var.layout->qualifiers.end(); ) { if(i->name=="location") { @@ -471,7 +579,7 @@ void LegacyConverter::visit(VariableDeclaration &var) bool LegacyConverter::supports_interface_blocks(const string &iface) const { - if(features.gl_api==OPENGL_ES2) + if(features.target_api==OPENGL_ES) { if(iface=="uniform") return check_version(Version(3, 0)); @@ -488,7 +596,7 @@ bool LegacyConverter::supports_interface_blocks(const string &iface) const bool LegacyConverter::supports_interface_block_location() const { - if(features.gl_api==OPENGL_ES2) + if(features.target_api==OPENGL_ES) return check_version(Version(3, 20)); else if(check_version(Version(4, 40))) return true; @@ -500,7 +608,7 @@ void LegacyConverter::visit(InterfaceBlock &iface) { if(iface.layout) { - for(vector::const_iterator i=iface.layout->qualifiers.begin(); i!=iface.layout->qualifiers.end(); ) + 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);