diff --git a/3rdparty/spirv-cross/main.cpp b/3rdparty/spirv-cross/main.cpp index 4442dbffe..b48c1c3cd 100644 --- a/3rdparty/spirv-cross/main.cpp +++ b/3rdparty/spirv-cross/main.cpp @@ -744,6 +744,7 @@ struct CLIArguments bool hlsl_enable_16bit_types = false; bool hlsl_flatten_matrix_vertex_input_semantics = false; bool hlsl_preserve_structured_buffers = false; + bool hlsl_user_semantic = false; HLSLBindingFlags hlsl_binding_flags = 0; bool vulkan_semantics = false; bool flatten_multidimensional_arrays = false; @@ -852,6 +853,7 @@ static void print_help_hlsl() "\t[--hlsl-enable-16bit-types]:\n\t\tEnables native use of half/int16_t/uint16_t and ByteAddressBuffer interaction with these types. Requires SM 6.2.\n" "\t[--hlsl-flatten-matrix-vertex-input-semantics]:\n\t\tEmits matrix vertex inputs with input semantics as if they were independent vectors, e.g. TEXCOORD{2,3,4} rather than matrix form TEXCOORD2_{0,1,2}.\n" "\t[--hlsl-preserve-structured-buffers]:\n\t\tEmit SturucturedBuffer rather than ByteAddressBuffer. Requires UserTypeGOOGLE to be emitted. Intended for DXC roundtrips.\n" + "\t[--hlsl-user-semantic]:\n\t\tUses UserSemantic decoration to generate vertex input and output semantics.\n" ); // clang-format on } @@ -1471,6 +1473,7 @@ static string compile_iteration(const CLIArguments &args, std::vector hlsl_opts.enable_16bit_types = args.hlsl_enable_16bit_types; hlsl_opts.flatten_matrix_vertex_input_semantics = args.hlsl_flatten_matrix_vertex_input_semantics; hlsl_opts.preserve_structured_buffers = args.hlsl_preserve_structured_buffers; + hlsl_opts.user_semantic = args.hlsl_user_semantic; hlsl->set_hlsl_options(hlsl_opts); hlsl->set_resource_binding_flags(args.hlsl_binding_flags); if (args.hlsl_base_vertex_index_explicit_binding) @@ -1673,6 +1676,7 @@ static int main_inner(int argc, char *argv[]) cbs.add("--hlsl-flatten-matrix-vertex-input-semantics", [&args](CLIParser &) { args.hlsl_flatten_matrix_vertex_input_semantics = true; }); cbs.add("--hlsl-preserve-structured-buffers", [&args](CLIParser &) { args.hlsl_preserve_structured_buffers = true; }); + cbs.add("--hlsl-user-semantic", [&args](CLIParser &) { args.hlsl_user_semantic = true; }); cbs.add("--vulkan-semantics", [&args](CLIParser &) { args.vulkan_semantics = true; }); cbs.add("-V", [&args](CLIParser &) { args.vulkan_semantics = true; }); cbs.add("--flatten-multidimensional-arrays", [&args](CLIParser &) { args.flatten_multidimensional_arrays = true; }); diff --git a/3rdparty/spirv-cross/spirv_common.hpp b/3rdparty/spirv-cross/spirv_common.hpp index 02d842303..f133586ae 100644 --- a/3rdparty/spirv-cross/spirv_common.hpp +++ b/3rdparty/spirv-cross/spirv_common.hpp @@ -1355,7 +1355,7 @@ struct SPIRConstant : IVariant inline float scalar_bf8(uint32_t col = 0, uint32_t row = 0) const { - return f16_to_f32(scalar_u8(col, row) << 8); + return f16_to_f32(uint16_t(scalar_u8(col, row) << 8)); } inline float scalar_f32(uint32_t col = 0, uint32_t row = 0) const @@ -1790,7 +1790,7 @@ struct Meta { std::string alias; std::string qualified_alias; - std::string hlsl_semantic; + std::string user_semantic; std::string user_type; Bitset decoration_flags; spv::BuiltIn builtin_type = spv::BuiltInMax; diff --git a/3rdparty/spirv-cross/spirv_cross_c.cpp b/3rdparty/spirv-cross/spirv_cross_c.cpp index e1b7b1d17..1604385e5 100644 --- a/3rdparty/spirv-cross/spirv_cross_c.cpp +++ b/3rdparty/spirv-cross/spirv_cross_c.cpp @@ -529,6 +529,10 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c case SPVC_COMPILER_OPTION_HLSL_PRESERVE_STRUCTURED_BUFFERS: options->hlsl.preserve_structured_buffers = value != 0; break; + + case SPVC_COMPILER_OPTION_HLSL_USER_SEMANTIC: + options->hlsl.user_semantic = value != 0; + break; #endif #if SPIRV_CROSS_C_API_MSL diff --git a/3rdparty/spirv-cross/spirv_cross_c.h b/3rdparty/spirv-cross/spirv_cross_c.h index f360711e8..30f1c459c 100644 --- a/3rdparty/spirv-cross/spirv_cross_c.h +++ b/3rdparty/spirv-cross/spirv_cross_c.h @@ -40,7 +40,7 @@ extern "C" { /* Bumped if ABI or API breaks backwards compatibility. */ #define SPVC_C_API_VERSION_MAJOR 0 /* Bumped if APIs or enumerations are added in a backwards compatible way. */ -#define SPVC_C_API_VERSION_MINOR 67 +#define SPVC_C_API_VERSION_MINOR 68 /* Bumped if internal implementation details change. */ #define SPVC_C_API_VERSION_PATCH 0 @@ -753,6 +753,8 @@ typedef enum spvc_compiler_option SPVC_COMPILER_OPTION_MSL_ENABLE_POINT_SIZE_DEFAULT = 93 | SPVC_COMPILER_OPTION_MSL_BIT, + SPVC_COMPILER_OPTION_HLSL_USER_SEMANTIC = 94 | SPVC_COMPILER_OPTION_HLSL_BIT, + SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff } spvc_compiler_option; diff --git a/3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp b/3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp index 1c23ece13..84d2e23c0 100644 --- a/3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp +++ b/3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp @@ -366,8 +366,8 @@ void ParsedIR::set_decoration_string(ID id, Decoration decoration, const string switch (decoration) { - case DecorationHlslSemanticGOOGLE: - dec.hlsl_semantic = argument; + case DecorationUserSemantic: + dec.user_semantic = argument; break; case DecorationUserTypeGOOGLE: @@ -686,8 +686,8 @@ const string &ParsedIR::get_decoration_string(ID id, Decoration decoration) cons switch (decoration) { - case DecorationHlslSemanticGOOGLE: - return dec.hlsl_semantic; + case DecorationUserSemantic: + return dec.user_semantic; case DecorationUserTypeGOOGLE: return dec.user_type; @@ -747,8 +747,8 @@ void ParsedIR::unset_decoration(ID id, Decoration decoration) dec.spec_id = 0; break; - case DecorationHlslSemanticGOOGLE: - dec.hlsl_semantic.clear(); + case DecorationUserSemantic: + dec.user_semantic.clear(); break; case DecorationFPRoundingMode: @@ -843,8 +843,8 @@ void ParsedIR::set_member_decoration_string(TypeID id, uint32_t index, Decoratio switch (decoration) { - case DecorationHlslSemanticGOOGLE: - dec.hlsl_semantic = argument; + case DecorationUserSemantic: + dec.user_semantic = argument; break; default: @@ -864,8 +864,8 @@ const string &ParsedIR::get_member_decoration_string(TypeID id, uint32_t index, switch (decoration) { - case DecorationHlslSemanticGOOGLE: - return dec.hlsl_semantic; + case DecorationUserSemantic: + return dec.user_semantic; default: return empty_string; @@ -918,8 +918,8 @@ void ParsedIR::unset_member_decoration(TypeID id, uint32_t index, Decoration dec dec.spec_id = 0; break; - case DecorationHlslSemanticGOOGLE: - dec.hlsl_semantic.clear(); + case DecorationUserSemantic: + dec.user_semantic.clear(); break; default: diff --git a/3rdparty/spirv-cross/spirv_hlsl.cpp b/3rdparty/spirv-cross/spirv_hlsl.cpp index 098beca55..a18fa3c60 100644 --- a/3rdparty/spirv-cross/spirv_hlsl.cpp +++ b/3rdparty/spirv-cross/spirv_hlsl.cpp @@ -1021,7 +1021,13 @@ void CompilerHLSL::emit_interface_block_member_in_struct(const SPIRVariable &var { auto &execution = get_entry_point(); auto type = get(var.basetype); - auto semantic = to_semantic(location, execution.model, var.storage); + + std::string semantic; + if (hlsl_options.user_semantic && has_member_decoration(var.self, member_index, DecorationUserSemantic)) + semantic = get_member_decoration_string(var.self, member_index, DecorationUserSemantic); + else + semantic = to_semantic(location, execution.model, var.storage); + auto mbr_name = join(to_name(type.self), "_", to_member_name(type, member_index)); auto &mbr_type = get(type.member_types[member_index]); @@ -1080,17 +1086,28 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord auto name = to_name(var.self); if (use_location_number) { - uint32_t location_number; + uint32_t location_number = UINT32_MAX; - // If an explicit location exists, use it with TEXCOORD[N] semantic. - // Otherwise, pick a vacant location. - if (has_decoration(var.self, DecorationLocation)) - location_number = get_decoration(var.self, DecorationLocation); + std::string semantic; + bool has_user_semantic = false; + + if (hlsl_options.user_semantic && has_decoration(var.self, DecorationUserSemantic)) + { + semantic = get_decoration_string(var.self, DecorationUserSemantic); + has_user_semantic = true; + } else - location_number = get_vacant_location(); + { + // If an explicit location exists, use it with TEXCOORD[N] semantic. + // Otherwise, pick a vacant location. + if (has_decoration(var.self, DecorationLocation)) + location_number = get_decoration(var.self, DecorationLocation); + else + location_number = get_vacant_location(); - // Allow semantic remap if specified. - auto semantic = to_semantic(location_number, execution.model, var.storage); + // Allow semantic remap if specified. + semantic = to_semantic(location_number, execution.model, var.storage); + } if (need_matrix_unroll && type.columns > 1) { @@ -1104,14 +1121,15 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord newtype.columns = 1; string effective_semantic; - if (hlsl_options.flatten_matrix_vertex_input_semantics) + if (hlsl_options.flatten_matrix_vertex_input_semantics && !has_user_semantic) effective_semantic = to_semantic(location_number, execution.model, var.storage); else effective_semantic = join(semantic, "_", i); statement(to_interpolation_qualifiers(get_decoration_bitset(var.self)), variable_decl(newtype, join(name, "_", i)), " : ", effective_semantic, ";"); - active_locations.insert(location_number++); + if (location_number != UINT32_MAX) + active_locations.insert(location_number++); } } else @@ -1127,10 +1145,13 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord statement(to_interpolation_qualifiers(get_decoration_bitset(var.self)), variable_decl(decl_type, name), " : ", semantic, ";"); - // Structs and arrays should consume more locations. - uint32_t consumed_locations = type_to_consumed_locations(decl_type); - for (uint32_t i = 0; i < consumed_locations; i++) - active_locations.insert(location_number + i); + if (location_number != UINT32_MAX) + { + // Structs and arrays should consume more locations. + uint32_t consumed_locations = type_to_consumed_locations(decl_type); + for (uint32_t i = 0; i < consumed_locations; i++) + active_locations.insert(location_number + i); + } } } else diff --git a/3rdparty/spirv-cross/spirv_hlsl.hpp b/3rdparty/spirv-cross/spirv_hlsl.hpp index 5f9c3139d..0d5181b9d 100644 --- a/3rdparty/spirv-cross/spirv_hlsl.hpp +++ b/3rdparty/spirv-cross/spirv_hlsl.hpp @@ -151,6 +151,9 @@ public: // This relies on UserTypeGOOGLE to encode the buffer type either as "structuredbuffer" or "rwstructuredbuffer" // whereas the type can be extended with an optional subtype, e.g. "structuredbuffer:int". bool preserve_structured_buffers = false; + + // Use UserSemantic decoration info (if specified), otherwise use default mechanism (such as add_vertex_attribute_remap or TEXCOORD#). + bool user_semantic = false; }; explicit CompilerHLSL(std::vector spirv_) diff --git a/3rdparty/spirv-cross/spirv_parser.cpp b/3rdparty/spirv-cross/spirv_parser.cpp index 634312940..d30972b11 100644 --- a/3rdparty/spirv-cross/spirv_parser.cpp +++ b/3rdparty/spirv-cross/spirv_parser.cpp @@ -43,7 +43,7 @@ static bool decoration_is_string(Decoration decoration) { switch (decoration) { - case DecorationHlslSemanticGOOGLE: + case DecorationUserSemantic: return true; default: