[llvm-branch-commits] [clang] [HLSL] Implement explicit layout for default constant buffer ($Globals) (PR #128991)
Damyan Pepper via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Feb 26 20:27:52 PST 2025
================
@@ -179,21 +179,45 @@ 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 quaranteed 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()) {
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();
+ size_t Offset = -1;
+ if (VD->hasAttrs()) {
+ for (auto *Attr : VD->getAttrs()) {
+ if (auto *POA = dyn_cast<HLSLPackOffsetAttr>(Attr)) {
+ Offset = POA->getOffsetInBytes();
+ } else if (auto *RBA = dyn_cast<HLSLResourceBindingAttr>(Attr)) {
+ if (RBA->getRegisterType() ==
+ HLSLResourceBindingAttr::RegisterType::C) {
+ // size of constant buffer row is 16 bytes
+ Offset = RBA->getSlotNumber() * 16U;
----------------
damyanp wrote:
It'd be nice if there was a named constant for this. At very least you wouldn't need the comment. At best, we have an easy way to find all the places that depend on the constant buffer row size.
https://github.com/llvm/llvm-project/pull/128991
More information about the llvm-branch-commits
mailing list