]> git.tdb.fi Git - libs/gl.git/commitdiff
Split up ComponentSpecializer
authorMikko Rasa <tdb@tdb.fi>
Thu, 1 Apr 2021 21:13:58 +0000 (00:13 +0300)
committerMikko Rasa <tdb@tdb.fi>
Thu, 1 Apr 2021 21:13:58 +0000 (00:13 +0300)
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.

source/glsl/compiler.cpp
source/glsl/compiler.h
source/glsl/generate.cpp
source/glsl/generate.h
source/glsl/optimize.cpp
source/glsl/optimize.h

index b810e52bef5e0af758379f4c12a086a13d22a8e5..fab054737a8872bc7e8631b2298615c0fc9b6cf0 100644 (file)
@@ -79,7 +79,7 @@ void Compiler::specialize(const map<string, int> &sv)
 void Compiler::compile(Mode mode)
 {
        for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
-               generate(*i, mode);
+               generate(*i);
 
        bool valid = true;
        for(list<Stage>::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<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++n)
+       if(mode==PROGRAM && specialized)
+       {
+               for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
+                       ConstantSpecializer().apply(*i, spec_values);
+       }
+       for(list<Stage>::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<typename T>
index 0ae2ed4114924946f2fbc04ae33a34b7d84b4676..674081a07e815beb1e2ac886fb8f32f75552d51b 100644 (file)
@@ -122,7 +122,7 @@ private:
 
        /** Generates any implicitly defines syntactic structures and resolves
        variables. */
-       void generate(Stage &, Mode);
+       void generate(Stage &);
 
        template<typename T>
        bool resolve(Stage &, unsigned &, unsigned);
index 13fb72c53039bfbd7e9fed3779bc718bdc6801d7..f345670b0451d462f0b1083eb047b605e4a006bb 100644 (file)
@@ -8,55 +8,23 @@ namespace Msp {
 namespace GL {
 namespace SL {
 
-ConstantSpecializer::ConstantSpecializer():
-       values(0)
-{ }
-
-void ConstantSpecializer::apply(Stage &stage, const map<string, int> *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<Layout::Qualifier> &qualifiers = var.layout->qualifiers;
                for(vector<Layout::Qualifier>::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<string, int>::const_iterator i = values->find(var.name);
-               if(i!=values->end())
-               {
-                       RefPtr<Literal> literal = new Literal;
-                       if(var.type=="bool")
-                       {
-                               literal->token = (i->second ? "true" : "false");
-                               literal->value = static_cast<bool>(i->second);
-                       }
-                       else if(var.type=="int")
-                       {
-                               literal->token = lexical_cast<string>(i->second);
-                               literal->value = i->second;
-                       }
-                       var.init_expression = literal;
-               }
        }
 }
 
index ef8ca10e35b198b5da4a38abc09708b08455f267..b2cfadc428f6184e7e44b74c310e300e7cc122c4 100644 (file)
@@ -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<std::string, int> *values;
-
 public:
-       ConstantSpecializer();
-
-       void apply(Stage &, const std::map<std::string, int> *);
+       void apply(Stage &);
 
 private:
        virtual void visit(VariableDeclaration &);
index 7b3f8f28c8ad00007b520446ed5c2cc1180c49d0..596d7e20b071365850cb8d3e894b6eb0db910c1b 100644 (file)
@@ -8,6 +8,55 @@ namespace Msp {
 namespace GL {
 namespace SL {
 
+ConstantSpecializer::ConstantSpecializer():
+       values(0)
+{ }
+
+void ConstantSpecializer::apply(Stage &stage, const map<string, int> &v)
+{
+       values = &v;
+       stage.content.visit(*this);
+}
+
+void ConstantSpecializer::visit(VariableDeclaration &var)
+{
+       bool specializable = false;
+       if(var.layout)
+       {
+               vector<Layout::Qualifier> &qualifiers = var.layout->qualifiers;
+               for(vector<Layout::Qualifier>::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<string, int>::const_iterator i = values->find(var.name);
+               if(i!=values->end())
+               {
+                       RefPtr<Literal> literal = new Literal;
+                       if(var.type=="bool")
+                       {
+                               literal->token = (i->second ? "true" : "false");
+                               literal->value = static_cast<bool>(i->second);
+                       }
+                       else if(var.type=="int")
+                       {
+                               literal->token = lexical_cast<string>(i->second);
+                               literal->value = i->second;
+                       }
+                       var.init_expression = literal;
+               }
+       }
+}
+
+
 InlineableFunctionLocator::InlineableFunctionLocator():
        current_function(0),
        return_count(0)
index e7592c00a29956e7ad4ab09384cf9798b3d1aacf..4c57eaea94844192b29d3a12c9862d754af6dc2c 100644 (file)
@@ -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<std::string, int> *values;
+
+public:
+       ConstantSpecializer();
+
+       void apply(Stage &, const std::map<std::string, int> &);
+
+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. */