@@ -1079,29 +1079,8 @@ void SemaHLSL::ActOnFinishRootSignatureDecl(
10791079
10801080bool SemaHLSL::handleRootSignatureDecl (HLSLRootSignatureDecl *D,
10811081 SourceLocation Loc) {
1082- // The following conducts analysis on resource ranges to detect and report
1083- // any overlaps in resource ranges.
1084- //
1085- // A resource range overlaps with another resource range if they have:
1086- // - equivalent ResourceClass (SRV, UAV, CBuffer, Sampler)
1087- // - equivalent resource space
1088- // - overlapping visbility
1089- //
1090- // The following algorithm is implemented in the following steps:
1091- //
1092- // 1. Collect RangeInfo from relevant RootElements:
1093- // - RangeInfo will retain the interval, ResourceClass, Space and Visibility
1094- // 2. Sort the RangeInfo's such that they are grouped together by
1095- // ResourceClass and Space (GroupT defined below)
1096- // 3. Iterate through the collected RangeInfos by their groups
1097- // - For each group we will have a ResourceRange for each visibility
1098- // - As we iterate through we will:
1099- // A: Insert the current RangeInfo into the corresponding Visibility
1100- // ResourceRange
1101- // B: Check for overlap with any overlapping Visibility ResourceRange
11021082 using RangeInfo = llvm::hlsl::rootsig::RangeInfo;
1103- using ResourceRange = llvm::hlsl::rootsig::ResourceRange;
1104- using GroupT = std::pair<ResourceClass, /* Space*/ uint32_t >;
1083+ using OverlappingRanges = llvm::hlsl::rootsig::OverlappingRanges;
11051084
11061085 // 1. Collect RangeInfos
11071086 llvm::SmallVector<RangeInfo> Infos;
@@ -1166,40 +1145,10 @@ bool SemaHLSL::handleRootSignatureDecl(HLSLRootSignatureDecl *D,
11661145 }
11671146 }
11681147
1169- // 2. Sort the RangeInfo's by their GroupT to form groupings
1170- std::sort (Infos.begin (), Infos.end (), [](RangeInfo A, RangeInfo B) {
1171- return std::tie (A.Class , A.Space ) < std::tie (B.Class , B.Space );
1172- });
1173-
1174- // 3. First we will init our state to track:
1175- if (Infos.size () == 0 )
1176- return false ; // No ranges to overlap
1177- GroupT CurGroup = {Infos[0 ].Class , Infos[0 ].Space };
1178- bool HadOverlap = false ;
1179-
1180- // Create a ResourceRange for each Visibility
1181- ResourceRange::MapT::Allocator Allocator;
1182- std::array<ResourceRange, 8 > Ranges = {
1183- ResourceRange (Allocator), // All
1184- ResourceRange (Allocator), // Vertex
1185- ResourceRange (Allocator), // Hull
1186- ResourceRange (Allocator), // Domain
1187- ResourceRange (Allocator), // Geometry
1188- ResourceRange (Allocator), // Pixel
1189- ResourceRange (Allocator), // Amplification
1190- ResourceRange (Allocator), // Mesh
1191- };
1192-
1193- // Reset the ResourceRanges for when we iterate through a new group
1194- auto ClearRanges = [&Ranges]() {
1195- for (ResourceRange &Range : Ranges)
1196- Range.clear ();
1197- };
1198-
11991148 // Helper to report diagnostics
1200- auto ReportOverlap = [this , Loc, &HadOverlap]( const RangeInfo *Info,
1201- const RangeInfo *OInfo) {
1202- HadOverlap = true ;
1149+ auto ReportOverlap = [this , Loc](OverlappingRanges Overlap) {
1150+ const RangeInfo *Info = Overlap. A ;
1151+ const RangeInfo *OInfo = Overlap. B ;
12031152 auto CommonVis = Info->Visibility == llvm::dxbc::ShaderVisibility::All
12041153 ? OInfo->Visibility
12051154 : Info->Visibility ;
@@ -1212,42 +1161,12 @@ bool SemaHLSL::handleRootSignatureDecl(HLSLRootSignatureDecl *D,
12121161 << OInfo->UpperBound << Info->Space << CommonVis;
12131162 };
12141163
1215- // 3: Iterate through collected RangeInfos
1216- for (const RangeInfo &Info : Infos) {
1217- GroupT InfoGroup = {Info.Class , Info.Space };
1218- // Reset our ResourceRanges when we enter a new group
1219- if (CurGroup != InfoGroup) {
1220- ClearRanges ();
1221- CurGroup = InfoGroup;
1222- }
1223-
1224- // 3A: Insert range info into corresponding Visibility ResourceRange
1225- ResourceRange &VisRange = Ranges[llvm::to_underlying (Info.Visibility )];
1226- if (std::optional<const RangeInfo *> Overlapping = VisRange.insert (Info))
1227- ReportOverlap (&Info, Overlapping.value ());
1228-
1229- // 3B: Check for overlap in all overlapping Visibility ResourceRanges
1230- //
1231- // If the range that we are inserting has ShaderVisiblity::All it needs to
1232- // check for an overlap in all other visibility types as well.
1233- // Otherwise, the range that is inserted needs to check that it does not
1234- // overlap with ShaderVisibility::All.
1235- //
1236- // OverlapRanges will be an ArrayRef to all non-all visibility
1237- // ResourceRanges in the former case and it will be an ArrayRef to just the
1238- // all visiblity ResourceRange in the latter case.
1239- ArrayRef<ResourceRange> OverlapRanges =
1240- Info.Visibility == llvm::dxbc::ShaderVisibility::All
1241- ? ArrayRef<ResourceRange>{Ranges}.drop_front ()
1242- : ArrayRef<ResourceRange>{Ranges}.take_front ();
1243-
1244- for (const ResourceRange &Range : OverlapRanges)
1245- if (std::optional<const RangeInfo *> Overlapping =
1246- Range.getOverlapping (Info))
1247- ReportOverlap (&Info, Overlapping.value ());
1248- }
1249-
1250- return HadOverlap;
1164+ llvm::SmallVector<OverlappingRanges> Overlaps =
1165+ llvm::hlsl::rootsig::findOverlappingRanges (Infos);
1166+ for (OverlappingRanges Overlap : Overlaps)
1167+ ReportOverlap (Overlap);
1168+
1169+ return Overlaps.size () != 0 ;
12511170}
12521171
12531172void SemaHLSL::handleRootSignatureAttr (Decl *D, const ParsedAttr &AL) {
0 commit comments