summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/SPIRV-Cross/spirv_hlsl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/SPIRV-Cross/spirv_hlsl.cpp')
-rw-r--r--src/3rdparty/SPIRV-Cross/spirv_hlsl.cpp82
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.