Skip to content

Commit e93a0d0

Browse files
authored
[HLSL][RootSignature] Add fdx-rootsignature-version option to specify root signature version (#144813)
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 `DXContainer.hI` to define the root signature versions - Update `Options.td` and `LangOpts.h` to define the `fdx-rootsignature-version` compiler option - Update `Options.td` to provide an alias `force-rootsig-ver` in clang-dxc - 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 Resolves #126557. Note: this does not implement validation based on versioning. #129940 is required to retrieve the version and use it for validations.
1 parent 52fbefb commit e93a0d0

File tree

13 files changed

+109
-27
lines changed

13 files changed

+109
-27
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"
@@ -5181,6 +5182,8 @@ class HLSLRootSignatureDecl final
51815182
llvm::hlsl::rootsig::RootElement> {
51825183
friend TrailingObjects;
51835184

5185+
llvm::dxbc::RootSignatureVersion Version;
5186+
51845187
unsigned NumElems;
51855188

51865189
llvm::hlsl::rootsig::RootElement *getElems() { return getTrailingObjects(); }
@@ -5190,16 +5193,20 @@ class HLSLRootSignatureDecl final
51905193
}
51915194

51925195
HLSLRootSignatureDecl(DeclContext *DC, SourceLocation Loc, IdentifierInfo *ID,
5196+
llvm::dxbc::RootSignatureVersion Version,
51935197
unsigned NumElems);
51945198

51955199
public:
51965200
static HLSLRootSignatureDecl *
51975201
Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, IdentifierInfo *ID,
5202+
llvm::dxbc::RootSignatureVersion Version,
51985203
ArrayRef<llvm::hlsl::rootsig::RootElement> RootElements);
51995204

52005205
static HLSLRootSignatureDecl *CreateDeserialized(ASTContext &C,
52015206
GlobalDeclID ID);
52025207

5208+
llvm::dxbc::RootSignatureVersion getVersion() const { return Version; }
5209+
52035210
ArrayRef<llvm::hlsl::rootsig::RootElement> getRootElements() const {
52045211
return {getElems(), NumElems};
52055212
}

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: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9312,6 +9312,20 @@ def fcgl : DXCFlag<"fcgl">, Alias<emit_pristine_llvm>;
93129312
def enable_16bit_types : DXCFlag<"enable-16bit-types">, Alias<fnative_half_type>,
93139313
HelpText<"Enable 16-bit types and disable min precision types."
93149314
"Available in HLSL 2018 and shader model 6.2.">;
9315+
def fdx_rootsignature_version :
9316+
Joined<["-"], "fdx-rootsignature-version=">,
9317+
Group<dxc_Group>,
9318+
Visibility<[ClangOption, CC1Option]>,
9319+
HelpText<"Root Signature Version">,
9320+
Values<"rootsig_1_0,rootsig_1_1">,
9321+
NormalizedValuesScope<"llvm::dxbc::RootSignatureVersion">,
9322+
NormalizedValues<["V1_0", "V1_1"]>,
9323+
MarshallingInfoEnum<LangOpts<"HLSLRootSigVer">, "V1_1">;
9324+
def dxc_rootsig_ver :
9325+
Separate<["/", "-"], "force-rootsig-ver">,
9326+
Alias<fdx_rootsignature_version>,
9327+
Group<dxc_Group>,
9328+
Visibility<[DXCOption]>;
93159329
def hlsl_entrypoint : Option<["-"], "hlsl-entry", KIND_SEPARATE>,
93169330
Group<dxc_Group>,
93179331
Visibility<[ClangOption, CC1Option]>,

clang/lib/AST/Decl.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5878,21 +5878,21 @@ bool HLSLBufferDecl::buffer_decls_empty() {
58785878
// HLSLRootSignatureDecl Implementation
58795879
//===----------------------------------------------------------------------===//
58805880

5881-
HLSLRootSignatureDecl::HLSLRootSignatureDecl(DeclContext *DC,
5882-
SourceLocation Loc,
5883-
IdentifierInfo *ID,
5884-
unsigned NumElems)
5881+
HLSLRootSignatureDecl::HLSLRootSignatureDecl(
5882+
DeclContext *DC, SourceLocation Loc, IdentifierInfo *ID,
5883+
llvm::dxbc::RootSignatureVersion Version, unsigned NumElems)
58855884
: NamedDecl(Decl::Kind::HLSLRootSignature, DC, Loc, DeclarationName(ID)),
5886-
NumElems(NumElems) {}
5885+
Version(Version), NumElems(NumElems) {}
58875886

58885887
HLSLRootSignatureDecl *HLSLRootSignatureDecl::Create(
58895888
ASTContext &C, DeclContext *DC, SourceLocation Loc, IdentifierInfo *ID,
5889+
llvm::dxbc::RootSignatureVersion Version,
58905890
ArrayRef<llvm::hlsl::rootsig::RootElement> RootElements) {
58915891
HLSLRootSignatureDecl *RSDecl =
58925892
new (C, DC,
58935893
additionalSizeToAlloc<llvm::hlsl::rootsig::RootElement>(
58945894
RootElements.size()))
5895-
HLSLRootSignatureDecl(DC, Loc, ID, RootElements.size());
5895+
HLSLRootSignatureDecl(DC, Loc, ID, Version, RootElements.size());
58965896
auto *StoredElems = RSDecl->getElems();
58975897
llvm::uninitialized_copy(RootElements, StoredElems);
58985898
return RSDecl;
@@ -5901,7 +5901,9 @@ HLSLRootSignatureDecl *HLSLRootSignatureDecl::Create(
59015901
HLSLRootSignatureDecl *
59025902
HLSLRootSignatureDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
59035903
HLSLRootSignatureDecl *Result = new (C, ID)
5904-
HLSLRootSignatureDecl(nullptr, SourceLocation(), nullptr, /*NumElems=*/0);
5904+
HLSLRootSignatureDecl(nullptr, SourceLocation(), nullptr,
5905+
/*Version*/ llvm::dxbc::RootSignatureVersion::V1_1,
5906+
/*NumElems=*/0);
59055907
return Result;
59065908
}
59075909

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: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,16 @@ 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();
7273

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

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));
77+
ConstantAsMetadata *Version = ConstantAsMetadata::get(ConstantInt::get(
78+
llvm::Type::getInt32Ty(Ctx), llvm::to_underlying(RootSigVer)));
8079
MDNode *MDVals =
8180
MDNode::get(Ctx, {ValueAsMetadata::get(Fn), RootSignature, Version});
8281

@@ -471,9 +470,11 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD,
471470

472471
// Add and identify root signature to function, if applicable
473472
for (const Attr *Attr : FD->getAttrs()) {
474-
if (const auto *RSAttr = dyn_cast<RootSignatureAttr>(Attr))
475-
addRootSignature(RSAttr->getSignatureDecl()->getRootElements(), EntryFn,
473+
if (const auto *RSAttr = dyn_cast<RootSignatureAttr>(Attr)) {
474+
auto *RSDecl = RSAttr->getSignatureDecl();
475+
addRootSignature(RSDecl->getVersion(), RSDecl->getRootElements(), EntryFn,
476476
M);
477+
}
477478
}
478479
}
479480

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3827,16 +3827,18 @@ static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs,
38273827

38283828
static void RenderHLSLOptions(const ArgList &Args, ArgStringList &CmdArgs,
38293829
types::ID InputType) {
3830-
const unsigned ForwardedArguments[] = {options::OPT_dxil_validator_version,
3831-
options::OPT_res_may_alias,
3832-
options::OPT_D,
3833-
options::OPT_I,
3834-
options::OPT_O,
3835-
options::OPT_emit_llvm,
3836-
options::OPT_emit_obj,
3837-
options::OPT_disable_llvm_passes,
3838-
options::OPT_fnative_half_type,
3839-
options::OPT_hlsl_entrypoint};
3830+
const unsigned ForwardedArguments[] = {
3831+
options::OPT_dxil_validator_version,
3832+
options::OPT_res_may_alias,
3833+
options::OPT_D,
3834+
options::OPT_I,
3835+
options::OPT_O,
3836+
options::OPT_emit_llvm,
3837+
options::OPT_emit_obj,
3838+
options::OPT_disable_llvm_passes,
3839+
options::OPT_fnative_half_type,
3840+
options::OPT_hlsl_entrypoint,
3841+
options::OPT_fdx_rootsignature_version};
38403842
if (!types::isHLSL(InputType))
38413843
return;
38423844
for (const auto &Arg : ForwardedArguments)

clang/lib/Driver/ToolChains/HLSL.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,13 @@ HLSLToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
295295
A->claim();
296296
continue;
297297
}
298+
if (A->getOption().getID() == options::OPT_dxc_rootsig_ver) {
299+
DAL->AddJoinedArg(nullptr,
300+
Opts.getOption(options::OPT_fdx_rootsignature_version),
301+
A->getValue());
302+
A->claim();
303+
continue;
304+
}
298305
if (A->getOption().getID() == options::OPT__SLASH_O) {
299306
StringRef OStr = A->getValue();
300307
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_rootsignature_version) && !LangOpts.HLSL)
640+
Diags.Report(diag::err_drv_argument_not_allowed_with)
641+
<< "-fdx-rootsignature-version" << 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-rootsignature-version=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-rootsignature-version=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
@@ -23,6 +29,8 @@
2329
"filter = FILTER_MIN_MAG_MIP_LINEAR )"
2430

2531
// CHECK: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[SAMPLE_RS_DECL:__hlsl_rootsig_decl_\d*]]
32+
// CHECK-V1_0: version: 1.0,
33+
// CHECK-V1_1: version: 1.1,
2634
// CHECK-SAME: RootElements{
2735
// CHECK-SAME: RootFlags(AllowInputAssemblerInputLayout | DenyVertexShaderRootAccess),
2836
// CHECK-SAME: RootCBV(b0,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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+
// Test to demonstrate that we can specify the root-signature versions
7+
8+
// CHECK: !dx.rootsignatures = !{![[#EMPTY_ENTRY:]]}
9+
// CHECK: ![[#EMPTY_ENTRY]] = !{ptr @EmptyEntry, ![[#EMPTY:]],
10+
// CHECK-V1_0: i32 1}
11+
// CHECK-V1_1: i32 2}
12+
// CHECK: ![[#EMPTY]] = !{}
13+
14+
[shader("compute"), RootSignature("")]
15+
[numthreads(1,1,1)]
16+
void EmptyEntry() {}

llvm/include/llvm/BinaryFormat/DXContainer.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,12 @@ struct DescriptorRange {
759759
} // namespace v2
760760
} // namespace RTS0
761761

762+
// D3D_ROOT_SIGNATURE_VERSION
763+
enum class RootSignatureVersion {
764+
V1_0 = 0x1,
765+
V1_1 = 0x2,
766+
};
767+
762768
} // namespace dxbc
763769
} // namespace llvm
764770

0 commit comments

Comments
 (0)