Skip to content

Commit 9d5ffe0

Browse files
committed
[HLSL] Implement SV_GroupThreadId semantic
Support SV_GroupThreadId attribute. Translate it into dx.thread.id.in.group in clang codeGen. Fixes: #70122
1 parent 78c7024 commit 9d5ffe0

File tree

11 files changed

+125
-5
lines changed

11 files changed

+125
-5
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4621,6 +4621,13 @@ def HLSLNumThreads: InheritableAttr {
46214621
let Documentation = [NumThreadsDocs];
46224622
}
46234623

4624+
def HLSLSV_GroupThreadID: HLSLAnnotationAttr {
4625+
let Spellings = [HLSLAnnotation<"SV_GroupThreadID">];
4626+
let Subjects = SubjectList<[ParmVar, Field]>;
4627+
let LangOpts = [HLSL];
4628+
let Documentation = [HLSLSV_GroupThreadIDDocs];
4629+
}
4630+
46244631
def HLSLSV_GroupID: HLSLAnnotationAttr {
46254632
let Spellings = [HLSLAnnotation<"SV_GroupID">];
46264633
let Subjects = SubjectList<[ParmVar, Field]>;

clang/include/clang/Basic/AttrDocs.td

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7934,6 +7934,17 @@ randomized.
79347934
}];
79357935
}
79367936

7937+
def HLSLSV_GroupThreadIDDocs : Documentation {
7938+
let Category = DocCatFunction;
7939+
let Content = [{
7940+
The ``SV_GroupThreadID`` semantic, when applied to an input parameter, specifies which
7941+
individual thread within a thread group is executing in. This attribute is
7942+
only supported in compute shaders.
7943+
7944+
The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sv-groupthreadid
7945+
}];
7946+
}
7947+
79377948
def HLSLSV_GroupIDDocs : Documentation {
79387949
let Category = DocCatFunction;
79397950
let Content = [{

clang/include/clang/Sema/SemaHLSL.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class SemaHLSL : public SemaBase {
119119
void handleNumThreadsAttr(Decl *D, const ParsedAttr &AL);
120120
void handleWaveSizeAttr(Decl *D, const ParsedAttr &AL);
121121
void handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL);
122+
void handleSV_GroupThreadIDAttr(Decl *D, const ParsedAttr &AL);
122123
void handleSV_GroupIDAttr(Decl *D, const ParsedAttr &AL);
123124
void handlePackOffsetAttr(Decl *D, const ParsedAttr &AL);
124125
void handleShaderAttr(Decl *D, const ParsedAttr &AL);

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,11 @@ llvm::Value *CGHLSLRuntime::emitInputSemantic(IRBuilder<> &B,
389389
CGM.getIntrinsic(getThreadIdIntrinsic());
390390
return buildVectorInput(B, ThreadIDIntrinsic, Ty);
391391
}
392+
if (D.hasAttr<HLSLSV_GroupThreadIDAttr>()) {
393+
llvm::Function *GroupThreadIDIntrinsic =
394+
CGM.getIntrinsic(Intrinsic::dx_thread_id_in_group);
395+
return buildVectorInput(B, GroupThreadIDIntrinsic, Ty);
396+
}
392397
if (D.hasAttr<HLSLSV_GroupIDAttr>()) {
393398
llvm::Function *GroupIDIntrinsic = CGM.getIntrinsic(Intrinsic::dx_group_id);
394399
return buildVectorInput(B, GroupIDIntrinsic, Ty);

clang/lib/Parse/ParseHLSL.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs,
280280
case ParsedAttr::UnknownAttribute:
281281
Diag(Loc, diag::err_unknown_hlsl_semantic) << II;
282282
return;
283+
case ParsedAttr::AT_HLSLSV_GroupThreadID:
283284
case ParsedAttr::AT_HLSLSV_GroupID:
284285
case ParsedAttr::AT_HLSLSV_GroupIndex:
285286
case ParsedAttr::AT_HLSLSV_DispatchThreadID:

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7103,6 +7103,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
71037103
case ParsedAttr::AT_HLSLWaveSize:
71047104
S.HLSL().handleWaveSizeAttr(D, AL);
71057105
break;
7106+
case ParsedAttr::AT_HLSLSV_GroupThreadID:
7107+
S.HLSL().handleSV_GroupThreadIDAttr(D, AL);
7108+
break;
71067109
case ParsedAttr::AT_HLSLSV_GroupID:
71077110
S.HLSL().handleSV_GroupIDAttr(D, AL);
71087111
break;

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ void SemaHLSL::CheckSemanticAnnotation(
434434
switch (AnnotationAttr->getKind()) {
435435
case attr::HLSLSV_DispatchThreadID:
436436
case attr::HLSLSV_GroupIndex:
437+
case attr::HLSLSV_GroupThreadID:
437438
case attr::HLSLSV_GroupID:
438439
if (ST == llvm::Triple::Compute)
439440
return;
@@ -787,6 +788,15 @@ void SemaHLSL::handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL) {
787788
HLSLSV_DispatchThreadIDAttr(getASTContext(), AL));
788789
}
789790

791+
void SemaHLSL::handleSV_GroupThreadIDAttr(Decl *D, const ParsedAttr &AL) {
792+
auto *VD = cast<ValueDecl>(D);
793+
if (!diagnoseInputIDType(VD->getType(), AL))
794+
return;
795+
796+
D->addAttr(::new (getASTContext())
797+
HLSLSV_GroupThreadIDAttr(getASTContext(), AL));
798+
}
799+
790800
void SemaHLSL::handleSV_GroupIDAttr(Decl *D, const ParsedAttr &AL) {
791801
auto *VD = cast<ValueDecl>(D);
792802
if (!diagnoseInputIDType(VD->getType(), AL))
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s
2+
3+
// Make sure SV_GroupThreadID translated into dx.thread.id.in.group.
4+
5+
// CHECK: define void @foo()
6+
// CHECK: %[[#ID:]] = call i32 @llvm.dx.thread.id.in.group(i32 0)
7+
// CHECK: call void @{{.*}}foo{{.*}}(i32 %[[#ID]])
8+
[shader("compute")]
9+
[numthreads(8,8,1)]
10+
void foo(uint Idx : SV_GroupThreadID) {}
11+
12+
// CHECK: define void @bar()
13+
// CHECK: %[[#ID_X:]] = call i32 @llvm.dx.thread.id.in.group(i32 0)
14+
// CHECK: %[[#ID_X_:]] = insertelement <2 x i32> poison, i32 %[[#ID_X]], i64 0
15+
// CHECK: %[[#ID_Y:]] = call i32 @llvm.dx.thread.id.in.group(i32 1)
16+
// CHECK: %[[#ID_XY:]] = insertelement <2 x i32> %[[#ID_X_]], i32 %[[#ID_Y]], i64 1
17+
// CHECK: call void @{{.*}}bar{{.*}}(<2 x i32> %[[#ID_XY]])
18+
[shader("compute")]
19+
[numthreads(8,8,1)]
20+
void bar(uint2 Idx : SV_GroupThreadID) {}
21+
22+
// CHECK: define void @test()
23+
// CHECK: %[[#ID_X:]] = call i32 @llvm.dx.thread.id.in.group(i32 0)
24+
// CHECK: %[[#ID_X_:]] = insertelement <3 x i32> poison, i32 %[[#ID_X]], i64 0
25+
// CHECK: %[[#ID_Y:]] = call i32 @llvm.dx.thread.id.in.group(i32 1)
26+
// CHECK: %[[#ID_XY:]] = insertelement <3 x i32> %[[#ID_X_]], i32 %[[#ID_Y]], i64 1
27+
// CHECK: %[[#ID_Z:]] = call i32 @llvm.dx.thread.id.in.group(i32 2)
28+
// CHECK: %[[#ID_XYZ:]] = insertelement <3 x i32> %[[#ID_XY]], i32 %[[#ID_Z]], i64 2
29+
// CHECK: call void @{{.*}}test{{.*}}(<3 x i32> %[[#ID_XYZ]])
30+
[shader("compute")]
31+
[numthreads(8,8,1)]
32+
void test(uint3 Idx : SV_GroupThreadID) {}

clang/test/SemaHLSL/Semantics/entry_parameter.hlsl

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@
22
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-mesh -hlsl-entry CSMain -x hlsl -finclude-default-header -verify -o - %s
33

44
[numthreads(8,8,1)]
5-
// expected-error@+3 {{attribute 'SV_GroupIndex' is unsupported in 'mesh' shaders, requires compute}}
6-
// expected-error@+2 {{attribute 'SV_DispatchThreadID' is unsupported in 'mesh' shaders, requires compute}}
7-
// expected-error@+1 {{attribute 'SV_GroupID' is unsupported in 'mesh' shaders, requires compute}}
8-
void CSMain(int GI : SV_GroupIndex, uint ID : SV_DispatchThreadID, uint GID : SV_GroupID) {
9-
// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain 'void (int, uint, uint)'
5+
// expected-error@+4 {{attribute 'SV_GroupIndex' is unsupported in 'mesh' shaders, requires compute}}
6+
// expected-error@+3 {{attribute 'SV_DispatchThreadID' is unsupported in 'mesh' shaders, requires compute}}
7+
// expected-error@+2 {{attribute 'SV_GroupID' is unsupported in 'mesh' shaders, requires compute}}
8+
// expected-error@+1 {{attribute 'SV_GroupThreadID' is unsupported in 'mesh' shaders, requires compute}}
9+
void CSMain(int GI : SV_GroupIndex, uint ID : SV_DispatchThreadID, uint GID : SV_GroupID, uint GThreadID : SV_GroupThreadID) {
10+
// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain 'void (int, uint, uint, uint)'
1011
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:17 GI 'int'
1112
// CHECK-NEXT: HLSLSV_GroupIndexAttr
1213
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:42 ID 'uint'
1314
// CHECK-NEXT: HLSLSV_DispatchThreadIDAttr
1415
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:73 GID 'uint'
1516
// CHECK-NEXT: HLSLSV_GroupIDAttr
17+
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:96 GThreadID 'uint'
18+
// CHECK-NEXT: HLSLSV_GroupThreadIDAttr
1619
}

clang/test/SemaHLSL/Semantics/invalid_entry_parameter.hlsl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,25 @@ struct ST2_GID {
4949
static uint GID : SV_GroupID;
5050
uint s_gid : SV_GroupID;
5151
};
52+
53+
[numthreads(8,8,1)]
54+
// expected-error@+1 {{attribute 'SV_GroupThreadID' only applies to a field or parameter of type 'uint/uint2/uint3'}}
55+
void CSMain_GThreadID(float ID : SV_GroupThreadID) {
56+
}
57+
58+
[numthreads(8,8,1)]
59+
// expected-error@+1 {{attribute 'SV_GroupThreadID' only applies to a field or parameter of type 'uint/uint2/uint3'}}
60+
void CSMain2_GThreadID(ST GID : SV_GroupThreadID) {
61+
62+
}
63+
64+
void foo_GThreadID() {
65+
// expected-warning@+1 {{'SV_GroupThreadID' attribute only applies to parameters and non-static data members}}
66+
uint GThreadIS : SV_GroupThreadID;
67+
}
68+
69+
struct ST2_GThreadID {
70+
// expected-warning@+1 {{'SV_GroupThreadID' attribute only applies to parameters and non-static data members}}
71+
static uint GThreadID : SV_GroupThreadID;
72+
uint s_gthreadid : SV_GroupThreadID;
73+
};

clang/test/SemaHLSL/Semantics/valid_entry_parameter.hlsl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,28 @@ void CSMain3_GID(uint3 : SV_GroupID) {
4949
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:24 'uint3'
5050
// CHECK-NEXT: HLSLSV_GroupIDAttr
5151
}
52+
53+
[numthreads(8,8,1)]
54+
void CSMain_GThreadID(uint ID : SV_GroupThreadID) {
55+
// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain_GThreadID 'void (uint)'
56+
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:28 ID 'uint'
57+
// CHECK-NEXT: HLSLSV_GroupThreadIDAttr
58+
}
59+
[numthreads(8,8,1)]
60+
void CSMain1_GThreadID(uint2 ID : SV_GroupThreadID) {
61+
// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain1_GThreadID 'void (uint2)'
62+
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:30 ID 'uint2'
63+
// CHECK-NEXT: HLSLSV_GroupThreadIDAttr
64+
}
65+
[numthreads(8,8,1)]
66+
void CSMain2_GThreadID(uint3 ID : SV_GroupThreadID) {
67+
// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain2_GThreadID 'void (uint3)'
68+
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:30 ID 'uint3'
69+
// CHECK-NEXT: HLSLSV_GroupThreadIDAttr
70+
}
71+
[numthreads(8,8,1)]
72+
void CSMain3_GThreadID(uint3 : SV_GroupThreadID) {
73+
// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain3_GThreadID 'void (uint3)'
74+
// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:30 'uint3'
75+
// CHECK-NEXT: HLSLSV_GroupThreadIDAttr
76+
}

0 commit comments

Comments
 (0)