Updated spirv-cross.

This commit is contained in:
Бранимир Караџић
2026-01-01 20:32:39 -08:00
committed by Branimir Karadžić
parent e55579ea69
commit 65a81c76c9
8 changed files with 65 additions and 31 deletions

View File

@@ -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<T> 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<uint32_t>
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; });

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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:

View File

@@ -1021,7 +1021,13 @@ void CompilerHLSL::emit_interface_block_member_in_struct(const SPIRVariable &var
{
auto &execution = get_entry_point();
auto type = get<SPIRType>(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<SPIRType>(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

View File

@@ -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<uint32_t> spirv_)

View File

@@ -43,7 +43,7 @@ static bool decoration_is_string(Decoration decoration)
{
switch (decoration)
{
case DecorationHlslSemanticGOOGLE:
case DecorationUserSemantic:
return true;
default: