https://github.com/inbelic created https://github.com/llvm/llvm-project/pull/156373
This pr implements support for a root signature as a target, as specified [here](https://github.com/llvm/wg-hlsl/blob/main/proposals/0029-root-signature-driver-options.md#target-root-signature-version). This is implemented in the following steps: 1. Add `rootsignature` as a shader model environment type and define `rootsig` as a `target_profile`. Only valid as versions 1.0 and 1 2. Updates `HLSLFrontendAction` to invoke a special handling of constructing the `ASTContext` if we are considering an `hlsl` file and with a `rootsignature` target 3. Defines the special handling to minimally instantiate the `Parser` and `Sema` to insert the `RootSignatureDecl` 4. Updates `CGHLSLRuntime` to emit the constructed root signature decl as part of `dx.rootsignatures` with a `null` entry function 5. Updates `DXILRootSignature` to handle emitting a root signature without an entry function 6. Updates `ToolChains/HLSL` to invoke `only-section=RTS0` to strip any other generated information Resolves: https://github.com/llvm/llvm-project/issues/150286. ##### Implementation Considerations Ideally we could invoke this as part of `clang-dxc` without the need of a source file. However, the initialization of the `Parser` and `Lexer` becomes quite complicated to handle this. Technically, we could avoid generating any of the extra information that is removed in step 6. However, it seems better to re-use the logic in `llvm-objcopy` without any need for additional custom logic in `DXILRootSignature`. >From 64237b0b410049018a093a4b9d35ba7346b729dc Mon Sep 17 00:00:00 2001 From: Finn Plummer <[email protected]> Date: Fri, 29 Aug 2025 09:42:59 -0700 Subject: [PATCH 01/11] add support for rootsig as an hlsl environment --- clang/include/clang/Basic/Attr.td | 1 + clang/include/clang/Driver/Options.td | 3 ++- clang/lib/Driver/ToolChains/HLSL.cpp | 5 +++++ clang/lib/Sema/SemaHLSL.cpp | 4 ++++ llvm/include/llvm/TargetParser/Triple.h | 3 ++- llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp | 2 ++ llvm/lib/TargetParser/Triple.cpp | 3 +++ 7 files changed, 19 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 29364c5903d31..f9a8f2f555fbe 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -1185,6 +1185,7 @@ static llvm::Triple::EnvironmentType getEnvironmentType(llvm::StringRef Environm .Case("callable", llvm::Triple::Callable) .Case("mesh", llvm::Triple::Mesh) .Case("amplification", llvm::Triple::Amplification) + .Case("rootsignature", llvm::Triple::RootSignature) .Case("library", llvm::Triple::Library) .Default(llvm::Triple::UnknownEnvironment); } diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index f507968d30670..0ca2baada1421 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -9430,7 +9430,8 @@ def target_profile : DXCJoinedOrSeparate<"T">, MetaVarName<"<profile>">, "cs_6_0, cs_6_1, cs_6_2, cs_6_3, cs_6_4, cs_6_5, cs_6_6, cs_6_7," "lib_6_3, lib_6_4, lib_6_5, lib_6_6, lib_6_7, lib_6_x," "ms_6_5, ms_6_6, ms_6_7," - "as_6_5, as_6_6, as_6_7">; + "as_6_5, as_6_6, as_6_7," + "rootsig_1_0, rootsig_1_1">; def emit_pristine_llvm : DXCFlag<"emit-pristine-llvm">, HelpText<"Emit pristine LLVM IR from the frontend by not running any LLVM passes at all." "Same as -S + -emit-llvm + -disable-llvm-passes.">; diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp index 660661945d62a..304c367cc4367 100644 --- a/clang/lib/Driver/ToolChains/HLSL.cpp +++ b/clang/lib/Driver/ToolChains/HLSL.cpp @@ -62,6 +62,10 @@ bool isLegalShaderModel(Triple &T) { VersionTuple MinVer(6, 5); return MinVer <= Version; } break; + case Triple::EnvironmentType::RootSignature: + VersionTuple MinVer(1, 0); + VersionTuple MaxVer(1, 1); + return MinVer <= Version && Version <= MaxVer; } return false; } @@ -84,6 +88,7 @@ std::optional<std::string> tryParseProfile(StringRef Profile) { .Case("lib", Triple::EnvironmentType::Library) .Case("ms", Triple::EnvironmentType::Mesh) .Case("as", Triple::EnvironmentType::Amplification) + .Case("rootsig", Triple::EnvironmentType::RootSignature) .Default(Triple::EnvironmentType::UnknownEnvironment); if (Kind == Triple::EnvironmentType::UnknownEnvironment) return std::nullopt; diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 1e5ec952c1ecf..9e99f9a1525a9 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -765,6 +765,8 @@ void SemaHLSL::ActOnTopLevelFunction(FunctionDecl *FD) { case llvm::Triple::UnknownEnvironment: case llvm::Triple::Library: break; + case llvm::Triple::RootSignature: + llvm_unreachable("rootsig environment has no functions"); default: llvm_unreachable("Unhandled environment in triple"); } @@ -827,6 +829,8 @@ void SemaHLSL::CheckEntryPoint(FunctionDecl *FD) { } } break; + case llvm::Triple::RootSignature: + llvm_unreachable("rootsig environment has no function entry point"); default: llvm_unreachable("Unhandled environment in triple"); } diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h index ede9797ac7488..891f2de60a4d4 100644 --- a/llvm/include/llvm/TargetParser/Triple.h +++ b/llvm/include/llvm/TargetParser/Triple.h @@ -303,6 +303,7 @@ class Triple { Callable, Mesh, Amplification, + RootSignature, OpenCL, OpenHOS, Mlibc, @@ -870,7 +871,7 @@ class Triple { Env == Triple::Intersection || Env == Triple::AnyHit || Env == Triple::ClosestHit || Env == Triple::Miss || Env == Triple::Callable || Env == Triple::Mesh || - Env == Triple::Amplification; + Env == Triple::Amplification || Env == Triple::RootSignature; } /// Tests whether the target is SPIR (32- or 64-bit). diff --git a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp index 82bcacee7a6dd..9eebcc9b13063 100644 --- a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp +++ b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp @@ -127,6 +127,8 @@ static StringRef getShortShaderStage(Triple::EnvironmentType Env) { return "ms"; case Triple::Amplification: return "as"; + case Triple::RootSignature: + return "rootsig"; default: break; } diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp index 6acb0bc49ecfe..fa0d6974b3042 100644 --- a/llvm/lib/TargetParser/Triple.cpp +++ b/llvm/lib/TargetParser/Triple.cpp @@ -387,6 +387,8 @@ StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) { case Callable: return "callable"; case Mesh: return "mesh"; case Amplification: return "amplification"; + case RootSignature: + return "rootsignature"; case OpenCL: return "opencl"; case OpenHOS: return "ohos"; @@ -780,6 +782,7 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { .StartsWith("callable", Triple::Callable) .StartsWith("mesh", Triple::Mesh) .StartsWith("amplification", Triple::Amplification) + .StartsWith("rootsignature", Triple::RootSignature) .StartsWith("opencl", Triple::OpenCL) .StartsWith("ohos", Triple::OpenHOS) .StartsWith("pauthtest", Triple::PAuthTest) >From 9fc43d49920e4545b02df9f9ece2ee5be5435163 Mon Sep 17 00:00:00 2001 From: Finn Plummer <[email protected]> Date: Mon, 1 Sep 2025 12:40:32 -0700 Subject: [PATCH 02/11] add profile test --- llvm/unittests/TargetParser/TripleTest.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/llvm/unittests/TargetParser/TripleTest.cpp b/llvm/unittests/TargetParser/TripleTest.cpp index 35927e340a257..635b9f4f1e219 100644 --- a/llvm/unittests/TargetParser/TripleTest.cpp +++ b/llvm/unittests/TargetParser/TripleTest.cpp @@ -546,6 +546,22 @@ TEST(TripleTest, ParsedIDs) { EXPECT_EQ(VersionTuple(1, 8), T.getDXILVersion()); EXPECT_EQ(Triple::Amplification, T.getEnvironment()); + T = Triple("dxilv1.0-unknown-shadermodel1.0-rootsignature"); + EXPECT_EQ(Triple::dxil, T.getArch()); + EXPECT_EQ(Triple::DXILSubArch_v1_0, T.getSubArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::ShaderModel, T.getOS()); + EXPECT_EQ(VersionTuple(1, 0), T.getDXILVersion()); + EXPECT_EQ(Triple::RootSignature, T.getEnvironment()); + + T = Triple("dxilv1.1-unknown-shadermodel1.1-rootsignature"); + EXPECT_EQ(Triple::dxil, T.getArch()); + EXPECT_EQ(Triple::DXILSubArch_v1_1, T.getSubArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::ShaderModel, T.getOS()); + EXPECT_EQ(VersionTuple(1, 1), T.getDXILVersion()); + EXPECT_EQ(Triple::RootSignature, T.getEnvironment()); + T = Triple("dxilv1.8-unknown-shadermodel6.15-library"); EXPECT_EQ(Triple::dxil, T.getArch()); EXPECT_EQ(Triple::DXILSubArch_v1_8, T.getSubArch()); >From 11f61c163cc7a89e15142b37958d205ff1973e0b Mon Sep 17 00:00:00 2001 From: Finn Plummer <[email protected]> Date: Fri, 29 Aug 2025 10:26:38 -0700 Subject: [PATCH 03/11] introduce custom handling for root signature target --- .../clang/Parse/ParseHLSLRootSignature.h | 2 ++ clang/lib/Frontend/FrontendActions.cpp | 14 ++++++++++-- clang/lib/Parse/ParseHLSLRootSignature.cpp | 22 ++++++++++++++++++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h b/clang/include/clang/Parse/ParseHLSLRootSignature.h index c87e6637c7fce..2ae383c38a486 100644 --- a/clang/include/clang/Parse/ParseHLSLRootSignature.h +++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h @@ -240,6 +240,8 @@ IdentifierInfo *ParseHLSLRootSignature(Sema &Actions, llvm::dxbc::RootSignatureVersion Version, StringLiteral *Signature); +void HandleRootSignatureTarget(Sema &S); + } // namespace hlsl } // namespace clang diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index ccda2c4ce4b6d..666923101401b 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -1296,6 +1296,9 @@ class InjectRootSignatureCallback : public PPCallbacks { void HLSLFrontendAction::ExecuteAction() { // Pre-requisites to invoke + if (getCurrentFileKind().getLanguage() != Language::HLSL) + return WrapperFrontendAction::ExecuteAction(); + CompilerInstance &CI = getCompilerInstance(); if (!CI.hasASTContext() || !CI.hasPreprocessor()) return WrapperFrontendAction::ExecuteAction(); @@ -1309,6 +1312,10 @@ void HLSLFrontendAction::ExecuteAction() { /*CodeCompleteConsumer=*/nullptr); Sema &S = CI.getSema(); + auto &TargetInfo = CI.getASTContext().getTargetInfo(); + bool IsRootSignatureTarget = + TargetInfo.getTriple().getEnvironment() == llvm::Triple::RootSignature; + // Register HLSL specific callbacks auto LangOpts = CI.getLangOpts(); auto MacroCallback = std::make_unique<InjectRootSignatureCallback>( @@ -1317,8 +1324,11 @@ void HLSLFrontendAction::ExecuteAction() { Preprocessor &PP = CI.getPreprocessor(); PP.addPPCallbacks(std::move(MacroCallback)); - // Invoke as normal - WrapperFrontendAction::ExecuteAction(); + // If we are targeting a root signature, invoke custom handling + if (IsRootSignatureTarget) + return hlsl::HandleRootSignatureTarget(S); + else // otherwise, invoke as normal + return WrapperFrontendAction::ExecuteAction(); } HLSLFrontendAction::HLSLFrontendAction( diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp index 1af72f8b1c934..11af62f132be8 100644 --- a/clang/lib/Parse/ParseHLSLRootSignature.cpp +++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp @@ -7,8 +7,9 @@ //===----------------------------------------------------------------------===// #include "clang/Parse/ParseHLSLRootSignature.h" - +#include "clang/AST/ASTConsumer.h" #include "clang/Lex/LiteralSupport.h" +#include "clang/Parse/Parser.h" #include "clang/Sema/Sema.h" using namespace llvm::hlsl::rootsig; @@ -1472,5 +1473,24 @@ IdentifierInfo *ParseHLSLRootSignature(Sema &Actions, return DeclIdent; } +void HandleRootSignatureTarget(Sema &S) { + ASTConsumer *Consumer = &S.getASTConsumer(); + + // Minimally initalize the parser. This does a couple things: + // - initializes Sema scope handling + // - invokes HLSLExternalSemaSource + // - invokes the preprocessor to lex the macros in the file + std::unique_ptr<Parser> P(new Parser(S.getPreprocessor(), S, true)); + S.getPreprocessor().EnterMainSourceFile(); + + bool HaveLexer = S.getPreprocessor().getCurrentLexer(); + if (HaveLexer) { + P->Initialize(); + S.ActOnStartOfTranslationUnit(); + } + + Consumer->HandleTranslationUnit(S.getASTContext()); +} + } // namespace hlsl } // namespace clang >From e6747824bd95cb0c048dfad4e29c0a52d6673458 Mon Sep 17 00:00:00 2001 From: Finn Plummer <[email protected]> Date: Fri, 29 Aug 2025 10:45:00 -0700 Subject: [PATCH 04/11] nfc: pull out lookup of root signature --- clang/include/clang/Sema/SemaHLSL.h | 2 ++ clang/lib/Sema/SemaHLSL.cpp | 34 ++++++++++++++++++----------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index 5cbe1b658f5cd..4bad26e7a09a7 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -157,6 +157,8 @@ class SemaHLSL : public SemaBase { RootSigOverrideIdent = DeclIdent; } + HLSLRootSignatureDecl *lookupRootSignatureOverrideDecl(DeclContext *DC) const; + // Returns true if any RootSignatureElement is invalid and a diagnostic was // produced bool diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 9e99f9a1525a9..6ef43b833b759 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -729,19 +729,15 @@ void SemaHLSL::ActOnTopLevelFunction(FunctionDecl *FD) { // If we have specified a root signature to override the entry function then // attach it now - if (RootSigOverrideIdent) { - LookupResult R(SemaRef, RootSigOverrideIdent, SourceLocation(), - Sema::LookupOrdinaryName); - if (SemaRef.LookupQualifiedName(R, FD->getDeclContext())) - if (auto *SignatureDecl = - dyn_cast<HLSLRootSignatureDecl>(R.getFoundDecl())) { - FD->dropAttr<RootSignatureAttr>(); - // We could look up the SourceRange of the macro here as well - AttributeCommonInfo AL(RootSigOverrideIdent, AttributeScopeInfo(), - SourceRange(), ParsedAttr::Form::Microsoft()); - FD->addAttr(::new (getASTContext()) RootSignatureAttr( - getASTContext(), AL, RootSigOverrideIdent, SignatureDecl)); - } + HLSLRootSignatureDecl *SignatureDecl = + lookupRootSignatureOverrideDecl(FD->getDeclContext()); + if (SignatureDecl) { + FD->dropAttr<RootSignatureAttr>(); + // We could look up the SourceRange of the macro here as well + AttributeCommonInfo AL(RootSigOverrideIdent, AttributeScopeInfo(), + SourceRange(), ParsedAttr::Form::Microsoft()); + FD->addAttr(::new (getASTContext()) RootSignatureAttr( + getASTContext(), AL, RootSigOverrideIdent, SignatureDecl)); } llvm::Triple::EnvironmentType Env = TargetInfo.getTriple().getEnvironment(); @@ -1111,6 +1107,18 @@ void SemaHLSL::ActOnFinishRootSignatureDecl( SemaRef.PushOnScopeChains(SignatureDecl, SemaRef.getCurScope()); } +HLSLRootSignatureDecl * +SemaHLSL::lookupRootSignatureOverrideDecl(DeclContext *DC) const { + if (RootSigOverrideIdent) { + LookupResult R(SemaRef, RootSigOverrideIdent, SourceLocation(), + Sema::LookupOrdinaryName); + if (SemaRef.LookupQualifiedName(R, DC)) + return dyn_cast<HLSLRootSignatureDecl>(R.getFoundDecl()); + } + + return nullptr; +} + namespace { struct PerVisibilityBindingChecker { >From f41c4c4aedbf010a0b8472315c30c8e452460b5d Mon Sep 17 00:00:00 2001 From: Finn Plummer <[email protected]> Date: Mon, 1 Sep 2025 11:34:15 -0700 Subject: [PATCH 05/11] construct the RootSignatureDecl node in ASTContext --- .../clang/Basic/DiagnosticSemaKinds.td | 2 ++ .../clang/Parse/ParseHLSLRootSignature.h | 2 +- clang/lib/Frontend/FrontendActions.cpp | 8 ++++-- clang/lib/Parse/ParseHLSLRootSignature.cpp | 12 +++++++- .../AST/HLSL/RootSignature-Target-AST.hlsl | 28 +++++++++++++++++++ .../SemaHLSL/RootSignature-target-err.hlsl | 5 ++++ 6 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 clang/test/AST/HLSL/RootSignature-Target-AST.hlsl create mode 100644 clang/test/SemaHLSL/RootSignature-target-err.hlsl diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index c934fed2c7462..f1d64cdca5da4 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -13136,6 +13136,8 @@ def err_hlsl_attribute_needs_intangible_type: Error<"attribute %0 can be used on def err_hlsl_incorrect_num_initializers: Error< "too %select{few|many}0 initializers in list for type %1 " "(expected %2 but found %3)">; +def err_hlsl_rootsignature_entry: Error< + "rootsignature specified as target environment but entry, %0, was not defined">; def err_hlsl_operator_unsupported : Error< "the '%select{&|*|->}0' operator is unsupported in HLSL">; diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h b/clang/include/clang/Parse/ParseHLSLRootSignature.h index 2ae383c38a486..b06846fd83c09 100644 --- a/clang/include/clang/Parse/ParseHLSLRootSignature.h +++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h @@ -240,7 +240,7 @@ IdentifierInfo *ParseHLSLRootSignature(Sema &Actions, llvm::dxbc::RootSignatureVersion Version, StringLiteral *Signature); -void HandleRootSignatureTarget(Sema &S); +void HandleRootSignatureTarget(Sema &S, StringRef EntryRootSig); } // namespace hlsl } // namespace clang diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 666923101401b..9e00494bcfbcf 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -1315,18 +1315,22 @@ void HLSLFrontendAction::ExecuteAction() { auto &TargetInfo = CI.getASTContext().getTargetInfo(); bool IsRootSignatureTarget = TargetInfo.getTriple().getEnvironment() == llvm::Triple::RootSignature; + StringRef HLSLEntry = TargetInfo.getTargetOpts().HLSLEntry; // Register HLSL specific callbacks auto LangOpts = CI.getLangOpts(); + StringRef RootSigName = + IsRootSignatureTarget ? HLSLEntry : LangOpts.HLSLRootSigOverride; + auto MacroCallback = std::make_unique<InjectRootSignatureCallback>( - S, LangOpts.HLSLRootSigOverride, LangOpts.HLSLRootSigVer); + S, RootSigName, LangOpts.HLSLRootSigVer); Preprocessor &PP = CI.getPreprocessor(); PP.addPPCallbacks(std::move(MacroCallback)); // If we are targeting a root signature, invoke custom handling if (IsRootSignatureTarget) - return hlsl::HandleRootSignatureTarget(S); + return hlsl::HandleRootSignatureTarget(S, HLSLEntry); else // otherwise, invoke as normal return WrapperFrontendAction::ExecuteAction(); } diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp index 11af62f132be8..4e5b8b83200e0 100644 --- a/clang/lib/Parse/ParseHLSLRootSignature.cpp +++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp @@ -1473,7 +1473,7 @@ IdentifierInfo *ParseHLSLRootSignature(Sema &Actions, return DeclIdent; } -void HandleRootSignatureTarget(Sema &S) { +void HandleRootSignatureTarget(Sema &S, StringRef EntryRootSig) { ASTConsumer *Consumer = &S.getASTConsumer(); // Minimally initalize the parser. This does a couple things: @@ -1487,6 +1487,16 @@ void HandleRootSignatureTarget(Sema &S) { if (HaveLexer) { P->Initialize(); S.ActOnStartOfTranslationUnit(); + + HLSLRootSignatureDecl *SignatureDecl = + S.HLSL().lookupRootSignatureOverrideDecl( + S.getASTContext().getTranslationUnitDecl()); + + if (SignatureDecl) + Consumer->HandleTopLevelDecl(DeclGroupRef(SignatureDecl)); + else + S.getDiagnostics().Report(diag::err_hlsl_rootsignature_entry) + << EntryRootSig; } Consumer->HandleTranslationUnit(S.getASTContext()); diff --git a/clang/test/AST/HLSL/RootSignature-Target-AST.hlsl b/clang/test/AST/HLSL/RootSignature-Target-AST.hlsl new file mode 100644 index 0000000000000..91441e32e047d --- /dev/null +++ b/clang/test/AST/HLSL/RootSignature-Target-AST.hlsl @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-rootsignature -ast-dump \ +// RUN: -hlsl-entry EntryRootSig -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-V1_1 + +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-rootsignature -ast-dump \ +// RUN: -fdx-rootsignature-version=rootsig_1_0 \ +// RUN: -hlsl-entry EntryRootSig -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-V1_0 + +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-rootsignature -ast-dump \ +// RUN: -D CmdRS='"UAV(u0)"'\ +// RUN: -hlsl-entry CmdRS -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=CMD + +// CHECK: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[ENTRY_RS_DECL:__hlsl_rootsig_decl_\d*]] +// CHECK-V1_0-SAME: version: 1.0, +// CHECK-V1_1-SAME: version: 1.1, +// CHECK-SAME: RootElements{ +// CHECK-SAME: RootCBV(b0, +// CHECK-SAME: space = 0, visibility = All, +// CHECK-V1_0-SAME: flags = DataVolatile +// CHECK-V1_1-SAME: flags = DataStaticWhileSetAtExecute +// CHECK-SAME: ) +// CHECK-SAME: } +#define EntryRootSig "CBV(b0)" + +// CMD: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[CMD_RS_DECL:__hlsl_rootsig_decl_\d*]] +// CMD-SAME: version: 1.1, +// CMD-SAME: RootElements{ +// CMD-SAME: RootUAV(u0, space = 0, visibility = All, flags = DataVolatile) +// CMD-SAME: } diff --git a/clang/test/SemaHLSL/RootSignature-target-err.hlsl b/clang/test/SemaHLSL/RootSignature-target-err.hlsl new file mode 100644 index 0000000000000..49aca9ed6b377 --- /dev/null +++ b/clang/test/SemaHLSL/RootSignature-target-err.hlsl @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-rootsignature -hlsl-entry NotFoundRS -fsyntax-only %s -verify + +// expected-error@* {{rootsignature specified as target environment but entry, NotFoundRS, was not defined}} + +#define EntryRootSig "CBV(b0)" >From 0033778084f517588382fb805f156cb0af76b27c Mon Sep 17 00:00:00 2001 From: Finn Plummer <[email protected]> Date: Mon, 1 Sep 2025 11:55:24 -0700 Subject: [PATCH 06/11] add support for generating the metadata --- clang/lib/CodeGen/CGHLSLRuntime.cpp | 28 ++++++++++++++----- clang/lib/CodeGen/CGHLSLRuntime.h | 2 ++ clang/lib/CodeGen/CodeGenModule.cpp | 2 +- .../CodeGenHLSL/RootSignature-Target.hlsl | 9 ++++++ 4 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 clang/test/CodeGenHLSL/RootSignature-Target.hlsl diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index f32d01ae78658..4370c0082ce7f 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -67,9 +67,9 @@ void addDxilValVersion(StringRef ValVersionStr, llvm::Module &M) { DXILValMD->addOperand(Val); } -void addRootSignature(llvm::dxbc::RootSignatureVersion RootSigVer, - ArrayRef<llvm::hlsl::rootsig::RootElement> Elements, - llvm::Function *Fn, llvm::Module &M) { +void addRootSignatureMD(llvm::dxbc::RootSignatureVersion RootSigVer, + ArrayRef<llvm::hlsl::rootsig::RootElement> Elements, + llvm::Function *Fn, llvm::Module &M) { auto &Ctx = M.getContext(); llvm::hlsl::rootsig::MetadataBuilder RSBuilder(Ctx, Elements); @@ -77,8 +77,8 @@ void addRootSignature(llvm::dxbc::RootSignatureVersion RootSigVer, ConstantAsMetadata *Version = ConstantAsMetadata::get(ConstantInt::get( llvm::Type::getInt32Ty(Ctx), llvm::to_underlying(RootSigVer))); - MDNode *MDVals = - MDNode::get(Ctx, {ValueAsMetadata::get(Fn), RootSignature, Version}); + ValueAsMetadata *EntryFunc = Fn ? ValueAsMetadata::get(Fn) : nullptr; + MDNode *MDVals = MDNode::get(Ctx, {EntryFunc, RootSignature, Version}); StringRef RootSignatureValKey = "dx.rootsignatures"; auto *RootSignatureValMD = M.getOrInsertNamedMetadata(RootSignatureValKey); @@ -381,6 +381,20 @@ void CGHLSLRuntime::addBuffer(const HLSLBufferDecl *BufDecl) { } } +void CGHLSLRuntime::addRootSignature( + const HLSLRootSignatureDecl *SignatureDecl) { + llvm::Module &M = CGM.getModule(); + Triple T(M.getTargetTriple()); + + // If we are not targeting a root signature enviornment then this decl will + // be generated when the function decl it is attached is handled + if (T.getEnvironment() != Triple::EnvironmentType::RootSignature) + return; + + addRootSignatureMD(SignatureDecl->getVersion(), + SignatureDecl->getRootElements(), nullptr, M); +} + llvm::TargetExtType * CGHLSLRuntime::getHLSLBufferLayoutType(const RecordType *StructType) { const auto Entry = LayoutTypes.find(StructType); @@ -584,8 +598,8 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD, for (const Attr *Attr : FD->getAttrs()) { if (const auto *RSAttr = dyn_cast<RootSignatureAttr>(Attr)) { auto *RSDecl = RSAttr->getSignatureDecl(); - addRootSignature(RSDecl->getVersion(), RSDecl->getRootElements(), EntryFn, - M); + addRootSignatureMD(RSDecl->getVersion(), RSDecl->getRootElements(), + EntryFn, M); } } } diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index b872f9ef0e9b6..613d0ad6bca5c 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -62,6 +62,7 @@ class VarDecl; class ParmVarDecl; class InitListExpr; class HLSLBufferDecl; +class HLSLRootSignatureDecl; class HLSLVkBindingAttr; class HLSLResourceBindingAttr; class Type; @@ -150,6 +151,7 @@ class CGHLSLRuntime { void generateGlobalCtorDtorCalls(); void addBuffer(const HLSLBufferDecl *D); + void addRootSignature(const HLSLRootSignatureDecl *D); void finishCodeGen(); void setHLSLEntryAttributes(const FunctionDecl *FD, llvm::Function *Fn); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 323823c964a79..f90a8196ecced 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -7535,7 +7535,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { break; case Decl::HLSLRootSignature: - // Will be handled by attached function + getHLSLRuntime().addRootSignature(cast<HLSLRootSignatureDecl>(D)); break; case Decl::HLSLBuffer: getHLSLRuntime().addBuffer(cast<HLSLBufferDecl>(D)); diff --git a/clang/test/CodeGenHLSL/RootSignature-Target.hlsl b/clang/test/CodeGenHLSL/RootSignature-Target.hlsl new file mode 100644 index 0000000000000..50e6bae6786f0 --- /dev/null +++ b/clang/test/CodeGenHLSL/RootSignature-Target.hlsl @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-rootsignature \ +// RUN: -hlsl-entry EntryRS -emit-llvm -o - %s | FileCheck %s + +// CHECK: !dx.rootsignatures = !{![[#ENTRY:]]} +// CHECK: ![[#ENTRY]] = !{null, ![[#ENTRY_RS:]], i32 2} +// CHECK: ![[#ENTRY_RS]] = !{![[#ROOT_CBV:]]} +// CHECK: ![[#ROOT_CBV]] = !{!"RootCBV", i32 0, i32 0, i32 0, i32 4} + +#define EntryRS "CBV(b0)" >From 34cce6b34ce52564344f1cab57aa9db8c83a91e4 Mon Sep 17 00:00:00 2001 From: Finn Plummer <[email protected]> Date: Mon, 1 Sep 2025 11:56:42 -0700 Subject: [PATCH 07/11] nfc: pull out handling of rs node --- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index 2436d3869464f..5b70e29a12073 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -72,11 +72,11 @@ analyzeModule(Module &M) { if (RootSignatureNode == nullptr) return RSDMap; - for (const auto &RSDefNode : RootSignatureNode->operands()) { + auto HandleNode = [&Ctx, &RSDMap](MDNode *RSDefNode) { if (RSDefNode->getNumOperands() != 3) { reportError(Ctx, "Invalid Root Signature metadata - expected function, " "signature, and version."); - continue; + return; } // Function was pruned during compilation. @@ -84,38 +84,38 @@ analyzeModule(Module &M) { if (FunctionPointerMdNode == nullptr) { reportError( Ctx, "Function associated with Root Signature definition is null."); - continue; + return; } ValueAsMetadata *VAM = llvm::dyn_cast<ValueAsMetadata>(FunctionPointerMdNode.get()); if (VAM == nullptr) { reportError(Ctx, "First element of root signature is not a Value"); - continue; + return; } Function *F = dyn_cast<Function>(VAM->getValue()); if (F == nullptr) { reportError(Ctx, "First element of root signature is not a Function"); - continue; + return; } Metadata *RootElementListOperand = RSDefNode->getOperand(1).get(); if (RootElementListOperand == nullptr) { reportError(Ctx, "Root Element mdnode is null."); - continue; + return; } MDNode *RootElementListNode = dyn_cast<MDNode>(RootElementListOperand); if (RootElementListNode == nullptr) { reportError(Ctx, "Root Element is not a metadata node."); - continue; + return; } std::optional<uint32_t> V = extractMdIntValue(RSDefNode, 2); if (!V.has_value()) { reportError(Ctx, "Invalid RSDefNode value, expected constant int"); - continue; + return; } llvm::hlsl::rootsig::MetadataParser MDParser(RootElementListNode); @@ -126,7 +126,7 @@ analyzeModule(Module &M) { handleAllErrors(RSDOrErr.takeError(), [&](ErrorInfoBase &EIB) { Ctx->emitError(EIB.message()); }); - continue; + return; } auto &RSD = *RSDOrErr; @@ -140,8 +140,12 @@ analyzeModule(Module &M) { RSD.StaticSamplersOffset = 0u; RSDMap.insert(std::make_pair(F, RSD)); + }; } + for (MDNode *RSDefNode : RootSignatureNode->operands()) + HandleNode(RSDefNode); + return RSDMap; } >From 229aa65013160ec062126d09c9ae168ba834fefc Mon Sep 17 00:00:00 2001 From: Finn Plummer <[email protected]> Date: Fri, 29 Aug 2025 15:38:09 -0700 Subject: [PATCH 08/11] add support constructing dxcontainer for rootsignature without entry function --- llvm/include/llvm/BinaryFormat/DXContainer.h | 2 +- .../lib/Target/DirectX/DXContainerGlobals.cpp | 16 +++++-- llvm/lib/Target/DirectX/DXILRootSignature.cpp | 46 +++++++++++-------- 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h index f74c9775cb3f3..0547d96a8dec7 100644 --- a/llvm/include/llvm/BinaryFormat/DXContainer.h +++ b/llvm/include/llvm/BinaryFormat/DXContainer.h @@ -45,7 +45,7 @@ namespace dxbc { LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); inline Triple::EnvironmentType getShaderStage(uint32_t Kind) { - assert(Kind <= Triple::Amplification - Triple::Pixel && + assert(Kind <= Triple::RootSignature - Triple::Pixel && "Shader kind out of expected range."); return static_cast<Triple::EnvironmentType>(Triple::Pixel + Kind); } diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp index a1ef2578f00aa..37c58e041f4df 100644 --- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp +++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp @@ -158,10 +158,14 @@ void DXContainerGlobals::addRootSignature(Module &M, if (MMI.ShaderProfile == llvm::Triple::Library) return; - assert(MMI.EntryPropertyVec.size() == 1); - auto &RSA = getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo(); - const Function *EntryFunction = MMI.EntryPropertyVec[0].Entry; + const Function *EntryFunction = nullptr; + + if (MMI.ShaderProfile != llvm::Triple::RootSignature) { + assert(MMI.EntryPropertyVec.size() == 1); + EntryFunction = MMI.EntryPropertyVec[0].Entry; + } + const mcdxbc::RootSignatureDesc *RS = RSA.getDescForFunction(EntryFunction); if (!RS) @@ -258,7 +262,8 @@ void DXContainerGlobals::addPipelineStateValidationInfo( dxil::ModuleMetadataInfo &MMI = getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata(); assert(MMI.EntryPropertyVec.size() == 1 || - MMI.ShaderProfile == Triple::Library); + MMI.ShaderProfile == Triple::Library || + MMI.ShaderProfile == Triple::RootSignature); PSV.BaseData.ShaderStage = static_cast<uint8_t>(MMI.ShaderProfile - Triple::Pixel); @@ -279,7 +284,8 @@ void DXContainerGlobals::addPipelineStateValidationInfo( break; } - if (MMI.ShaderProfile != Triple::Library) + if (MMI.ShaderProfile != Triple::Library && + MMI.ShaderProfile != Triple::RootSignature) PSV.EntryName = MMI.EntryPropertyVec[0].Entry->getName(); PSV.finalize(MMI.ShaderProfile); diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp index 5b70e29a12073..8db9436eabc57 100644 --- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp +++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp @@ -72,32 +72,35 @@ analyzeModule(Module &M) { if (RootSignatureNode == nullptr) return RSDMap; - auto HandleNode = [&Ctx, &RSDMap](MDNode *RSDefNode) { + auto HandleNode = [&Ctx, &RSDMap](MDNode *RSDefNode, bool NullFunc = false) { if (RSDefNode->getNumOperands() != 3) { reportError(Ctx, "Invalid Root Signature metadata - expected function, " "signature, and version."); return; } - // Function was pruned during compilation. - const MDOperand &FunctionPointerMdNode = RSDefNode->getOperand(0); - if (FunctionPointerMdNode == nullptr) { - reportError( - Ctx, "Function associated with Root Signature definition is null."); - return; - } + Function *F = nullptr; + if (!NullFunc) { + // Function was pruned during compilation. + const MDOperand &FunctionPointerMdNode = RSDefNode->getOperand(0); + if (FunctionPointerMdNode == nullptr) { + reportError( + Ctx, "Function associated with Root Signature definition is null."); + return; + } - ValueAsMetadata *VAM = - llvm::dyn_cast<ValueAsMetadata>(FunctionPointerMdNode.get()); - if (VAM == nullptr) { - reportError(Ctx, "First element of root signature is not a Value"); - return; - } + ValueAsMetadata *VAM = + llvm::dyn_cast<ValueAsMetadata>(FunctionPointerMdNode.get()); + if (VAM == nullptr) { + reportError(Ctx, "First element of root signature is not a Value"); + return; + } - Function *F = dyn_cast<Function>(VAM->getValue()); - if (F == nullptr) { - reportError(Ctx, "First element of root signature is not a Function"); - return; + F = dyn_cast<Function>(VAM->getValue()); + if (F == nullptr) { + reportError(Ctx, "First element of root signature is not a Function"); + return; + } } Metadata *RootElementListOperand = RSDefNode->getOperand(1).get(); @@ -141,6 +144,13 @@ analyzeModule(Module &M) { RSDMap.insert(std::make_pair(F, RSD)); }; + + if (M.getTargetTriple().getEnvironment() == + Triple::EnvironmentType::RootSignature) { + assert(RootSignatureNode->getNumOperands() == 1); + MDNode *RSDefNode = RootSignatureNode->getOperand(0); + HandleNode(RSDefNode, true); + return RSDMap; } for (MDNode *RSDefNode : RootSignatureNode->operands()) >From 028a74a38805a8a8d4bf81046edbce155813ddfe Mon Sep 17 00:00:00 2001 From: Finn Plummer <[email protected]> Date: Mon, 1 Sep 2025 12:39:50 -0700 Subject: [PATCH 09/11] nfc: extract intermediate parse profile step --- clang/lib/Driver/ToolChains/HLSL.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp index 304c367cc4367..0c96935ba93b7 100644 --- a/clang/lib/Driver/ToolChains/HLSL.cpp +++ b/clang/lib/Driver/ToolChains/HLSL.cpp @@ -70,7 +70,7 @@ bool isLegalShaderModel(Triple &T) { return false; } -std::optional<std::string> tryParseProfile(StringRef Profile) { +std::optional<llvm::Triple> tryParseTriple(StringRef Profile) { // [ps|vs|gs|hs|ds|cs|ms|as]_[major]_[minor] SmallVector<StringRef, 3> Parts; Profile.split(Parts, "_"); @@ -149,8 +149,14 @@ std::optional<std::string> tryParseProfile(StringRef Profile) { T.setOSName(Triple::getOSTypeName(Triple::OSType::ShaderModel).str() + VersionTuple(Major, Minor).getAsString()); T.setEnvironment(Kind); - if (isLegalShaderModel(T)) - return T.getTriple(); + + return T; +} + +std::optional<std::string> tryParseProfile(StringRef Profile) { + std::optional<llvm::Triple> MaybeT = tryParseTriple(Profile); + if (MaybeT && isLegalShaderModel(*MaybeT)) + return MaybeT->getTriple(); else return std::nullopt; } >From 060eae14a68056e2ffc082608244da03137d4c5f Mon Sep 17 00:00:00 2001 From: Finn Plummer <[email protected]> Date: Mon, 1 Sep 2025 12:40:20 -0700 Subject: [PATCH 10/11] add invocation to just emit root signature of dxcontainer --- clang/lib/Driver/ToolChains/HLSL.cpp | 22 ++++++++++++++++++- .../test/Driver/dxc_rootsignature_target.hlsl | 8 +++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 clang/test/Driver/dxc_rootsignature_target.hlsl diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp index 0c96935ba93b7..543ab268540da 100644 --- a/clang/lib/Driver/ToolChains/HLSL.cpp +++ b/clang/lib/Driver/ToolChains/HLSL.cpp @@ -266,6 +266,19 @@ bool checkExtensionArgsAreValid(ArrayRef<std::string> SpvExtensionArgs, } return AllValid; } + +bool isRootSignatureTarget(StringRef Profile) { + if (std::optional<llvm::Triple> T = tryParseTriple(Profile)) + return T->getEnvironment() == Triple::EnvironmentType::RootSignature; + return false; +} + +bool isRootSignatureTarget(DerivedArgList &Args) { + if (const Arg *A = Args.getLastArg(options::OPT_target_profile)) + return isRootSignatureTarget(A->getValue()); + return false; +} + } // namespace void tools::hlsl::Validator::ConstructJob(Compilation &C, const JobAction &JA, @@ -325,6 +338,12 @@ void tools::hlsl::LLVMObjcopy::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Frs); } + if (const Arg *A = Args.getLastArg(options::OPT_target_profile)) + if (isRootSignatureTarget(A->getValue())) { + const char *Fos = Args.MakeArgString("--only-section=RTS0"); + CmdArgs.push_back(Fos); + } + assert(CmdArgs.size() > 2 && "Unnecessary invocation of objcopy."); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), @@ -501,7 +520,8 @@ bool HLSLToolChain::requiresBinaryTranslation(DerivedArgList &Args) const { bool HLSLToolChain::requiresObjcopy(DerivedArgList &Args) const { return Args.hasArg(options::OPT_dxc_Fo) && - Args.hasArg(options::OPT_dxc_strip_rootsignature); + (Args.hasArg(options::OPT_dxc_strip_rootsignature) || + isRootSignatureTarget(Args)); } bool HLSLToolChain::isLastJob(DerivedArgList &Args, diff --git a/clang/test/Driver/dxc_rootsignature_target.hlsl b/clang/test/Driver/dxc_rootsignature_target.hlsl new file mode 100644 index 0000000000000..a732c50507cdb --- /dev/null +++ b/clang/test/Driver/dxc_rootsignature_target.hlsl @@ -0,0 +1,8 @@ +// RUN: %clang_dxc -E EntryRS -T rootsig_1_1 /Fo %t.dxo -### %s 2>&1 | FileCheck %s --check-prefix=CMDS + +// CMDS: "{{.*}}clang{{.*}}" "-cc1" +// CMDS-SAME: "-triple" "dxilv1.1-unknown-shadermodel1.1-rootsignature" +// CMDS-SAME: "-hlsl-entry" "EntryRS" +// CMDS: "{{.*}}llvm-objcopy{{(.exe)?}}" "{{.*}}.dxo" "--only-section=RTS0" + +#define EntryRS "CBV(b0)" >From 50d72e692c0d45134422956fff10e779ce822b7f Mon Sep 17 00:00:00 2001 From: Finn Plummer <[email protected]> Date: Mon, 1 Sep 2025 12:57:54 -0700 Subject: [PATCH 11/11] add clang_dxc test to demonstrate lexing bug --- clang/lib/Parse/ParseHLSLRootSignature.cpp | 4 +++ .../test/Driver/dxc_rootsignature_target.hlsl | 34 ++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp index 4e5b8b83200e0..91976489ee660 100644 --- a/clang/lib/Parse/ParseHLSLRootSignature.cpp +++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp @@ -1488,6 +1488,10 @@ void HandleRootSignatureTarget(Sema &S, StringRef EntryRootSig) { P->Initialize(); S.ActOnStartOfTranslationUnit(); + // Skim through the file to parse to find the define + while (P->getCurToken().getKind() != tok::eof) + P->ConsumeAnyToken(); + HLSLRootSignatureDecl *SignatureDecl = S.HLSL().lookupRootSignatureOverrideDecl( S.getASTContext().getTranslationUnitDecl()); diff --git a/clang/test/Driver/dxc_rootsignature_target.hlsl b/clang/test/Driver/dxc_rootsignature_target.hlsl index a732c50507cdb..011fa4be9050d 100644 --- a/clang/test/Driver/dxc_rootsignature_target.hlsl +++ b/clang/test/Driver/dxc_rootsignature_target.hlsl @@ -1,8 +1,40 @@ // RUN: %clang_dxc -E EntryRS -T rootsig_1_1 /Fo %t.dxo -### %s 2>&1 | FileCheck %s --check-prefix=CMDS +// RUN: %clang_dxc -E EntryRS -T rootsig_1_1 /Fo %t.dxo %s +// RUN: obj2yaml %t.dxo | FileCheck %s --check-prefix=OBJ + // CMDS: "{{.*}}clang{{.*}}" "-cc1" // CMDS-SAME: "-triple" "dxilv1.1-unknown-shadermodel1.1-rootsignature" // CMDS-SAME: "-hlsl-entry" "EntryRS" // CMDS: "{{.*}}llvm-objcopy{{(.exe)?}}" "{{.*}}.dxo" "--only-section=RTS0" -#define EntryRS "CBV(b0)" +#define EntryRS "UAV(u0)" + +// OBJ: --- !dxcontainer +// FileSize = 32 (header) + 48 (RTS0 content) + 4 (1 part offset) + 8 (1 part header) +// OBJ: FileSize: 92 +// OBJ-NEXT: PartCount: 1 +// OBJ-NEXT: PartOffsets: [ 36 ] +// OBJ-NEXT: Parts: +// OBJ-NOT: DXIL +// OBJ-NOT: SFI0 +// OBJ-NOT: HASH +// OBJ-NOT: ISG0 +// OBJ-NOT: OSG0 + +// OBJ: - Name: RTS0 +// OBJ-NEXT: Size: 48 +// OBJ-NEXT: RootSignature: +// OBJ-NEXT: Version: 2 +// OBJ-NEXT: NumRootParameters: 1 +// OBJ-NEXT: RootParametersOffset: 24 + +// OBJ: Parameters: +// UAV(u0) +// OBJ: - ParameterType: 4 +// OBJ-NEXT: ShaderVisibility: 0 +// OBJ-NEXT: Descriptor: +// OBJ-NEXT: RegisterSpace: 0 +// OBJ-NEXT: ShaderRegister: 0 + +// OBJ-NOT: PSV0 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
