]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/generate.cpp
Use default member initializers for simple types
[libs/gl.git] / source / glsl / generate.cpp
index 13fb72c53039bfbd7e9fed3779bc718bdc6801d7..ec51c19cdd9cc90472a0b2471eff915823fae0d7 100644 (file)
@@ -1,3 +1,4 @@
+#include <msp/core/algorithm.h>
 #include <msp/core/hash.h>
 #include <msp/core/raii.h>
 #include "generate.h"
@@ -8,66 +9,41 @@ namespace Msp {
 namespace GL {
 namespace SL {
 
-ConstantSpecializer::ConstantSpecializer():
-       values(0)
-{ }
-
-void ConstantSpecializer::apply(Stage &stage, const map<string, int> *v)
+void ConstantIdAssigner::apply(Module &module, const Features &features)
 {
-       values = v;
-       stage.content.visit(*this);
-}
+       for(Stage &s: module.stages)
+               s.content.visit(*this);
 
-void ConstantSpecializer::visit(VariableDeclaration &var)
-{
-       bool specializable = false;
-       if(var.layout)
+       for(VariableDeclaration *v: auto_constants)
        {
-               vector<Layout::Qualifier> &qualifiers = var.layout->qualifiers;
-               for(vector<Layout::Qualifier>::iterator i=qualifiers.begin(); i!=qualifiers.end(); ++i)
-                       if(i->name=="constant_id")
-                       {
-                               specializable = true;
-                               if(values)
-                                       qualifiers.erase(i);
-                               else if(i->value==-1)
-                                       i->value = hash32(var.name)&0x7FFFFFFF;
-                               break;
-                       }
+               unsigned id = hash32(v->name)%features.constant_id_range;
+               while(used_ids.count(id))
+                       id = (id+1)%features.constant_id_range;
 
-               if(qualifiers.empty())
-                       var.layout = 0;
+               auto i = find_member(v->layout->qualifiers, string("constant_id"), &Layout::Qualifier::name);
+               if(i!=v->layout->qualifiers.end())
+                       i->value = id;
+
+               used_ids.insert(id);
        }
+}
 
-       if(specializable && values)
+void ConstantIdAssigner::visit(VariableDeclaration &var)
+{
+       if(var.layout)
        {
-               map<string, int>::const_iterator i = values->find(var.name);
-               if(i!=values->end())
+               auto i = find_member(var.layout->qualifiers, string("constant_id"), &Layout::Qualifier::name);
+               if(i!=var.layout->qualifiers.end() && i->has_value)
                {
-                       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;
+                       if(i->value==-1)
+                               auto_constants.push_back(&var);
+                       else
+                               used_ids.insert(i->value);
                }
        }
 }
 
 
-InterfaceGenerator::InterfaceGenerator():
-       stage(0),
-       function_scope(false),
-       copy_block(false),
-       iface_target_block(0)
-{ }
-
 string InterfaceGenerator::get_out_prefix(Stage::Type type)
 {
        if(type==Stage::VERTEX)
@@ -92,7 +68,7 @@ void InterfaceGenerator::apply(Stage &s)
 void InterfaceGenerator::visit(Block &block)
 {
        SetForScope<Block *> set_block(current_block, &block);
-       for(NodeList<Statement>::iterator i=block.body.begin(); i!=block.body.end(); ++i)
+       for(auto i=block.body.begin(); i!=block.body.end(); ++i)
        {
                assignment_insert_point = i;
                if(&block==&stage->content)
@@ -146,7 +122,7 @@ VariableDeclaration *InterfaceGenerator::generate_interface(VariableDeclaration
 
 InterfaceBlock *InterfaceGenerator::generate_interface(InterfaceBlock &out_block)
 {
-       if(stage->interface_blocks.count("in"+out_block.block_name))
+       if(stage->interface_blocks.count("in "+out_block.block_name))
                return 0;
 
        InterfaceBlock *in_block = new InterfaceBlock;
@@ -172,9 +148,9 @@ InterfaceBlock *InterfaceGenerator::generate_interface(InterfaceBlock &out_block
        }
 
        iface_target_block->body.insert(iface_insert_point, in_block);
-       stage->interface_blocks.insert(make_pair("in"+in_block->block_name, in_block));
+       stage->interface_blocks.insert(make_pair("in "+in_block->block_name, in_block));
        if(!in_block->instance_name.empty())
-               stage->interface_blocks.insert(make_pair("_"+in_block->instance_name, in_block));
+               stage->interface_blocks.insert(make_pair(in_block->instance_name, in_block));
 
        SetFlag set_scope(function_scope, false);
        SetForScope<Block *> set_block(current_block, &stage->content);
@@ -210,7 +186,7 @@ void InterfaceGenerator::visit(VariableReference &var)
                return;
 
        const map<string, VariableDeclaration *> &prev_vars = stage->previous->content.variables;
-       map<string, VariableDeclaration *>::const_iterator i = prev_vars.find(var.name);
+       auto i = prev_vars.find(var.name);
        if(i==prev_vars.end() || i->second->interface!="out")
                i = prev_vars.find(in_prefix+var.name);
        if(i!=prev_vars.end() && i->second->interface=="out")
@@ -227,7 +203,7 @@ void InterfaceGenerator::visit(VariableReference &var)
        }
 
        const map<string, InterfaceBlock *> &prev_blocks = stage->previous->interface_blocks;
-       map<string, InterfaceBlock *>::const_iterator j = prev_blocks.find("_"+var.name);
+       auto j = prev_blocks.find(var.name);
        if(j!=prev_blocks.end() && j->second->interface=="out")
        {
                generate_interface(*j->second);
@@ -236,14 +212,14 @@ void InterfaceGenerator::visit(VariableReference &var)
                return;
        }
 
-       for(j=prev_blocks.begin(); j!=prev_blocks.end(); ++j)
-               if(j->second->instance_name.empty() && j->second->struct_declaration)
+       for(const auto &kvp: prev_blocks)
+               if(kvp.second->instance_name.empty() && kvp.second->struct_declaration)
                {
-                       const map<string, VariableDeclaration *> &iface_vars = j->second->struct_declaration->members.variables;
+                       const map<string, VariableDeclaration *> &iface_vars = kvp.second->struct_declaration->members.variables;
                        i = iface_vars.find(var.name);
                        if(i!=iface_vars.end())
                        {
-                               generate_interface(*j->second);
+                               generate_interface(*kvp.second);
                                return;
                        }
                }
@@ -282,7 +258,7 @@ void InterfaceGenerator::visit(VariableDeclaration &var)
                if(!var.linked_declaration && stage->previous)
                {
                        const map<string, VariableDeclaration *> &prev_vars = stage->previous->content.variables;
-                       map<string, VariableDeclaration *>::const_iterator i = prev_vars.find(var.name);
+                       auto i = prev_vars.find(var.name);
                        if(i!=prev_vars.end() && i->second->interface=="out")
                        {
                                var.linked_declaration = i->second;
@@ -303,7 +279,7 @@ void InterfaceGenerator::visit(InterfaceBlock &iface)
                if(!iface.linked_block && stage->previous)
                {
                        const map<string, InterfaceBlock *> &prev_blocks = stage->previous->interface_blocks;
-                       map<string, InterfaceBlock *>::const_iterator i = prev_blocks.find("out"+iface.block_name);
+                       auto i = prev_blocks.find("out "+iface.block_name);
                        if(i!=prev_blocks.end())
                        {
                                iface.linked_block = i->second;
@@ -329,16 +305,15 @@ void InterfaceGenerator::visit(Passthrough &pass)
 
        if(stage->previous)
        {
-               const map<string, VariableDeclaration *> &prev_vars = stage->previous->content.variables;
-               for(map<string, VariableDeclaration *>::const_iterator i=prev_vars.begin(); i!=prev_vars.end(); ++i)
+               for(const auto &kvp: stage->previous->content.variables)
                {
-                       if(i->second->interface!="out")
+                       if(kvp.second->interface!="out")
                                continue;
 
                        /* Pass through output variables from the previous stage, but only
                        those which are not already linked to an input here. */
-                       if(!i->second->linked_declaration && generate_interface(*i->second, "in", i->second->name))
-                               pass_vars.push_back(i->second);
+                       if(!kvp.second->linked_declaration && generate_interface(*kvp.second, "in", kvp.second->name))
+                               pass_vars.push_back(kvp.second);
                }
        }
 
@@ -361,13 +336,13 @@ void InterfaceGenerator::visit(Passthrough &pass)
                insert_assignment("gl_Position", memacc);
        }
 
-       for(vector<VariableDeclaration *>::const_iterator i=pass_vars.begin(); i!=pass_vars.end(); ++i)
+       for(VariableDeclaration *v: pass_vars)
        {
-               string out_name = change_prefix((*i)->name, out_prefix);
-               generate_interface(**i, "out", out_name);
+               string out_name = change_prefix(v->name, out_prefix);
+               generate_interface(*v, "out", out_name);
 
                VariableReference *ref = new VariableReference;
-               ref->name = (*i)->name;
+               ref->name = v->name;
                if(pass.subscript)
                {
                        BinaryExpression *subscript = new BinaryExpression;