X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Fspirv.cpp;h=4828a00c452ad1e35e54156f97dfaf2ef4a4ffd8;hb=03b2ea5c9c611cfa5f02afb49ed7e05743e691b4;hp=13c58a695ab3668d9c0a605ce679f1d00565a997;hpb=e98188ff6c9bba9761b71f2a69f3be7eb89ba3da;p=libs%2Fgl.git diff --git a/source/glsl/spirv.cpp b/source/glsl/spirv.cpp index 13c58a69..4828a00c 100644 --- a/source/glsl/spirv.cpp +++ b/source/glsl/spirv.cpp @@ -135,8 +135,9 @@ SpirVGenerator::SpirVGenerator(): writer(content) { } -void SpirVGenerator::apply(Module &module) +void SpirVGenerator::apply(Module &module, const Features &f) { + features = f; use_capability(CAP_SHADER); for(Stage &s: module.stages) @@ -337,10 +338,10 @@ bool SpirVGenerator::is_scalar_type(Id type_id, BasicTypeDeclaration::Kind kind) return (i!=standard_type_ids.end() && i->second==type_id); } -SpirVGenerator::Id SpirVGenerator::get_array_type_id(TypeDeclaration &base_type, Id size_id) +SpirVGenerator::Id SpirVGenerator::get_array_type_id(TypeDeclaration &base_type, Id size_id, bool extended_align) { Id base_type_id = get_id(base_type); - Id &array_type_id = array_type_ids[TypeKey(base_type_id, size_id)]; + Id &array_type_id = array_type_ids[TypeKey(base_type_id, extended_align*0x400000 | size_id)]; if(!array_type_id) { array_type_id = next_id++; @@ -350,6 +351,8 @@ SpirVGenerator::Id SpirVGenerator::get_array_type_id(TypeDeclaration &base_type, writer.write_op(content.globals, OP_TYPE_RUNTIME_ARRAY, array_type_id, base_type_id); unsigned stride = MemoryRequirementsCalculator().apply(base_type).stride; + if(extended_align) + stride = (stride+15)&~15U; writer.write_op_decorate(array_type_id, DECO_ARRAY_STRIDE, stride); } @@ -382,7 +385,7 @@ SpirVGenerator::Id SpirVGenerator::get_variable_type_id(const VariableDeclaratio } else size_id = get_constant_id(get_standard_type_id(BasicTypeDeclaration::INT, 1), 1); - return get_array_type_id(*basic->base_type, size_id); + return get_array_type_id(*basic->base_type, size_id, basic->extended_alignment); } return get_id(*var.type_declaration); @@ -538,16 +541,6 @@ void SpirVGenerator::visit(VariableReference &var) r_expression_result_id = get_load_id(*var.declaration); } -void SpirVGenerator::visit(InterfaceBlockReference &iface) -{ - if(!composite_access || !current_function) - throw internal_error("invalid interface block reference"); - - r_composite_base = iface.declaration; - r_expression_result_id = 0; - r_constant_result = false; -} - void SpirVGenerator::generate_composite_access(TypeDeclaration &result_type) { Opcode opcode; @@ -1525,10 +1518,10 @@ void SpirVGenerator::visit(StructDeclaration &strct) Id type_id = allocate_id(strct, 0); writer.write_op_name(type_id, strct.name); - if(strct.interface_block) + if(!strct.block_name.empty()) writer.write_op_decorate(type_id, DECO_BLOCK); - bool builtin = (strct.interface_block && !strct.interface_block->block_name.compare(0, 3, "gl_")); + bool builtin = !strct.block_name.compare(0, 3, "gl_"); vector member_type_ids; member_type_ids.reserve(strct.members.body.size()); for(const RefPtr &s: strct.members.body) @@ -1612,11 +1605,20 @@ void SpirVGenerator::visit(VariableDeclaration &var) } else { - StorageClass storage = (current_function ? STORAGE_FUNCTION : get_interface_storage(var.interface, false)); + bool push_const = has_layout_qualifier(var.layout.get(), "push_constant"); + + StorageClass storage; + if(current_function) + storage = STORAGE_FUNCTION; + else if(push_const) + storage = STORAGE_PUSH_CONSTANT; + else + storage = get_interface_storage(var.interface, var.block_declaration); + Id ptr_type_id = get_pointer_type_id(type_id, storage); if(var.interface=="uniform") { - Id &uni_id = declared_uniform_ids["v"+var.name]; + Id &uni_id = declared_uniform_ids[var.block_declaration ? "b"+var.block_declaration->block_name : "v"+var.name]; if(uni_id) { insert_unique(declared_ids, &var, Declaration(uni_id, ptr_type_id)); @@ -1659,7 +1661,7 @@ void SpirVGenerator::visit(VariableDeclaration &var) writer.write_op_decorate(var_id, DECO_BINDING, q.value); } } - if(!var.name.compare(0, 3, "gl_")) + if(!var.block_declaration && !var.name.compare(0, 3, "gl_")) { BuiltinSemantic semantic = get_builtin_semantic(var.name); writer.write_op_decorate(var_id, DECO_BUILTIN, semantic); @@ -1675,48 +1677,6 @@ void SpirVGenerator::visit(VariableDeclaration &var) writer.write_op_name(var_id, var.name); } -void SpirVGenerator::visit(InterfaceBlock &iface) -{ - bool push_const = has_layout_qualifier(iface.layout.get(), "push_constant"); - - StorageClass storage = (push_const ? STORAGE_PUSH_CONSTANT : get_interface_storage(iface.interface, true)); - Id type_id; - if(iface.array) - type_id = get_array_type_id(*iface.struct_declaration, 0); - else - type_id = get_id(*iface.struct_declaration); - Id ptr_type_id = get_pointer_type_id(type_id, storage); - - Id block_id; - if(iface.interface=="uniform") - { - Id &uni_id = declared_uniform_ids["b"+iface.block_name]; - if(uni_id) - { - insert_unique(declared_ids, &iface, Declaration(uni_id, ptr_type_id)); - return; - } - - uni_id = block_id = allocate_id(iface, ptr_type_id); - } - else - block_id = allocate_id(iface, ptr_type_id); - writer.write_op_name(block_id, iface.instance_name); - - writer.write_op(content.globals, OP_VARIABLE, ptr_type_id, block_id, storage); - - if(iface.layout) - { - for(const Layout::Qualifier &q: iface.layout->qualifiers) - { - if(q.name=="set") - writer.write_op_decorate(block_id, DECO_DESCRIPTOR_SET, q.value); - else if(q.name=="binding") - writer.write_op_decorate(block_id, DECO_BINDING, q.value); - } - } -} - void SpirVGenerator::visit_entry_point(FunctionDeclaration &func, Id func_id) { writer.begin_op(content.entry_points, OP_ENTRY_POINT); @@ -1732,20 +1692,17 @@ void SpirVGenerator::visit_entry_point(FunctionDeclaration &func, Id func_id) set dependencies = DependencyCollector().apply(func); for(Node *n: dependencies) - { if(const VariableDeclaration *var = dynamic_cast(n)) - { if(!var->interface.empty()) writer.write(get_id(*n)); - } - else if(dynamic_cast(n)) - writer.write(get_id(*n)); - } writer.end_op(OP_ENTRY_POINT); if(stage->type==Stage::FRAGMENT) - writer.write_op(content.exec_modes, OP_EXECUTION_MODE, func_id, EXEC_ORIGIN_LOWER_LEFT); + { + SpirVExecutionMode origin = (features.target_api==VULKAN ? EXEC_ORIGIN_UPPER_LEFT : EXEC_ORIGIN_LOWER_LEFT); + writer.write_op(content.exec_modes, OP_EXECUTION_MODE, func_id, origin); + } else if(stage->type==Stage::GEOMETRY) use_capability(CAP_GEOMETRY);