From 9cfccf5c4e366e033cfd5eebf8955d2b13202b46 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 3 Apr 2021 13:20:34 +0300 Subject: [PATCH] Improve compatibility checks of location qualifiers in various contexts --- extensions/arb_enhanced_layouts.glext | 1 + .../arb_explicit_uniform_location.glext | 1 + extensions/arb_separate_shader_objects.glext | 3 + source/glsl/features.cpp | 13 ++- source/glsl/features.h | 3 + source/glsl/finalize.cpp | 80 ++++++++++++++++--- source/glsl/finalize.h | 3 + source/glsl/output.cpp | 6 ++ 8 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 extensions/arb_enhanced_layouts.glext create mode 100644 extensions/arb_explicit_uniform_location.glext create mode 100644 extensions/arb_separate_shader_objects.glext diff --git a/extensions/arb_enhanced_layouts.glext b/extensions/arb_enhanced_layouts.glext new file mode 100644 index 00000000..82742446 --- /dev/null +++ b/extensions/arb_enhanced_layouts.glext @@ -0,0 +1 @@ +extension ARB_enhanced_layouts diff --git a/extensions/arb_explicit_uniform_location.glext b/extensions/arb_explicit_uniform_location.glext new file mode 100644 index 00000000..20b8685e --- /dev/null +++ b/extensions/arb_explicit_uniform_location.glext @@ -0,0 +1 @@ +extension ARB_explicit_uniform_location diff --git a/extensions/arb_separate_shader_objects.glext b/extensions/arb_separate_shader_objects.glext new file mode 100644 index 00000000..af01a01a --- /dev/null +++ b/extensions/arb_separate_shader_objects.glext @@ -0,0 +1,3 @@ +extension ARB_separate_shader_objects +# Also defined in ARB_geometry_shader4 +ignore glProgramParameteri diff --git a/source/glsl/features.cpp b/source/glsl/features.cpp index dab230d3..1c19c0b0 100644 --- a/source/glsl/features.cpp +++ b/source/glsl/features.cpp @@ -1,5 +1,8 @@ +#include #include +#include #include +#include #include #include #include @@ -11,8 +14,11 @@ namespace SL { Features::Features(): gl_api(OPENGL), + arb_enhanced_layouts(false), arb_explicit_attrib_location(false), + arb_explicit_uniform_location(false), arb_gpu_shader5(false), + arb_separate_shader_objects(false), arb_uniform_buffer_object(false), ext_gpu_shader4(false), ext_texture_array(false), @@ -24,9 +30,11 @@ Features Features::from_context() Features features; features.gl_api = get_gl_api(); features.glsl_version = get_glsl_version(); + features.arb_enhanced_layouts = ARB_enhanced_layouts; features.arb_explicit_attrib_location = ARB_explicit_attrib_location; + features.arb_explicit_uniform_location = ARB_explicit_uniform_location; features.arb_gpu_shader5 = ARB_gpu_shader5; - //features.arb_texture_cube_map_array = ARB_texture_cube_map_array; + features.arb_separate_shader_objects = ARB_separate_shader_objects; features.arb_uniform_buffer_object = ARB_uniform_buffer_object; features.ext_gpu_shader4 = EXT_gpu_shader4; features.ext_texture_array = EXT_texture_array; @@ -38,8 +46,11 @@ Features Features::all() Features features; features.gl_api = OPENGL; features.glsl_version = Version(4, 60); + features.arb_enhanced_layouts = true; features.arb_explicit_attrib_location = true; + features.arb_explicit_uniform_location = true; features.arb_gpu_shader5 = true; + features.arb_separate_shader_objects = true; features.arb_uniform_buffer_object = true; features.ext_gpu_shader4 = true; features.ext_texture_array = true; diff --git a/source/glsl/features.h b/source/glsl/features.h index b65a61e2..c18efe05 100644 --- a/source/glsl/features.h +++ b/source/glsl/features.h @@ -11,8 +11,11 @@ struct Features { GLApi gl_api; Version glsl_version; + bool arb_enhanced_layouts; bool arb_explicit_attrib_location; + bool arb_explicit_uniform_location; bool arb_gpu_shader5; + bool arb_separate_shader_objects; bool arb_uniform_buffer_object; bool ext_gpu_shader4; bool ext_texture_array; diff --git a/source/glsl/finalize.cpp b/source/glsl/finalize.cpp index 030cb432..0adb2960 100644 --- a/source/glsl/finalize.cpp +++ b/source/glsl/finalize.cpp @@ -234,6 +234,16 @@ bool LegacyConverter::supports_interface_layouts() const 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 { if(features.gl_api==OPENGL_ES2) @@ -254,25 +264,53 @@ 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) { for(vector::const_iterator i=var.layout->qualifiers.begin(); i!=var.layout->qualifiers.end(); ) { - if(i->name=="location" && !supports_interface_layouts()) + if(i->name=="location") { - if(stage->type==Stage::VERTEX && var.interface=="in") - stage->locations[var.name] = i->value; - else if(stage->type==Stage::FRAGMENT && var.interface=="out") + bool supported = true; + bool external = false; + if(var.interface=="in") { - 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"); + 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(); - i = var.layout->qualifiers.erase(i); + if(!supported) + { + if(external) + stage->locations[var.name] = i->value; + i = var.layout->qualifiers.erase(i); + } + else + ++i; } else ++i; @@ -322,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()) diff --git a/source/glsl/finalize.h b/source/glsl/finalize.h index e0904b2e..357351b4 100644 --- a/source/glsl/finalize.h +++ b/source/glsl/finalize.h @@ -58,10 +58,13 @@ private: bool supports_unified_sampling_functions() const; virtual void visit(FunctionCall &); bool supports_interface_layouts() const; + bool supports_stage_interface_layouts() const; bool supports_centroid_sampling() const; bool supports_sample_sampling() const; + bool supports_uniform_location() const; virtual void visit(VariableDeclaration &); bool supports_interface_blocks(const std::string &) const; + bool supports_interface_block_location() const; virtual void visit(InterfaceBlock &); }; diff --git a/source/glsl/output.cpp b/source/glsl/output.cpp index b86cdd0a..1d82cae6 100644 --- a/source/glsl/output.cpp +++ b/source/glsl/output.cpp @@ -32,10 +32,16 @@ const string &Formatter::apply(Stage &s) formatted += '\n'; } + if(s.required_features.arb_enhanced_layouts) + append("#extension GL_ARB_enhanced_layouts: require\n"); if(s.required_features.arb_explicit_attrib_location) append("#extension GL_ARB_explicit_attrib_location: require\n"); + if(s.required_features.arb_explicit_uniform_location) + append("#extension GL_ARB_explicit_uniform_location: require\n"); if(s.required_features.arb_gpu_shader5) append("#extension GL_ARB_gpu_shader5: require\n"); + if(s.required_features.arb_separate_shader_objects) + append("#extension GL_ARB_separate_shader_objects: require\n"); if(s.required_features.arb_uniform_buffer_object) append("#extension GL_ARB_uniform_buffer_object: require\n"); if(s.required_features.ext_gpu_shader4) -- 2.43.0