Skip to content

[HLSL] Implement default constant buffer $Globals (2nd attempt) #128589

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

Merged
merged 3 commits into from
Feb 26, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions clang/include/clang/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -5045,22 +5045,26 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext {
// LayoutStruct - Layout struct for the buffer
CXXRecordDecl *LayoutStruct;

// For default (implicit) constant buffer, a lisf of references of global
// For default (implicit) constant buffer, an array of references of global
// decls that belong to the buffer. The decls are already parented by the
// translation unit context.
SmallVector<Decl *> DefaultBufferDecls;
// translation unit context. The array is allocated by the ASTContext
// allocator in HLSLBufferDecl::CreateDefaultCBuffer.
ArrayRef<Decl *> DefaultBufferDecls;

HLSLBufferDecl(DeclContext *DC, bool CBuffer, SourceLocation KwLoc,
IdentifierInfo *ID, SourceLocation IDLoc,
SourceLocation LBrace);

void setDefaultBufferDecls(ArrayRef<Decl *> Decls);

public:
static HLSLBufferDecl *Create(ASTContext &C, DeclContext *LexicalParent,
bool CBuffer, SourceLocation KwLoc,
IdentifierInfo *ID, SourceLocation IDLoc,
SourceLocation LBrace);
static HLSLBufferDecl *CreateDefaultCBuffer(ASTContext &C,
DeclContext *LexicalParent);
static HLSLBufferDecl *
CreateDefaultCBuffer(ASTContext &C, DeclContext *LexicalParent,
ArrayRef<Decl *> DefaultCBufferDecls);
static HLSLBufferDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

SourceRange getSourceRange() const override LLVM_READONLY {
Expand All @@ -5075,7 +5079,6 @@ class HLSLBufferDecl final : public NamedDecl, public DeclContext {
bool hasValidPackoffset() const { return HasValidPackoffset; }
const CXXRecordDecl *getLayoutStruct() const { return LayoutStruct; }
void addLayoutStruct(CXXRecordDecl *LS);
void addDefaultBufferDecl(Decl *D);

// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Expand Down
5 changes: 3 additions & 2 deletions clang/include/clang/Sema/SemaHLSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,9 @@ class SemaHLSL : public SemaBase {
// List of all resource bindings
ResourceBindings Bindings;

// default constant buffer $Globals
HLSLBufferDecl *DefaultCBuffer;
// Global declaration collected for the $Globals default constant
// buffer which will be created at the end of the translation unit.
llvm::SmallVector<Decl *> DefaultCBufferDecls;

private:
void collectResourceBindingsOnVarDecl(VarDecl *D);
Expand Down
15 changes: 11 additions & 4 deletions clang/lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5747,13 +5747,20 @@ HLSLBufferDecl *HLSLBufferDecl::Create(ASTContext &C,
}

HLSLBufferDecl *
HLSLBufferDecl::CreateDefaultCBuffer(ASTContext &C,
DeclContext *LexicalParent) {
HLSLBufferDecl::CreateDefaultCBuffer(ASTContext &C, DeclContext *LexicalParent,
ArrayRef<Decl *> DefaultCBufferDecls) {
DeclContext *DC = LexicalParent;
IdentifierInfo *II = &C.Idents.get("$Globals", tok::TokenKind::identifier);
HLSLBufferDecl *Result = new (C, DC) HLSLBufferDecl(
DC, true, SourceLocation(), II, SourceLocation(), SourceLocation());
Result->setImplicit(true);

// allocate array for default decls with ASTContext allocator
assert(!DefaultCBufferDecls.empty());
Decl **DeclsArray = new (C) Decl *[DefaultCBufferDecls.size()];
std::copy(DefaultCBufferDecls.begin(), DefaultCBufferDecls.end(), DeclsArray);
Result->setDefaultBufferDecls(
ArrayRef<Decl *>(DeclsArray, DefaultCBufferDecls.size()));
return Result;
}

Expand All @@ -5769,11 +5776,11 @@ void HLSLBufferDecl::addLayoutStruct(CXXRecordDecl *LS) {
addDecl(LS);
}

void HLSLBufferDecl::addDefaultBufferDecl(Decl *D) {
void HLSLBufferDecl::setDefaultBufferDecls(ArrayRef<Decl *> Decls) {
assert(isImplicit() &&
"default decls can only be added to the implicit/default constant "
"buffer $Globals");
DefaultBufferDecls.push_back(D);
DefaultBufferDecls = Decls;
}

HLSLBufferDecl::buffer_decl_iterator
Expand Down
14 changes: 7 additions & 7 deletions clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ bool ResourceBindings::hasBindingInfoForDecl(const VarDecl *VD) const {
return DeclToBindingListIndex.contains(VD);
}

SemaHLSL::SemaHLSL(Sema &S) : SemaBase(S), DefaultCBuffer(nullptr) {}
SemaHLSL::SemaHLSL(Sema &S) : SemaBase(S) {}

Decl *SemaHLSL::ActOnStartBuffer(Scope *BufferScope, bool CBuffer,
SourceLocation KwLoc, IdentifierInfo *Ident,
Expand Down Expand Up @@ -1931,7 +1931,10 @@ void DiagnoseHLSLAvailability::CheckDeclAvailability(NamedDecl *D,

void SemaHLSL::ActOnEndOfTranslationUnit(TranslationUnitDecl *TU) {
// process default CBuffer - create buffer layout struct and invoke codegenCGH
if (DefaultCBuffer) {
if (!DefaultCBufferDecls.empty()) {
HLSLBufferDecl *DefaultCBuffer = HLSLBufferDecl::CreateDefaultCBuffer(
SemaRef.getASTContext(), SemaRef.getCurLexicalContext(),
DefaultCBufferDecls);
SemaRef.getCurLexicalContext()->addDecl(DefaultCBuffer);
createHostLayoutStructForBuffer(SemaRef, DefaultCBuffer);

Expand Down Expand Up @@ -3025,16 +3028,13 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {

// Global variables outside a cbuffer block that are not a resource, static,
// groupshared, or an empty array or struct belong to the default constant
// buffer $Globals
// buffer $Globals (to be created at the end of the translation unit).
if (IsDefaultBufferConstantDecl(VD)) {
if (DefaultCBuffer == nullptr)
DefaultCBuffer = HLSLBufferDecl::CreateDefaultCBuffer(
SemaRef.getASTContext(), SemaRef.getCurLexicalContext());
// update address space to hlsl_constant
QualType NewTy = getASTContext().getAddrSpaceQualType(
VD->getType(), LangAS::hlsl_constant);
VD->setType(NewTy);
DefaultCBuffer->addDefaultBufferDecl(VD);
DefaultCBufferDecls.push_back(VD);
}

// find all resources bindings on decl
Expand Down