Skip to content

Commit c4a9c64

Browse files
committed
[HLSL][DirectX] Use a padding type for HLSL buffers.
This change drops the use of the "Layout" type and instead uses explicit padding throughout the compiler to represent types in HLSL buffers. There are a few parts to this, though it's difficult to split them up as they're very interdependent: 1. Refactor HLSLBufferLayoutBuilder to allow us to calculate the padding of arbitrary types. 2. Teach Clang CodeGen to use HLSL specific paths for cbuffers when generating aggregate copies, array accesses, and structure accesses. 3. Simplify DXILCBufferAccesses such that it directly replaces accesses with dx.resource.getpointer rather than recalculating the layout. 4. Basic infrastructure for SPIR-V handling, but the implementation itself will need work in follow ups. Fixes several issues, including #138996, #144573, and #156084. Resolves #147352.
1 parent 75ef0be commit c4a9c64

37 files changed

+972
-1330
lines changed

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4641,11 +4641,17 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
46414641
LHS.getBaseInfo(), TBAAAccessInfo());
46424642
}
46434643

4644-
// The HLSL runtime handle the subscript expression on global resource arrays.
4645-
if (getLangOpts().HLSL && (E->getType()->isHLSLResourceRecord() ||
4646-
E->getType()->isHLSLResourceRecordArray())) {
4647-
std::optional<LValue> LV =
4648-
CGM.getHLSLRuntime().emitResourceArraySubscriptExpr(E, *this);
4644+
// The HLSL runtime handles subscript expressions on global resource arrays
4645+
// and objects with HLSL buffer layouts.
4646+
if (getLangOpts().HLSL) {
4647+
std::optional<LValue> LV;
4648+
if (E->getType()->isHLSLResourceRecord() ||
4649+
E->getType()->isHLSLResourceRecordArray()) {
4650+
LV = CGM.getHLSLRuntime().emitResourceArraySubscriptExpr(E, *this);
4651+
} else if (E->getType().getAddressSpace() == LangAS::hlsl_constant) {
4652+
LV = CGM.getHLSLRuntime().emitBufferArraySubscriptExpr(E, *this,
4653+
EmitIdxAfterBase);
4654+
}
46494655
if (LV.has_value())
46504656
return *LV;
46514657
}
@@ -5110,6 +5116,11 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
51105116
EmitIgnoredExpr(E->getBase());
51115117
return EmitDeclRefLValue(DRE);
51125118
}
5119+
if (getLangOpts().HLSL &&
5120+
E->getType().getAddressSpace() == LangAS::hlsl_constant) {
5121+
// We have an HLSL buffer - emit using HLSL's layout rules.
5122+
return CGM.getHLSLRuntime().emitBufferMemberExpr(*this, E);
5123+
}
51135124

51145125
Expr *BaseExpr = E->getBase();
51155126
// Check whether the underlying base pointer is a constant null.

clang/lib/CodeGen/CGExprAgg.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2279,6 +2279,10 @@ void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, QualType Ty,
22792279
}
22802280
}
22812281

2282+
if (getLangOpts().HLSL && Ty.getAddressSpace() == LangAS::hlsl_constant)
2283+
if (CGM.getHLSLRuntime().emitBufferCopy(*this, DestPtr, SrcPtr, Ty))
2284+
return;
2285+
22822286
// Aggregate assignment turns into llvm.memcpy. This is almost valid per
22832287
// C99 6.5.16.1p3, which states "If the value being stored in an object is
22842288
// read from another object that overlaps in anyway the storage of the first

0 commit comments

Comments
 (0)