From f901fcf41d8ca544085f448227f84bc6f966660d Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 24 Apr 2021 00:43:56 +0300 Subject: [PATCH] Redesign loading of GLSL sources There's now a new class which holds parsed modules. Parser no longer creates modules and the parse functions take the target module as a parameter. --- source/glsl/builtin.cpp | 7 ++-- source/glsl/compiler.cpp | 37 ++++++++----------- source/glsl/compiler.h | 6 +-- source/glsl/modulecache.cpp | 73 +++++++++++++++++++++++++++++++++++++ source/glsl/modulecache.h | 33 +++++++++++++++++ source/glsl/parser.cpp | 20 ++++------ source/glsl/parser.h | 10 +++-- 7 files changed, 142 insertions(+), 44 deletions(-) create mode 100644 source/glsl/modulecache.cpp create mode 100644 source/glsl/modulecache.h diff --git a/source/glsl/builtin.cpp b/source/glsl/builtin.cpp index 12602707..b9fe487c 100644 --- a/source/glsl/builtin.cpp +++ b/source/glsl/builtin.cpp @@ -28,8 +28,9 @@ Module *get_builtins_module() if(!io) return 0; - Parser parser; - Module *module = new Module(parser.parse(*io, "", BUILTIN_SOURCE)); + RefPtr module = new Module; + Parser parser(0); + parser.parse(*module, *io, "", BUILTIN_SOURCE); NodeList &shared_body = module->shared.content.body; NodeList::iterator insert_point = shared_body.begin(); @@ -73,7 +74,7 @@ Module *get_builtins_module() for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) populate_types(*i); - builtins_module = module; + builtins_module = module.release(); } return builtins_module.get(); } diff --git a/source/glsl/compiler.cpp b/source/glsl/compiler.cpp index 74eec856..5b488f4d 100644 --- a/source/glsl/compiler.cpp +++ b/source/glsl/compiler.cpp @@ -8,10 +8,10 @@ #include "finalize.h" #include "generate.h" #include "glsl_error.h" +#include "modulecache.h" #include "optimize.h" #include "output.h" #include "resolve.h" -#include "resources.h" #include "spirv.h" #include "validate.h" @@ -53,17 +53,17 @@ void Compiler::clear() void Compiler::set_source(const string &source, const string &src_name) { clear(); - Parser parser; imported_names.push_back(src_name); - append_module(parser.parse(source, src_name, 1), 0); + ModuleCache mod_cache(0); + append_module(mod_cache.add_module(source, src_name), mod_cache); } void Compiler::load_source(IO::Base &io, DataFile::Collection *res, const string &src_name) { clear(); - Parser parser; imported_names.push_back(src_name); - append_module(parser.parse(io, src_name, 1), res); + ModuleCache mod_cache(res); + append_module(mod_cache.add_module(io, src_name), mod_cache); } void Compiler::load_source(IO::Base &io, const string &src_name) @@ -223,7 +223,7 @@ string Compiler::get_diagnostics() const return combined; } -void Compiler::append_module(Module &mod, DataFile::Collection *res) +void Compiler::append_module(const Module &mod, ModuleCache &mod_cache) { module->source_map.merge_from(mod.source_map); @@ -232,15 +232,14 @@ void Compiler::append_module(Module &mod, DataFile::Collection *res) if(Import *imp = dynamic_cast(i->get())) imports.push_back(imp); for(vector::iterator i=imports.begin(); i!=imports.end(); ++i) - import(res, (*i)->module); - NodeRemover().apply(mod.shared, set(imports.begin(), imports.end())); + import(mod_cache, (*i)->module); append_stage(mod.shared); - for(list::iterator i=mod.stages.begin(); i!=mod.stages.end(); ++i) + for(list::const_iterator i=mod.stages.begin(); i!=mod.stages.end(); ++i) append_stage(*i); } -void Compiler::append_stage(Stage &stage) +void Compiler::append_stage(const Stage &stage) { Stage *target = 0; if(stage.type==Stage::SHARED) @@ -264,22 +263,18 @@ void Compiler::append_stage(Stage &stage) 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); + for(NodeList::const_iterator i=stage.content.body.begin(); i!=stage.content.body.end(); ++i) + if(!dynamic_cast(i->get())) + target->content.body.push_back(*i); } -void Compiler::import(DataFile::Collection *resources, const string &name) +void Compiler::import(ModuleCache &mod_cache, const string &name) { - string fn = name+".glsl"; - if(find(imported_names, fn)!=imported_names.end()) + if(find(imported_names, name)!=imported_names.end()) return; - imported_names.push_back(fn); + imported_names.push_back(name); - RefPtr io = (resources ? resources->open_raw(fn) : Resources::get_builtins().open(fn)); - if(!io) - throw runtime_error(format("module %s not found", name)); - Parser import_parser; - append_module(import_parser.parse(*io, fn, module->source_map.get_count()), resources); + append_module(mod_cache.get_module(name), mod_cache); } void Compiler::generate(Stage &stage) diff --git a/source/glsl/compiler.h b/source/glsl/compiler.h index 51b4f00a..3b540a8c 100644 --- a/source/glsl/compiler.h +++ b/source/glsl/compiler.h @@ -126,13 +126,13 @@ public: private: /** Appends a module to the target, processing any imports found in it. */ - void append_module(Module &, DataFile::Collection *); + void append_module(const Module &, ModuleCache &); /** Appends a single stage to the matching stage of the target. */ - void append_stage(Stage &); + void append_stage(const Stage &); /// Imports a module by name and appends it to the target. */ - void import(DataFile::Collection *, const std::string &); + void import(ModuleCache &, const std::string &); /** Generates any implicitly defines syntactic structures and resolves variables. */ diff --git a/source/glsl/modulecache.cpp b/source/glsl/modulecache.cpp new file mode 100644 index 00000000..116eb20a --- /dev/null +++ b/source/glsl/modulecache.cpp @@ -0,0 +1,73 @@ +#include +#include "modulecache.h" +#include "parser.h" +#include "resources.h" + +using namespace std; + +namespace Msp { +namespace GL { +namespace SL { + +ModuleCache::ModuleCache(DataFile::Collection *r): + resources(r), + next_source(1) +{ } + +ModuleCache::ModuleCache(const ModuleCache &other) +{ + for(map::const_iterator i=other.modules.begin(); i!=other.modules.end(); ++i) + modules[i->first] = new Module(*i->second); +} + +ModuleCache &ModuleCache::operator=(const ModuleCache &other) +{ + for(map::iterator i=modules.begin(); i!=modules.end(); ++i) + delete i->second; + modules.clear(); + for(map::const_iterator i=other.modules.begin(); i!=other.modules.end(); ++i) + modules[i->first] = new Module(*i->second); + return *this; +} + +ModuleCache::~ModuleCache() +{ + for(map::iterator i=modules.begin(); i!=modules.end(); ++i) + delete i->second; +} + +const Module &ModuleCache::add_module(const string &source, const string &src_name) +{ + RefPtr module = new Module; + Parser parser(this); + unsigned src_index = next_source++; + parser.parse(*module, source, src_name, src_index); + return *(modules[src_name] = module.release()); +} + +const Module &ModuleCache::add_module(IO::Base &io, const string &src_name) +{ + RefPtr module = new Module; + Parser parser(this); + unsigned src_index = next_source++; + parser.parse(*module, io, src_name, src_index); + return *(modules[src_name] = module.release()); +} + +const Module &ModuleCache::get_module(const string &name) +{ + string fn = name+".glsl"; + map::const_iterator i = modules.find(fn); + if(i!=modules.end()) + return *i->second; + + RefPtr io = (resources ? resources->open_raw(fn) : Resources::get_builtins().open(fn)); + if(!io) + throw runtime_error(format("module %s not found", name)); + + return add_module(*io, fn); +} + +} // namespace SL +} // namespace GL +} // namespace Msp diff --git a/source/glsl/modulecache.h b/source/glsl/modulecache.h new file mode 100644 index 00000000..ba892f93 --- /dev/null +++ b/source/glsl/modulecache.h @@ -0,0 +1,33 @@ +#ifndef MSP_GL_SL_MODULECACHE_H_ +#define MSP_GL_SL_MODULECACHE_H_ + +#include +#include "syntax.h" + +namespace Msp { +namespace GL { +namespace SL { + +class ModuleCache +{ +private: + DataFile::Collection *resources; + std::map modules; + unsigned next_source; + +public: + ModuleCache(DataFile::Collection *); + ModuleCache(const ModuleCache &); + ModuleCache &operator=(const ModuleCache &); + ~ModuleCache(); + + const Module &add_module(const std::string &, const std::string &); + const Module &add_module(IO::Base &, const std::string &); + const Module &get_module(const std::string &); +}; + +} // namespace SL +} // namespace GL +} // namespace Msp + +#endif diff --git a/source/glsl/parser.cpp b/source/glsl/parser.cpp index 0512c10b..cbfa593a 100644 --- a/source/glsl/parser.cpp +++ b/source/glsl/parser.cpp @@ -4,6 +4,7 @@ #include #include "builtin.h" #include "glsl_error.h" +#include "modulecache.h" #include "parser.h" #undef interface @@ -14,7 +15,8 @@ namespace Msp { namespace GL { namespace SL { -Parser::Parser(): +Parser::Parser(ModuleCache *s): + mod_cache(s), preprocessor(tokenizer), module(0) { @@ -25,20 +27,16 @@ Parser::Parser(): preprocessor.signal_line.connect(sigc::mem_fun(this, &Parser::line_change)); } -Parser::~Parser() -{ - delete module; -} - -Module &Parser::parse(const string &s, const string &n, int i) +void Parser::parse(Module &m, const string &s, const string &n, int i) { + SetForScope set_module(module, &m); source = s; parse_source(n, i); - return *module; } -Module &Parser::parse(IO::Base &io, const string &n, int i) +void Parser::parse(Module &m, IO::Base &io, const string &n, int i) { + SetForScope set_module(module, &m); source = string(); while(!io.eof()) { @@ -47,14 +45,10 @@ Module &Parser::parse(IO::Base &io, const string &n, int i) source.append(buffer, len); } parse_source(n, i); - return *module; } void Parser::parse_source(const string &name, int index) { - delete module; - module = new Module; - cur_stage = &module->shared; base_index = index; source_index = index; diff --git a/source/glsl/parser.h b/source/glsl/parser.h index c98867a3..e087f27f 100644 --- a/source/glsl/parser.h +++ b/source/glsl/parser.h @@ -12,9 +12,12 @@ namespace Msp { namespace GL { namespace SL { +class ModuleCache; + class Parser { private: + ModuleCache *mod_cache; std::string source; int base_index; int source_index; @@ -27,11 +30,10 @@ private: std::vector errors; public: - Parser(); - ~Parser(); + Parser(ModuleCache *); - Module &parse(const std::string &, const std::string &, int); - Module &parse(IO::Base &, const std::string &, int); + void parse(Module &, const std::string &, const std::string &, int); + void parse(Module &, IO::Base &, const std::string &, int); private: void parse_source(const std::string &, int); -- 2.43.0