@@ -39,89 +39,9 @@ Decl *SemaHLSL::ActOnStartBuffer(Scope *BufferScope, bool CBuffer,
3939 return Result;
4040}
4141
42- // Calculate the size of a legacy cbuffer type based on
43- // https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-packing-rules
44- static unsigned calculateLegacyCbufferSize (const ASTContext &Context,
45- QualType T) {
46- unsigned Size = 0 ;
47- constexpr unsigned CBufferAlign = 128 ;
48- if (const RecordType *RT = T->getAs <RecordType>()) {
49- const RecordDecl *RD = RT->getDecl ();
50- for (const FieldDecl *Field : RD->fields ()) {
51- QualType Ty = Field->getType ();
52- unsigned FieldSize = calculateLegacyCbufferSize (Context, Ty);
53- unsigned FieldAlign = 32 ;
54- if (Ty->isAggregateType ())
55- FieldAlign = CBufferAlign;
56- Size = llvm::alignTo (Size, FieldAlign);
57- Size += FieldSize;
58- }
59- } else if (const ConstantArrayType *AT = Context.getAsConstantArrayType (T)) {
60- if (unsigned ElementCount = AT->getSize ().getZExtValue ()) {
61- unsigned ElementSize =
62- calculateLegacyCbufferSize (Context, AT->getElementType ());
63- unsigned AlignedElementSize = llvm::alignTo (ElementSize, CBufferAlign);
64- Size = AlignedElementSize * (ElementCount - 1 ) + ElementSize;
65- }
66- } else if (const VectorType *VT = T->getAs <VectorType>()) {
67- unsigned ElementCount = VT->getNumElements ();
68- unsigned ElementSize =
69- calculateLegacyCbufferSize (Context, VT->getElementType ());
70- Size = ElementSize * ElementCount;
71- } else {
72- Size = Context.getTypeSize (T);
73- }
74- return Size;
75- }
76-
7742void SemaHLSL::ActOnFinishBuffer (Decl *Dcl, SourceLocation RBrace) {
7843 auto *BufDecl = cast<HLSLBufferDecl>(Dcl);
7944 BufDecl->setRBraceLoc (RBrace);
80-
81- // Validate packoffset.
82- llvm::SmallVector<std::pair<VarDecl *, HLSLPackOffsetAttr *>> PackOffsetVec;
83- bool HasPackOffset = false ;
84- bool HasNonPackOffset = false ;
85- for (auto *Field : BufDecl->decls ()) {
86- VarDecl *Var = dyn_cast<VarDecl>(Field);
87- if (!Var)
88- continue ;
89- if (Field->hasAttr <HLSLPackOffsetAttr>()) {
90- PackOffsetVec.emplace_back (Var, Field->getAttr <HLSLPackOffsetAttr>());
91- HasPackOffset = true ;
92- } else {
93- HasNonPackOffset = true ;
94- }
95- }
96-
97- if (HasPackOffset && HasNonPackOffset)
98- Diag (BufDecl->getLocation (), diag::warn_hlsl_packoffset_mix);
99-
100- if (HasPackOffset) {
101- ASTContext &Context = getASTContext ();
102- // Make sure no overlap in packoffset.
103- // Sort PackOffsetVec by offset.
104- std::sort (PackOffsetVec.begin (), PackOffsetVec.end (),
105- [](const std::pair<VarDecl *, HLSLPackOffsetAttr *> &LHS,
106- const std::pair<VarDecl *, HLSLPackOffsetAttr *> &RHS) {
107- return LHS.second ->getOffset () < RHS.second ->getOffset ();
108- });
109-
110- for (unsigned i = 0 ; i < PackOffsetVec.size () - 1 ; i++) {
111- VarDecl *Var = PackOffsetVec[i].first ;
112- HLSLPackOffsetAttr *Attr = PackOffsetVec[i].second ;
113- unsigned Size = calculateLegacyCbufferSize (Context, Var->getType ());
114- unsigned Begin = Attr->getOffset () * 32 ;
115- unsigned End = Begin + Size;
116- unsigned NextBegin = PackOffsetVec[i + 1 ].second ->getOffset () * 32 ;
117- if (End > NextBegin) {
118- VarDecl *NextVar = PackOffsetVec[i + 1 ].first ;
119- Diag (NextVar->getLocation (), diag::err_hlsl_packoffset_overlap)
120- << NextVar << Var;
121- }
122- }
123- }
124-
12545 SemaRef.PopDeclContext ();
12646}
12747
0 commit comments