From: Mikko Rasa Date: Thu, 1 Apr 2021 21:13:58 +0000 (+0300) Subject: Split up ComponentSpecializer X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=d9d7ab44d5f88c4537906e77c49db06d6bdc099c Split up ComponentSpecializer It was weird having the same class do two things, and also those things should be done at slightly different points of the compilation process. --- diff --git a/source/glsl/compiler.cpp b/source/glsl/compiler.cpp index b810e52b..fab05473 100644 --- a/source/glsl/compiler.cpp +++ b/source/glsl/compiler.cpp @@ -79,7 +79,7 @@ void Compiler::specialize(const map &sv) void Compiler::compile(Mode mode) { for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) - generate(*i, mode); + generate(*i); bool valid = true; for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) @@ -88,8 +88,12 @@ void Compiler::compile(Mode mode) if(!valid) throw invalid_shader_source(get_diagnostics()); - unsigned n = 0; - for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++n) + if(mode==PROGRAM && specialized) + { + for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) + ConstantSpecializer().apply(*i, spec_values); + } + for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ) { OptimizeResult result = optimize(*i); if(result==REDO_PREVIOUS) @@ -244,7 +248,7 @@ void Compiler::import(DataFile::Collection *resources, const string &name) append_module(import_parser.parse(*io, fn, module->source_map.get_count()), resources); } -void Compiler::generate(Stage &stage, Mode mode) +void Compiler::generate(Stage &stage) { stage.required_features.gl_api = features.gl_api; if(module->shared.required_features.glsl_version>stage.required_features.glsl_version) @@ -264,7 +268,7 @@ void Compiler::generate(Stage &stage, Mode mode) InterfaceGenerator().apply(stage); resolve(stage, RESOLVE_BLOCKS|RESOLVE_TYPES|RESOLVE_VARIABLES); - ConstantSpecializer().apply(stage, (mode==PROGRAM && specialized ? &spec_values : 0)); + ConstantIdAssigner().apply(stage); } template diff --git a/source/glsl/compiler.h b/source/glsl/compiler.h index 0ae2ed41..674081a0 100644 --- a/source/glsl/compiler.h +++ b/source/glsl/compiler.h @@ -122,7 +122,7 @@ private: /** Generates any implicitly defines syntactic structures and resolves variables. */ - void generate(Stage &, Mode); + void generate(Stage &); template bool resolve(Stage &, unsigned &, unsigned); diff --git a/source/glsl/generate.cpp b/source/glsl/generate.cpp index 13fb72c5..f345670b 100644 --- a/source/glsl/generate.cpp +++ b/source/glsl/generate.cpp @@ -8,55 +8,23 @@ namespace Msp { namespace GL { namespace SL { -ConstantSpecializer::ConstantSpecializer(): - values(0) -{ } - -void ConstantSpecializer::apply(Stage &stage, const map *v) +void ConstantIdAssigner::apply(Stage &stage) { - values = v; stage.content.visit(*this); } -void ConstantSpecializer::visit(VariableDeclaration &var) +void ConstantIdAssigner::visit(VariableDeclaration &var) { - bool specializable = false; if(var.layout) { vector &qualifiers = var.layout->qualifiers; for(vector::iterator i=qualifiers.begin(); i!=qualifiers.end(); ++i) - if(i->name=="constant_id") + if(i->name=="constant_id" && i->has_value) { - specializable = true; - if(values) - qualifiers.erase(i); - else if(i->value==-1) + if(i->value==-1) i->value = hash32(var.name)&0x7FFFFFFF; break; } - - if(qualifiers.empty()) - var.layout = 0; - } - - if(specializable && values) - { - map::const_iterator i = values->find(var.name); - if(i!=values->end()) - { - RefPtr literal = new Literal; - if(var.type=="bool") - { - literal->token = (i->second ? "true" : "false"); - literal->value = static_cast(i->second); - } - else if(var.type=="int") - { - literal->token = lexical_cast(i->second); - literal->value = i->second; - } - var.init_expression = literal; - } } } diff --git a/source/glsl/generate.h b/source/glsl/generate.h index ef8ca10e..b2cfadc4 100644 --- a/source/glsl/generate.h +++ b/source/glsl/generate.h @@ -11,18 +11,11 @@ namespace Msp { namespace GL { namespace SL { -/** Manipulates specialization constants. If values are specified, turns -specialization constants into normal constants. Without values assigns -automatic constant_ids to specialization constants. */ -class ConstantSpecializer: private TraversingVisitor +/** Assigns IDs to specialization constants with an automatic ID. */ +class ConstantIdAssigner: private TraversingVisitor { -private: - const std::map *values; - public: - ConstantSpecializer(); - - void apply(Stage &, const std::map *); + void apply(Stage &); private: virtual void visit(VariableDeclaration &); diff --git a/source/glsl/optimize.cpp b/source/glsl/optimize.cpp index 7b3f8f28..596d7e20 100644 --- a/source/glsl/optimize.cpp +++ b/source/glsl/optimize.cpp @@ -8,6 +8,55 @@ namespace Msp { namespace GL { namespace SL { +ConstantSpecializer::ConstantSpecializer(): + values(0) +{ } + +void ConstantSpecializer::apply(Stage &stage, const map &v) +{ + values = &v; + stage.content.visit(*this); +} + +void ConstantSpecializer::visit(VariableDeclaration &var) +{ + bool specializable = false; + if(var.layout) + { + vector &qualifiers = var.layout->qualifiers; + for(vector::iterator i=qualifiers.begin(); (!specializable && i!=qualifiers.end()); ++i) + if(i->name=="constant_id") + { + specializable = true; + qualifiers.erase(i); + } + + if(qualifiers.empty()) + var.layout = 0; + } + + if(specializable) + { + map::const_iterator i = values->find(var.name); + if(i!=values->end()) + { + RefPtr literal = new Literal; + if(var.type=="bool") + { + literal->token = (i->second ? "true" : "false"); + literal->value = static_cast(i->second); + } + else if(var.type=="int") + { + literal->token = lexical_cast(i->second); + literal->value = i->second; + } + var.init_expression = literal; + } + } +} + + InlineableFunctionLocator::InlineableFunctionLocator(): current_function(0), return_count(0) diff --git a/source/glsl/optimize.h b/source/glsl/optimize.h index e7592c00..4c57eaea 100644 --- a/source/glsl/optimize.h +++ b/source/glsl/optimize.h @@ -9,6 +9,22 @@ namespace Msp { namespace GL { namespace SL { +/** Assigns values to specialization constants, turning them into normal +constants. */ +class ConstantSpecializer: private TraversingVisitor +{ +private: + const std::map *values; + +public: + ConstantSpecializer(); + + void apply(Stage &, const std::map &); + +private: + virtual void visit(VariableDeclaration &); +}; + /** Finds functions which are candidates for inlining. Currently this means functions which have no flow control statements, no more than one return statement, and are only called once. */