X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fglsl%2Fspirv.cpp;h=233d15488dd043de95408e3642c075aba9d2d280;hp=63c76f9a2233050851e9491af42855ee9f0e8a8c;hb=38712d8ecc57d043a2419ffbaeeb57f7a6586f14;hpb=e0caeb9be47bc140978552bb7149f1c9c8c973db diff --git a/source/glsl/spirv.cpp b/source/glsl/spirv.cpp index 63c76f9a..233d1548 100644 --- a/source/glsl/spirv.cpp +++ b/source/glsl/spirv.cpp @@ -1,3 +1,4 @@ +#include #include #include #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::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::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::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::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::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::iterator i=block.body.begin(); i!=block.body.end(); ++i) - (*i)->visit(*this); + for(const RefPtr &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::iterator i=r_composite_chain.begin(); i!=r_composite_chain.end(); ++i) - *i = (*i<0x400000 ? get_constant_id(int32_type_id, static_cast(*i)) : *i&0x3FFFFF); + for(unsigned &i: r_composite_chain) + i = (i<0x400000 ? get_constant_id(int32_type_id, static_cast(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::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::iterator i=r_composite_chain.begin(); i!=r_composite_chain.end(); ++i) - for(map::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::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 argument_ids; argument_ids.reserve(call.arguments.size()); bool all_args_const = true; - for(NodeArray::const_iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i) + for(const RefPtr &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::const_iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i) - if(BasicTypeDeclaration *basic_arg = dynamic_cast((*i)->type)) + for(const RefPtr &a: call.arguments) + if(BasicTypeDeclaration *basic_arg = dynamic_cast(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::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 dependencies = DependencyCollector().apply(*call.declaration->definition); - for(set::const_iterator i=dependencies.begin(); i!=dependencies.end(); ++i) - if(const VariableDeclaration *var = dynamic_cast(*i)) + for(Node *n: dependencies) + if(const VariableDeclaration *var = dynamic_cast(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::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::const_iterator i=declared_ids.begin(); i!=declared_ids.end(); ++i) - if(TypeDeclaration *type2 = dynamic_cast(i->first)) + for(const auto &kvp: declared_ids) + if(TypeDeclaration *type2 = dynamic_cast(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 member_type_ids; member_type_ids.reserve(strct.members.body.size()); - for(NodeList::const_iterator i=strct.members.body.begin(); i!=strct.members.body.end(); ++i) + for(const RefPtr &s: strct.members.body) { - const VariableDeclaration *var = dynamic_cast(i->get()); + const VariableDeclaration *var = dynamic_cast(s.get()); if(!var) continue; @@ -1547,14 +1535,13 @@ void SpirVGenerator::visit(StructDeclaration &strct) { if(var->layout) { - const vector &qualifiers = var->layout->qualifiers; - for(vector::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::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::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::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 &qualifiers = iface.layout->qualifiers; - for(vector::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 dependencies = DependencyCollector().apply(func); - for(set::const_iterator i=dependencies.begin(); i!=dependencies.end(); ++i) + for(Node *n: dependencies) { - if(const VariableDeclaration *var = dynamic_cast(*i)) + if(const VariableDeclaration *var = dynamic_cast(n)) { if(!var->interface.empty()) - writer.write(get_id(**i)); + writer.write(get_id(*n)); } - else if(dynamic_cast(*i)) - writer.write(get_id(**i)); + else if(dynamic_cast(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_iterator i=interface_layouts.begin(); i!=interface_layouts.end(); ++i) + for(const InterfaceLayout *i: interface_layouts) { - const vector &qualifiers = (*i)->layout.qualifiers; - for(vector::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 param_type_ids; param_type_ids.reserve(func.parameters.size()); - for(NodeArray::const_iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i) - param_type_ids.push_back(get_variable_type_id(**i)); + for(const RefPtr &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::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); @@ -1902,6 +1887,7 @@ void SpirVGenerator::visit(Iteration &iter) writer.write_op(content.function_body, OP_BRANCH, header_id); writer.write_op_label(merge_block_id); + prune_loads(header_id); reachable = true; }