X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Ffinalize.cpp;h=0adb2960b1da3784a4554d9a97b447b12163481d;hb=9cfccf5c4e366e033cfd5eebf8955d2b13202b46;hp=532e2ffcbb3914fd2d7e81dafab0f784e0b52daf;hpb=6ff7aea73057e4a650d8b0ac659d9bba05ba02e2;p=libs%2Fgl.git diff --git a/source/glsl/finalize.cpp b/source/glsl/finalize.cpp index 532e2ffc..0adb2960 100644 --- a/source/glsl/finalize.cpp +++ b/source/glsl/finalize.cpp @@ -91,6 +91,7 @@ void LegacyConverter::apply(Stage &s, const Features &feat) if(supports_stage(s.type)) { s.content.visit(*this); + 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)); @@ -227,8 +228,20 @@ bool LegacyConverter::supports_interface_layouts() const return check_version(Version(3, 0)); else if(check_version(Version(3, 30))) return true; - else + else if(check_version(Version(1, 30))) return check_extension(&Features::arb_explicit_attrib_location); + else + return false; +} + +bool LegacyConverter::supports_stage_interface_layouts() const +{ + if(features.gl_api==OPENGL_ES2) + return check_version(Version(3, 10)); + else if(check_version(Version(4, 10))) + return true; + else + return check_extension(&Features::arb_separate_shader_objects); } bool LegacyConverter::supports_centroid_sampling() const @@ -251,31 +264,60 @@ bool LegacyConverter::supports_sample_sampling() const return check_extension(&Features::arb_gpu_shader5); } +bool LegacyConverter::supports_uniform_location() const +{ + if(features.gl_api==OPENGL_ES2) + return check_version(Version(3, 10)); + else if(check_version(Version(4, 30))) + return true; + else + return check_extension(&Features::arb_explicit_uniform_location); +} + void LegacyConverter::visit(VariableDeclaration &var) { - if(var.layout && !supports_interface_layouts()) + if(var.layout) { - vector::iterator i; - for(i=var.layout->qualifiers.begin(); (i!=var.layout->qualifiers.end() && i->name!="location"); ++i) ; - if(i!=var.layout->qualifiers.end()) + for(vector::const_iterator i=var.layout->qualifiers.begin(); i!=var.layout->qualifiers.end(); ) { - if(stage->type==Stage::VERTEX && var.interface=="in") + if(i->name=="location") { - stage->locations[var.name] = i->value; - var.layout->qualifiers.erase(i); - } - else if(stage->type==Stage::FRAGMENT && var.interface=="out") - { - if(check_extension(&Features::ext_gpu_shader4)) - stage->locations[var.name] = i->value; - else if(i->value!=0) - unsupported("EXT_gpu_shader4 required for multiple fragment shader outputs"); - var.layout->qualifiers.erase(i); - } + bool supported = true; + bool external = false; + if(var.interface=="in") + { + external = (stage->type==Stage::VERTEX); + supported = (external ? supports_interface_layouts() : supports_stage_interface_layouts()); + } + else if(var.interface=="out") + { + external = (stage->type==Stage::FRAGMENT); + supported = (external ? supports_interface_layouts() : supports_stage_interface_layouts()); + if(external && !supported && !check_extension(&Features::ext_gpu_shader4)) + { + external = false; + if(i->value!=0) + unsupported("EXT_gpu_shader4 required for multiple fragment shader outputs"); + } + } + else if(var.interface=="uniform") + supported = supports_uniform_location(); - if(var.layout->qualifiers.empty()) - var.layout = 0; + if(!supported) + { + if(external) + stage->locations[var.name] = i->value; + i = var.layout->qualifiers.erase(i); + } + else + ++i; + } + else + ++i; } + + if(var.layout->qualifiers.empty()) + var.layout = 0; } if(var.sampling=="centroid") @@ -318,8 +360,32 @@ bool LegacyConverter::supports_interface_blocks(const string &iface) const return false; } +bool LegacyConverter::supports_interface_block_location() const +{ + if(features.gl_api==OPENGL_ES2) + return check_version(Version(3, 20)); + else if(check_version(Version(4, 40))) + return true; + else + return check_extension(&Features::arb_enhanced_layouts); +} + void LegacyConverter::visit(InterfaceBlock &iface) { + if(iface.layout) + { + for(vector::const_iterator 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 + ++i; + } + + if(iface.layout->qualifiers.empty()) + iface.layout = 0; + } + if(!supports_interface_blocks(iface.interface) && iface.type_declaration) { if(!iface.instance_name.empty())