-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[HLSL] Add implicit binding attribute to resource arrays #152452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
10a06e3
4e153a4
ac99f5a
b5ca61c
e12a7a9
b596824
c946b08
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -71,6 +71,10 @@ static RegisterType getRegisterType(ResourceClass RC) { | |
llvm_unreachable("unexpected ResourceClass value"); | ||
} | ||
|
||
static RegisterType getRegisterType(const HLSLAttributedResourceType *ResTy) { | ||
return getRegisterType(ResTy->getAttrs().ResourceClass); | ||
} | ||
|
||
// Converts the first letter of string Slot to RegisterType. | ||
// Returns false if the letter does not correspond to a valid register type. | ||
static bool convertToRegisterType(StringRef Slot, RegisterType *RT) { | ||
|
@@ -337,16 +341,20 @@ static bool isZeroSizedArray(const ConstantArrayType *CAT) { | |
return CAT != nullptr; | ||
} | ||
|
||
// Returns true if the record type is an HLSL resource class or an array of | ||
// resource classes | ||
static bool isResourceRecordTypeOrArrayOf(const Type *Ty) { | ||
while (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Ty)) | ||
Ty = CAT->getArrayElementTypeNoTypeQual(); | ||
return HLSLAttributedResourceType::findHandleTypeOnResource(Ty) != nullptr; | ||
static bool isResourceRecordTypeOrArrayOf(VarDecl *VD) { | ||
const Type *Ty = VD->getType().getTypePtr(); | ||
return Ty->isHLSLResourceRecord() || Ty->isHLSLResourceRecordArray(); | ||
} | ||
|
||
static bool isResourceRecordTypeOrArrayOf(VarDecl *VD) { | ||
return isResourceRecordTypeOrArrayOf(VD->getType().getTypePtr()); | ||
static const HLSLAttributedResourceType * | ||
getResourceArrayHandleType(VarDecl *VD) { | ||
assert(VD->getType()->isHLSLResourceRecordArray() && | ||
"expected array of resource records"); | ||
const Type *Ty = VD->getType()->getUnqualifiedDesugaredType(); | ||
while (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Ty)) { | ||
Ty = CAT->getArrayElementTypeNoTypeQual()->getUnqualifiedDesugaredType(); | ||
} | ||
hekota marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
return HLSLAttributedResourceType::findHandleTypeOnResource(Ty); | ||
} | ||
|
||
// Returns true if the type is a leaf element type that is not valid to be | ||
|
@@ -355,7 +363,7 @@ static bool isResourceRecordTypeOrArrayOf(VarDecl *VD) { | |
// type or if it is a record type that needs to be inspected further. | ||
static bool isInvalidConstantBufferLeafElementType(const Type *Ty) { | ||
Ty = Ty->getUnqualifiedDesugaredType(); | ||
if (isResourceRecordTypeOrArrayOf(Ty)) | ||
if (Ty->isHLSLResourceRecord() || Ty->isHLSLResourceRecordArray()) | ||
return true; | ||
if (Ty->isRecordType()) | ||
return Ty->getAsCXXRecordDecl()->isEmpty(); | ||
|
@@ -575,16 +583,13 @@ void createHostLayoutStructForBuffer(Sema &S, HLSLBufferDecl *BufDecl) { | |
BufDecl->addLayoutStruct(LS); | ||
} | ||
|
||
static void addImplicitBindingAttrToBuffer(Sema &S, HLSLBufferDecl *BufDecl, | ||
uint32_t ImplicitBindingOrderID) { | ||
RegisterType RT = | ||
BufDecl->isCBuffer() ? RegisterType::CBuffer : RegisterType::SRV; | ||
static void addImplicitBindingAttrToDecl(Sema &S, Decl *D, RegisterType RT, | ||
uint32_t ImplicitBindingOrderID) { | ||
auto *Attr = | ||
HLSLResourceBindingAttr::CreateImplicit(S.getASTContext(), "", "0", {}); | ||
std::optional<unsigned> RegSlot; | ||
Attr->setBinding(RT, RegSlot, 0); | ||
Attr->setBinding(RT, std::nullopt, 0); | ||
Attr->setImplicitBindingOrderID(ImplicitBindingOrderID); | ||
BufDecl->addAttr(Attr); | ||
D->addAttr(Attr); | ||
} | ||
|
||
// Handle end of cbuffer/tbuffer declaration | ||
|
@@ -607,7 +612,10 @@ void SemaHLSL::ActOnFinishBuffer(Decl *Dcl, SourceLocation RBrace) { | |
if (RBA) | ||
RBA->setImplicitBindingOrderID(OrderID); | ||
else | ||
addImplicitBindingAttrToBuffer(SemaRef, BufDecl, OrderID); | ||
addImplicitBindingAttrToDecl(SemaRef, BufDecl, | ||
BufDecl->isCBuffer() ? RegisterType::CBuffer | ||
: RegisterType::SRV, | ||
OrderID); | ||
} | ||
|
||
SemaRef.PopDeclContext(); | ||
|
@@ -1913,7 +1921,7 @@ static bool DiagnoseLocalRegisterBinding(Sema &S, SourceLocation &ArgLoc, | |
if (const HLSLAttributedResourceType *AttrResType = | ||
HLSLAttributedResourceType::findHandleTypeOnResource( | ||
VD->getType().getTypePtr())) { | ||
if (RegType == getRegisterType(AttrResType->getAttrs().ResourceClass)) | ||
if (RegType == getRegisterType(AttrResType)) | ||
return true; | ||
|
||
S.Diag(D->getLocation(), diag::err_hlsl_binding_type_mismatch) | ||
|
@@ -2446,8 +2454,8 @@ void SemaHLSL::ActOnEndOfTranslationUnit(TranslationUnitDecl *TU) { | |
HLSLBufferDecl *DefaultCBuffer = HLSLBufferDecl::CreateDefaultCBuffer( | ||
SemaRef.getASTContext(), SemaRef.getCurLexicalContext(), | ||
DefaultCBufferDecls); | ||
addImplicitBindingAttrToBuffer(SemaRef, DefaultCBuffer, | ||
getNextImplicitBindingOrderID()); | ||
addImplicitBindingAttrToDecl(SemaRef, DefaultCBuffer, RegisterType::CBuffer, | ||
getNextImplicitBindingOrderID()); | ||
SemaRef.getCurLexicalContext()->addDecl(DefaultCBuffer); | ||
createHostLayoutStructForBuffer(SemaRef, DefaultCBuffer); | ||
|
||
|
@@ -3597,7 +3605,7 @@ void SemaHLSL::deduceAddressSpace(VarDecl *Decl) { | |
return; | ||
|
||
// Resource handles. | ||
if (isResourceRecordTypeOrArrayOf(Type->getUnqualifiedDesugaredType())) | ||
if (Type->isHLSLResourceRecord() || Type->isHLSLResourceRecordArray()) | ||
return; | ||
|
||
// Only static globals belong to the Private address space. | ||
|
@@ -3637,10 +3645,7 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) { | |
if (VD->getType()->isHLSLIntangibleType()) | ||
collectResourceBindingsOnVarDecl(VD); | ||
|
||
const Type *VarType = VD->getType().getTypePtr(); | ||
while (VarType->isArrayType()) | ||
VarType = VarType->getArrayElementTypeNoTypeQual(); | ||
if (VarType->isHLSLResourceRecord() || | ||
if (isResourceRecordTypeOrArrayOf(VD) || | ||
VD->hasAttr<HLSLVkConstantIdAttr>()) { | ||
// Make the variable for resources static. The global externally visible | ||
// storage is accessed through the handle, which is a member. The variable | ||
|
@@ -3650,6 +3655,24 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) { | |
|
||
// process explicit bindings | ||
processExplicitBindingsOnDecl(VD); | ||
|
||
if (VD->getType()->isHLSLResourceRecordArray()) { | ||
// If the resource array does not have an explicit binding attribute, | ||
// create an implicit one. It will be used to transfer implicit binding | ||
// order_ID to codegen. | ||
if (!VD->hasAttr<HLSLVkBindingAttr>()) { | ||
bob80905 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
HLSLResourceBindingAttr *RBA = VD->getAttr<HLSLResourceBindingAttr>(); | ||
if (!RBA || !RBA->hasRegisterSlot()) { | ||
uint32_t OrderID = getNextImplicitBindingOrderID(); | ||
if (RBA) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually no. The condition |
||
RBA->setImplicitBindingOrderID(OrderID); | ||
else | ||
addImplicitBindingAttrToDecl( | ||
SemaRef, VD, getRegisterType(getResourceArrayHandleType(VD)), | ||
OrderID); | ||
} | ||
} | ||
} | ||
} | ||
|
||
deduceAddressSpace(VD); | ||
|
Uh oh!
There was an error while loading. Please reload this page.