From c0be4e4ae1a8b6ac31ff6b7080e2242c13d947ff Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 22 Feb 2021 00:58:57 +0200 Subject: [PATCH] Reduce coupling between the GLSL compiler and the graphics engine Feature states are now recorded in a struct. --- source/glsl/compatibility.cpp | 54 +++++++++++++++-------------------- source/glsl/compatibility.h | 7 ++--- source/glsl/compiler.cpp | 17 +++++++---- source/glsl/compiler.h | 2 ++ source/glsl/features.cpp | 37 ++++++++++++++++++++++++ source/glsl/features.h | 29 +++++++++++++++++++ source/glsl/output.cpp | 24 ++++++++++------ source/glsl/parser.cpp | 2 +- source/glsl/syntax.h | 5 ++-- 9 files changed, 124 insertions(+), 53 deletions(-) create mode 100644 source/glsl/features.cpp create mode 100644 source/glsl/features.h diff --git a/source/glsl/compatibility.cpp b/source/glsl/compatibility.cpp index 0308a391..2e13a5f6 100644 --- a/source/glsl/compatibility.cpp +++ b/source/glsl/compatibility.cpp @@ -1,10 +1,5 @@ #include #include -#include -#include -#include -#include -#include #include #include "compatibility.h" @@ -85,14 +80,13 @@ void PrecisionRemover::visit(VariableDeclaration &var) LegacyConverter::LegacyConverter(): - target_api(get_gl_api()), - target_version(get_glsl_version()), frag_out(0) { } -void LegacyConverter::apply(Stage &s) +void LegacyConverter::apply(Stage &s, const Features &feat) { stage = &s; + features = feat; visit(s.content); } @@ -108,29 +102,27 @@ void LegacyConverter::visit(Block &block) bool LegacyConverter::check_version(const Version &feature_version) const { - if(target_versionrequired_versionrequired_version = feature_version; + else if(stage->required_features.glsl_versionrequired_features.glsl_version = feature_version; return true; } -bool LegacyConverter::check_extension(const Extension &extension) const +bool LegacyConverter::check_extension(bool Features::*extension) const { - if(!extension) + if(!(features.*extension)) return false; - vector::iterator i = find(stage->required_extensions, &extension); - if(i==stage->required_extensions.end()) - stage->required_extensions.push_back(&extension); + stage->required_features.*extension = true; return true; } bool LegacyConverter::supports_unified_interface_syntax() const { - if(target_api==OPENGL_ES2) + if(features.gl_api==OPENGL_ES2) return check_version(Version(3, 0)); else return check_version(Version(1, 30)); @@ -159,7 +151,7 @@ void LegacyConverter::visit(Assignment &assign) bool LegacyConverter::supports_unified_sampling_functions() const { - if(target_api==OPENGL_ES2) + if(features.gl_api==OPENGL_ES2) return check_version(Version(3, 0)); else return check_version(Version(1, 30)); @@ -197,22 +189,22 @@ void LegacyConverter::visit(FunctionCall &call) call.name = "shadow2D"; else if(sampler_type=="sampler1DArray") { - check_extension(EXT_texture_array); + check_extension(&Features::ext_texture_array); call.name = "texture1DArray"; } else if(sampler_type=="sampler2DArray") { - check_extension(EXT_texture_array); + check_extension(&Features::ext_texture_array); call.name = "texture2DArray"; } else if(sampler_type=="sampler1DArrayShadow") { - check_extension(EXT_texture_array); + check_extension(&Features::ext_texture_array); call.name = "shadow1DArray"; } else if(sampler_type=="sampler2DArrayShadow") { - check_extension(EXT_texture_array); + check_extension(&Features::ext_texture_array); call.name = "shadow2DArray"; } } @@ -223,32 +215,32 @@ void LegacyConverter::visit(FunctionCall &call) bool LegacyConverter::supports_interface_layouts() const { - if(target_api==OPENGL_ES2) + if(features.gl_api==OPENGL_ES2) return check_version(Version(3, 0)); else if(check_version(Version(3, 30))) return true; else - return check_extension(ARB_explicit_attrib_location); + return check_extension(&Features::arb_explicit_attrib_location); } bool LegacyConverter::supports_centroid_sampling() const { - if(target_api==OPENGL_ES2) + if(features.gl_api==OPENGL_ES2) return check_version(Version(3, 0)); else if(check_version(Version(1, 20))) return true; else - return check_extension(EXT_gpu_shader4); + return check_extension(&Features::ext_gpu_shader4); } bool LegacyConverter::supports_sample_sampling() const { - if(target_api==OPENGL_ES2) + if(features.gl_api==OPENGL_ES2) return check_version(Version(3, 20)); else if(check_version(Version(4, 0))) return true; else - return check_extension(ARB_gpu_shader5); + return check_extension(&Features::arb_gpu_shader5); } void LegacyConverter::visit(VariableDeclaration &var) @@ -268,7 +260,7 @@ void LegacyConverter::visit(VariableDeclaration &var) else if(stage->type==Stage::FRAGMENT && var.interface=="out") { if(location!=0) - static Require _req(EXT_gpu_shader4); + check_extension(&Features::ext_gpu_shader4); stage->locations[var.name] = location; var.layout->qualifiers.erase(i); } @@ -303,7 +295,7 @@ void LegacyConverter::visit(VariableDeclaration &var) bool LegacyConverter::supports_interface_blocks(const string &iface) const { - if(target_api==OPENGL_ES2) + if(features.gl_api==OPENGL_ES2) { if(iface=="uniform") return check_version(Version(3, 0)); @@ -313,7 +305,7 @@ bool LegacyConverter::supports_interface_blocks(const string &iface) const else if(check_version(Version(1, 50))) return true; else if(iface=="uniform") - return check_extension(ARB_uniform_buffer_object); + return check_extension(&Features::arb_uniform_buffer_object); else return false; } diff --git a/source/glsl/compatibility.h b/source/glsl/compatibility.h index a391aab0..d3a3a74c 100644 --- a/source/glsl/compatibility.h +++ b/source/glsl/compatibility.h @@ -45,8 +45,7 @@ class LegacyConverter: private TraversingVisitor { private: Stage *stage; - GLApi target_api; - Version target_version; + Features features; std::string type; VariableDeclaration *frag_out; NodeList::iterator uniform_insert_point; @@ -55,12 +54,12 @@ private: public: LegacyConverter(); - virtual void apply(Stage &); + virtual void apply(Stage &, const Features &); private: virtual void visit(Block &); bool check_version(const Version &) const; - bool check_extension(const Extension &) const; + bool check_extension(bool Features::*) const; bool supports_unified_interface_syntax() const; virtual void visit(VariableReference &); virtual void visit(Assignment &); diff --git a/source/glsl/compiler.cpp b/source/glsl/compiler.cpp index 89ffd7f3..4a7a19e2 100644 --- a/source/glsl/compiler.cpp +++ b/source/glsl/compiler.cpp @@ -19,6 +19,12 @@ namespace GL { namespace SL { Compiler::Compiler(): + features(Features::from_context()), + module(0) +{ } + +Compiler::Compiler(const Features &f): + features(f), module(0) { } @@ -162,8 +168,8 @@ void Compiler::append_stage(Stage &stage) target = &*i; } - if(stage.required_version>target->required_version) - target->required_version = stage.required_version; + if(stage.required_features.glsl_version>target->required_features.glsl_version) + target->required_features.glsl_version = stage.required_features.glsl_version; for(NodeList::iterator i=stage.content.body.begin(); i!=stage.content.body.end(); ++i) target->content.body.push_back(*i); DeclarationCombiner().apply(*target); @@ -185,8 +191,9 @@ void Compiler::import(DataFile::Collection *resources, const string &name) void Compiler::generate(Stage &stage, Mode mode) { - if(module->shared.required_version>stage.required_version) - stage.required_version = module->shared.required_version; + stage.required_features.gl_api = features.gl_api; + if(module->shared.required_features.glsl_version>stage.required_features.glsl_version) + stage.required_features.glsl_version = module->shared.required_features.glsl_version; inject_block(stage.content, module->shared.content); DeclarationReorderer().apply(stage); @@ -198,7 +205,7 @@ void Compiler::generate(Stage &stage, Mode mode) DeclarationReorderer().apply(stage); FunctionResolver().apply(stage); if(mode==PROGRAM) - LegacyConverter().apply(stage); + LegacyConverter().apply(stage, features); } bool Compiler::optimize(Stage &stage) diff --git a/source/glsl/compiler.h b/source/glsl/compiler.h index 6564d50a..8340aa6d 100644 --- a/source/glsl/compiler.h +++ b/source/glsl/compiler.h @@ -21,11 +21,13 @@ public: }; private: + Features features; Module *module; std::vector imported_names; public: Compiler(); + Compiler(const Features &); ~Compiler(); private: diff --git a/source/glsl/features.cpp b/source/glsl/features.cpp new file mode 100644 index 00000000..d1c8101d --- /dev/null +++ b/source/glsl/features.cpp @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include "features.h" + +namespace Msp { +namespace GL { +namespace SL { + +Features::Features(): + gl_api(OPENGL), + arb_explicit_attrib_location(false), + arb_gpu_shader5(false), + arb_uniform_buffer_object(false), + ext_gpu_shader4(false), + ext_texture_array(false) +{ } + +Features Features::from_context() +{ + Features features; + features.gl_api = get_gl_api(); + features.glsl_version = get_glsl_version(); + features.arb_explicit_attrib_location = ARB_explicit_attrib_location; + features.arb_gpu_shader5 = ARB_gpu_shader5; + //features.arb_texture_cube_map_array = ARB_texture_cube_map_array; + features.arb_uniform_buffer_object = ARB_uniform_buffer_object; + features.ext_gpu_shader4 = EXT_gpu_shader4; + features.ext_texture_array = EXT_texture_array; + return features; +} + +} // namespace SL +} // namespace GL +} // namespace Msp diff --git a/source/glsl/features.h b/source/glsl/features.h new file mode 100644 index 00000000..8f7a3e7c --- /dev/null +++ b/source/glsl/features.h @@ -0,0 +1,29 @@ +#ifndef MSP_GL_SL_FEATURES_H_ +#define MSP_GL_SL_FEATURES_H_ + +#include + +namespace Msp { +namespace GL { +namespace SL { + +struct Features +{ + GLApi gl_api; + Version glsl_version; + bool arb_explicit_attrib_location; + bool arb_gpu_shader5; + bool arb_uniform_buffer_object; + bool ext_gpu_shader4; + bool ext_texture_array; + + Features(); + + static Features from_context(); +}; + +} // namespace SL +} // namespace GL +} // namespace Msp + +#endif diff --git a/source/glsl/output.cpp b/source/glsl/output.cpp index 9d4383e4..3fc703c1 100644 --- a/source/glsl/output.cpp +++ b/source/glsl/output.cpp @@ -22,21 +22,27 @@ const string &Formatter::apply(Stage &s, Compiler::Mode m) mode = m; stage = &s; - GLApi api = get_gl_api(); - const Version &ver = s.required_version; + const Version &ver = s.required_features.glsl_version; if(ver) { append(format("#version %d%02d", ver.major, ver.minor)); - if(api==OPENGL_ES2 && ver>=Version(3, 0)) + if(s.required_features.gl_api==OPENGL_ES2 && ver>=Version(3, 0)) append(" es"); formatted += '\n'; } - for(vector::const_iterator i=s.required_extensions.begin(); i!=s.required_extensions.end(); ++i) - append(format("#extension %s: require\n", (*i)->get_name())); - if(!s.required_extensions.empty()) - formatted += '\n'; + if(s.required_features.arb_explicit_attrib_location) + append("#extension arb_explicit_attrib_location: require\n"); + if(s.required_features.arb_gpu_shader5) + append("#extension arb_gpu_shader5: require\n"); + if(s.required_features.arb_uniform_buffer_object) + append("#extension arb_uniform_buffer_object: require\n"); + if(s.required_features.ext_gpu_shader4) + append("#extension ext_gpu_shader4: require\n"); + if(s.required_features.ext_texture_array) + append("#extension ext_texture_array: require\n"); + formatted += '\n'; visit(s.content); @@ -67,7 +73,7 @@ void Formatter::set_source(unsigned index, unsigned line) else { unsigned l = line; - if(mode==Compiler::PROGRAM && stage && stage->required_versionrequired_features.glsl_versionrequired_versionrequired_features.glsl_versiontype==Stage::VERTEX && var.interface=="in") interface = "attribute"; diff --git a/source/glsl/parser.cpp b/source/glsl/parser.cpp index 7044a8c3..ec6ce6eb 100644 --- a/source/glsl/parser.cpp +++ b/source/glsl/parser.cpp @@ -62,7 +62,7 @@ void Parser::parse_source(const string &name, unsigned index) void Parser::set_required_version(const Version &ver) { - cur_stage->required_version = ver; + cur_stage->required_features.glsl_version = ver; } void Parser::source_reference(unsigned index, const string &name) diff --git a/source/glsl/syntax.h b/source/glsl/syntax.h index e9c76eba..3fb848d2 100644 --- a/source/glsl/syntax.h +++ b/source/glsl/syntax.h @@ -6,7 +6,7 @@ #include #include #include -#include "extension.h" +#include "features.h" #include "sourcemap.h" #pragma push_macro("interface") @@ -386,8 +386,7 @@ struct Stage std::map in_variables; std::map out_variables; std::map locations; - Version required_version; - std::vector required_extensions; + Features required_features; Stage(Type); -- 2.43.0