55#include < iomanip>
66#include < sstream>
77#include < string>
8+ #include < unordered_set>
89#include < vector>
910
1011enum 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
935937void 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,
15341552void 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
16471670void 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