]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/spirv.cpp
Use default member initializers for simple types
[libs/gl.git] / source / glsl / spirv.cpp
index 72f73bd56bdf9c4ff1d3738342986b6fbf7a315f..233d15488dd043de95408e3642c075aba9d2d280 100644 (file)
@@ -1,3 +1,4 @@
+#include <msp/core/algorithm.h>
 #include <msp/core/maputils.h>
 #include <msp/core/raii.h>
 #include "reflect.h"
@@ -131,31 +132,18 @@ const SpirVGenerator::BuiltinFunctionInfo SpirVGenerator::builtin_functions[] =
 };
 
 SpirVGenerator::SpirVGenerator():
-       stage(0),
-       current_function(0),
-       writer(content),
-       next_id(1),
-       r_expression_result_id(0),
-       constant_expression(false),
-       spec_constant(false),
-       reachable(false),
-       composite_access(false),
-       r_composite_base_id(0),
-       r_composite_base(0),
-       assignment_source_id(0),
-       loop_merge_block_id(0),
-       loop_continue_target_id(0)
+       writer(content)
 { }
 
 void SpirVGenerator::apply(Module &module)
 {
        use_capability(CAP_SHADER);
 
-       for(list<Stage>::iterator i=module.stages.begin(); i!=module.stages.end(); ++i)
+       for(Stage &s: module.stages)
        {
-               stage = &*i;
+               stage = &s;
                interface_layouts.clear();
-               i->content.visit(*this);
+               s.content.visit(*this);
        }
 
        writer.finalize(SPIRV_GENERATOR_MSP, next_id);
@@ -239,7 +227,7 @@ SpirVGenerator::Id SpirVGenerator::get_id(Node &node) const
 
 SpirVGenerator::Id SpirVGenerator::allocate_id(Node &node, Id type_id)
 {
-       map<Node *, Declaration>::iterator i = declared_ids.find(&node);
+       auto i = declared_ids.find(&node);
        if(i!=declared_ids.end())
        {
                if(i->second.type_id)
@@ -255,7 +243,7 @@ SpirVGenerator::Id SpirVGenerator::allocate_id(Node &node, Id type_id)
 
 SpirVGenerator::Id SpirVGenerator::allocate_forward_id(Node &node)
 {
-       map<Node *, Declaration>::iterator i = declared_ids.find(&node);
+       auto i = declared_ids.find(&node);
        if(i!=declared_ids.end())
                return i->second.id;
 
@@ -345,7 +333,7 @@ SpirVGenerator::Id SpirVGenerator::get_standard_type_id(BasicTypeDeclaration::Ki
 
 bool SpirVGenerator::is_scalar_type(Id type_id, BasicTypeDeclaration::Kind kind) const
 {
-       map<TypeKey, Id>::const_iterator i = standard_type_ids.find(TypeKey(kind, true));
+       auto i = standard_type_ids.find(TypeKey(kind, true));
        return (i!=standard_type_ids.end() && i->second==type_id);
 }
 
@@ -413,7 +401,7 @@ SpirVGenerator::Id SpirVGenerator::get_load_id(VariableDeclaration &var)
 
 void SpirVGenerator::prune_loads(Id min_id)
 {
-       for(map<const VariableDeclaration *, Id>::iterator i=variable_load_ids.begin(); i!=variable_load_ids.end(); )
+       for(auto i=variable_load_ids.begin(); i!=variable_load_ids.end(); )
        {
                if(i->second>=min_id)
                        variable_load_ids.erase(i++);
@@ -499,8 +487,8 @@ SpirVGenerator::Id SpirVGenerator::write_construct(Id type_id, const Id *elem_id
 
 void SpirVGenerator::visit(Block &block)
 {
-       for(NodeList<Statement>::iterator i=block.body.begin(); i!=block.body.end(); ++i)
-               (*i)->visit(*this);
+       for(const RefPtr<Statement> &s: block.body)
+               s->visit(*this);
 }
 
 void SpirVGenerator::visit(Literal &literal)
@@ -564,13 +552,13 @@ void SpirVGenerator::generate_composite_access(TypeDeclaration &result_type)
                        throw internal_error("composite access through pointer in constant context");
 
                Id int32_type_id = get_standard_type_id(BasicTypeDeclaration::INT, 1);
-               for(vector<unsigned>::iterator i=r_composite_chain.begin(); i!=r_composite_chain.end(); ++i)
-                       *i = (*i<0x400000 ? get_constant_id(int32_type_id, static_cast<int>(*i)) : *i&0x3FFFFF);
+               for(unsigned &i: r_composite_chain)
+                       i = (i<0x400000 ? get_constant_id(int32_type_id, static_cast<int>(i)) : i&0x3FFFFF);
 
                /* Find the storage class of the base and obtain appropriate pointer type
                for the result. */
                const Declaration &base_decl = get_item(declared_ids, r_composite_base);
-               map<TypeKey, Id>::const_iterator i = pointer_type_ids.begin();
+               auto i = pointer_type_ids.begin();
                for(; (i!=pointer_type_ids.end() && i->second!=base_decl.type_id); ++i) ;
                if(i==pointer_type_ids.end())
                        throw internal_error("could not find storage class");
@@ -582,18 +570,18 @@ void SpirVGenerator::generate_composite_access(TypeDeclaration &result_type)
                throw internal_error("assignment to temporary composite");
        else
        {
-               for(vector<unsigned>::iterator i=r_composite_chain.begin(); i!=r_composite_chain.end(); ++i)
-                       for(map<ConstantKey, Id>::iterator j=constant_ids.begin(); (*i>=0x400000 && j!=constant_ids.end()); ++j)
-                               if(j->second==(*i&0x3FFFFF))
-                                       *i = j->first.int_value;
+               for(unsigned i: r_composite_chain)
+                       for(auto j=constant_ids.begin(); (i>=0x400000 && j!=constant_ids.end()); ++j)
+                               if(j->second==(i&0x3FFFFF))
+                                       i = j->first.int_value;
 
                opcode = OP_COMPOSITE_EXTRACT;
        }
 
        Id access_id = begin_expression(opcode, access_type_id, 1+r_composite_chain.size());
        writer.write(r_composite_base_id);
-       for(vector<unsigned>::const_iterator i=r_composite_chain.begin(); i!=r_composite_chain.end(); ++i)
-               writer.write(*i);
+       for(unsigned i: r_composite_chain)
+               writer.write(i);
        end_expression(opcode);
 
        r_constant_result = false;
@@ -1062,9 +1050,9 @@ void SpirVGenerator::visit(FunctionCall &call)
        vector<Id> argument_ids;
        argument_ids.reserve(call.arguments.size());
        bool all_args_const = true;
-       for(NodeArray<Expression>::const_iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i)
+       for(const RefPtr<Expression> &a: call.arguments)
        {
-               (*i)->visit(*this);
+               a->visit(*this);
                argument_ids.push_back(r_expression_result_id);
                all_args_const &= r_constant_result;
        }
@@ -1080,8 +1068,8 @@ void SpirVGenerator::visit(FunctionCall &call)
        else if(call.declaration->source==BUILTIN_SOURCE)
        {
                string arg_types;
-               for(NodeArray<Expression>::const_iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i)
-                       if(BasicTypeDeclaration *basic_arg = dynamic_cast<BasicTypeDeclaration *>((*i)->type))
+               for(const RefPtr<Expression> &a: call.arguments)
+                       if(BasicTypeDeclaration *basic_arg = dynamic_cast<BasicTypeDeclaration *>(a->type))
                        {
                                BasicTypeDeclaration &elem_arg = *get_element_type(*basic_arg);
                                switch(elem_arg.kind)
@@ -1137,14 +1125,14 @@ void SpirVGenerator::visit(FunctionCall &call)
        {
                r_expression_result_id = begin_expression(OP_FUNCTION_CALL, result_type_id, 1+call.arguments.size());
                writer.write(get_id(*call.declaration->definition));
-               for(vector<Id>::const_iterator i=argument_ids.begin(); i!=argument_ids.end(); ++i)
-                       writer.write(*i);
+               for(Id i: argument_ids)
+                       writer.write(i);
                end_expression(OP_FUNCTION_CALL);
 
                // Any global variables the called function uses might have changed value
                set<Node *> dependencies = DependencyCollector().apply(*call.declaration->definition);
-               for(set<Node *>::const_iterator i=dependencies.begin(); i!=dependencies.end(); ++i)
-                       if(const VariableDeclaration *var = dynamic_cast<const VariableDeclaration *>(*i))
+               for(Node *n: dependencies)
+                       if(const VariableDeclaration *var = dynamic_cast<const VariableDeclaration *>(n))
                                variable_load_ids.erase(var);
        }
 }
@@ -1405,7 +1393,7 @@ void SpirVGenerator::visit_builtin_interpolate(FunctionCall &call, const vector<
        writer.write(ext_id);
        writer.write(opcode);
        writer.write(get_id(*var->declaration));
-       for(vector<Id>::const_iterator i=argument_ids.begin(); ++i!=argument_ids.end(); )
+       for(auto i=argument_ids.begin(); ++i!=argument_ids.end(); )
                writer.write(*i);
        end_expression(OP_EXT_INST);
 }
@@ -1422,11 +1410,11 @@ void SpirVGenerator::visit(InterfaceLayout &layout)
 
 bool SpirVGenerator::check_duplicate_type(TypeDeclaration &type)
 {
-       for(map<Node *, Declaration>::const_iterator i=declared_ids.begin(); i!=declared_ids.end(); ++i)
-               if(TypeDeclaration *type2 = dynamic_cast<TypeDeclaration *>(i->first))
+       for(const auto &kvp: declared_ids)
+               if(TypeDeclaration *type2 = dynamic_cast<TypeDeclaration *>(kvp.first))
                        if(TypeComparer().apply(type, *type2))
                        {
-                               insert_unique(declared_ids, &type, i->second);
+                               insert_unique(declared_ids, &type, kvp.second);
                                return true;
                        }
 
@@ -1527,9 +1515,9 @@ void SpirVGenerator::visit(StructDeclaration &strct)
        bool builtin = (strct.interface_block && !strct.interface_block->block_name.compare(0, 3, "gl_"));
        vector<Id> member_type_ids;
        member_type_ids.reserve(strct.members.body.size());
-       for(NodeList<Statement>::const_iterator i=strct.members.body.begin(); i!=strct.members.body.end(); ++i)
+       for(const RefPtr<Statement> &s: strct.members.body)
        {
-               const VariableDeclaration *var = dynamic_cast<const VariableDeclaration *>(i->get());
+               const VariableDeclaration *var = dynamic_cast<const VariableDeclaration *>(s.get());
                if(!var)
                        continue;
 
@@ -1547,14 +1535,13 @@ void SpirVGenerator::visit(StructDeclaration &strct)
                {
                        if(var->layout)
                        {
-                               const vector<Layout::Qualifier> &qualifiers = var->layout->qualifiers;
-                               for(vector<Layout::Qualifier>::const_iterator j=qualifiers.begin(); j!=qualifiers.end(); ++j)
+                               for(const Layout::Qualifier &q: var->layout->qualifiers)
                                {
-                                       if(j->name=="offset")
-                                               writer.write_op_member_decorate(type_id, index, DECO_OFFSET, j->value);
-                                       else if(j->name=="column_major")
+                                       if(q.name=="offset")
+                                               writer.write_op_member_decorate(type_id, index, DECO_OFFSET, q.value);
+                                       else if(q.name=="column_major")
                                                writer.write_op_member_decorate(type_id, index, DECO_COL_MAJOR);
-                                       else if(j->name=="row_major")
+                                       else if(q.name=="row_major")
                                                writer.write_op_member_decorate(type_id, index, DECO_ROW_MAJOR);
                                }
                        }
@@ -1572,8 +1559,8 @@ void SpirVGenerator::visit(StructDeclaration &strct)
 
        writer.begin_op(content.globals, OP_TYPE_STRUCT);
        writer.write(type_id);
-       for(vector<Id>::const_iterator i=member_type_ids.begin(); i!=member_type_ids.end(); ++i)
-               writer.write(*i);
+       for(Id i: member_type_ids)
+               writer.write(i);
        writer.end_op(OP_TYPE_STRUCT);
 }
 
@@ -1584,9 +1571,9 @@ void SpirVGenerator::visit(VariableDeclaration &var)
        int spec_id = -1;
        if(layout_ql)
        {
-               for(vector<Layout::Qualifier>::const_iterator i=layout_ql->begin(); (spec_id<0 && i!=layout_ql->end()); ++i)
-                       if(i->name=="constant_id")
-                               spec_id = i->value;
+               auto i = find_member(*layout_ql, string("constant_id"), &Layout::Qualifier::name);
+               if(i!=layout_ql->end())
+                       spec_id = i->value;
        }
 
        Id type_id = get_variable_type_id(var);
@@ -1649,14 +1636,14 @@ void SpirVGenerator::visit(VariableDeclaration &var)
 
                if(layout_ql)
                {
-                       for(vector<Layout::Qualifier>::const_iterator i=layout_ql->begin(); i!=layout_ql->end(); ++i)
+                       for(const Layout::Qualifier &q: *layout_ql)
                        {
-                               if(i->name=="location")
-                                       writer.write_op_decorate(var_id, DECO_LOCATION, i->value);
-                               else if(i->name=="set")
-                                       writer.write_op_decorate(var_id, DECO_DESCRIPTOR_SET, i->value);
-                               else if(i->name=="binding")
-                                       writer.write_op_decorate(var_id, DECO_BINDING, i->value);
+                               if(q.name=="location")
+                                       writer.write_op_decorate(var_id, DECO_LOCATION, q.value);
+                               else if(q.name=="set")
+                                       writer.write_op_decorate(var_id, DECO_DESCRIPTOR_SET, q.value);
+                               else if(q.name=="binding")
+                                       writer.write_op_decorate(var_id, DECO_BINDING, q.value);
                        }
                }
 
@@ -1700,10 +1687,9 @@ void SpirVGenerator::visit(InterfaceBlock &iface)
 
        if(iface.layout)
        {
-               const vector<Layout::Qualifier> &qualifiers = iface.layout->qualifiers;
-               for(vector<Layout::Qualifier>::const_iterator i=qualifiers.begin(); i!=qualifiers.end(); ++i)
-                       if(i->name=="binding")
-                               writer.write_op_decorate(block_id, DECO_BINDING, i->value);
+               auto i = find_member(iface.layout->qualifiers, string("binding"), &Layout::Qualifier::name);
+               if(i!=iface.layout->qualifiers.end())
+                       writer.write_op_decorate(block_id, DECO_BINDING, i->value);
        }
 }
 
@@ -1721,15 +1707,15 @@ void SpirVGenerator::visit_entry_point(FunctionDeclaration &func, Id func_id)
        writer.write_string(func.name);
 
        set<Node *> dependencies = DependencyCollector().apply(func);
-       for(set<Node *>::const_iterator i=dependencies.begin(); i!=dependencies.end(); ++i)
+       for(Node *n: dependencies)
        {
-               if(const VariableDeclaration *var = dynamic_cast<const VariableDeclaration *>(*i))
+               if(const VariableDeclaration *var = dynamic_cast<const VariableDeclaration *>(n))
                {
                        if(!var->interface.empty())
-                               writer.write(get_id(**i));
+                               writer.write(get_id(*n));
                }
-               else if(dynamic_cast<InterfaceBlock *>(*i))
-                       writer.write(get_id(**i));
+               else if(dynamic_cast<InterfaceBlock *>(n))
+                       writer.write(get_id(*n));
        }
 
        writer.end_op(OP_ENTRY_POINT);
@@ -1739,28 +1725,27 @@ void SpirVGenerator::visit_entry_point(FunctionDeclaration &func, Id func_id)
        else if(stage->type==Stage::GEOMETRY)
                use_capability(CAP_GEOMETRY);
 
-       for(vector<const InterfaceLayout *>::const_iterator i=interface_layouts.begin(); i!=interface_layouts.end(); ++i)
+       for(const InterfaceLayout *i: interface_layouts)
        {
-               const vector<Layout::Qualifier> &qualifiers = (*i)->layout.qualifiers;
-               for(vector<Layout::Qualifier>::const_iterator j=qualifiers.begin(); j!=qualifiers.end(); ++j)
+               for(const Layout::Qualifier &q: i->layout.qualifiers)
                {
-                       if(j->name=="point")
+                       if(q.name=="point")
                                writer.write_op(content.exec_modes, OP_EXECUTION_MODE, func_id,
-                                       ((*i)->interface=="in" ? EXEC_INPUT_POINTS : EXEC_OUTPUT_POINTS));
-                       else if(j->name=="lines")
+                                       (i->interface=="in" ? EXEC_INPUT_POINTS : EXEC_OUTPUT_POINTS));
+                       else if(q.name=="lines")
                                writer.write_op(content.exec_modes, OP_EXECUTION_MODE, func_id, EXEC_INPUT_LINES);
-                       else if(j->name=="lines_adjacency")
+                       else if(q.name=="lines_adjacency")
                                writer.write_op(content.exec_modes, OP_EXECUTION_MODE, func_id, EXEC_INPUT_LINES_ADJACENCY);
-                       else if(j->name=="triangles")
+                       else if(q.name=="triangles")
                                writer.write_op(content.exec_modes, OP_EXECUTION_MODE, func_id, EXEC_TRIANGLES);
-                       else if(j->name=="triangles_adjacency")
+                       else if(q.name=="triangles_adjacency")
                                writer.write_op(content.exec_modes, OP_EXECUTION_MODE, func_id, EXEC_INPUT_TRIANGLES_ADJACENCY);
-                       else if(j->name=="line_strip")
+                       else if(q.name=="line_strip")
                                writer.write_op(content.exec_modes, OP_EXECUTION_MODE, func_id, EXEC_OUTPUT_LINE_STRIP);
-                       else if(j->name=="triangle_strip")
+                       else if(q.name=="triangle_strip")
                                writer.write_op(content.exec_modes, OP_EXECUTION_MODE, func_id, EXEC_OUTPUT_TRIANGLE_STRIP);
-                       else if(j->name=="max_vertices")
-                               writer.write_op(content.exec_modes, OP_EXECUTION_MODE, func_id, EXEC_OUTPUT_VERTICES, j->value);
+                       else if(q.name=="max_vertices")
+                               writer.write_op(content.exec_modes, OP_EXECUTION_MODE, func_id, EXEC_OUTPUT_VERTICES, q.value);
                }
        }
 }
@@ -1779,8 +1764,8 @@ void SpirVGenerator::visit(FunctionDeclaration &func)
        Id return_type_id = get_id(*func.return_type_declaration);
        vector<unsigned> param_type_ids;
        param_type_ids.reserve(func.parameters.size());
-       for(NodeArray<VariableDeclaration>::const_iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i)
-               param_type_ids.push_back(get_variable_type_id(**i));
+       for(const RefPtr<VariableDeclaration> &p: func.parameters)
+               param_type_ids.push_back(get_variable_type_id(*p));
 
        string sig_with_return = func.return_type+func.signature;
        Id &type_id = function_type_ids[sig_with_return];
@@ -1790,8 +1775,8 @@ void SpirVGenerator::visit(FunctionDeclaration &func)
                writer.begin_op(content.globals, OP_TYPE_FUNCTION);
                writer.write(type_id);
                writer.write(return_type_id);
-               for(vector<unsigned>::const_iterator i=param_type_ids.begin(); i!=param_type_ids.end(); ++i)
-                       writer.write(*i);
+               for(unsigned i: param_type_ids)
+                       writer.write(i);
                writer.end_op(OP_TYPE_FUNCTION);
 
                writer.write_op_name(type_id, sig_with_return);