Correctly reflect declared buffer size for out of order members.
Need to deduce size based on member with highest offset, not highest
index.
diff --git a/reference/shaders-reflection/comp/out-of-order-block-offsets.comp.json b/reference/shaders-reflection/comp/out-of-order-block-offsets.comp.json
new file mode 100644
index 0000000..b697b45
--- /dev/null
+++ b/reference/shaders-reflection/comp/out-of-order-block-offsets.comp.json
@@ -0,0 +1,44 @@
+{
+ "entryPoints" : [
+ {
+ "name" : "main",
+ "mode" : "comp",
+ "workgroup_size" : [
+ 1,
+ 1,
+ 1
+ ],
+ "workgroup_size_is_spec_constant_id" : [
+ false,
+ false,
+ false
+ ]
+ }
+ ],
+ "types" : {
+ "_7" : {
+ "name" : "SSBO",
+ "members" : [
+ {
+ "name" : "foo",
+ "type" : "uint",
+ "offset" : 8
+ },
+ {
+ "name" : "bar",
+ "type" : "uint",
+ "offset" : 4
+ }
+ ]
+ }
+ },
+ "ssbos" : [
+ {
+ "type" : "_7",
+ "name" : "SSBO",
+ "block_size" : 12,
+ "set" : 0,
+ "binding" : 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/shaders-reflection/comp/out-of-order-block-offsets.comp b/shaders-reflection/comp/out-of-order-block-offsets.comp
new file mode 100644
index 0000000..da5c86e
--- /dev/null
+++ b/shaders-reflection/comp/out-of-order-block-offsets.comp
@@ -0,0 +1,12 @@
+#version 450
+
+layout(set = 0, binding = 0) buffer SSBO
+{
+ layout(offset = 8) uint foo;
+ layout(offset = 4) uint bar;
+};
+
+void main()
+{
+ bar = foo;
+}
diff --git a/spirv_cross.cpp b/spirv_cross.cpp
index 5193506..edcf8e7 100644
--- a/spirv_cross.cpp
+++ b/spirv_cross.cpp
@@ -1729,10 +1729,22 @@
if (type.member_types.empty())
SPIRV_CROSS_THROW("Declared struct in block cannot be empty.");
- uint32_t last = uint32_t(type.member_types.size() - 1);
- size_t offset = type_struct_member_offset(type, last);
- size_t size = get_declared_struct_member_size(type, last);
- return offset + size;
+ // Offsets can be declared out of order, so we need to deduce the actual size
+ // based on last member instead.
+ uint32_t member_index = 0;
+ size_t highest_offset = 0;
+ for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++)
+ {
+ size_t offset = type_struct_member_offset(type, i);
+ if (offset > highest_offset)
+ {
+ highest_offset = offset;
+ member_index = i;
+ }
+ }
+
+ size_t size = get_declared_struct_member_size(type, member_index);
+ return highest_offset + size;
}
size_t Compiler::get_declared_struct_size_runtime_array(const SPIRType &type, size_t array_size) const