@@ -71,6 +71,10 @@ static RegisterType getRegisterType(ResourceClass RC) {
71
71
llvm_unreachable (" unexpected ResourceClass value" );
72
72
}
73
73
74
+ static RegisterType getRegisterType (const HLSLAttributedResourceType *ResTy) {
75
+ return getRegisterType (ResTy->getAttrs ().ResourceClass );
76
+ }
77
+
74
78
// Converts the first letter of string Slot to RegisterType.
75
79
// Returns false if the letter does not correspond to a valid register type.
76
80
static bool convertToRegisterType (StringRef Slot, RegisterType *RT) {
@@ -342,6 +346,16 @@ static bool isResourceRecordTypeOrArrayOf(VarDecl *VD) {
342
346
return Ty->isHLSLResourceRecord () || Ty->isHLSLResourceRecordArray ();
343
347
}
344
348
349
+ static const HLSLAttributedResourceType *
350
+ getResourceArrayHandleType (VarDecl *VD) {
351
+ assert (VD->getType ()->isHLSLResourceRecordArray () &&
352
+ " expected array of resource records" );
353
+ const Type *Ty = VD->getType ()->getUnqualifiedDesugaredType ();
354
+ while (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Ty))
355
+ Ty = CAT->getArrayElementTypeNoTypeQual ()->getUnqualifiedDesugaredType ();
356
+ return HLSLAttributedResourceType::findHandleTypeOnResource (Ty);
357
+ }
358
+
345
359
// Returns true if the type is a leaf element type that is not valid to be
346
360
// included in HLSL Buffer, such as a resource class, empty struct, zero-sized
347
361
// array, or a builtin intangible type. Returns false it is a valid leaf element
@@ -568,16 +582,13 @@ void createHostLayoutStructForBuffer(Sema &S, HLSLBufferDecl *BufDecl) {
568
582
BufDecl->addLayoutStruct (LS);
569
583
}
570
584
571
- static void addImplicitBindingAttrToBuffer (Sema &S, HLSLBufferDecl *BufDecl,
572
- uint32_t ImplicitBindingOrderID) {
573
- RegisterType RT =
574
- BufDecl->isCBuffer () ? RegisterType::CBuffer : RegisterType::SRV;
585
+ static void addImplicitBindingAttrToDecl (Sema &S, Decl *D, RegisterType RT,
586
+ uint32_t ImplicitBindingOrderID) {
575
587
auto *Attr =
576
588
HLSLResourceBindingAttr::CreateImplicit (S.getASTContext (), " " , " 0" , {});
577
- std::optional<unsigned > RegSlot;
578
- Attr->setBinding (RT, RegSlot, 0 );
589
+ Attr->setBinding (RT, std::nullopt, 0 );
579
590
Attr->setImplicitBindingOrderID (ImplicitBindingOrderID);
580
- BufDecl ->addAttr (Attr);
591
+ D ->addAttr (Attr);
581
592
}
582
593
583
594
// Handle end of cbuffer/tbuffer declaration
@@ -600,7 +611,10 @@ void SemaHLSL::ActOnFinishBuffer(Decl *Dcl, SourceLocation RBrace) {
600
611
if (RBA)
601
612
RBA->setImplicitBindingOrderID (OrderID);
602
613
else
603
- addImplicitBindingAttrToBuffer (SemaRef, BufDecl, OrderID);
614
+ addImplicitBindingAttrToDecl (SemaRef, BufDecl,
615
+ BufDecl->isCBuffer () ? RegisterType::CBuffer
616
+ : RegisterType::SRV,
617
+ OrderID);
604
618
}
605
619
606
620
SemaRef.PopDeclContext ();
@@ -1906,7 +1920,7 @@ static bool DiagnoseLocalRegisterBinding(Sema &S, SourceLocation &ArgLoc,
1906
1920
if (const HLSLAttributedResourceType *AttrResType =
1907
1921
HLSLAttributedResourceType::findHandleTypeOnResource (
1908
1922
VD->getType ().getTypePtr ())) {
1909
- if (RegType == getRegisterType (AttrResType-> getAttrs (). ResourceClass ))
1923
+ if (RegType == getRegisterType (AttrResType))
1910
1924
return true ;
1911
1925
1912
1926
S.Diag (D->getLocation (), diag::err_hlsl_binding_type_mismatch)
@@ -2439,8 +2453,8 @@ void SemaHLSL::ActOnEndOfTranslationUnit(TranslationUnitDecl *TU) {
2439
2453
HLSLBufferDecl *DefaultCBuffer = HLSLBufferDecl::CreateDefaultCBuffer (
2440
2454
SemaRef.getASTContext (), SemaRef.getCurLexicalContext (),
2441
2455
DefaultCBufferDecls);
2442
- addImplicitBindingAttrToBuffer (SemaRef, DefaultCBuffer,
2443
- getNextImplicitBindingOrderID ());
2456
+ addImplicitBindingAttrToDecl (SemaRef, DefaultCBuffer, RegisterType::CBuffer ,
2457
+ getNextImplicitBindingOrderID ());
2444
2458
SemaRef.getCurLexicalContext ()->addDecl (DefaultCBuffer);
2445
2459
createHostLayoutStructForBuffer (SemaRef, DefaultCBuffer);
2446
2460
@@ -3640,6 +3654,24 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
3640
3654
3641
3655
// process explicit bindings
3642
3656
processExplicitBindingsOnDecl (VD);
3657
+
3658
+ if (VD->getType ()->isHLSLResourceRecordArray ()) {
3659
+ // If the resource array does not have an explicit binding attribute,
3660
+ // create an implicit one. It will be used to transfer implicit binding
3661
+ // order_ID to codegen.
3662
+ if (!VD->hasAttr <HLSLVkBindingAttr>()) {
3663
+ HLSLResourceBindingAttr *RBA = VD->getAttr <HLSLResourceBindingAttr>();
3664
+ if (!RBA || !RBA->hasRegisterSlot ()) {
3665
+ uint32_t OrderID = getNextImplicitBindingOrderID ();
3666
+ if (RBA)
3667
+ RBA->setImplicitBindingOrderID (OrderID);
3668
+ else
3669
+ addImplicitBindingAttrToDecl (
3670
+ SemaRef, VD, getRegisterType (getResourceArrayHandleType (VD)),
3671
+ OrderID);
3672
+ }
3673
+ }
3674
+ }
3643
3675
}
3644
3676
3645
3677
deduceAddressSpace (VD);
0 commit comments