HLSL: Report more explicitly which member failed validation.
This will be awkward to report in GLSL where we check multiple packing standards, but for HLSL it should be easy since there's only CBuffer packing standard to worry about.
This commit is contained in:
parent
e73d9bee38
commit
0b417b586a
@ -1336,7 +1336,8 @@ uint32_t CompilerGLSL::type_to_packed_size(const SPIRType &type, const Bitset &f
|
||||
}
|
||||
|
||||
bool CompilerGLSL::buffer_is_packing_standard(const SPIRType &type, BufferPackingStandard packing,
|
||||
uint32_t start_offset, uint32_t end_offset)
|
||||
uint32_t *failed_validation_index, uint32_t start_offset,
|
||||
uint32_t end_offset)
|
||||
{
|
||||
// This is very tricky and error prone, but try to be exhaustive and correct here.
|
||||
// SPIR-V doesn't directly say if we're using std430 or std140.
|
||||
@ -1417,18 +1418,28 @@ bool CompilerGLSL::buffer_is_packing_standard(const SPIRType &type, BufferPackin
|
||||
if (!packing_has_flexible_offset(packing))
|
||||
{
|
||||
if (actual_offset != offset) // This cannot be the packing we're looking for.
|
||||
{
|
||||
if (failed_validation_index)
|
||||
*failed_validation_index = i;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ((actual_offset & (alignment - 1)) != 0)
|
||||
{
|
||||
// We still need to verify that alignment rules are observed, even if we have explicit offset.
|
||||
if (failed_validation_index)
|
||||
*failed_validation_index = i;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify array stride rules.
|
||||
if (!memb_type.array.empty() && type_to_packed_array_stride(memb_type, member_flags, packing) !=
|
||||
type_struct_member_array_stride(type, i))
|
||||
{
|
||||
if (failed_validation_index)
|
||||
*failed_validation_index = i;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify that sub-structs also follow packing rules.
|
||||
// We cannot use enhanced layouts on substructs, so they better be up to spec.
|
||||
@ -1437,6 +1448,8 @@ bool CompilerGLSL::buffer_is_packing_standard(const SPIRType &type, BufferPackin
|
||||
if (!memb_type.pointer && !memb_type.member_types.empty() &&
|
||||
!buffer_is_packing_standard(memb_type, substruct_packing))
|
||||
{
|
||||
if (failed_validation_index)
|
||||
*failed_validation_index = i;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -558,7 +558,8 @@ protected:
|
||||
virtual void emit_block_hints(const SPIRBlock &block);
|
||||
virtual std::string to_initializer_expression(const SPIRVariable &var);
|
||||
|
||||
bool buffer_is_packing_standard(const SPIRType &type, BufferPackingStandard packing, uint32_t start_offset = 0,
|
||||
bool buffer_is_packing_standard(const SPIRType &type, BufferPackingStandard packing,
|
||||
uint32_t *failed_index = nullptr, uint32_t start_offset = 0,
|
||||
uint32_t end_offset = ~(0u));
|
||||
std::string buffer_to_packing_standard(const SPIRType &type, bool support_std430_without_scalar_layout);
|
||||
|
||||
|
@ -1887,11 +1887,13 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var)
|
||||
if (buffer_name.empty())
|
||||
buffer_name = join("_", get<SPIRType>(var.basetype).self, "_", var.self);
|
||||
|
||||
if (buffer_is_packing_standard(type, BufferPackingHLSLCbufferPackOffset))
|
||||
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,
|
||||
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."));
|
||||
}
|
||||
|
||||
@ -1934,9 +1936,11 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var)
|
||||
add_resource_name(var.self);
|
||||
|
||||
// ConstantBuffer<T> does not support packoffset, so it is unuseable unless everything aligns as we expect.
|
||||
if (!buffer_is_packing_standard(type, BufferPackingHLSLCbuffer))
|
||||
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."));
|
||||
}
|
||||
|
||||
@ -1959,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();
|
||||
|
Loading…
Reference in New Issue
Block a user