python3kgae created this revision.
python3kgae added reviewers: beanz, pow2clk, bogner.
Herald added a reviewer: aaron.ballman.
Herald added a subscriber: Anastasia.
Herald added a project: All.
python3kgae requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Support SV_DispatchThreadID attribute.
Translate it into dx.thread.id in clang codeGen.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D133983

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/lib/CodeGen/CGHLSLRuntime.cpp
  clang/lib/CodeGen/CGHLSLRuntime.h
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl

Index: clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl
===================================================================
--- /dev/null
+++ clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s
+
+// Make sure SV_DispatchThreadID translated into dx.thread.id.
+
+const RWBuffer<float> In;
+RWBuffer<float> Out;
+
+// CHECK: define void @foo()
+// CHECK: call i32 @llvm.dx.thread.id(i32 0)
+// CHECK: call void @"?foo@@YAXH@Z"(i32 %{{.*}})
+[shader("compute")]
+[numthreads(8,8,1)]
+void foo(int Idx : SV_DispatchThreadID) {
+  Out[Idx] = In[Idx];
+}
+
+// CHECK: define void @bar()
+// CHECK: call i32 @llvm.dx.thread.id(i32 0)
+// CHECK: call i32 @llvm.dx.thread.id(i32 1)
+// CHECK: call void @"?bar@@YAXT?$__vector@H$01@__clang@@@Z"(<2 x i32> %{{.*}})
+[shader("compute")]
+[numthreads(8,8,1)]
+void bar(int2 Idx : SV_DispatchThreadID) {
+  Out[Idx.y] = In[Idx.x];
+}
+
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -6907,6 +6907,25 @@
   D->addAttr(::new (S.Context) HLSLSV_GroupIndexAttr(S.Context, AL));
 }
 
+static void handleHLSLSV_DispatchThreadIDAttr(Sema &S, Decl *D,
+                                              const ParsedAttr &AL) {
+  using llvm::Triple;
+  Triple Target = S.Context.getTargetInfo().getTriple();
+  // FIXME: it is OK for a compute shader entry and pixiel shader entry live in
+  // same HLSL file.
+  if (Target.getEnvironment() != Triple::Compute &&
+      Target.getEnvironment() != Triple::Library) {
+    uint32_t Pipeline =
+        (uint32_t)S.Context.getTargetInfo().getTriple().getEnvironment() -
+        (uint32_t)llvm::Triple::Pixel;
+    S.Diag(AL.getLoc(), diag::err_hlsl_attr_unsupported_in_stage)
+        << AL << Pipeline << "Compute";
+    return;
+  }
+
+  D->addAttr(::new (S.Context) HLSLSV_DispatchThreadIDAttr(S.Context, AL));
+}
+
 static void handleHLSLShaderAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   StringRef Str;
   SourceLocation ArgLoc;
@@ -8920,6 +8939,9 @@
   case ParsedAttr::AT_HLSLSV_GroupIndex:
     handleHLSLSVGroupIndexAttr(S, D, AL);
     break;
+  case ParsedAttr::AT_HLSLSV_DispatchThreadID:
+    handleHLSLSV_DispatchThreadIDAttr(S, D, AL);
+    break;
   case ParsedAttr::AT_HLSLShader:
     handleHLSLShaderAttr(S, D, AL);
     break;
Index: clang/lib/CodeGen/CGHLSLRuntime.h
===================================================================
--- clang/lib/CodeGen/CGHLSLRuntime.h
+++ clang/lib/CodeGen/CGHLSLRuntime.h
@@ -39,7 +39,8 @@
   uint32_t ResourceCounters[static_cast<uint32_t>(
       hlsl::ResourceClass::NumClasses)] = {0};
 
-  llvm::Value *emitInputSemantic(llvm::IRBuilder<> &B, const ParmVarDecl &D);
+  llvm::Value *emitInputSemantic(llvm::IRBuilder<> &B, const ParmVarDecl &D,
+                                 llvm::Type *Ty);
 
 public:
   CGHLSLRuntime(CodeGenModule &CGM) : CGM(CGM) {}
Index: clang/lib/CodeGen/CGHLSLRuntime.cpp
===================================================================
--- clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -109,14 +109,32 @@
                 ShaderAttr->ConvertShaderTypeToStr(ShaderAttr->getType()));
 }
 
+static Value *buildVectorInput(IRBuilder<> &B, Function *F, llvm::Type *Ty) {
+  if (FixedVectorType *VT = dyn_cast<FixedVectorType>(Ty)) {
+    Value *Result = PoisonValue::get(Ty);
+    for (unsigned I = 0; I < VT->getNumElements(); ++I) {
+      Value *Elt = B.CreateCall(F, {B.getInt32(I)});
+      Result = B.CreateInsertElement(Result, Elt, I);
+    }
+    return Result;
+  } else
+    return B.CreateCall(F, {B.getInt32(0)});
+}
+
 llvm::Value *CGHLSLRuntime::emitInputSemantic(IRBuilder<> &B,
-                                              const ParmVarDecl &D) {
+                                              const ParmVarDecl &D,
+                                              llvm::Type *Ty) {
   assert(D.hasAttrs() && "Entry parameter missing annotation attribute!");
   if (D.hasAttr<HLSLSV_GroupIndexAttr>()) {
     llvm::Function *DxGroupIndex =
         CGM.getIntrinsic(Intrinsic::dx_flattened_thread_id_in_group);
     return B.CreateCall(FunctionCallee(DxGroupIndex));
   }
+  if (D.hasAttr<HLSLSV_DispatchThreadIDAttr>()) {
+    llvm::Function *DxThreadID = CGM.getIntrinsic(Intrinsic::dx_thread_id);
+    // dx_thread_id
+    return buildVectorInput(B, DxThreadID, Ty);
+  }
   assert(false && "Unhandled parameter attribute");
   return nullptr;
 }
@@ -143,8 +161,16 @@
   IRBuilder<> B(BB);
   llvm::SmallVector<Value *> Args;
   // FIXME: support struct parameters where semantics are on members.
-  for (const auto *Param : FD->parameters()) {
-    Args.push_back(emitInputSemantic(B, *Param));
+  llvm::FunctionType *FnTy = Fn->getFunctionType();
+  unsigned SRetOffset = 0;
+  for (const auto &Param : Fn->args()) {
+    if (Param.hasStructRetAttr()) {
+      // FIXME: support output.
+      SRetOffset = 1;
+      continue;
+    }
+    const ParmVarDecl *PD = FD->getParamDecl(Param.getArgNo() - SRetOffset);
+    Args.push_back(emitInputSemantic(B, *PD, Param.getType()));
   }
 
   CallInst *CI = B.CreateCall(FunctionCallee(Fn), Args);
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -6567,6 +6567,17 @@
   }];
 }
 
+def HLSLSV_DispatchThreadIDDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``SV_DispatchThreadID`` semantic, when applied to an input parameter, specifies a
+data binding to map global thread offset within the Dispatch call(per dimension of the group) to the specified parameter.
+This attribute is only supported in compute shaders.
+
+The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sv-dispatchthreadid
+  }];
+}
+
 def AnnotateTypeDocs : Documentation {
   let Category = DocCatType;
   let Heading = "annotate_type";
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -4031,6 +4031,13 @@
   let Documentation = [HLSLSV_GroupIndexDocs];
 }
 
+def HLSLSV_DispatchThreadID: HLSLAnnotationAttr {
+  let Spellings = [HLSLSemantic<"SV_DispatchThreadID">];
+  let Subjects = SubjectList<[ParmVar, GlobalVar]>;
+  let LangOpts = [HLSL];
+  let Documentation = [HLSLSV_DispatchThreadIDDocs];
+}
+
 def HLSLShader : InheritableAttr {
   let Spellings = [Microsoft<"shader">];
   let Subjects = SubjectList<[HLSLEntry]>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to