Skip to content

[HLSL][RootSignature] Enable resource range analysis for remaining RootElements #145109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jun 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -13054,10 +13054,13 @@ def err_invalid_hlsl_resource_type: Error<
def err_hlsl_spirv_only: Error<"%0 is only available for the SPIR-V target">;
def err_hlsl_vk_literal_must_contain_constant: Error<"the argument to vk::Literal must be a vk::integral_constant">;

def subst_hlsl_format_ranges: TextSubstitution<
"%select{t|u|b|s}0[%1;%select{%3]|unbounded)}2">;

def err_hlsl_resource_range_overlap: Error<
"resource ranges %select{t|u|b|s}0[%1;%2] and %select{t|u|b|s}3[%4;%5] "
"overlap within space = %6 and visibility = "
"%select{All|Vertex|Hull|Domain|Geometry|Pixel|Amplification|Mesh}7">;
"resource ranges %sub{subst_hlsl_format_ranges}0,1,2,3 and %sub{subst_hlsl_format_ranges}4,5,6,7 "
"overlap within space = %8 and visibility = "
"%select{All|Vertex|Hull|Domain|Geometry|Pixel|Amplification|Mesh}9">;

// Layout randomization diagnostics.
def err_non_designated_init_used : Error<
Expand Down
51 changes: 50 additions & 1 deletion clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1116,6 +1116,52 @@ bool SemaHLSL::handleRootSignatureDecl(HLSLRootSignatureDecl *D,
Info.Space = Descriptor->Space;
Info.Visibility = Descriptor->Visibility;
Infos.push_back(Info);
} else if (const auto *Constants =
std::get_if<llvm::hlsl::rootsig::RootConstants>(&Elem)) {
RangeInfo Info;
Info.LowerBound = Constants->Reg.Number;
Info.UpperBound = Info.LowerBound; // use inclusive ranges []

Info.Class = llvm::dxil::ResourceClass::CBuffer;
Info.Space = Constants->Space;
Info.Visibility = Constants->Visibility;
Infos.push_back(Info);
} else if (const auto *Sampler =
std::get_if<llvm::hlsl::rootsig::StaticSampler>(&Elem)) {
RangeInfo Info;
Info.LowerBound = Sampler->Reg.Number;
Info.UpperBound = Info.LowerBound; // use inclusive ranges []

Info.Class = llvm::dxil::ResourceClass::Sampler;
Info.Space = Sampler->Space;
Info.Visibility = Sampler->Visibility;
Infos.push_back(Info);
} else if (const auto *Clause =
std::get_if<llvm::hlsl::rootsig::DescriptorTableClause>(
&Elem)) {
RangeInfo Info;
Info.LowerBound = Clause->Reg.Number;
assert(0 < Clause->NumDescriptors && "Verified as part of TODO(#129940)");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we get #129940 in first then?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, there shouldn't be anything to prevent us from doing so

Info.UpperBound = Clause->NumDescriptors == RangeInfo::Unbounded
? RangeInfo::Unbounded
: Info.LowerBound + Clause->NumDescriptors -
1; // use inclusive ranges []

Info.Class = Clause->Type;
Info.Space = Clause->Space;
// Note: Clause does not hold the visibility this will need to
Infos.push_back(Info);
} else if (const auto *Table =
std::get_if<llvm::hlsl::rootsig::DescriptorTable>(&Elem)) {
// Table holds the Visibility of all owned Clauses in Table, so iterate
// owned Clauses and update their corresponding RangeInfo
assert(Table->NumClauses <= Infos.size() && "RootElement");
// The last Table->NumClauses elements of Infos are the owned Clauses
// generated RangeInfo
auto TableInfos =
MutableArrayRef<RangeInfo>(Infos).take_back(Table->NumClauses);
for (RangeInfo &Info : TableInfos)
Info.Visibility = Table->Visibility;
}
}

Expand Down Expand Up @@ -1159,8 +1205,11 @@ bool SemaHLSL::handleRootSignatureDecl(HLSLRootSignatureDecl *D,
: Info->Visibility;
this->Diag(Loc, diag::err_hlsl_resource_range_overlap)
<< llvm::to_underlying(Info->Class) << Info->LowerBound
<< /*unbounded=*/(Info->UpperBound == RangeInfo::Unbounded)
<< Info->UpperBound << llvm::to_underlying(OInfo->Class)
<< OInfo->LowerBound << OInfo->UpperBound << Info->Space << CommonVis;
<< OInfo->LowerBound
<< /*unbounded=*/(OInfo->UpperBound == RangeInfo::Unbounded)
<< OInfo->UpperBound << Info->Space << CommonVis;
};

// 3: Iterate through collected RangeInfos
Expand Down
1 change: 0 additions & 1 deletion clang/test/AST/HLSL/RootSignatures-AST.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ void same_rs_main() {}
"addressU = TEXTURE_ADDRESS_CLAMP, " \
"filter = FILTER_MIN_MAG_MIP_LINEAR )"


// CHECK: -RootSignatureAttr 0x{{.*}} {{.*}} [[SAMPLE_RS_DECL]]
[RootSignature(SampleSameRS)]
void same_rs_string_main() {}
Expand Down
43 changes: 43 additions & 0 deletions clang/test/SemaHLSL/RootSignature-resource-ranges-err.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,46 @@ void bad_root_signature_3() {}
// expected-error@+1 {{resource ranges u[0;0] and u[0;0] overlap within space = 0 and visibility = Pixel}}
[RootSignature("UAV(u0, visibility = SHADER_VISIBILITY_PIXEL), UAV(u0, visibility = SHADER_VISIBILITY_ALL)")]
void bad_root_signature_4() {}

// expected-error@+1 {{resource ranges b[0;0] and b[0;0] overlap within space = 0 and visibility = All}}
[RootSignature("RootConstants(num32BitConstants=4, b0), RootConstants(num32BitConstants=2, b0)")]
void bad_root_signature_5() {}

// expected-error@+1 {{resource ranges s[3;3] and s[3;3] overlap within space = 0 and visibility = All}}
[RootSignature("StaticSampler(s3), StaticSampler(s3)")]
void bad_root_signature_6() {}

// expected-error@+1 {{resource ranges t[2;5] and t[0;3] overlap within space = 0 and visibility = All}}
[RootSignature("DescriptorTable(SRV(t0, numDescriptors=4), SRV(t2, numDescriptors=4))")]
void bad_root_signature_7() {}

// expected-error@+1 {{resource ranges u[2;5] and u[0;unbounded) overlap within space = 0 and visibility = Hull}}
[RootSignature("DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility = SHADER_VISIBILITY_HULL), DescriptorTable(UAV(u2, numDescriptors=4))")]
void bad_root_signature_8() {}

// expected-error@+1 {{resource ranges b[0;2] and b[2;2] overlap within space = 0 and visibility = All}}
[RootSignature("RootConstants(num32BitConstants=4, b2), DescriptorTable(CBV(b0, numDescriptors=3))")]
void bad_root_signature_9() {}

// expected-error@+1 {{resource ranges s[4;unbounded) and s[17;17] overlap within space = 0 and visibility = All}}
[RootSignature("StaticSampler(s17), DescriptorTable(Sampler(s0, numDescriptors=3),Sampler(s4, numDescriptors=unbounded))")]
void bad_root_signature_10() {}

// expected-error@+1 {{resource ranges b[45;45] and b[4;unbounded) overlap within space = 0 and visibility = Geometry}}
[RootSignature("DescriptorTable(CBV(b4, numDescriptors=unbounded)), CBV(b45, visibility = SHADER_VISIBILITY_GEOMETRY)")]
void bad_root_signature_11() {}

#define ReportFirstOverlap \
"DescriptorTable( " \
" CBV(b4, numDescriptors = 4), " \
" CBV(b1, numDescriptors = 2), " \
" CBV(b0, numDescriptors = 8), " \
")"

// expected-error@+1 {{resource ranges b[0;7] and b[1;2] overlap within space = 0 and visibility = All}}
[RootSignature(ReportFirstOverlap)]
void bad_root_signature_12() {}

// expected-error@+1 {{resource ranges s[2;2] and s[2;2] overlap within space = 0 and visibility = Vertex}}
[RootSignature("StaticSampler(s2, visibility=SHADER_VISIBILITY_ALL), DescriptorTable(Sampler(s2), visibility=SHADER_VISIBILITY_VERTEX)")]
void valid_root_signature_13() {}
9 changes: 9 additions & 0 deletions clang/test/SemaHLSL/RootSignature-resource-ranges.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,12 @@ void valid_root_signature_2() {}

[RootSignature("CBV(b0), SRV(t0)")]
void valid_root_signature_3() {}

[RootSignature("RootConstants(num32BitConstants=4, b0, space=0), DescriptorTable(CBV(b0, space=1))")]
void valid_root_signature_4() {}

[RootSignature("StaticSampler(s2, visibility=SHADER_VISIBILITY_PIXEL), DescriptorTable(Sampler(s2), visibility=SHADER_VISIBILITY_VERTEX)")]
void valid_root_signature_5() {}

[RootSignature("DescriptorTable(SRV(t5), UAV(u5, numDescriptors=2))")]
void valid_root_signature_6() {}
Loading