Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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);
}
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