Skip to content

Commit 04d225e

Browse files
committed
Layout fix and tests
1 parent c8a39c7 commit 04d225e

File tree

5 files changed

+81
-16
lines changed

5 files changed

+81
-16
lines changed

tools/clang/lib/SPIRV/AlignmentSizeCalculator.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ std::pair<uint32_t, uint32_t> AlignmentSizeCalculator::getAlignmentAndSize(
170170
if (rule == SpirvLayoutRule::Scalar) {
171171
// A structure has a scalar alignment equal to the largest scalar
172172
// alignment of any of its members in VK_EXT_scalar_block_layout.
173+
// Its size is rounded up to its final alignment for compatibility with
174+
// C structure layout, even if not strictly necessary.
175+
structSize = roundToPow2(structSize, maxAlignment);
173176
return {maxAlignment, structSize};
174177
}
175178

tools/clang/test/CodeGenSPIRV/array.scalar.layout.hlsl renamed to tools/clang/test/CodeGenSPIRV/scalar.layout.array.hlsl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %dxc -T cs_6_2 -E main %s -fvk-use-scalar-layout -spirv | FileCheck %s
22

3-
// Check that the array stride and offsets are corrects. The uint64_t has alignment
3+
// Check that the array stride and offsets are correct. The uint64_t has alignment
44
// 8 and the struct has size 12. So the stride should be the smallest multiple of 8
55
// greater than or equal to 12, which is 16.
66

@@ -9,13 +9,13 @@
99
// CHECK-DAG: OpDecorate %_runtimearr_Data ArrayStride 16
1010
// CHECK-DAG: OpMemberDecorate %type_RWStructuredBuffer_Data 0 Offset 0
1111
struct Data {
12-
uint64_t y;
13-
uint x;
12+
uint64_t y;
13+
uint x;
1414
};
15+
1516
RWStructuredBuffer<Data> buffer;
1617

1718
[numthreads(1, 1, 1)]
18-
void main()
19-
{
20-
buffer[0].x = 5;
19+
void main() {
20+
buffer[0].x = 5;
2121
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// RUN: %dxc -T cs_6_2 -E main %s -fvk-use-scalar-layout -spirv | FileCheck %s
2+
3+
// Check that the size of Foo and Bar gets rounded up to its alignment to follow
4+
// C-style layout rules. See #7894
5+
6+
// CHECK-DAG: OpMemberDecorate %Foo 0 Offset 0
7+
// CHECK-DAG: OpMemberDecorate %Foo 1 Offset 8
8+
// CHECK-DAG: OpMemberDecorate %Bar 0 Offset 0
9+
// CHECK-DAG: OpMemberDecorate %Bar 1 Offset 16
10+
// CHECK-DAG: OpDecorate %_runtimearr_Bar ArrayStride 24
11+
// CHECK-DAG: OpMemberDecorate %type_RWStructuredBuffer_Bar 0 Offset 0
12+
13+
struct Foo {
14+
uint64_t a;
15+
int b;
16+
};
17+
18+
struct Bar {
19+
Foo foo;
20+
int c;
21+
};
22+
23+
RWStructuredBuffer<Bar> buffer;
24+
25+
[numthreads(1, 1, 1)]
26+
void main(in uint3 threadId : SV_DispatchThreadID) {
27+
// CHECK: [[buf_0:%[0-9]+]] = OpAccessChain %_ptr_Uniform_int %buffer %int_0 %uint_0 %int_1
28+
// CHECK-NEXT: OpStore [[buf_0]] %int_16
29+
buffer[0].c = sizeof(Foo);
30+
// CHECK: [[buf_1:%[0-9]+]] = OpAccessChain %_ptr_Uniform_int %buffer %int_0 %uint_1 %int_1
31+
// CHECK-NEXT: OpStore [[buf_1]] %int_24
32+
buffer[1].c = sizeof(Bar);
33+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %dxc -T cs_6_2 -E main %s -fvk-use-scalar-layout -spirv | FileCheck %s
2+
3+
// Check that arrays of structs respect alignment requirements. Note that this
4+
// test does not distinguish between C-style and "strict" scalar layout.
5+
6+
// CHECK-DAG: OpMemberDecorate %Foo 0 Offset 0
7+
// CHECK-DAG: OpMemberDecorate %Foo 1 Offset 8
8+
// CHECK-DAG: OpDecorate %_arr_Foo_uint_3 ArrayStride 16
9+
// CHECK-DAG: OpMemberDecorate %Bar 0 Offset 0
10+
// CHECK-DAG: OpDecorate %_runtimearr_Bar ArrayStride 56
11+
// CHECK-DAG: OpMemberDecorate %type_RWStructuredBuffer_Bar 0 Offset 0
12+
13+
struct Foo {
14+
uint64_t a;
15+
int b;
16+
};
17+
18+
struct Bar {
19+
Foo foo[3];
20+
uint64_t c;
21+
};
22+
23+
RWStructuredBuffer<Bar> buffer;
24+
25+
[numthreads(1, 1, 1)] void main() {
26+
// CHECK: [[buf_0:%[0-9]+]] = OpAccessChain %_ptr_Uniform_ulong %buffer %int_0 %uint_0 %int_1
27+
// CHECK-NEXT: OpStore [[buf_0]] %ulong_56
28+
buffer[0].c = sizeof(Bar);
29+
}

tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.scalar.hlsl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ struct S { // Alignment Offset Size
99
float sf2; // 4 -> 8 + 4 = 12
1010
float3 sf3; // 4 -> 12 + 4 * 3 = 24
1111
float sf4; // 4 -> 24 + 4 = 28
12-
}; // 8(max) 28
12+
}; // 8(max) 32 (size rounded up to alignment)
1313

1414
struct T { // Alignment Offset Size = Next
1515
int tf1; // 4 -> 0 + 4 = 4
1616
R tf2[3]; // 8 -> 8 (4 round up to R alignment) + 3 * stride(8) = 32
1717
float3x2 tf3; // 4 -> 32 + 4 * 3 * 2 = 56
18-
S tf4; // 8 -> 56 + 28 = 84
19-
float16_t tf5; // 2 -> 84 + 2 = 86
20-
float tf6; // 4 -> 88 (86 round up to float align) + 4 = 92
21-
}; // 8(max) 92
18+
S tf4; // 8 -> 56 + 32 = 88
19+
float16_t tf5; // 2 -> 88 + 2 = 90
20+
float tf6; // 4 -> 92 (90 round up to float align) + 4 = 96
21+
}; // 8(max) 96
2222

2323
cbuffer MyCBuffer { // Alignment Offset Size Next
2424
bool a; // 4 -> 0 + 4 = 4
@@ -29,8 +29,8 @@ cbuffer MyCBuffer { // Alignment Offset
2929
float2x1 f; // 4 -> 68 + 4 * 2 = 76
3030
row_major float2x3 g[3]; // 4 -> 76 + 4 * 2 * 3 * 3 = 148
3131
column_major float2x2 h[4]; // 4 -> 148 + 4 * 2 * 2 * 4 = 212
32-
T t; // 8 -> 216 (212 round up to T alignment) + 92 = 308
33-
float z; // 4 -> 308
32+
T t; // 8 -> 216 (212 round up to T alignment) + 96 = 312
33+
float z; // 4 -> 312
3434
};
3535

3636
// CHECK: OpDecorate %_arr_mat2v3float_uint_3 ArrayStride 24
@@ -51,8 +51,8 @@ cbuffer MyCBuffer { // Alignment Offset
5151
// CHECK-NEXT: OpMemberDecorate %T 2 MatrixStride 12
5252
// CHECK-NEXT: OpMemberDecorate %T 2 RowMajor
5353
// CHECK-NEXT: OpMemberDecorate %T 3 Offset 56
54-
// CHECK-NEXT: OpMemberDecorate %T 4 Offset 84
55-
// CHECK-NEXT: OpMemberDecorate %T 5 Offset 88
54+
// CHECK-NEXT: OpMemberDecorate %T 4 Offset 88
55+
// CHECK-NEXT: OpMemberDecorate %T 5 Offset 92
5656

5757
// CHECK: OpMemberDecorate %type_MyCBuffer 0 Offset 0
5858
// CHECK-NEXT: OpMemberDecorate %type_MyCBuffer 1 Offset 4
@@ -71,7 +71,7 @@ cbuffer MyCBuffer { // Alignment Offset
7171
// CHECK-NEXT: OpMemberDecorate %type_MyCBuffer 7 MatrixStride 8
7272
// CHECK-NEXT: OpMemberDecorate %type_MyCBuffer 7 RowMajor
7373
// CHECK-NEXT: OpMemberDecorate %type_MyCBuffer 8 Offset 216
74-
// CHECK-NEXT: OpMemberDecorate %type_MyCBuffer 9 Offset 308
74+
// CHECK-NEXT: OpMemberDecorate %type_MyCBuffer 9 Offset 312
7575
// CHECK-NEXT: OpDecorate %type_MyCBuffer Block
7676

7777
float main() : A {

0 commit comments

Comments
 (0)