diff options
Diffstat (limited to 'src/3rdparty/SPIRV-Cross/spirv_hlsl.cpp')
-rw-r--r-- | src/3rdparty/SPIRV-Cross/spirv_hlsl.cpp | 82 |
1 files changed, 63 insertions, 19 deletions
diff --git a/src/3rdparty/SPIRV-Cross/spirv_hlsl.cpp b/src/3rdparty/SPIRV-Cross/spirv_hlsl.cpp index 4d4e276..ae7a4d5 100644 --- a/src/3rdparty/SPIRV-Cross/spirv_hlsl.cpp +++ b/src/3rdparty/SPIRV-Cross/spirv_hlsl.cpp @@ -1867,11 +1867,6 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var) { if (type.array.empty()) { - if (buffer_is_packing_standard(type, BufferPackingHLSLCbufferPackOffset)) - set_extended_decoration(type.self, SPIRVCrossDecorationExplicitOffset); - else - SPIRV_CROSS_THROW("cbuffer cannot be expressed with either HLSL packing layout or packoffset."); - // Flatten the top-level struct so we can use packoffset, // this restriction is similar to GLSL where layout(offset) is not possible on sub-structs. flattened_structs.insert(var.self); @@ -1892,6 +1887,16 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var) if (buffer_name.empty()) buffer_name = join("_", get<SPIRType>(var.basetype).self, "_", var.self); + uint32_t failed_index = 0; + if (buffer_is_packing_standard(type, BufferPackingHLSLCbufferPackOffset, &failed_index)) + set_extended_decoration(type.self, SPIRVCrossDecorationExplicitOffset); + else + { + SPIRV_CROSS_THROW(join("cbuffer ID ", var.self, " (name: ", buffer_name, "), member index ", + failed_index, " (name: ", to_member_name(type, failed_index), + ") cannot be expressed with either HLSL packing layout or packoffset.")); + } + block_names.insert(buffer_name); // Save for post-reflection later. @@ -1927,13 +1932,18 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var) SPIRV_CROSS_THROW( "Need ConstantBuffer<T> to use arrays of UBOs, but this is only supported in SM 5.1."); - // ConstantBuffer<T> does not support packoffset, so it is unuseable unless everything aligns as we expect. - if (!buffer_is_packing_standard(type, BufferPackingHLSLCbuffer)) - SPIRV_CROSS_THROW("HLSL ConstantBuffer<T> cannot be expressed with normal HLSL packing rules."); - add_resource_name(type.self); add_resource_name(var.self); + // ConstantBuffer<T> does not support packoffset, so it is unuseable unless everything aligns as we expect. + uint32_t failed_index = 0; + if (!buffer_is_packing_standard(type, BufferPackingHLSLCbuffer, &failed_index)) + { + SPIRV_CROSS_THROW(join("HLSL ConstantBuffer<T> ID ", var.self, " (name: ", to_name(type.self), + "), member index ", failed_index, " (name: ", to_member_name(type, failed_index), + ") cannot be expressed with normal HLSL packing rules.")); + } + emit_struct(get<SPIRType>(type.self)); statement("ConstantBuffer<", to_name(type.self), "> ", to_name(var.self), type_to_array_glsl(type), to_resource_binding(var), ";"); @@ -1953,11 +1963,16 @@ void CompilerHLSL::emit_push_constant_block(const SPIRVariable &var) { auto &type = get<SPIRType>(var.basetype); - if (buffer_is_packing_standard(type, BufferPackingHLSLCbufferPackOffset, layout.start, layout.end)) + uint32_t failed_index = 0; + if (buffer_is_packing_standard(type, BufferPackingHLSLCbufferPackOffset, &failed_index, layout.start, + layout.end)) set_extended_decoration(type.self, SPIRVCrossDecorationExplicitOffset); else - SPIRV_CROSS_THROW( - "root constant cbuffer cannot be expressed with either HLSL packing layout or packoffset."); + { + SPIRV_CROSS_THROW(join("Root constant cbuffer ID ", var.self, " (name: ", to_name(type.self), ")", + ", member index ", failed_index, " (name: ", to_member_name(type, failed_index), + ") cannot be expressed with either HLSL packing layout or packoffset.")); + } flattened_structs.insert(var.self); type.member_name_cache.clear(); @@ -1965,7 +1980,7 @@ void CompilerHLSL::emit_push_constant_block(const SPIRVariable &var) auto &memb = ir.meta[type.self].members; statement("cbuffer SPIRV_CROSS_RootConstant_", to_name(var.self), - to_resource_register('b', layout.binding, layout.space)); + to_resource_register(HLSL_BINDING_AUTO_PUSH_CONSTANT_BIT, 'b', layout.binding, layout.space)); begin_scope(); // Index of the next field in the generated root constant constant buffer @@ -2928,21 +2943,31 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var) const auto &type = get<SPIRType>(var.basetype); char space = '\0'; + HLSLBindingFlags resource_flags = 0; + switch (type.basetype) { case SPIRType::SampledImage: space = 't'; // SRV + resource_flags = HLSL_BINDING_AUTO_SRV_BIT; break; case SPIRType::Image: if (type.image.sampled == 2 && type.image.dim != DimSubpassData) + { space = 'u'; // UAV + resource_flags = HLSL_BINDING_AUTO_UAV_BIT; + } else + { space = 't'; // SRV + resource_flags = HLSL_BINDING_AUTO_SRV_BIT; + } break; case SPIRType::Sampler: space = 's'; + resource_flags = HLSL_BINDING_AUTO_SAMPLER_BIT; break; case SPIRType::Struct: @@ -2955,18 +2980,26 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var) Bitset flags = ir.get_buffer_block_flags(var); bool is_readonly = flags.get(DecorationNonWritable); space = is_readonly ? 't' : 'u'; // UAV + resource_flags = is_readonly ? HLSL_BINDING_AUTO_SRV_BIT : HLSL_BINDING_AUTO_UAV_BIT; } else if (has_decoration(type.self, DecorationBlock)) + { space = 'b'; // Constant buffers + resource_flags = HLSL_BINDING_AUTO_CBV_BIT; + } } else if (storage == StorageClassPushConstant) + { space = 'b'; // Constant buffers + resource_flags = HLSL_BINDING_AUTO_PUSH_CONSTANT_BIT; + } else if (storage == StorageClassStorageBuffer) { // UAV or SRV depending on readonly flag. Bitset flags = ir.get_buffer_block_flags(var); bool is_readonly = flags.get(DecorationNonWritable); space = is_readonly ? 't' : 'u'; + resource_flags = is_readonly ? HLSL_BINDING_AUTO_SRV_BIT : HLSL_BINDING_AUTO_UAV_BIT; } break; @@ -2978,7 +3011,7 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var) if (!space) return ""; - return to_resource_register(space, get_decoration(var.self, DecorationBinding), + return to_resource_register(resource_flags, space, get_decoration(var.self, DecorationBinding), get_decoration(var.self, DecorationDescriptorSet)); } @@ -2988,16 +3021,21 @@ string CompilerHLSL::to_resource_binding_sampler(const SPIRVariable &var) if (!has_decoration(var.self, DecorationBinding)) return ""; - return to_resource_register('s', get_decoration(var.self, DecorationBinding), + return to_resource_register(HLSL_BINDING_AUTO_SAMPLER_BIT, 's', get_decoration(var.self, DecorationBinding), get_decoration(var.self, DecorationDescriptorSet)); } -string CompilerHLSL::to_resource_register(char space, uint32_t binding, uint32_t space_set) +string CompilerHLSL::to_resource_register(uint32_t flags, char space, uint32_t binding, uint32_t space_set) { - if (hlsl_options.shader_model >= 51) - return join(" : register(", space, binding, ", space", space_set, ")"); + if ((flags & resource_binding_flags) == 0) + { + if (hlsl_options.shader_model >= 51) + return join(" : register(", space, binding, ", space", space_set, ")"); + else + return join(" : register(", space, binding, ")"); + } else - return join(" : register(", space, binding, ")"); + return ""; } void CompilerHLSL::emit_modern_uniform(const SPIRVariable &var) @@ -4562,6 +4600,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction) // When using the pointer, we need to know which variable it is actually loaded from. auto *var = maybe_get_backing_variable(ops[2]); e.loaded_from = var ? var->self : ID(0); + inherit_expression_dependencies(id, ops[3]); break; } @@ -4877,6 +4916,11 @@ VariableID CompilerHLSL::remap_num_workgroups_builtin() return variable_id; } +void CompilerHLSL::set_resource_binding_flags(HLSLBindingFlags flags) +{ + resource_binding_flags = flags; +} + void CompilerHLSL::validate_shader_model() { // Check for nonuniform qualifier. |