Browse Source

[spirv] Add support explicit binding for CTBuffer (#672)

This commit adds support for explicit binding assignment in
cbuffer/tbuffer/ConstantBuffer/TextureBuffer.
Lei Zhang 8 years ago
parent
commit
cd5299e946

+ 3 - 3
tools/clang/include/clang/Basic/Attr.td

@@ -865,7 +865,7 @@ def VKLocation : InheritableAttr {
 
 def VKBinding : InheritableAttr {
   let Spellings = [CXX11<"vk", "binding">];
-  let Subjects = SubjectList<[GlobalVar], ErrorDiag, "ExpectedVariable">;
+  let Subjects = SubjectList<[GlobalVar, HLSLBuffer], ErrorDiag, "ExpectedVariable">;
   let Args = [IntArgument<"Binding">, DefaultIntArgument<"Set", 0>];
   let LangOpts = [SPIRV];
   let Documentation = [Undocumented];
@@ -1421,7 +1421,7 @@ def Overloadable : Attr {
   let Documentation = [OverloadableDocs];
 }
 
-def Override : InheritableAttr { 
+def Override : InheritableAttr {
   let Spellings = [Keyword<"override">];
   let SemaHandler = 0;
   let Documentation = [Undocumented];
@@ -1488,7 +1488,7 @@ def ReqdWorkGroupSize : InheritableAttr {
 
 def WorkGroupSizeHint :  InheritableAttr {
   let Spellings = [GNU<"work_group_size_hint">];
-  let Args = [UnsignedArgument<"XDim">, 
+  let Args = [UnsignedArgument<"XDim">,
               UnsignedArgument<"YDim">,
               UnsignedArgument<"ZDim">];
   let Subjects = SubjectList<[Function], ErrorDiag>;

+ 2 - 2
tools/clang/include/clang/Parse/Parser.h

@@ -2377,9 +2377,9 @@ private:
 
   // HLSL Change Starts
   Decl *ParseCTBuffer(unsigned Context, SourceLocation &DeclEnd,
-    SourceLocation InlineLoc = SourceLocation());
+    ParsedAttributesWithRange &attrs, SourceLocation InlineLoc = SourceLocation());
   Decl *ParseConstBuffer(unsigned Context, SourceLocation &DeclEnd,
-    SourceLocation InlineLoc = SourceLocation());
+    ParsedAttributesWithRange &attrs, SourceLocation InlineLoc = SourceLocation());
   // HLSL Change Ends
 
   Decl *ParseNamespace(unsigned Context, SourceLocation &DeclEnd,

+ 2 - 4
tools/clang/lib/Parse/ParseDecl.cpp

@@ -1922,13 +1922,11 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context,
   // HLSL Change Starts
   case tok::kw_cbuffer:
   case tok::kw_tbuffer:
-    ProhibitAttributes(attrs);
-    SingleDecl = ParseCTBuffer(Context, DeclEnd);
+    SingleDecl = ParseCTBuffer(Context, DeclEnd, attrs);
     break;
   case tok::kw_ConstantBuffer:
   case tok::kw_TextureBuffer:
-    ProhibitAttributes(attrs);
-    SingleDecl = ParseConstBuffer(Context, DeclEnd);
+    SingleDecl = ParseConstBuffer(Context, DeclEnd, attrs);
     break;
   // HLSL Change Ends
   case tok::kw_namespace:

+ 7 - 0
tools/clang/lib/Parse/ParseHLSL.cpp

@@ -27,6 +27,7 @@
 using namespace clang;
 
 Decl *Parser::ParseCTBuffer(unsigned Context, SourceLocation &DeclEnd,
+                            ParsedAttributesWithRange &CTBAttrs,
                             SourceLocation InlineLoc) {
   assert((Tok.is(tok::kw_cbuffer) || Tok.is(tok::kw_tbuffer)) &&
          "Not a cbuffer or tbuffer!");
@@ -54,6 +55,9 @@ Decl *Parser::ParseCTBuffer(unsigned Context, SourceLocation &DeclEnd,
                                             identifier, identifierLoc,
                                             hlslAttrs, T.getOpenLocation());
 
+  // Process potential C++11 attribute specifiers
+  Actions.ProcessDeclAttributeList(getCurScope(), decl, CTBAttrs.getList());
+
   while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
     ParsedAttributesWithRange attrs(AttrFactory);
     MaybeParseCXX11Attributes(attrs);
@@ -71,6 +75,7 @@ Decl *Parser::ParseCTBuffer(unsigned Context, SourceLocation &DeclEnd,
 }
 
 Decl *Parser::ParseConstBuffer(unsigned Context, SourceLocation &DeclEnd,
+                               ParsedAttributesWithRange &attrs,
                                SourceLocation InlineLoc) {
   bool isCBuffer = Tok.is(tok::kw_ConstantBuffer);
   assert((isCBuffer || Tok.is(tok::kw_TextureBuffer)) && "Not a ConstantBuffer or TextureBuffer!");
@@ -92,6 +97,8 @@ Decl *Parser::ParseConstBuffer(unsigned Context, SourceLocation &DeclEnd,
   }
   ConsumeToken(); // eat the >
 
+  PDS.takeAttributesFrom(attrs);
+
   Actions.ActOnStartHLSLBufferView();
   Parser::DeclGroupPtrTy dcl = ParseDeclGroup(PDS, Declarator::FileContext);
 

+ 11 - 2
tools/clang/test/CodeGenSPIRV/vk.binding.explicit.hlsl

@@ -30,13 +30,22 @@ Buffer<int> myBuffer : register(t1, space0);
 [[vk::binding(4, 1)]]
 RWBuffer<float4> myRWBuffer : register(u0, space1);
 
-// TODO: support [[vk::binding()]] on cbuffer
-// TODO: support [[vk::binding()]] on ConstantBuffer
+// CHECK: OpDecorate %var_myCBuffer DescriptorSet 3
+// CHECK-NEXT: OpDecorate %var_myCBuffer Binding 10
+[[vk::binding(10, 3)]]
+cbuffer myCBuffer : register(b5, space1) {
+    float cbfield;
+};
 
 struct S {
     float f;
 };
 
+// CHECK: OpDecorate %myConstantBuffer DescriptorSet 3
+// CHECK-NEXT: OpDecorate %myConstantBuffer Binding 5
+[[vk::binding(5, 3)]]
+ConstantBuffer<S> myConstantBuffer: register(b1, space1);
+
 // CHECK:      OpDecorate %sbuffer1 DescriptorSet 0
 // CHECK-NEXT: OpDecorate %sbuffer1 Binding 3
 [[vk::binding(3)]]

+ 8 - 0
tools/clang/test/HLSL/cxx11-attributes.hlsl

@@ -1,10 +1,18 @@
 // RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s
 
+[[vk::binding(4, 3)]] // expected-warning {{'binding' attribute ignored}}
+cbuffer myCBuffer {
+    float cbfield;
+};
+
 struct S {
     [[vk::location(1)]] // expected-warning {{'location' attribute ignored}}
     float a: A;
 };
 
+[[vk::binding(5, 3)]] // expected-warning {{'binding' attribute ignored}}
+ConstantBuffer<S> myConstantBuffer;
+
 [[maybe_unused]] // expected-warning {{unknown attribute 'maybe_unused' ignored}}
 float main([[scope::attr(0, "str")]] // expected-warning {{unknown attribute 'attr' ignored}}
            float m: B,