Skip to content

Commit 4aedb50

Browse files
Handle multiple PhysicalStorageBuffer in same struct (#232)
1 parent 896de4f commit 4aedb50

23 files changed

Lines changed: 1968 additions & 747 deletions

common/output_stream.cpp

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <iomanip>
66
#include <sstream>
77
#include <string>
8+
#include <unordered_set>
89
#include <vector>
910

1011
enum TextLineType {
@@ -643,6 +644,7 @@ std::string ToStringTypeFlags(SpvReflectTypeFlags type_flags) {
643644
std::stringstream sstream;
644645
PRINT_AND_CLEAR_TYPE_FLAG(sstream, type_flags, ARRAY);
645646
PRINT_AND_CLEAR_TYPE_FLAG(sstream, type_flags, STRUCT);
647+
PRINT_AND_CLEAR_TYPE_FLAG(sstream, type_flags, REF);
646648
PRINT_AND_CLEAR_TYPE_FLAG(sstream, type_flags, EXTERNAL_MASK);
647649
PRINT_AND_CLEAR_TYPE_FLAG(sstream, type_flags, EXTERNAL_BLOCK);
648650
PRINT_AND_CLEAR_TYPE_FLAG(sstream, type_flags, EXTERNAL_SAMPLED_IMAGE);
@@ -934,7 +936,7 @@ std::string ToStringComponentType(const SpvReflectTypeDescription& type, uint32_
934936

935937
void ParseBlockMembersToTextLines(const char* indent, int indent_depth, bool flatten_cbuffers, const std::string& parent_name,
936938
uint32_t member_count, const SpvReflectBlockVariable* p_members,
937-
std::vector<TextLine>* p_text_lines) {
939+
std::vector<TextLine>* p_text_lines, std::unordered_set<uint32_t>& physical_pointer_spirv_id) {
938940
const char* t = indent;
939941
for (uint32_t member_index = 0; member_index < member_count; ++member_index) {
940942
indent_depth = flatten_cbuffers ? 2 : indent_depth;
@@ -949,8 +951,10 @@ void ParseBlockMembersToTextLines(const char* indent, int indent_depth, bool fla
949951
// TODO 212 - If a buffer ref has an array of itself, all members are null
950952
continue;
951953
}
954+
952955
bool is_struct = ((member.type_description->type_flags & static_cast<SpvReflectTypeFlags>(SPV_REFLECT_TYPE_FLAG_STRUCT)) != 0);
953956
bool is_ref = ((member.type_description->type_flags & static_cast<SpvReflectTypeFlags>(SPV_REFLECT_TYPE_FLAG_REF)) != 0);
957+
bool is_array = ((member.type_description->type_flags & static_cast<SpvReflectTypeFlags>(SPV_REFLECT_TYPE_FLAG_ARRAY)) != 0);
954958
if (is_struct) {
955959
const std::string name = (member.name == nullptr ? "" : member.name);
956960

@@ -969,17 +973,29 @@ void ParseBlockMembersToTextLines(const char* indent, int indent_depth, bool fla
969973
p_text_lines->push_back(tl);
970974
}
971975

972-
// Members
973-
tl = {};
974-
std::string current_parent_name;
975-
if (flatten_cbuffers) {
976-
current_parent_name = parent_name.empty() ? name : (parent_name + "." + name);
976+
const bool array_of_structs = is_array && member.type_description->struct_type_description;
977+
const uint32_t struct_id =
978+
array_of_structs ? member.type_description->struct_type_description->id : member.type_description->id;
979+
980+
if (physical_pointer_spirv_id.count(struct_id) == 0) {
981+
physical_pointer_spirv_id.insert(member.type_description->id);
982+
if (array_of_structs) {
983+
physical_pointer_spirv_id.insert(member.type_description->struct_type_description->id);
984+
}
985+
986+
// Members
987+
tl = {};
988+
std::string current_parent_name;
989+
if (flatten_cbuffers) {
990+
current_parent_name = parent_name.empty() ? name : (parent_name + "." + name);
991+
}
992+
std::vector<TextLine>* p_target_text_line = flatten_cbuffers ? p_text_lines : &tl.lines;
993+
ParseBlockMembersToTextLines(t, indent_depth + 1, flatten_cbuffers, current_parent_name, member.member_count,
994+
member.members, p_target_text_line, physical_pointer_spirv_id);
995+
tl.text_line_flags = TEXT_LINE_TYPE_LINES;
996+
p_text_lines->push_back(tl);
977997
}
978-
std::vector<TextLine>* p_target_text_line = flatten_cbuffers ? p_text_lines : &tl.lines;
979-
ParseBlockMembersToTextLines(t, indent_depth + 1, flatten_cbuffers, current_parent_name, member.member_count, member.members,
980-
p_target_text_line);
981-
tl.text_line_flags = TEXT_LINE_TYPE_LINES;
982-
p_text_lines->push_back(tl);
998+
physical_pointer_spirv_id.erase(member.type_description->id);
983999

9841000
// End struct
9851001
tl = {};
@@ -1064,7 +1080,9 @@ void ParseBlockVariableToTextLines(const char* indent, bool flatten_cbuffers, co
10641080

10651081
// Members
10661082
tl = {};
1067-
ParseBlockMembersToTextLines(indent, 2, flatten_cbuffers, "", block_var.member_count, block_var.members, &tl.lines);
1083+
std::unordered_set<uint32_t> physical_pointer_spirv_id;
1084+
ParseBlockMembersToTextLines(indent, 2, flatten_cbuffers, "", block_var.member_count, block_var.members, &tl.lines,
1085+
physical_pointer_spirv_id);
10681086
tl.text_line_flags = TEXT_LINE_TYPE_LINES;
10691087
p_text_lines->push_back(tl);
10701088

@@ -1534,8 +1552,10 @@ SpvReflectToYaml::SpvReflectToYaml(const SpvReflectShaderModule& shader_module,
15341552
void SpvReflectToYaml::WriteTypeDescription(std::ostream& os, const SpvReflectTypeDescription& td, uint32_t indent_level) {
15351553
// YAML anchors can only refer to points earlier in the doc, so child type
15361554
// descriptions must be processed before the parent.
1537-
for (uint32_t i = 0; i < td.member_count; ++i) {
1538-
WriteTypeDescription(os, td.members[i], indent_level);
1555+
if (!td.copied) {
1556+
for (uint32_t i = 0; i < td.member_count; ++i) {
1557+
WriteTypeDescription(os, td.members[i], indent_level);
1558+
}
15391559
}
15401560
const std::string t0 = Indent(indent_level);
15411561
const std::string t1 = Indent(indent_level + 1);
@@ -1544,7 +1564,6 @@ void SpvReflectToYaml::WriteTypeDescription(std::ostream& os, const SpvReflectTy
15441564
const std::string t4 = Indent(indent_level + 4);
15451565

15461566
// Determine the index of this type within the shader module's list.
1547-
assert(type_description_to_index_.find(&td) == type_description_to_index_.end());
15481567
uint32_t type_description_index = static_cast<uint32_t>(type_description_to_index_.size());
15491568
type_description_to_index_[&td] = type_description_index;
15501569

@@ -1638,13 +1657,21 @@ void SpvReflectToYaml::WriteTypeDescription(std::ostream& os, const SpvReflectTy
16381657
os << t1 << "member_count: " << td.member_count << std::endl;
16391658
// struct SpvReflectTypeDescription* members;
16401659
os << t1 << "members:" << std::endl;
1641-
for (uint32_t i_member = 0; i_member < td.member_count; ++i_member) {
1642-
os << t2 << "- *td" << type_description_to_index_[&(td.members[i_member])] << std::endl;
1660+
if (td.copied) {
1661+
os << t1 << "- [forward pointer]" << std::endl;
1662+
} else {
1663+
for (uint32_t i_member = 0; i_member < td.member_count; ++i_member) {
1664+
os << t2 << "- *td" << type_description_to_index_[&(td.members[i_member])] << std::endl;
1665+
}
16431666
}
16441667
// } SpvReflectTypeDescription;
16451668
}
16461669

16471670
void SpvReflectToYaml::WriteBlockVariable(std::ostream& os, const SpvReflectBlockVariable& bv, uint32_t indent_level) {
1671+
if ((bv.flags & SPV_REFLECT_VARIABLE_FLAGS_PHYSICAL_POINTER_COPY)) {
1672+
return; // catches recursive buffer references
1673+
}
1674+
16481675
for (uint32_t i = 0; i < bv.member_count; ++i) {
16491676
WriteBlockVariable(os, bv.members[i], indent_level);
16501677
}
@@ -1722,8 +1749,11 @@ void SpvReflectToYaml::WriteBlockVariable(std::ostream& os, const SpvReflectBloc
17221749
os << t1 << "members:" << std::endl;
17231750
for (uint32_t i = 0; i < bv.member_count; ++i) {
17241751
auto itor = block_variable_to_index_.find(&bv.members[i]);
1725-
assert(itor != block_variable_to_index_.end());
1726-
os << t2 << "- *bv" << itor->second << std::endl;
1752+
if (itor != block_variable_to_index_.end()) {
1753+
os << t2 << "- *bv" << itor->second << std::endl;
1754+
} else {
1755+
os << t2 << "- [recursive]" << std::endl;
1756+
}
17271757
}
17281758
if (verbosity_ >= 1) {
17291759
// SpvReflectTypeDescription* type_description;
@@ -1974,6 +2004,9 @@ void SpvReflectToYaml::WriteBlockVariableTypes(std::ostream& os, const SpvReflec
19742004
WriteTypeDescription(os, *td, indent_level);
19752005
}
19762006

2007+
if (bv.flags & SPV_REFLECT_VARIABLE_FLAGS_PHYSICAL_POINTER_COPY) {
2008+
return;
2009+
}
19772010
for (uint32_t i = 0; i < bv.member_count; ++i) {
19782011
WriteBlockVariableTypes(os, bv.members[i], indent_level);
19792012
}

0 commit comments

Comments
 (0)