Skip to content

Commit 86da226

Browse files
authored
Fix aligment for empty structs (microsoft#6635)
We have a special case to that the the size and alignment for an empty struct is `{1,0}`. However that is not correct. See https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#interfaces-alignment-requirements. > An empty structure has a base alignment equal to the size of the smallest scalar type permitted by the capabilities declared in the SPIR-V module. (e.g., for a 1 byte aligned empty struct in the StorageBuffer storage class, StorageBuffer8BitAccess or UniformAndStorageBuffer8BitAccess must be declared in the SPIR-V module. I'm not 100% sure how DXC handle this minimum alignment, but I figured I would inialize the alignment to 1. If there are not members, then it will remain 1, and I would let the rest of the logic happen. No special case. Fixes microsoft#2882
1 parent 0bdd15b commit 86da226

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

tools/clang/lib/SPIRV/AlignmentSizeCalculator.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,7 @@ void AlignmentSizeCalculator::alignUsingHLSLRelaxedLayout(
6666
std::pair<uint32_t, uint32_t> AlignmentSizeCalculator::getAlignmentAndSize(
6767
QualType type, const RecordType *structType, SpirvLayoutRule rule,
6868
llvm::Optional<bool> isRowMajor, uint32_t *stride) const {
69-
bool hasBaseStructs = type->getAsCXXRecordDecl() &&
70-
type->getAsCXXRecordDecl()->getNumBases() > 0;
71-
72-
// Special case for handling empty structs, whose size is 0 and has no
73-
// requirement over alignment (thus 1).
74-
if (structType->getDecl()->field_empty() && !hasBaseStructs)
75-
return {1, 0};
76-
77-
uint32_t maxAlignment = 0;
69+
uint32_t maxAlignment = 1;
7870
uint32_t structSize = 0;
7971

8072
// If this struct is derived from some other structs, place an implicit
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s -check-prefix=RELAXED
2+
// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv -fvk-use-gl-layout | FileCheck %s -check-prefix=RELAXED
3+
// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv -fvk-use-scalar-layout | FileCheck %s -check-prefix=SCALAR
4+
5+
struct empty_struct { };
6+
7+
8+
// RELAXED: OpMemberDecorate %type_cb 0 Offset 0
9+
// RELAXED: OpMemberDecorate %type_cb 1 Offset 16
10+
// RELAXED: OpMemberDecorate %type_cb 2 Offset 16
11+
// RELAXED: OpMemberDecorate %type_cb 3 Offset 32
12+
13+
// SCALAR: OpMemberDecorate %type_cb 0 Offset 0
14+
// SCALAR: OpMemberDecorate %type_cb 1 Offset 12
15+
// SCALAR: OpMemberDecorate %type_cb 2 Offset 12
16+
// SCALAR: OpMemberDecorate %type_cb 3 Offset 20
17+
18+
cbuffer cb
19+
{
20+
float3 a;
21+
empty_struct b;
22+
float2 c;
23+
24+
float4 test;
25+
};
26+
27+
float4 main() : SV_TARGET
28+
{
29+
return test;
30+
}

0 commit comments

Comments
 (0)