Add a helper function to improve reflection on runtime sized arrays.

This commit is contained in:
Hans-Kristian Arntzen 2018-09-10 11:08:47 +02:00
parent 6ca16b2a5e
commit e86018f8a1
3 changed files with 36 additions and 1 deletions

View File

@ -244,8 +244,14 @@ static void print_resources(const Compiler &compiler, const char *tag, const vec
uint32_t fallback_id = !is_push_constant && is_block ? res.base_type_id : res.id;
uint32_t block_size = 0;
uint32_t runtime_array_stride = 0;
if (is_sized_block)
block_size = uint32_t(compiler.get_declared_struct_size(compiler.get_type(res.base_type_id)));
{
auto &base_type = compiler.get_type(res.base_type_id);
block_size = uint32_t(compiler.get_declared_struct_size(base_type));
runtime_array_stride = uint32_t(compiler.get_declared_struct_size_runtime_array(base_type, 1) -
compiler.get_declared_struct_size_runtime_array(base_type, 0));
}
Bitset mask;
if (print_ssbo)
@ -273,7 +279,11 @@ static void print_resources(const Compiler &compiler, const char *tag, const vec
if (mask.get(DecorationNonWritable))
fprintf(stderr, " readonly");
if (is_sized_block)
{
fprintf(stderr, " (BlockSize : %u bytes)", block_size);
if (runtime_array_stride)
fprintf(stderr, " (Unsized array stride: %u bytes)", runtime_array_stride);
}
uint32_t counter_id = 0;
if (print_ssbo && compiler.buffer_get_hlsl_counter_buffer(res.id, counter_id))

View File

@ -2596,6 +2596,19 @@ size_t Compiler::get_declared_struct_size(const SPIRType &type) const
return offset + size;
}
size_t Compiler::get_declared_struct_size_runtime_array(const SPIRType &type, size_t array_size) const
{
if (type.member_types.empty())
SPIRV_CROSS_THROW("Declared struct in block cannot be empty.");
size_t size = get_declared_struct_size(type);
auto &last_type = get<SPIRType>(type.member_types.back());
if (!last_type.array.empty() && last_type.array_size_literal[0] && last_type.array[0] == 0) // Runtime array
size += array_size * type_struct_member_array_stride(type, uint32_t(type.member_types.size() - 1));
return size;
}
size_t Compiler::get_declared_struct_member_size(const SPIRType &struct_type, uint32_t index) const
{
if (struct_type.member_types.empty())

View File

@ -239,6 +239,18 @@ public:
// Returns the effective size of a buffer block.
size_t get_declared_struct_size(const SPIRType &struct_type) const;
// Returns the effective size of a buffer block, with a given array size
// for a runtime array.
// SSBOs are typically declared as runtime arrays. get_declared_struct_size() will return 0 for the size.
// This is not very helpful for applications which might need to know the array stride of its last member.
// This can be done through the API, but it is not very intuitive how to accomplish this, so here we provide a helper function
// to query the size of the buffer, assuming that the last member has a certain size.
// If the buffer does not contain a runtime array, array_size is ignored, and the function will behave as
// get_declared_struct_size().
// To get the array stride of the last member, something like:
// get_declared_struct_size_runtime_array(type, 1) - get_declared_struct_size_runtime_array(type, 0) will work.
size_t get_declared_struct_size_runtime_array(const SPIRType &struct_type, size_t array_size) const;
// Returns the effective size of a buffer block struct member.
virtual size_t get_declared_struct_member_size(const SPIRType &struct_type, uint32_t index) const;