Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions tools/clang/lib/SPIRV/AlignmentSizeCalculator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ std::pair<uint32_t, uint32_t> AlignmentSizeCalculator::getAlignmentAndSize(
if (rule == SpirvLayoutRule::Scalar) {
// A structure has a scalar alignment equal to the largest scalar
// alignment of any of its members in VK_EXT_scalar_block_layout.
// Its size is rounded up to its final alignment for compatibility with
// C structure layout, even if not strictly necessary.
structSize = roundToPow2(structSize, maxAlignment);
return {maxAlignment, structSize};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// RUN: %dxc -T cs_6_2 -E main %s -fvk-use-scalar-layout -spirv | FileCheck %s

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

Expand All @@ -9,13 +9,13 @@
// CHECK-DAG: OpDecorate %_runtimearr_Data ArrayStride 16
// CHECK-DAG: OpMemberDecorate %type_RWStructuredBuffer_Data 0 Offset 0
struct Data {
uint64_t y;
uint x;
uint64_t y;
uint x;
};

RWStructuredBuffer<Data> buffer;

[numthreads(1, 1, 1)]
void main()
{
buffer[0].x = 5;
void main() {
buffer[0].x = 5;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// RUN: %dxc -T cs_6_2 -E main %s -fvk-use-scalar-layout -spirv | FileCheck %s

// Check that the size of Foo and Bar gets rounded up to its alignment to follow
// C-style layout rules. See #7894

// CHECK-DAG: OpMemberDecorate %Foo 0 Offset 0
// CHECK-DAG: OpMemberDecorate %Foo 1 Offset 8
// CHECK-DAG: OpMemberDecorate %Bar 0 Offset 0
// CHECK-DAG: OpMemberDecorate %Bar 1 Offset 16
// CHECK-DAG: OpDecorate %_runtimearr_Bar ArrayStride 24
// CHECK-DAG: OpMemberDecorate %type_RWStructuredBuffer_Bar 0 Offset 0

struct Foo {
uint64_t a;
int b;
};

struct Bar {
Foo foo;
int c;
};

RWStructuredBuffer<Bar> buffer;

[numthreads(1, 1, 1)]
void main(in uint3 threadId : SV_DispatchThreadID) {
// CHECK: [[buf_0:%[0-9]+]] = OpAccessChain %_ptr_Uniform_int %buffer %int_0 %uint_0 %int_1
// CHECK-NEXT: OpStore [[buf_0]] %int_16
buffer[0].c = sizeof(Foo);
// CHECK: [[buf_1:%[0-9]+]] = OpAccessChain %_ptr_Uniform_int %buffer %int_0 %uint_1 %int_1
// CHECK-NEXT: OpStore [[buf_1]] %int_24
buffer[1].c = sizeof(Bar);
}
29 changes: 29 additions & 0 deletions tools/clang/test/CodeGenSPIRV/scalar.layout.struct.array.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// RUN: %dxc -T cs_6_2 -E main %s -fvk-use-scalar-layout -spirv | FileCheck %s

// Check that arrays of structs respect alignment requirements. Note that this
// test does not distinguish between C-style and "strict" scalar layout.

// CHECK-DAG: OpMemberDecorate %Foo 0 Offset 0
// CHECK-DAG: OpMemberDecorate %Foo 1 Offset 8
// CHECK-DAG: OpDecorate %_arr_Foo_uint_3 ArrayStride 16
// CHECK-DAG: OpMemberDecorate %Bar 0 Offset 0
// CHECK-DAG: OpDecorate %_runtimearr_Bar ArrayStride 56
// CHECK-DAG: OpMemberDecorate %type_RWStructuredBuffer_Bar 0 Offset 0

struct Foo {
uint64_t a;
int b;
};

struct Bar {
Foo foo[3];
uint64_t c;
};

RWStructuredBuffer<Bar> buffer;

[numthreads(1, 1, 1)] void main() {
// CHECK: [[buf_0:%[0-9]+]] = OpAccessChain %_ptr_Uniform_ulong %buffer %int_0 %uint_0 %int_1
// CHECK-NEXT: OpStore [[buf_0]] %ulong_56
buffer[0].c = sizeof(Bar);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a new line here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

20 changes: 10 additions & 10 deletions tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.scalar.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ struct S { // Alignment Offset Size
float sf2; // 4 -> 8 + 4 = 12
float3 sf3; // 4 -> 12 + 4 * 3 = 24
float sf4; // 4 -> 24 + 4 = 28
}; // 8(max) 28
}; // 8(max) 32 (size rounded up to alignment)

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

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

// CHECK: OpDecorate %_arr_mat2v3float_uint_3 ArrayStride 24
Expand All @@ -51,8 +51,8 @@ cbuffer MyCBuffer { // Alignment Offset
// CHECK-NEXT: OpMemberDecorate %T 2 MatrixStride 12
// CHECK-NEXT: OpMemberDecorate %T 2 RowMajor
// CHECK-NEXT: OpMemberDecorate %T 3 Offset 56
// CHECK-NEXT: OpMemberDecorate %T 4 Offset 84
// CHECK-NEXT: OpMemberDecorate %T 5 Offset 88
// CHECK-NEXT: OpMemberDecorate %T 4 Offset 88
// CHECK-NEXT: OpMemberDecorate %T 5 Offset 92

// CHECK: OpMemberDecorate %type_MyCBuffer 0 Offset 0
// CHECK-NEXT: OpMemberDecorate %type_MyCBuffer 1 Offset 4
Expand All @@ -71,7 +71,7 @@ cbuffer MyCBuffer { // Alignment Offset
// CHECK-NEXT: OpMemberDecorate %type_MyCBuffer 7 MatrixStride 8
// CHECK-NEXT: OpMemberDecorate %type_MyCBuffer 7 RowMajor
// CHECK-NEXT: OpMemberDecorate %type_MyCBuffer 8 Offset 216
// CHECK-NEXT: OpMemberDecorate %type_MyCBuffer 9 Offset 308
// CHECK-NEXT: OpMemberDecorate %type_MyCBuffer 9 Offset 312
// CHECK-NEXT: OpDecorate %type_MyCBuffer Block

float main() : A {
Expand Down