Updated spirv-cross.
This commit is contained in:
parent
e7f4420d1f
commit
8727f3c823
4
3rdparty/spirv-cross/main.cpp
vendored
4
3rdparty/spirv-cross/main.cpp
vendored
@ -732,6 +732,7 @@ struct CLIArguments
|
||||
bool hlsl_nonwritable_uav_texture_as_srv = false;
|
||||
bool hlsl_enable_16bit_types = false;
|
||||
bool hlsl_flatten_matrix_vertex_input_semantics = false;
|
||||
bool hlsl_preserve_structured_buffers = false;
|
||||
HLSLBindingFlags hlsl_binding_flags = 0;
|
||||
bool vulkan_semantics = false;
|
||||
bool flatten_multidimensional_arrays = false;
|
||||
@ -839,6 +840,7 @@ static void print_help_hlsl()
|
||||
"\t\tOpName reflection information must be intact.\n"
|
||||
"\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"
|
||||
);
|
||||
// clang-format on
|
||||
}
|
||||
@ -1421,6 +1423,7 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
|
||||
hlsl_opts.nonwritable_uav_texture_as_srv = args.hlsl_nonwritable_uav_texture_as_srv;
|
||||
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->set_hlsl_options(hlsl_opts);
|
||||
hlsl->set_resource_binding_flags(args.hlsl_binding_flags);
|
||||
if (args.hlsl_base_vertex_index_explicit_binding)
|
||||
@ -1622,6 +1625,7 @@ static int main_inner(int argc, char *argv[])
|
||||
cbs.add("--hlsl-enable-16bit-types", [&args](CLIParser &) { args.hlsl_enable_16bit_types = true; });
|
||||
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("--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; });
|
||||
|
1
3rdparty/spirv-cross/spirv_common.hpp
vendored
1
3rdparty/spirv-cross/spirv_common.hpp
vendored
@ -1663,6 +1663,7 @@ struct Meta
|
||||
std::string alias;
|
||||
std::string qualified_alias;
|
||||
std::string hlsl_semantic;
|
||||
std::string user_type;
|
||||
Bitset decoration_flags;
|
||||
spv::BuiltIn builtin_type = spv::BuiltInMax;
|
||||
uint32_t location = 0;
|
||||
|
@ -370,6 +370,10 @@ void ParsedIR::set_decoration_string(ID id, Decoration decoration, const string
|
||||
dec.hlsl_semantic = argument;
|
||||
break;
|
||||
|
||||
case DecorationUserTypeGOOGLE:
|
||||
dec.user_type = argument;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -659,6 +663,9 @@ const string &ParsedIR::get_decoration_string(ID id, Decoration decoration) cons
|
||||
case DecorationHlslSemanticGOOGLE:
|
||||
return dec.hlsl_semantic;
|
||||
|
||||
case DecorationUserTypeGOOGLE:
|
||||
return dec.user_type;
|
||||
|
||||
default:
|
||||
return empty_string;
|
||||
}
|
||||
|
56
3rdparty/spirv-cross/spirv_glsl.cpp
vendored
56
3rdparty/spirv-cross/spirv_glsl.cpp
vendored
@ -9858,6 +9858,9 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
bool pending_array_enclose = false;
|
||||
bool dimension_flatten = false;
|
||||
|
||||
// If we are translating access to a structured buffer, the first subscript '._m0' must be hidden
|
||||
bool hide_first_subscript = count > 1 && is_user_type_structured(base);
|
||||
|
||||
const auto append_index = [&](uint32_t index, bool is_literal, bool is_ptr_chain = false) {
|
||||
AccessChainFlags mod_flags = flags;
|
||||
if (!is_literal)
|
||||
@ -10044,32 +10047,40 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
if (index >= type->member_types.size())
|
||||
SPIRV_CROSS_THROW("Member index is out of bounds!");
|
||||
|
||||
BuiltIn builtin = BuiltInMax;
|
||||
if (is_member_builtin(*type, index, &builtin) && access_chain_needs_stage_io_builtin_translation(base))
|
||||
if (hide_first_subscript)
|
||||
{
|
||||
if (access_chain_is_arrayed)
|
||||
{
|
||||
expr += ".";
|
||||
expr += builtin_to_glsl(builtin, type->storage);
|
||||
}
|
||||
else
|
||||
expr = builtin_to_glsl(builtin, type->storage);
|
||||
// First "._m0" subscript has been hidden, subsequent fields must be emitted even for structured buffers
|
||||
hide_first_subscript = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the member has a qualified name, use it as the entire chain
|
||||
string qual_mbr_name = get_member_qualified_name(type_id, index);
|
||||
if (!qual_mbr_name.empty())
|
||||
expr = qual_mbr_name;
|
||||
else if (flatten_member_reference)
|
||||
expr += join("_", to_member_name(*type, index));
|
||||
BuiltIn builtin = BuiltInMax;
|
||||
if (is_member_builtin(*type, index, &builtin) && access_chain_needs_stage_io_builtin_translation(base))
|
||||
{
|
||||
if (access_chain_is_arrayed)
|
||||
{
|
||||
expr += ".";
|
||||
expr += builtin_to_glsl(builtin, type->storage);
|
||||
}
|
||||
else
|
||||
expr = builtin_to_glsl(builtin, type->storage);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Any pointer de-refences for values are handled in the first access chain.
|
||||
// For pointer chains, the pointer-ness is resolved through an array access.
|
||||
// The only time this is not true is when accessing array of SSBO/UBO.
|
||||
// This case is explicitly handled.
|
||||
expr += to_member_reference(base, *type, index, ptr_chain || i != 0);
|
||||
// If the member has a qualified name, use it as the entire chain
|
||||
string qual_mbr_name = get_member_qualified_name(type_id, index);
|
||||
if (!qual_mbr_name.empty())
|
||||
expr = qual_mbr_name;
|
||||
else if (flatten_member_reference)
|
||||
expr += join("_", to_member_name(*type, index));
|
||||
else
|
||||
{
|
||||
// Any pointer de-refences for values are handled in the first access chain.
|
||||
// For pointer chains, the pointer-ness is resolved through an array access.
|
||||
// The only time this is not true is when accessing array of SSBO/UBO.
|
||||
// This case is explicitly handled.
|
||||
expr += to_member_reference(base, *type, index, ptr_chain || i != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15587,6 +15598,11 @@ bool CompilerGLSL::builtin_translates_to_nonarray(spv::BuiltIn /*builtin*/) cons
|
||||
return false; // GLSL itself does not need to translate array builtin types to non-array builtin types
|
||||
}
|
||||
|
||||
bool CompilerGLSL::is_user_type_structured(uint32_t /*id*/) const
|
||||
{
|
||||
return false; // GLSL itself does not have structured user type, but HLSL does with StructuredBuffer and RWStructuredBuffer resources.
|
||||
}
|
||||
|
||||
bool CompilerGLSL::check_atomic_image(uint32_t id)
|
||||
{
|
||||
auto &type = expression_type(id);
|
||||
|
2
3rdparty/spirv-cross/spirv_glsl.hpp
vendored
2
3rdparty/spirv-cross/spirv_glsl.hpp
vendored
@ -477,6 +477,8 @@ protected:
|
||||
|
||||
virtual bool builtin_translates_to_nonarray(spv::BuiltIn builtin) const;
|
||||
|
||||
virtual bool is_user_type_structured(uint32_t id) const;
|
||||
|
||||
void emit_copy_logical_type(uint32_t lhs_id, uint32_t lhs_type_id, uint32_t rhs_id, uint32_t rhs_type_id,
|
||||
SmallVector<uint32_t> chain);
|
||||
|
||||
|
47
3rdparty/spirv-cross/spirv_hlsl.cpp
vendored
47
3rdparty/spirv-cross/spirv_hlsl.cpp
vendored
@ -2603,11 +2603,30 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var)
|
||||
bool is_readonly = flags.get(DecorationNonWritable) && !is_hlsl_force_storage_buffer_as_uav(var.self);
|
||||
bool is_coherent = flags.get(DecorationCoherent) && !is_readonly;
|
||||
bool is_interlocked = interlocked_resources.count(var.self) > 0;
|
||||
const char *type_name = "ByteAddressBuffer ";
|
||||
if (!is_readonly)
|
||||
type_name = is_interlocked ? "RasterizerOrderedByteAddressBuffer " : "RWByteAddressBuffer ";
|
||||
|
||||
auto to_structuredbuffer_subtype_name = [this](const SPIRType &parent_type) -> std::string
|
||||
{
|
||||
if (parent_type.basetype == SPIRType::Struct && parent_type.member_types.size() == 1)
|
||||
{
|
||||
// Use type of first struct member as a StructuredBuffer will have only one '._m0' field in SPIR-V
|
||||
const auto &member0_type = this->get<SPIRType>(parent_type.member_types.front());
|
||||
return this->type_to_glsl(member0_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, this StructuredBuffer only has a basic subtype, e.g. StructuredBuffer<int>
|
||||
return this->type_to_glsl(parent_type);
|
||||
}
|
||||
};
|
||||
|
||||
std::string type_name;
|
||||
if (is_user_type_structured(var.self))
|
||||
type_name = join(is_readonly ? "" : is_interlocked ? "RasterizerOrdered" : "RW", "StructuredBuffer<", to_structuredbuffer_subtype_name(type), ">");
|
||||
else
|
||||
type_name = is_readonly ? "ByteAddressBuffer" : is_interlocked ? "RasterizerOrderedByteAddressBuffer" : "RWByteAddressBuffer";
|
||||
|
||||
add_resource_name(var.self);
|
||||
statement(is_coherent ? "globallycoherent " : "", type_name, to_name(var.self), type_to_array_glsl(type),
|
||||
statement(is_coherent ? "globallycoherent " : "", type_name, " ", to_name(var.self), type_to_array_glsl(type),
|
||||
to_resource_binding(var), ";");
|
||||
}
|
||||
else
|
||||
@ -4969,6 +4988,12 @@ void CompilerHLSL::emit_access_chain(const Instruction &instruction)
|
||||
|
||||
auto *backing_variable = maybe_get_backing_variable(ops[2]);
|
||||
|
||||
if (backing_variable != nullptr && is_user_type_structured(backing_variable->self))
|
||||
{
|
||||
CompilerGLSL::emit_instruction(instruction);
|
||||
return;
|
||||
}
|
||||
|
||||
string base;
|
||||
if (to_plain_buffer_length != 0)
|
||||
base = access_chain(ops[2], &ops[3], to_plain_buffer_length, get<SPIRType>(ops[0]));
|
||||
@ -6693,3 +6718,17 @@ bool CompilerHLSL::builtin_translates_to_nonarray(spv::BuiltIn builtin) const
|
||||
{
|
||||
return (builtin == BuiltInSampleMask);
|
||||
}
|
||||
|
||||
bool CompilerHLSL::is_user_type_structured(uint32_t id) const
|
||||
{
|
||||
if (hlsl_options.preserve_structured_buffers)
|
||||
{
|
||||
// Compare left hand side of string only as these user types can contain more meta data such as their subtypes,
|
||||
// e.g. "structuredbuffer:int"
|
||||
const std::string &user_type = get_decoration_string(id, DecorationUserTypeGOOGLE);
|
||||
return user_type.compare(0, 16, "structuredbuffer") == 0 ||
|
||||
user_type.compare(0, 18, "rwstructuredbuffer") == 0 ||
|
||||
user_type.compare(0, 33, "rasterizerorderedstructuredbuffer") == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
8
3rdparty/spirv-cross/spirv_hlsl.hpp
vendored
8
3rdparty/spirv-cross/spirv_hlsl.hpp
vendored
@ -145,6 +145,11 @@ public:
|
||||
|
||||
// Rather than emitting main() for the entry point, use the name in SPIR-V.
|
||||
bool use_entry_point_name = false;
|
||||
|
||||
// Preserve (RW)StructuredBuffer types if the input source was HLSL.
|
||||
// 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;
|
||||
};
|
||||
|
||||
explicit CompilerHLSL(std::vector<uint32_t> spirv_)
|
||||
@ -398,6 +403,9 @@ private:
|
||||
// Returns true for BuiltInSampleMask because gl_SampleMask[] is an array in SPIR-V, but SV_Coverage is a scalar in HLSL.
|
||||
bool builtin_translates_to_nonarray(spv::BuiltIn builtin) const override;
|
||||
|
||||
// Returns true if the specified ID has a UserTypeGOOGLE decoration for StructuredBuffer or RWStructuredBuffer resources.
|
||||
bool is_user_type_structured(uint32_t id) const override;
|
||||
|
||||
std::vector<TypeID> composite_selection_workaround_types;
|
||||
|
||||
std::string get_inner_entry_point_name() const;
|
||||
|
11
3rdparty/spirv-cross/spirv_msl.cpp
vendored
11
3rdparty/spirv-cross/spirv_msl.cpp
vendored
@ -10902,26 +10902,29 @@ string CompilerMSL::to_function_args(const TextureFunctionArguments &args, bool
|
||||
// Therefore, dP/dx = dP/dy = exp2(lod)/extent.
|
||||
// (Subtracting 0.5 before exponentiation gives better results.)
|
||||
string grad_opt, extent;
|
||||
VariableID base_img = img;
|
||||
if (auto *combined = maybe_get<SPIRCombinedImageSampler>(img))
|
||||
base_img = combined->image;
|
||||
switch (imgtype.image.dim)
|
||||
{
|
||||
case Dim1D:
|
||||
grad_opt = "2d";
|
||||
extent = join("float2(", to_expression(img), ".get_width(), 1.0)");
|
||||
extent = join("float2(", to_expression(base_img), ".get_width(), 1.0)");
|
||||
break;
|
||||
case Dim2D:
|
||||
grad_opt = "2d";
|
||||
extent = join("float2(", to_expression(img), ".get_width(), ", to_expression(img), ".get_height())");
|
||||
extent = join("float2(", to_expression(base_img), ".get_width(), ", to_expression(base_img), ".get_height())");
|
||||
break;
|
||||
case DimCube:
|
||||
if (imgtype.image.arrayed && msl_options.emulate_cube_array)
|
||||
{
|
||||
grad_opt = "2d";
|
||||
extent = join("float2(", to_expression(img), ".get_width())");
|
||||
extent = join("float2(", to_expression(base_img), ".get_width())");
|
||||
}
|
||||
else
|
||||
{
|
||||
grad_opt = "cube";
|
||||
extent = join("float3(", to_expression(img), ".get_width())");
|
||||
extent = join("float3(", to_expression(base_img), ".get_width())");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
Loading…
x
Reference in New Issue
Block a user