-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[HLSL] Use static create methods to initialize individual resources #156544
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 all commits
7a0d3ca
dcbbda4
02342c9
b13a530
a0cfc72
1e6f4de
dfc07bd
a41cf8a
e7641e1
6028194
ea93f39
e7d6ee6
84883bc
7782eea
f64525e
dfa4144
c7b35b9
b487a54
cdc85ca
ce719b2
b53d261
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 |
---|---|---|
|
@@ -1212,6 +1212,15 @@ struct PerVisibilityBindingChecker { | |
} | ||
}; | ||
|
||
static CXXMethodDecl *lookupMethod(Sema &S, CXXRecordDecl *RecordDecl, | ||
StringRef Name, SourceLocation Loc) { | ||
DeclarationName DeclName(&S.getASTContext().Idents.get(Name)); | ||
LookupResult Result(S, DeclName, Loc, Sema::LookupMemberName); | ||
if (!S.LookupQualifiedName(Result, static_cast<DeclContext *>(RecordDecl))) | ||
return nullptr; | ||
return cast<CXXMethodDecl>(Result.getFoundDecl()); | ||
} | ||
|
||
} // end anonymous namespace | ||
|
||
bool SemaHLSL::handleRootSignatureElements( | ||
|
@@ -3738,26 +3747,6 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) { | |
deduceAddressSpace(VD); | ||
} | ||
|
||
static bool initVarDeclWithCtor(Sema &S, VarDecl *VD, | ||
MutableArrayRef<Expr *> Args) { | ||
InitializedEntity Entity = InitializedEntity::InitializeVariable(VD); | ||
InitializationKind Kind = InitializationKind::CreateDirect( | ||
VD->getLocation(), SourceLocation(), SourceLocation()); | ||
|
||
InitializationSequence InitSeq(S, Entity, Kind, Args); | ||
if (InitSeq.Failed()) | ||
return false; | ||
|
||
ExprResult Init = InitSeq.Perform(S, Entity, Kind, Args); | ||
if (!Init.get()) | ||
return false; | ||
|
||
VD->setInit(S.MaybeCreateExprWithCleanups(Init.get())); | ||
VD->setInitStyle(VarDecl::CallInit); | ||
S.CheckCompleteVariableDeclaration(VD); | ||
return true; | ||
} | ||
|
||
void SemaHLSL::createResourceRecordCtorArgs( | ||
const Type *ResourceTy, StringRef VarName, HLSLResourceBindingAttr *RBA, | ||
HLSLVkBindingAttr *VkBinding, uint32_t ArrayIndex, | ||
|
@@ -3808,11 +3797,106 @@ void SemaHLSL::createResourceRecordCtorArgs( | |
} | ||
|
||
bool SemaHLSL::initGlobalResourceDecl(VarDecl *VD) { | ||
SmallVector<Expr *> Args; | ||
createResourceRecordCtorArgs(VD->getType().getTypePtr(), VD->getName(), | ||
VD->getAttr<HLSLResourceBindingAttr>(), | ||
VD->getAttr<HLSLVkBindingAttr>(), 0, Args); | ||
return initVarDeclWithCtor(SemaRef, VD, Args); | ||
assert(VD->getType()->isHLSLResourceRecord() && | ||
"expected resource record type"); | ||
|
||
ASTContext &AST = SemaRef.getASTContext(); | ||
uint64_t UIntTySize = AST.getTypeSize(AST.UnsignedIntTy); | ||
uint64_t IntTySize = AST.getTypeSize(AST.IntTy); | ||
|
||
// Gather resource binding information from attributes. | ||
HLSLResourceBindingAttr *RBA = VD->getAttr<HLSLResourceBindingAttr>(); | ||
HLSLVkBindingAttr *VkBinding = VD->getAttr<HLSLVkBindingAttr>(); | ||
std::optional<uint32_t> RegisterSlot; | ||
uint32_t SpaceNo = 0; | ||
if (VkBinding) { | ||
RegisterSlot = VkBinding->getBinding(); | ||
SpaceNo = VkBinding->getSet(); | ||
} else if (RBA) { | ||
if (RBA->hasRegisterSlot()) | ||
RegisterSlot = RBA->getSlotNumber(); | ||
SpaceNo = RBA->getSpaceNumber(); | ||
} | ||
|
||
// Find correct initialization method and create its arguments. | ||
QualType ResourceTy = VD->getType(); | ||
CXXRecordDecl *ResourceDecl = ResourceTy->getAsCXXRecordDecl(); | ||
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. I did look up the call tree here to be sure, but it does seem like we're guaranteed that ResourceTy will be complete by the time we get here. 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. Correct, in |
||
CXXMethodDecl *CreateMethod = nullptr; | ||
llvm::SmallVector<Expr *> Args; | ||
|
||
if (RegisterSlot.has_value()) { | ||
// The resource has explicit binding. | ||
CreateMethod = lookupMethod(SemaRef, ResourceDecl, "__createFromBinding", | ||
VD->getLocation()); | ||
IntegerLiteral *RegSlot = IntegerLiteral::Create( | ||
AST, llvm::APInt(UIntTySize, RegisterSlot.value()), AST.UnsignedIntTy, | ||
SourceLocation()); | ||
Args.push_back(RegSlot); | ||
} else { | ||
// The resource has implicit binding. | ||
CreateMethod = | ||
lookupMethod(SemaRef, ResourceDecl, "__createFromImplicitBinding", | ||
VD->getLocation()); | ||
uint32_t OrderID = (RBA && RBA->hasImplicitBindingOrderID()) | ||
? RBA->getImplicitBindingOrderID() | ||
: getNextImplicitBindingOrderID(); | ||
IntegerLiteral *OrderId = | ||
IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, OrderID), | ||
AST.UnsignedIntTy, SourceLocation()); | ||
Args.push_back(OrderId); | ||
} | ||
|
||
if (!CreateMethod) | ||
hekota marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// This can happen if someone creates a struct that looks like an HLSL | ||
// resource record but does not have the required static create method. | ||
// No binding will be generated for it. | ||
return false; | ||
|
||
IntegerLiteral *Space = | ||
IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, SpaceNo), | ||
AST.UnsignedIntTy, SourceLocation()); | ||
Args.push_back(Space); | ||
|
||
IntegerLiteral *RangeSize = IntegerLiteral::Create( | ||
AST, llvm::APInt(IntTySize, 1), AST.IntTy, SourceLocation()); | ||
Args.push_back(RangeSize); | ||
|
||
IntegerLiteral *Index = IntegerLiteral::Create( | ||
AST, llvm::APInt(UIntTySize, 0), AST.UnsignedIntTy, SourceLocation()); | ||
Args.push_back(Index); | ||
|
||
StringRef VarName = VD->getName(); | ||
StringLiteral *Name = StringLiteral::Create( | ||
AST, VarName, StringLiteralKind::Ordinary, false, | ||
AST.getStringLiteralArrayType(AST.CharTy.withConst(), VarName.size()), | ||
SourceLocation()); | ||
ImplicitCastExpr *NameCast = ImplicitCastExpr::Create( | ||
AST, AST.getPointerType(AST.CharTy.withConst()), CK_ArrayToPointerDecay, | ||
Name, nullptr, VK_PRValue, FPOptionsOverride()); | ||
Args.push_back(NameCast); | ||
|
||
// Make sure the create method template is instantiated and emitted. | ||
if (!CreateMethod->isDefined() && CreateMethod->isTemplateInstantiation()) | ||
SemaRef.InstantiateFunctionDefinition(VD->getLocation(), CreateMethod, | ||
true); | ||
|
||
// Create CallExpr with a call to the static method and set it as the decl | ||
// initialization. | ||
DeclRefExpr *DRE = DeclRefExpr::Create( | ||
AST, NestedNameSpecifierLoc(), SourceLocation(), CreateMethod, false, | ||
CreateMethod->getNameInfo(), CreateMethod->getType(), VK_PRValue); | ||
|
||
auto *ImpCast = ImplicitCastExpr::Create( | ||
AST, AST.getPointerType(CreateMethod->getType()), | ||
CK_FunctionToPointerDecay, DRE, nullptr, VK_PRValue, FPOptionsOverride()); | ||
|
||
CallExpr *InitExpr = | ||
CallExpr::Create(AST, ImpCast, Args, ResourceTy, VK_PRValue, | ||
SourceLocation(), FPOptionsOverride()); | ||
VD->setInit(InitExpr); | ||
VD->setInitStyle(VarDecl::CallInit); | ||
SemaRef.CheckCompleteVariableDeclaration(VD); | ||
return true; | ||
} | ||
|
||
bool SemaHLSL::initGlobalResourceArrayDecl(VarDecl *VD) { | ||
|
Uh oh!
There was an error while loading. Please reload this page.