Skip to content

Commit 6af81bb

Browse files
committed
[HLSL][RootSignature] Add option to specify version of RootSignatureDecl
This pr provides the ability to specify the root signature version as a compiler option and to retain this in the root signature decl. It also updates the methods to serialize the version when dumping the declaration and to output the version when generating the metadata. - Update `DXILABI` to define the root signature versions - Update `Options.td` and `LangOpts.h` to define the `fdx-rootsig-ver` Clang/CC1 compiler option - Update `Options.td` to specify DXC compatible aliases `force-rootsig-ver` and `force_rootsig-ver` - Update `Decl.[h|cpp]` and `SeamHLSL.cpp` so that `RootSignatureDecl` will retain its version type - Updates `CGHLSLRuntime.cpp` to generate the extra metadata field - Add tests to illustrate
1 parent 6b9fe9e commit 6af81bb

File tree

13 files changed

+112
-20
lines changed

13 files changed

+112
-20
lines changed

clang/include/clang/AST/Decl.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "llvm/ADT/PointerUnion.h"
4242
#include "llvm/ADT/StringRef.h"
4343
#include "llvm/ADT/iterator_range.h"
44+
#include "llvm/BinaryFormat/DXContainer.h"
4445
#include "llvm/Frontend/HLSL/HLSLRootSignature.h"
4546
#include "llvm/Support/Casting.h"
4647
#include "llvm/Support/Compiler.h"
@@ -5179,6 +5180,8 @@ class HLSLRootSignatureDecl final
51795180
llvm::hlsl::rootsig::RootElement> {
51805181
friend TrailingObjects;
51815182

5183+
llvm::dxbc::RootSignatureVersion Version;
5184+
51825185
unsigned NumElems;
51835186

51845187
llvm::hlsl::rootsig::RootElement *getElems() { return getTrailingObjects(); }
@@ -5188,16 +5191,20 @@ class HLSLRootSignatureDecl final
51885191
}
51895192

51905193
HLSLRootSignatureDecl(DeclContext *DC, SourceLocation Loc, IdentifierInfo *ID,
5194+
llvm::dxbc::RootSignatureVersion Verison,
51915195
unsigned NumElems);
51925196

51935197
public:
51945198
static HLSLRootSignatureDecl *
51955199
Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, IdentifierInfo *ID,
5200+
llvm::dxbc::RootSignatureVersion Version,
51965201
ArrayRef<llvm::hlsl::rootsig::RootElement> RootElements);
51975202

51985203
static HLSLRootSignatureDecl *CreateDeserialized(ASTContext &C,
51995204
GlobalDeclID ID);
52005205

5206+
llvm::dxbc::RootSignatureVersion getVersion() const { return Version; }
5207+
52015208
ArrayRef<llvm::hlsl::rootsig::RootElement> getRootElements() const {
52025209
return {getElems(), NumElems};
52035210
}

clang/include/clang/Basic/LangOptions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "clang/Basic/Visibility.h"
2525
#include "llvm/ADT/FloatingPointMode.h"
2626
#include "llvm/ADT/StringRef.h"
27+
#include "llvm/BinaryFormat/DXContainer.h"
2728
#include "llvm/TargetParser/Triple.h"
2829
#include <optional>
2930
#include <string>
@@ -623,6 +624,10 @@ class LangOptions : public LangOptionsBase {
623624
// implementation on real-world examples.
624625
std::string OpenACCMacroOverride;
625626

627+
/// The HLSL root signature version for dxil.
628+
llvm::dxbc::RootSignatureVersion HLSLRootSigVer =
629+
llvm::dxbc::RootSignatureVersion::V1_1;
630+
626631
// Indicates if the wasm-opt binary must be ignored in the case of a
627632
// WebAssembly target.
628633
bool NoWasmOpt = false;

clang/include/clang/Driver/Options.td

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9288,6 +9288,17 @@ def fcgl : DXCFlag<"fcgl">, Alias<emit_pristine_llvm>;
92889288
def enable_16bit_types : DXCFlag<"enable-16bit-types">, Alias<fnative_half_type>,
92899289
HelpText<"Enable 16-bit types and disable min precision types."
92909290
"Available in HLSL 2018 and shader model 6.2.">;
9291+
def fdx_rootsig_ver :
9292+
Joined<["-"], "fdx-rootsig-ver=">,
9293+
Group<dxc_Group>,
9294+
Visibility<[ClangOption, CC1Option]>,
9295+
HelpText<"Root Signature Version">,
9296+
Values<"rootsig_1_0,rootsig_1_1">,
9297+
NormalizedValuesScope<"llvm::dxbc::RootSignatureVersion">,
9298+
NormalizedValues<["V1_0", "V1_1"]>,
9299+
MarshallingInfoEnum<LangOpts<"HLSLRootSigVer">, "V1_1">;
9300+
def dxc_rootsig_ver : DXCJoinedOrSeparate<"force-rootsig-ver">, Alias<fdx_rootsig_ver>;
9301+
def dxc_rootsig_ver_ : DXCJoinedOrSeparate<"force_rootsig_ver">, Alias<fdx_rootsig_ver>;
92919302
def hlsl_entrypoint : Option<["-"], "hlsl-entry", KIND_SEPARATE>,
92929303
Group<dxc_Group>,
92939304
Visibility<[ClangOption, CC1Option]>,

clang/lib/AST/Decl.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5853,21 +5853,21 @@ bool HLSLBufferDecl::buffer_decls_empty() {
58535853
// HLSLRootSignatureDecl Implementation
58545854
//===----------------------------------------------------------------------===//
58555855

5856-
HLSLRootSignatureDecl::HLSLRootSignatureDecl(DeclContext *DC,
5857-
SourceLocation Loc,
5858-
IdentifierInfo *ID,
5859-
unsigned NumElems)
5856+
HLSLRootSignatureDecl::HLSLRootSignatureDecl(
5857+
DeclContext *DC, SourceLocation Loc, IdentifierInfo *ID,
5858+
llvm::dxbc::RootSignatureVersion Version, unsigned NumElems)
58605859
: NamedDecl(Decl::Kind::HLSLRootSignature, DC, Loc, DeclarationName(ID)),
5861-
NumElems(NumElems) {}
5860+
Version(Version), NumElems(NumElems) {}
58625861

58635862
HLSLRootSignatureDecl *HLSLRootSignatureDecl::Create(
58645863
ASTContext &C, DeclContext *DC, SourceLocation Loc, IdentifierInfo *ID,
5864+
llvm::dxbc::RootSignatureVersion Version,
58655865
ArrayRef<llvm::hlsl::rootsig::RootElement> RootElements) {
58665866
HLSLRootSignatureDecl *RSDecl =
58675867
new (C, DC,
58685868
additionalSizeToAlloc<llvm::hlsl::rootsig::RootElement>(
58695869
RootElements.size()))
5870-
HLSLRootSignatureDecl(DC, Loc, ID, RootElements.size());
5870+
HLSLRootSignatureDecl(DC, Loc, ID, Version, RootElements.size());
58715871
auto *StoredElems = RSDecl->getElems();
58725872
std::uninitialized_copy(RootElements.begin(), RootElements.end(),
58735873
StoredElems);
@@ -5877,7 +5877,9 @@ HLSLRootSignatureDecl *HLSLRootSignatureDecl::Create(
58775877
HLSLRootSignatureDecl *
58785878
HLSLRootSignatureDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
58795879
HLSLRootSignatureDecl *Result = new (C, ID)
5880-
HLSLRootSignatureDecl(nullptr, SourceLocation(), nullptr, /*NumElems=*/0);
5880+
HLSLRootSignatureDecl(nullptr, SourceLocation(), nullptr,
5881+
/*Version*/ llvm::dxbc::RootSignatureVersion::V1_1,
5882+
/*NumElems=*/0);
58815883
return Result;
58825884
}
58835885

clang/lib/AST/TextNodeDumper.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3041,6 +3041,16 @@ void TextNodeDumper::VisitHLSLBufferDecl(const HLSLBufferDecl *D) {
30413041
void TextNodeDumper::VisitHLSLRootSignatureDecl(
30423042
const HLSLRootSignatureDecl *D) {
30433043
dumpName(D);
3044+
OS << " version: ";
3045+
switch (D->getVersion()) {
3046+
case llvm::dxbc::RootSignatureVersion::V1_0:
3047+
OS << "1.0";
3048+
break;
3049+
case llvm::dxbc::RootSignatureVersion::V1_1:
3050+
OS << "1.1";
3051+
break;
3052+
}
3053+
OS << ", ";
30443054
llvm::hlsl::rootsig::dumpRootElements(OS, D->getRootElements());
30453055
}
30463056

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,22 @@ void addDxilValVersion(StringRef ValVersionStr, llvm::Module &M) {
6666
DXILValMD->addOperand(Val);
6767
}
6868

69-
void addRootSignature(ArrayRef<llvm::hlsl::rootsig::RootElement> Elements,
69+
void addRootSignature(llvm::dxbc::RootSignatureVersion RootSigVer,
70+
ArrayRef<llvm::hlsl::rootsig::RootElement> Elements,
7071
llvm::Function *Fn, llvm::Module &M) {
7172
auto &Ctx = M.getContext();
73+
IRBuilder<> Builder(Ctx);
7274

73-
llvm::hlsl::rootsig::MetadataBuilder Builder(Ctx, Elements);
74-
MDNode *RootSignature = Builder.BuildRootSignature();
75+
llvm::hlsl::rootsig::MetadataBuilder RSBuilder(Ctx, Elements);
76+
MDNode *RootSignature = RSBuilder.BuildRootSignature();
7577

76-
// TODO: We need to wire the root signature version up through the frontend
77-
// rather than hardcoding it.
78-
ConstantAsMetadata *Version =
79-
ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx), 2));
80-
MDNode *MDVals =
81-
MDNode::get(Ctx, {ValueAsMetadata::get(Fn), RootSignature, Version});
78+
Metadata *Operands[] = {
79+
ValueAsMetadata::get(Fn),
80+
RootSignature,
81+
ConstantAsMetadata::get(
82+
Builder.getInt32(llvm::to_underlying(RootSigVer))),
83+
};
84+
MDNode *FnPairing = MDNode::get(Ctx, Operands);
8285

8386
StringRef RootSignatureValKey = "dx.rootsignatures";
8487
auto *RootSignatureValMD = M.getOrInsertNamedMetadata(RootSignatureValKey);
@@ -471,9 +474,11 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD,
471474

472475
// Add and identify root signature to function, if applicable
473476
for (const Attr *Attr : FD->getAttrs()) {
474-
if (const auto *RSAttr = dyn_cast<RootSignatureAttr>(Attr))
475-
addRootSignature(RSAttr->getSignatureDecl()->getRootElements(), EntryFn,
477+
if (const auto *RSAttr = dyn_cast<RootSignatureAttr>(Attr)) {
478+
auto *RSDecl = RSAttr->getSignatureDecl();
479+
addRootSignature(RSDecl->getVersion(), RSDecl->getRootElements(), EntryFn,
476480
M);
481+
}
477482
}
478483
}
479484

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3834,7 +3834,8 @@ static void RenderHLSLOptions(const ArgList &Args, ArgStringList &CmdArgs,
38343834
options::OPT_emit_obj,
38353835
options::OPT_disable_llvm_passes,
38363836
options::OPT_fnative_half_type,
3837-
options::OPT_hlsl_entrypoint};
3837+
options::OPT_hlsl_entrypoint,
3838+
options::OPT_fdx_rootsig_ver};
38383839
if (!types::isHLSL(InputType))
38393840
return;
38403841
for (const auto &Arg : ForwardedArguments)

clang/lib/Driver/ToolChains/HLSL.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,14 @@ HLSLToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
295295
A->claim();
296296
continue;
297297
}
298+
if (A->getOption().getID() == options::OPT_dxc_rootsig_ver ||
299+
A->getOption().getID() == options::OPT_dxc_rootsig_ver_) {
300+
DAL->AddJoinedArg(nullptr,
301+
Opts.getOption(options::OPT_fdx_rootsig_ver),
302+
A->getValue());
303+
A->claim();
304+
continue;
305+
}
298306
if (A->getOption().getID() == options::OPT__SLASH_O) {
299307
StringRef OStr = A->getValue();
300308
if (OStr == "d") {

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,10 @@ static bool FixupInvocation(CompilerInvocation &Invocation,
636636
Diags.Report(diag::err_drv_argument_not_allowed_with)
637637
<< "-hlsl-entry" << GetInputKindName(IK);
638638

639+
if (Args.hasArg(OPT_fdx_rootsig_ver) && !LangOpts.HLSL)
640+
Diags.Report(diag::err_drv_argument_not_allowed_with)
641+
<< "-fdx-rootsig-ver" << GetInputKindName(IK);
642+
639643
if (Args.hasArg(OPT_fgpu_allow_device_init) && !LangOpts.HIP)
640644
Diags.Report(diag::warn_ignored_hip_only_option)
641645
<< Args.getLastArg(OPT_fgpu_allow_device_init)->getAsString(Args);

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1067,7 +1067,7 @@ void SemaHLSL::ActOnFinishRootSignatureDecl(
10671067

10681068
auto *SignatureDecl = HLSLRootSignatureDecl::Create(
10691069
SemaRef.getASTContext(), /*DeclContext=*/SemaRef.CurContext, Loc,
1070-
DeclIdent, Elements);
1070+
DeclIdent, SemaRef.getLangOpts().HLSLRootSigVer, Elements);
10711071

10721072
if (handleRootSignatureDecl(SignatureDecl, Loc))
10731073
return;

clang/test/AST/HLSL/RootSignatures-AST.hlsl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -ast-dump \
22
// RUN: -disable-llvm-passes -o - %s | FileCheck %s
3+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -ast-dump \
4+
// RUN: -fdx-rootsig-ver=rootsig_1_0 \
5+
// RUN: -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=CHECK-V1_0
6+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -ast-dump \
7+
// RUN: -fdx-rootsig-ver=rootsig_1_1 \
8+
// RUN: -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=CHECK-V1_1
39

410
// This test ensures that the sample root signature is parsed without error and
511
// the Attr AST Node is created succesfully. If an invalid root signature was
@@ -16,6 +22,8 @@
1622
"DescriptorTable(Sampler(s0, numDescriptors = 4, space = 1))"
1723

1824
// CHECK: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[SAMPLE_RS_DECL:__hlsl_rootsig_decl_\d*]]
25+
// CHECK-V1_0: version: 1.0,
26+
// CHECK-V1_1: version: 1.1,
1927
// CHECK-SAME: RootElements{
2028
// CHECK-SAME: CBV(b1, numDescriptors = 1, space = 0,
2129
// CHECK-SAME: offset = DescriptorTableOffsetAppend, flags = DataStaticWhileSetAtExecute),
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %clang_dxc -T cs_6_0 -fcgl %s | FileCheck %s --check-prefix=CHECK-V1_1
2+
3+
// RUN: %clang_dxc -T cs_6_0 -fcgl -force-rootsig-ver rootsig_1_0 %s | FileCheck %s --check-prefix=CHECK-V1_0
4+
// RUN: %clang_dxc -T cs_6_0 -fcgl -force-rootsig-ver rootsig_1_1 %s | FileCheck %s --check-prefix=CHECK-V1_1
5+
6+
// RUN: %clang_dxc -T cs_6_0 -fcgl -force_rootsig_ver rootsig_1_0 %s | FileCheck %s --check-prefix=CHECK-V1_0
7+
// RUN: %clang_dxc -T cs_6_0 -fcgl -force_rootsig_ver rootsig_1_1 %s | FileCheck %s --check-prefix=CHECK-V1_1
8+
9+
// RUN: %clang_dxc -T cs_6_0 -fcgl -force-rootsig-verrootsig_1_0 %s | FileCheck %s --check-prefix=CHECK-V1_0
10+
// RUN: %clang_dxc -T cs_6_0 -fcgl -force-rootsig-verrootsig_1_1 %s | FileCheck %s --check-prefix=CHECK-V1_1
11+
12+
// RUN: %clang_dxc -T cs_6_0 -fcgl -force_rootsig_verrootsig_1_0 %s | FileCheck %s --check-prefix=CHECK-V1_0
13+
// RUN: %clang_dxc -T cs_6_0 -fcgl -force_rootsig_verrootsig_1_1 %s | FileCheck %s --check-prefix=CHECK-V1_1
14+
15+
// Test to demonstrate that we can specify the root-signature versions
16+
17+
// CHECK: !dx.rootsignatures = !{![[#EMPTY_ENTRY:]]}
18+
// CHECK: ![[#EMPTY_ENTRY]] = !{ptr @EmptyEntry, ![[#EMPTY:]],
19+
// CHECK-V1_0: i32 1}
20+
// CHECK-V1_1: i32 2}
21+
// CHECK: ![[#EMPTY]] = !{}
22+
23+
[shader("compute"), RootSignature("")]
24+
[numthreads(1,1,1)]
25+
void EmptyEntry() {}

llvm/include/llvm/BinaryFormat/DXContainer.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,12 @@ struct DescriptorRange : public v1::DescriptorRange {
750750
} // namespace v2
751751
} // namespace RTS0
752752

753+
// D3D_ROOT_SIGNATURE_VERSION
754+
enum class RootSignatureVersion {
755+
V1_0 = 0x1,
756+
V1_1 = 0x2,
757+
};
758+
753759
} // namespace dxbc
754760
} // namespace llvm
755761

0 commit comments

Comments
 (0)