-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[HLSL] Implement explicit layout for default constant buffer ($Globals) #128991
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
9faff90
e982a61
458d5f0
22d9d1f
7a45f4b
496ed3f
333966b
670f92f
c70a662
29db170
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 |
---|---|---|
|
@@ -40,6 +40,8 @@ using namespace CodeGen; | |
using namespace clang::hlsl; | ||
using namespace llvm; | ||
|
||
using llvm::hlsl::CBufferRowSizeInBytes; | ||
|
||
static void createResourceInitFn(CodeGenModule &CGM, llvm::GlobalVariable *GV, | ||
unsigned Slot, unsigned Space); | ||
|
||
|
@@ -70,7 +72,7 @@ void addDxilValVersion(StringRef ValVersionStr, llvm::Module &M) { | |
|
||
llvm::Type * | ||
CGHLSLRuntime::convertHLSLSpecificType(const Type *T, | ||
SmallVector<unsigned> *Packoffsets) { | ||
SmallVector<int32_t> *Packoffsets) { | ||
assert(T->isHLSLSpecificType() && "Not an HLSL specific type!"); | ||
|
||
// Check if the target has a specific translation for this type first. | ||
|
@@ -174,21 +176,50 @@ createBufferHandleType(const HLSLBufferDecl *BufDecl) { | |
return cast<HLSLAttributedResourceType>(QT.getTypePtr()); | ||
} | ||
|
||
// Iterates over all declarations in the HLSL buffer and based on the | ||
// packoffset or register(c#) annotations it fills outs the Layout | ||
// vector with the user-specified layout offsets. | ||
// The buffer offsets can be specified 2 ways: | ||
// 1. declarations in cbuffer {} block can have a packoffset annotation | ||
// (translates to HLSLPackOffsetAttr) | ||
// 2. default constant buffer declarations at global scope can have | ||
// register(c#) annotations (translates to HLSLResourceBindingAttr with | ||
// RegisterType::C) | ||
// It is not guaranteed that all declarations in a buffer have an annotation. | ||
// For those where it is not specified a -1 value is added to the Layout | ||
// vector. In the final layout these declarations will be placed at the end | ||
// of the HLSL buffer after all of the elements with specified offset. | ||
static void fillPackoffsetLayout(const HLSLBufferDecl *BufDecl, | ||
SmallVector<unsigned> &Layout) { | ||
SmallVector<int32_t> &Layout) { | ||
assert(Layout.empty() && "expected empty vector for layout"); | ||
assert(BufDecl->hasValidPackoffset()); | ||
|
||
for (Decl *D : BufDecl->decls()) { | ||
for (Decl *D : BufDecl->buffer_decls()) { | ||
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. nit: On formatting, it sounds like the llvm repo prefers 'auto *name' for for loops? 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. It depends. I got feedback in the past to not use |
||
if (isa<CXXRecordDecl, EmptyDecl>(D) || isa<FunctionDecl>(D)) { | ||
continue; | ||
} | ||
VarDecl *VD = dyn_cast<VarDecl>(D); | ||
if (!VD || VD->getType().getAddressSpace() != LangAS::hlsl_constant) | ||
continue; | ||
assert(VD->hasAttr<HLSLPackOffsetAttr>() && | ||
"expected packoffset attribute on every declaration"); | ||
size_t Offset = VD->getAttr<HLSLPackOffsetAttr>()->getOffsetInBytes(); | ||
|
||
if (!VD->hasAttrs()) { | ||
Layout.push_back(-1); | ||
continue; | ||
} | ||
|
||
int32_t Offset = -1; | ||
for (auto *Attr : VD->getAttrs()) { | ||
if (auto *POA = dyn_cast<HLSLPackOffsetAttr>(Attr)) { | ||
Offset = POA->getOffsetInBytes(); | ||
break; | ||
} | ||
auto *RBA = dyn_cast<HLSLResourceBindingAttr>(Attr); | ||
if (RBA && | ||
RBA->getRegisterType() == HLSLResourceBindingAttr::RegisterType::C) { | ||
Offset = RBA->getSlotNumber() * CBufferRowSizeInBytes; | ||
break; | ||
} | ||
} | ||
Layout.push_back(Offset); | ||
} | ||
} | ||
|
@@ -207,7 +238,7 @@ void CGHLSLRuntime::addBuffer(const HLSLBufferDecl *BufDecl) { | |
return; | ||
|
||
// create global variable for the constant buffer | ||
SmallVector<unsigned> Layout; | ||
SmallVector<int32_t> Layout; | ||
if (BufDecl->hasValidPackoffset()) | ||
fillPackoffsetLayout(BufDecl, Layout); | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.