Skip to content

Commit 3f5ecca

Browse files
Xiang Lipython3kgae
Xiang Li
authored andcommitted
[HLSL] Add shader attribute
Shader attribute is for shader library identify entry functions. Here's an example, [shader("pixel")] float ps_main() : SV_Target { return 1; } When compile this shader to library target like -E lib_6_3, compiler needs to know ps_main is an entry function for pixel shader. Shader attribute is to offer the information. A new attribute HLSLShader is added to support shader attribute. It has an EnumArgument which included all possible shader stages.
1 parent bac6cd5 commit 3f5ecca

File tree

6 files changed

+145
-0
lines changed

6 files changed

+145
-0
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3968,6 +3968,23 @@ def HLSLSV_GroupIndex: InheritableAttr {
39683968
let Documentation = [HLSLSV_GroupIndexDocs];
39693969
}
39703970

3971+
def HLSLShader : InheritableAttr {
3972+
let Spellings = [Microsoft<"shader">];
3973+
let Subjects = SubjectList<[HLSLEntry]>;
3974+
let LangOpts = [HLSL];
3975+
let Args = [EnumArgument<"Type", "ShaderType",
3976+
["pixel", "vertex", "geometry", "hull", "domain",
3977+
"compute", "raygeneration", "intersection",
3978+
"anyhit", "closesthit", "miss", "callable", "mesh",
3979+
"amplification"],
3980+
["Pixel", "Vertex", "Geometry", "Hull", "Domain",
3981+
"Compute", "RayGeneration", "Intersection",
3982+
"AnyHit", "ClosestHit", "Miss", "Callable", "Mesh",
3983+
"Amplification"]
3984+
>];
3985+
let Documentation = [HLSLSV_ShaderTypeAttrDocs];
3986+
}
3987+
39713988
def RandomizeLayout : InheritableAttr {
39723989
let Spellings = [GCC<"randomize_layout">];
39733990
let Subjects = SubjectList<[Record]>;

clang/include/clang/Basic/AttrDocs.td

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6380,6 +6380,23 @@ The full documentation is available here: https://docs.microsoft.com/en-us/windo
63806380
}];
63816381
}
63826382

6383+
def HLSLSV_ShaderTypeAttrDocs : Documentation {
6384+
let Category = DocCatFunction;
6385+
let Content = [{
6386+
The ``shader`` type attribute applies to HLSL shader entry functions to
6387+
identify the shader type for the entry function.
6388+
The syntax is:
6389+
``[shader(string-literal)]``
6390+
where the string literal is one of: <list the options>.
6391+
Normally the shader type is set by shader target with the ``-T`` option like
6392+
``-Tps_6_1``.
6393+
When compiling to a library target like ``lib_6_3``, the shader type attribute
6394+
can help the compiler to identify the shader type.
6395+
It is mostly used by Raytracing shaders where shaders must be compiled into a
6396+
library and linked at runtime.
6397+
}];
6398+
}
6399+
63836400
def ClangRandomizeLayoutDocs : Documentation {
63846401
let Category = DocCatDecl;
63856402
let Heading = "randomize_layout, no_randomize_layout";

clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3506,6 +3506,8 @@ class Sema final {
35063506
HLSLNumThreadsAttr *mergeHLSLNumThreadsAttr(Decl *D,
35073507
const AttributeCommonInfo &AL,
35083508
int X, int Y, int Z);
3509+
HLSLShaderAttr *mergeHLSLShaderAttr(Decl *D, const AttributeCommonInfo &AL,
3510+
HLSLShaderAttr::ShaderType ShaderType);
35093511

35103512
void mergeDeclAttributes(NamedDecl *New, Decl *Old,
35113513
AvailabilityMergeKind AMK = AMK_Redeclaration);

clang/lib/Sema/SemaDecl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2806,6 +2806,8 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D,
28062806
else if (const auto *NT = dyn_cast<HLSLNumThreadsAttr>(Attr))
28072807
NewAttr =
28082808
S.mergeHLSLNumThreadsAttr(D, *NT, NT->getX(), NT->getY(), NT->getZ());
2809+
else if (const auto *SA = dyn_cast<HLSLShaderAttr>(Attr))
2810+
NewAttr = S.mergeHLSLShaderAttr(D, *SA, SA->getType());
28092811
else if (Attr->shouldInheritEvenIfAlreadyPresent() || !DeclHasAttr(D, Attr))
28102812
NewAttr = cast<InheritableAttr>(Attr->clone(S.Context));
28112813

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6940,6 +6940,39 @@ static void handleHLSLSVGroupIndexAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
69406940
D->addAttr(::new (S.Context) HLSLSV_GroupIndexAttr(S.Context, AL));
69416941
}
69426942

6943+
static void handleHLSLShaderAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6944+
StringRef Str;
6945+
SourceLocation ArgLoc;
6946+
if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
6947+
return;
6948+
6949+
HLSLShaderAttr::ShaderType ShaderType;
6950+
if (!HLSLShaderAttr::ConvertStrToShaderType(Str, ShaderType)) {
6951+
S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
6952+
<< AL << Str << ArgLoc;
6953+
return;
6954+
}
6955+
6956+
// FIXME: check function match the shader stage.
6957+
6958+
HLSLShaderAttr *NewAttr = S.mergeHLSLShaderAttr(D, AL, ShaderType);
6959+
if (NewAttr)
6960+
D->addAttr(NewAttr);
6961+
}
6962+
6963+
HLSLShaderAttr *
6964+
Sema::mergeHLSLShaderAttr(Decl *D, const AttributeCommonInfo &AL,
6965+
HLSLShaderAttr::ShaderType ShaderType) {
6966+
if (HLSLShaderAttr *NT = D->getAttr<HLSLShaderAttr>()) {
6967+
if (NT->getType() != ShaderType) {
6968+
Diag(NT->getLocation(), diag::err_hlsl_attribute_param_mismatch) << AL;
6969+
Diag(AL.getLoc(), diag::note_conflicting_attribute);
6970+
}
6971+
return nullptr;
6972+
}
6973+
return HLSLShaderAttr::Create(Context, ShaderType, AL);
6974+
}
6975+
69436976
static void handleMSInheritanceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
69446977
if (!S.LangOpts.CPlusPlus) {
69456978
S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
@@ -8815,6 +8848,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
88158848
case ParsedAttr::AT_HLSLSV_GroupIndex:
88168849
handleHLSLSVGroupIndexAttr(S, D, AL);
88178850
break;
8851+
case ParsedAttr::AT_HLSLShader:
8852+
handleHLSLShaderAttr(S, D, AL);
8853+
break;
88188854

88198855
case ParsedAttr::AT_AbiTag:
88208856
handleAbiTagAttr(S, D, AL);
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -ast-dump -o - %s | FileCheck %s
2+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -ast-dump -o - %s -DFAIL -verify
3+
4+
#ifdef FAIL
5+
6+
// expected-warning@+1 {{'shader' attribute only applies to global functions}}
7+
[shader("compute")]
8+
struct Fido {
9+
// expected-warning@+1 {{'shader' attribute only applies to global functions}}
10+
[shader("pixel")]
11+
void wag() {}
12+
// expected-warning@+1 {{'shader' attribute only applies to global functions}}
13+
[shader("vertex")]
14+
static void oops() {}
15+
};
16+
17+
// expected-warning@+1 {{'shader' attribute only applies to global functions}}
18+
[shader("vertex")]
19+
static void oops() {}
20+
21+
namespace spec {
22+
// expected-warning@+1 {{'shader' attribute only applies to global functions}}
23+
[shader("vertex")]
24+
static void oops() {}
25+
} // namespace spec
26+
27+
// expected-error@+1 {{'shader' attribute parameters do not match the previous declaration}}
28+
[shader("compute")]
29+
// expected-note@+1 {{conflicting attribute is here}}
30+
[shader("vertex")]
31+
int doubledUp() {
32+
return 1;
33+
}
34+
35+
// expected-note@+1 {{conflicting attribute is here}}
36+
[shader("vertex")]
37+
int forwardDecl();
38+
39+
// expected-error@+1 {{'shader' attribute parameters do not match the previous declaration}}
40+
[shader("compute")]
41+
int forwardDecl() {
42+
return 1;
43+
}
44+
45+
// expected-error@+1 {{'shader' attribute takes one argument}}
46+
[shader()]
47+
// expected-error@+1 {{'shader' attribute takes one argument}}
48+
[shader(1, 2)]
49+
// expected-error@+1 {{'shader' attribute requires a string}}
50+
[shader(1)]
51+
// expected-warning@+1 {{'shader' attribute argument not supported: cs}}
52+
[shader("cs")]
53+
54+
#endif // END of FAIL
55+
56+
// CHECK:HLSLShaderAttr 0x{{[0-9a-fA-F]+}} <line:57:2, col:18> Compute
57+
[shader("compute")]
58+
int entry() {
59+
return 1;
60+
}
61+
62+
// Because these two attributes match, they should both appear in the AST
63+
[shader("compute")]
64+
// CHECK:HLSLShaderAttr 0x{{[0-9a-fA-F]+}} <line:63:2, col:18> Compute
65+
int secondFn();
66+
67+
[shader("compute")]
68+
// CHECK:HLSLShaderAttr 0x{{[0-9a-fA-F]+}} <line:67:2, col:18> Compute
69+
int secondFn() {
70+
return 1;
71+
}

0 commit comments

Comments
 (0)