Skip to content

Commit c6f3871

Browse files
committed
Address comments
1 parent e8b3032 commit c6f3871

File tree

2 files changed

+70
-55
lines changed

2 files changed

+70
-55
lines changed

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -174,23 +174,19 @@ Decl *SemaHLSL::ActOnStartBuffer(Scope *BufferScope, bool CBuffer,
174174

175175
static unsigned calculateLegacyCbufferFieldAlign(const ASTContext &Context,
176176
QualType T) {
177-
// Aggregate types are always aligned to new buffer rows
178-
if (T->isAggregateType())
177+
// Arrays and Structs are always aligned to new buffer rows
178+
if (T->isArrayType() || T->isStructureType())
179179
return 16;
180180

181+
// Vectors are aligned to the type they contain
182+
if (const VectorType *VT = T->getAs<VectorType>())
183+
return calculateLegacyCbufferFieldAlign(Context, VT->getElementType());
184+
181185
assert(Context.getTypeSize(T) <= 64 &&
182186
"Scalar bit widths larger than 64 not supported");
183187

184-
// 64 bit types such as double and uint64_t align to 8 bytes
185-
if (Context.getTypeSize(T) == 64)
186-
return 8;
187-
188-
// Half types align to 2 bytes only if native half is available
189-
if (T->isHalfType() && Context.getLangOpts().NativeHalfType)
190-
return 2;
191-
192-
// Everything else aligns to 4 bytes
193-
return 4;
188+
// Scalar types are aligned to their byte width
189+
return Context.getTypeSize(T) / 8;
194190
}
195191

196192
// Calculate the size of a legacy cbuffer type in bytes based on
@@ -205,6 +201,14 @@ static unsigned calculateLegacyCbufferSize(const ASTContext &Context,
205201
QualType Ty = Field->getType();
206202
unsigned FieldSize = calculateLegacyCbufferSize(Context, Ty);
207203
unsigned FieldAlign = calculateLegacyCbufferFieldAlign(Context, Ty);
204+
205+
// If the field crosses the row boundary after alignment it drops to the
206+
// next row
207+
unsigned AlignSize = llvm::alignTo(Size, FieldAlign);
208+
if ((AlignSize % CBufferAlign) + FieldSize > CBufferAlign) {
209+
FieldAlign = CBufferAlign;
210+
}
211+
208212
Size = llvm::alignTo(Size, FieldAlign);
209213
Size += FieldSize;
210214
}
Lines changed: 54 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,71 @@
11
// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
22
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
3-
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefix=CHECK-HALF
3+
// RUN: -fsyntax-only -verify -verify-ignore-unexpected=warning
44

5-
// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
6-
// RUN: dxil-pc-shadermodel6.3-library %s \
7-
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefix=CHECK-FLOAT
5+
struct S0 {
6+
half a;
7+
half b;
8+
half c;
9+
half d;
10+
half e;
11+
half f;
12+
half g;
13+
half h;
14+
};
15+
16+
cbuffer CB0Pass {
17+
S0 s0p : packoffset(c0.x);
18+
float f0p : packoffset(c1.x);
19+
}
820

21+
cbuffer CB0Fail {
22+
S0 s0f : packoffset(c0.x);
23+
float f0f : packoffset(c0.w);
24+
// expected-error@-1 {{packoffset overlap between 'f0f', 's0f'}}
25+
}
926

1027
struct S1 {
11-
half a; // 2 bytes + 2 bytes pad or 4 bytes
12-
float b; // 4 bytes
13-
half c; // 2 bytes + 2 bytes pad or 4 bytes
14-
float d; // 4 bytes
15-
double e; // 8 bytes
28+
float a;
29+
double b;
30+
float c;
1631
};
1732

18-
struct S2 {
19-
half a; // 2 bytes or 4 bytes
20-
half b; // 2 bytes or 4 bytes
21-
float e; // 4 bytes or 4 bytes + 4 padding
22-
double f; // 8 bytes
23-
};
33+
cbuffer CB1Pass {
34+
S1 s1p : packoffset(c0.x);
35+
float f1p : packoffset(c1.y);
36+
}
2437

25-
struct S3 {
26-
half a; // 2 bytes + 6 bytes pad or 4 bytes + 4 bytes pad
27-
uint64_t b; // 8 bytes
28-
};
38+
cbuffer CB1Fail {
39+
S1 s1f : packoffset(c0.x);
40+
float f1f : packoffset(c1.x);
41+
// expected-error@-1 {{packoffset overlap between 'f1f', 's1f'}}
42+
}
2943

30-
struct S4 {
31-
float a; // 4 bytes
32-
half b; // 2 bytes or 4 bytes
33-
half c; // 2 bytes or 4 bytes + 4 bytes pad
34-
double d; // 8 bytes
44+
struct S2 {
45+
float3 a;
46+
float2 b;
3547
};
3648

37-
38-
cbuffer CB0 {
39-
// CHECK-HALF: @CB0.cb = external constant target("dx.CBuffer", target("dx.Layout", %__cblayout_CB0, 24, 0))
40-
// CHECK-FLOAT: @CB0.cb = external constant target("dx.CBuffer", target("dx.Layout", %__cblayout_CB0, 24, 0))
41-
S1 s1;
49+
cbuffer CB2Pass {
50+
S2 s2p : packoffset(c0.x);
51+
float f2p : packoffset(c1.z);
4252
}
4353

44-
cbuffer CB1 {
45-
// CHECK-HALF: @CB1.cb = external constant target("dx.CBuffer", target("dx.Layout", %__cblayout_CB1, 16, 0))
46-
// CHECK-FLOAT: @CB1.cb = external constant target("dx.CBuffer", target("dx.Layout", %__cblayout_CB1, 24, 0))
47-
S2 s2;
54+
cbuffer CB2Fail {
55+
S2 s2f : packoffset(c0.x);
56+
float f2f : packoffset(c1.y);
57+
// expected-error@-1 {{packoffset overlap between 'f2f', 's2f'}}
4858
}
4959

50-
cbuffer CB2 {
51-
// CHECK-HALF: @CB2.cb = external constant target("dx.CBuffer", target("dx.Layout", %__cblayout_CB2, 16, 0))
52-
// CHECK-FLOAT: @CB2.cb = external constant target("dx.CBuffer", target("dx.Layout", %__cblayout_CB2, 16, 0))
53-
S3 s3;
54-
}
5560

56-
cbuffer CB3 {
57-
// CHECK-HALF: @CB3.cb = external constant target("dx.CBuffer", target("dx.Layout", %__cblayout_CB3, 16, 0))
58-
// CHECK-FLOAT: @CB3.cb = external constant target("dx.CBuffer", target("dx.Layout", %__cblayout_CB3, 24, 0))
59-
S4 s4;
60-
}
61+
#if 0
62+
struct S3 {
63+
float3 a;
64+
float b;
65+
};
66+
67+
struct S4 {
68+
float2 a;
69+
float2 b;
70+
};
71+
#endif

0 commit comments

Comments
 (0)