Skip to content

Reland "[HLSL][RootSignature] Define and integrate HLSLRootSignatureAttr" #134293

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

Closed
wants to merge 2 commits into from

Conversation

inbelic
Copy link
Contributor

@inbelic inbelic commented Apr 3, 2025

This pr relands #134124.

It resolves the many linking errors during build, here. There was a missing dependency for clangParse in clangSema now that we depend on clangParse to get acces to the RootSignatureParser during semantic analysis. This library was added to the dependencies to resolve the error. It wasn't caught previously as the library was transitively linked in local and pre-merge build environments.

Resolves #119011

Finn Plummer added 2 commits April 3, 2025 17:22
- Defines HLSLRootSignature Attr in `Attr.td`
- Define and implement handleHLSLRootSignature in `SemaHLSL`
- Adds sample test case to show AST Node is generated in
`RootSignatures-AST.hlsl`

This commit will "hook-up" the seperately defined RootSignature parser
and invoke it to create the RootElements, then store them on the
ASTContext and finally store the reference to the Elements in
RootSignatureAttr
we require access to the RootSignatureParser/Lexer which are located in
clang/parse and clang/lex respectively.

clangLex is already listed as a linked library whereas clangParse isn't
so this commit resolves this issue by linking the clangParse library
to provide access to RootSignatureParser
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" HLSL HLSL Language Support labels Apr 3, 2025
@inbelic inbelic force-pushed the inbelic/rootsig-attr branch from 6d46d30 to 7d4e84c Compare April 3, 2025 19:05
@llvmbot
Copy link
Member

llvmbot commented Apr 3, 2025

@llvm/pr-subscribers-hlsl

@llvm/pr-subscribers-clang

Author: Finn Plummer (inbelic)

Changes

This pr relands #134124.

It resolves the many linking errors during build, here. There was a missing dependency for clangParse in clangSema now that we depend on clangParse to get acces to the RootSignatureParser during semantic analysis. This library was added to the dependencies to resolve the error. It wasn't caught previously as the library was transitively linked in local and pre-merge build environments


Full diff: https://github.com/llvm/llvm-project/pull/134293.diff

9 Files Affected:

  • (modified) clang/include/clang/AST/Attr.h (+1)
  • (modified) clang/include/clang/Basic/Attr.td (+19)
  • (modified) clang/include/clang/Basic/AttrDocs.td (+11)
  • (modified) clang/include/clang/Sema/SemaHLSL.h (+1)
  • (modified) clang/lib/Sema/CMakeLists.txt (+1)
  • (modified) clang/lib/Sema/SemaDeclAttr.cpp (+3)
  • (modified) clang/lib/Sema/SemaHLSL.cpp (+35)
  • (added) clang/test/AST/HLSL/RootSignatures-AST.hlsl (+24)
  • (added) clang/test/SemaHLSL/RootSignature-err.hlsl (+9)
diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h
index 994f236337b99..37c3f8bbfb5f9 100644
--- a/clang/include/clang/AST/Attr.h
+++ b/clang/include/clang/AST/Attr.h
@@ -26,6 +26,7 @@
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Support/Compiler.h"
 #include "llvm/Frontend/HLSL/HLSLResource.h"
+#include "llvm/Frontend/HLSL/HLSLRootSignature.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/VersionTuple.h"
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 0999d8065e9f5..93524a0c873c1 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -4709,6 +4709,25 @@ def Error : InheritableAttr {
   let Documentation = [ErrorAttrDocs];
 }
 
+def HLSLRootSignature : Attr {
+  /// [RootSignature(Signature)]
+  let Spellings = [Microsoft<"RootSignature">];
+  let Args = [StringArgument<"Signature">];
+  let Subjects = SubjectList<[Function],
+                             ErrorDiag, "'function'">;
+  let LangOpts = [HLSL];
+  let Documentation = [HLSLRootSignatureDocs];
+  let AdditionalMembers = [{
+private:
+  ArrayRef<llvm::hlsl::rootsig::RootElement> RootElements;
+public:
+  void setElements(ArrayRef<llvm::hlsl::rootsig::RootElement> Elements) {
+    RootElements = Elements;
+  }
+  auto getElements() const { return RootElements; }
+}];
+}
+
 def HLSLNumThreads: InheritableAttr {
   let Spellings = [Microsoft<"numthreads">];
   let Args = [IntArgument<"X">, IntArgument<"Y">, IntArgument<"Z">];
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index a52ece467ec70..2ac9e2a4eaf39 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -8143,6 +8143,17 @@ and https://microsoft.github.io/hlsl-specs/proposals/0013-wave-size-range.html
   }];
 }
 
+def HLSLRootSignatureDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``RootSignature`` attribute applies to HLSL entry functions to define what
+types of resources are bound to the graphics pipeline.
+
+For details about the use and specification of Root Signatures please see here:
+https://learn.microsoft.com/en-us/windows/win32/direct3d12/root-signatures
+  }];
+}
+
 def NumThreadsDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h
index f333fe30e8da0..1bd35332612cd 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -118,6 +118,7 @@ class SemaHLSL : public SemaBase {
                                        bool IsCompAssign);
   void emitLogicalOperatorFixIt(Expr *LHS, Expr *RHS, BinaryOperatorKind Opc);
 
+  void handleRootSignatureAttr(Decl *D, const ParsedAttr &AL);
   void handleNumThreadsAttr(Decl *D, const ParsedAttr &AL);
   void handleWaveSizeAttr(Decl *D, const ParsedAttr &AL);
   void handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL);
diff --git a/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt
index d3fe80f659f69..4a25d61e06409 100644
--- a/clang/lib/Sema/CMakeLists.txt
+++ b/clang/lib/Sema/CMakeLists.txt
@@ -110,5 +110,6 @@ add_clang_library(clangSema
   clangBasic
   clangEdit
   clangLex
+  clangParse
   clangSupport
   )
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 6cb6f6d105a32..60b8c98eeec0d 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -7480,6 +7480,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
     break;
 
   // HLSL attributes:
+  case ParsedAttr::AT_HLSLRootSignature:
+    S.HLSL().handleRootSignatureAttr(D, AL);
+    break;
   case ParsedAttr::AT_HLSLNumThreads:
     S.HLSL().handleNumThreadsAttr(D, AL);
     break;
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 07d03e2c58b9a..eafb2b97d7db1 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -28,6 +28,7 @@
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/Parse/ParseHLSLRootSignature.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/ParsedAttr.h"
 #include "clang/Sema/Sema.h"
@@ -941,6 +942,40 @@ void SemaHLSL::emitLogicalOperatorFixIt(Expr *LHS, Expr *RHS,
       << NewFnName << FixItHint::CreateReplacement(FullRange, OS.str());
 }
 
+void SemaHLSL::handleRootSignatureAttr(Decl *D, const ParsedAttr &AL) {
+  if (AL.getNumArgs() != 1) {
+    Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
+    return;
+  }
+
+  StringRef Signature;
+  if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, Signature))
+    return;
+
+  SourceLocation Loc = AL.getArgAsExpr(0)->getExprLoc();
+  // TODO(#126565): pass down below to lexer when fp is supported
+  // llvm::RoundingMode RM = SemaRef.CurFPFeatures.getRoundingMode();
+  hlsl::RootSignatureLexer Lexer(Signature, Loc);
+  SmallVector<llvm::hlsl::rootsig::RootElement> Elements;
+  hlsl::RootSignatureParser Parser(Elements, Lexer, SemaRef.getPreprocessor());
+
+  if (Parser.parse())
+    return;
+
+  // Allocate elements onto AST context
+  unsigned N = Elements.size();
+  auto RootElements = MutableArrayRef<llvm::hlsl::rootsig::RootElement>(
+      ::new (getASTContext()) llvm::hlsl::rootsig::RootElement[N], N);
+  for (unsigned I = 0; I < N; ++I)
+    RootElements[I] = Elements[I];
+
+  // Set elements
+  auto *Result = ::new (getASTContext())
+      HLSLRootSignatureAttr(getASTContext(), AL, Signature);
+  Result->setElements(ArrayRef<llvm::hlsl::rootsig::RootElement>(RootElements));
+  D->addAttr(Result);
+}
+
 void SemaHLSL::handleNumThreadsAttr(Decl *D, const ParsedAttr &AL) {
   llvm::VersionTuple SMVersion =
       getASTContext().getTargetInfo().getTriple().getOSVersion();
diff --git a/clang/test/AST/HLSL/RootSignatures-AST.hlsl b/clang/test/AST/HLSL/RootSignatures-AST.hlsl
new file mode 100644
index 0000000000000..948f2484ff5d0
--- /dev/null
+++ b/clang/test/AST/HLSL/RootSignatures-AST.hlsl
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -ast-dump \
+// RUN:  -disable-llvm-passes -o - %s | FileCheck %s
+
+// This test ensures that the sample root signature is parsed without error and
+// the Attr AST Node is created succesfully. If an invalid root signature was
+// passed in then we would exit out of Sema before the Attr is created.
+
+#define SampleRS \
+  "DescriptorTable( " \
+  "  CBV(), " \
+  "  SRV(), " \
+  "  UAV()" \
+  "), " \
+  "DescriptorTable(Sampler())"
+
+// CHECK:      HLSLRootSignatureAttr
+// CHECK-SAME: "DescriptorTable(
+// CHECK-SAME:   CBV(),
+// CHECK-SAME:   SRV(),
+// CHECK-SAME:   UAV()
+// CHECK-SAME: ),
+// CHECK-SAME: DescriptorTable(Sampler())"
+[RootSignature(SampleRS)]
+void main() {}
diff --git a/clang/test/SemaHLSL/RootSignature-err.hlsl b/clang/test/SemaHLSL/RootSignature-err.hlsl
new file mode 100644
index 0000000000000..647a4ba2470a7
--- /dev/null
+++ b/clang/test/SemaHLSL/RootSignature-err.hlsl
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -o - %s -verify
+
+// Attr test
+
+[RootSignature()] // expected-error {{'RootSignature' attribute takes one argument}}
+void bad_root_signature_0() {}
+
+[RootSignature("Arg1", "Arg2")] // expected-error {{'RootSignature' attribute takes one argument}}
+void bad_root_signature_1() {}

Copy link
Contributor

@spall spall left a comment

Choose a reason for hiding this comment

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

LGTM based on previous pr approval and looking at the change in the latest reland commit

@inbelic
Copy link
Contributor Author

inbelic commented Apr 24, 2025

Closing as this would actually introduce a circular dependency between clangParse and clangSema, as surprisingly, clangParse has a dependency on clangSema. This will need to reland after we move the HLSLRootSignatureParser into an accessible location (most likely within clangSema itself)

@inbelic inbelic closed this Apr 24, 2025
@inbelic inbelic deleted the inbelic/rootsig-attr branch May 16, 2025 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category HLSL HLSL Language Support
Projects
Status: Closed
Development

Successfully merging this pull request may close these issues.

[HLSL] Generate AST for Root Signatures
4 participants