Add semantic::Struct::SizeNoPadding

This is the size of the structure without the trailing alignment
padding. This is what the Dawn needs from the Inspector.

Fixed: tint:653
Change-Id: Iaa01ba949e114973e4a33e084fc10ef9e111016c
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/45120
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2021-03-17 21:54:13 +00:00 committed by Commit Bot service account
parent 96829ed314
commit ad97343214
7 changed files with 170 additions and 5 deletions

View File

@ -392,6 +392,7 @@ std::vector<ResourceBinding> Inspector::GetUniformBufferResourceBindings(
entry.bind_group = binding_info.group->value();
entry.binding = binding_info.binding->value();
entry.size = sem->Size();
entry.size_no_padding = sem->SizeNoPadding();
result.push_back(entry);
}
@ -567,6 +568,7 @@ std::vector<ResourceBinding> Inspector::GetStorageBufferResourceBindingsImpl(
entry.bind_group = binding_info.group->value();
entry.binding = binding_info.binding->value();
entry.size = sem->Size();
entry.size_no_padding = sem->SizeNoPadding();
result.push_back(entry);
}

View File

@ -114,6 +114,9 @@ struct ResourceBinding {
uint32_t binding;
/// Size for this binding, in bytes, if defined.
uint64_t size;
/// Size for this binding without trailing structure padding, in bytes, if
/// defined.
uint64_t size_no_padding;
/// Dimensionality of this binding, if defined.
TextureDimension dim;
/// Kind of data being sampled, if defined.

View File

@ -1573,6 +1573,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, Simple) {
EXPECT_EQ(0u, result[0].bind_group);
EXPECT_EQ(0u, result[0].binding);
EXPECT_EQ(4u, result[0].size);
EXPECT_EQ(4u, result[0].size_no_padding);
}
TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleMembers) {
@ -1600,6 +1601,35 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleMembers) {
EXPECT_EQ(0u, result[0].bind_group);
EXPECT_EQ(0u, result[0].binding);
EXPECT_EQ(12u, result[0].size);
EXPECT_EQ(12u, result[0].size_no_padding);
}
TEST_F(InspectorGetUniformBufferResourceBindingsTest, ContainingPadding) {
type::Struct* foo_struct_type =
MakeUniformBufferType("foo_type", {ty.vec3<f32>()});
AddUniformBuffer("foo_ub", foo_struct_type, 0, 0);
MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub",
{{0, ty.vec3<f32>()}});
MakeCallerBodyFunction(
"ep_func", {"ub_func"},
ast::DecorationList{
create<ast::StageDecoration>(ast::PipelineStage::kVertex),
});
Inspector& inspector = Build();
auto result = inspector.GetUniformBufferResourceBindings("ep_func");
ASSERT_FALSE(inspector.has_error()) << inspector.error();
ASSERT_EQ(1u, result.size());
EXPECT_EQ(ResourceBinding::ResourceType::kUniformBuffer,
result[0].resource_type);
EXPECT_EQ(0u, result[0].bind_group);
EXPECT_EQ(0u, result[0].binding);
EXPECT_EQ(16u, result[0].size);
EXPECT_EQ(12u, result[0].size_no_padding);
}
TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleUniformBuffers) {
@ -1641,18 +1671,21 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleUniformBuffers) {
EXPECT_EQ(0u, result[0].bind_group);
EXPECT_EQ(0u, result[0].binding);
EXPECT_EQ(12u, result[0].size);
EXPECT_EQ(12u, result[0].size_no_padding);
EXPECT_EQ(ResourceBinding::ResourceType::kUniformBuffer,
result[1].resource_type);
EXPECT_EQ(0u, result[1].bind_group);
EXPECT_EQ(1u, result[1].binding);
EXPECT_EQ(12u, result[1].size);
EXPECT_EQ(12u, result[1].size_no_padding);
EXPECT_EQ(ResourceBinding::ResourceType::kUniformBuffer,
result[2].resource_type);
EXPECT_EQ(2u, result[2].bind_group);
EXPECT_EQ(0u, result[2].binding);
EXPECT_EQ(12u, result[2].size);
EXPECT_EQ(12u, result[2].size_no_padding);
}
TEST_F(InspectorGetUniformBufferResourceBindingsTest, ContainingArray) {
@ -1682,6 +1715,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, ContainingArray) {
EXPECT_EQ(0u, result[0].bind_group);
EXPECT_EQ(0u, result[0].binding);
EXPECT_EQ(20u, result[0].size);
EXPECT_EQ(20u, result[0].size_no_padding);
}
TEST_F(InspectorGetStorageBufferResourceBindingsTest, Simple) {
@ -1710,6 +1744,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, Simple) {
EXPECT_EQ(0u, result[0].bind_group);
EXPECT_EQ(0u, result[0].binding);
EXPECT_EQ(4u, result[0].size);
EXPECT_EQ(4u, result[0].size_no_padding);
}
TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleMembers) {
@ -1739,6 +1774,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleMembers) {
EXPECT_EQ(0u, result[0].bind_group);
EXPECT_EQ(0u, result[0].binding);
EXPECT_EQ(12u, result[0].size);
EXPECT_EQ(12u, result[0].size_no_padding);
}
TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleStorageBuffers) {
@ -1785,18 +1821,21 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleStorageBuffers) {
EXPECT_EQ(0u, result[0].bind_group);
EXPECT_EQ(0u, result[0].binding);
EXPECT_EQ(12u, result[0].size);
EXPECT_EQ(12u, result[0].size_no_padding);
EXPECT_EQ(ResourceBinding::ResourceType::kStorageBuffer,
result[1].resource_type);
EXPECT_EQ(0u, result[1].bind_group);
EXPECT_EQ(1u, result[1].binding);
EXPECT_EQ(12u, result[1].size);
EXPECT_EQ(12u, result[1].size_no_padding);
EXPECT_EQ(ResourceBinding::ResourceType::kStorageBuffer,
result[2].resource_type);
EXPECT_EQ(2u, result[2].bind_group);
EXPECT_EQ(0u, result[2].binding);
EXPECT_EQ(12u, result[2].size);
EXPECT_EQ(12u, result[2].size_no_padding);
}
TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingArray) {
@ -1825,6 +1864,7 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingArray) {
EXPECT_EQ(0u, result[0].bind_group);
EXPECT_EQ(0u, result[0].binding);
EXPECT_EQ(20u, result[0].size);
EXPECT_EQ(20u, result[0].size_no_padding);
}
TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingRuntimeArray) {
@ -1853,6 +1893,37 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingRuntimeArray) {
EXPECT_EQ(0u, result[0].bind_group);
EXPECT_EQ(0u, result[0].binding);
EXPECT_EQ(8u, result[0].size);
EXPECT_EQ(8u, result[0].size_no_padding);
}
TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingPadding) {
type::Struct* foo_struct_type;
type::AccessControl* foo_control_type;
std::tie(foo_struct_type, foo_control_type) =
MakeStorageBufferTypes("foo_type", {ty.vec3<f32>()});
AddStorageBuffer("foo_sb", foo_control_type, 0, 0);
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
{{0, ty.vec3<f32>()}});
MakeCallerBodyFunction(
"ep_func", {"sb_func"},
ast::DecorationList{
create<ast::StageDecoration>(ast::PipelineStage::kVertex),
});
Inspector& inspector = Build();
auto result = inspector.GetStorageBufferResourceBindings("ep_func");
ASSERT_FALSE(inspector.has_error()) << inspector.error();
ASSERT_EQ(1u, result.size());
EXPECT_EQ(ResourceBinding::ResourceType::kStorageBuffer,
result[0].resource_type);
EXPECT_EQ(0u, result[0].bind_group);
EXPECT_EQ(0u, result[0].binding);
EXPECT_EQ(16u, result[0].size);
EXPECT_EQ(12u, result[0].size_no_padding);
}
TEST_F(InspectorGetStorageBufferResourceBindingsTest, SkipReadOnly) {
@ -1903,6 +1974,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, Simple) {
EXPECT_EQ(0u, result[0].bind_group);
EXPECT_EQ(0u, result[0].binding);
EXPECT_EQ(4u, result[0].size);
EXPECT_EQ(4u, result[0].size_no_padding);
}
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
@ -1950,18 +2022,21 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
EXPECT_EQ(0u, result[0].bind_group);
EXPECT_EQ(0u, result[0].binding);
EXPECT_EQ(12u, result[0].size);
EXPECT_EQ(12u, result[0].size_no_padding);
EXPECT_EQ(ResourceBinding::ResourceType::kReadOnlyStorageBuffer,
result[1].resource_type);
EXPECT_EQ(0u, result[1].bind_group);
EXPECT_EQ(1u, result[1].binding);
EXPECT_EQ(12u, result[1].size);
EXPECT_EQ(12u, result[1].size_no_padding);
EXPECT_EQ(ResourceBinding::ResourceType::kReadOnlyStorageBuffer,
result[2].resource_type);
EXPECT_EQ(2u, result[2].bind_group);
EXPECT_EQ(0u, result[2].binding);
EXPECT_EQ(12u, result[2].size);
EXPECT_EQ(12u, result[2].size_no_padding);
}
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, ContainingArray) {
@ -1990,6 +2065,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, ContainingArray) {
EXPECT_EQ(0u, result[0].bind_group);
EXPECT_EQ(0u, result[0].binding);
EXPECT_EQ(20u, result[0].size);
EXPECT_EQ(20u, result[0].size_no_padding);
}
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
@ -2019,6 +2095,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
EXPECT_EQ(0u, result[0].bind_group);
EXPECT_EQ(0u, result[0].binding);
EXPECT_EQ(8u, result[0].size);
EXPECT_EQ(8u, result[0].size_no_padding);
}
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, SkipNonReadOnly) {

View File

@ -1448,10 +1448,11 @@ const semantic::Struct* Resolver::Structure(type::Struct* str) {
struct_align = std::max(struct_align, align);
}
auto size_no_padding = struct_size;
struct_size = utils::RoundUp(struct_align, struct_size);
auto* sem = builder_->create<semantic::Struct>(str, std::move(sem_members),
struct_align, struct_size);
auto* sem = builder_->create<semantic::Struct>(
str, std::move(sem_members), struct_align, struct_size, size_no_padding);
builder_->Sem().Add(str, sem);
return sem;
}

View File

@ -36,13 +36,17 @@ TEST_F(ResolverStructLayoutTest, Scalars) {
auto* sem = Sem().Get(s);
ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 12u);
EXPECT_EQ(sem->SizeNoPadding(), 12u);
EXPECT_EQ(sem->Align(), 4u);
ASSERT_EQ(sem->Members().size(), 3u);
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 4u);
EXPECT_EQ(sem->Members()[0]->Size(), 4u);
EXPECT_EQ(sem->Members()[1]->Offset(), 4u);
EXPECT_EQ(sem->Members()[1]->Align(), 4u);
EXPECT_EQ(sem->Members()[1]->Size(), 4u);
EXPECT_EQ(sem->Members()[2]->Offset(), 8u);
EXPECT_EQ(sem->Members()[2]->Align(), 4u);
EXPECT_EQ(sem->Members()[2]->Size(), 4u);
}
@ -57,11 +61,14 @@ TEST_F(ResolverStructLayoutTest, Alias) {
auto* sem = Sem().Get(s);
ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 8u);
EXPECT_EQ(sem->SizeNoPadding(), 8u);
EXPECT_EQ(sem->Align(), 4u);
ASSERT_EQ(sem->Members().size(), 2u);
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 4u);
EXPECT_EQ(sem->Members()[0]->Size(), 4u);
EXPECT_EQ(sem->Members()[1]->Offset(), 4u);
EXPECT_EQ(sem->Members()[1]->Align(), 4u);
EXPECT_EQ(sem->Members()[1]->Size(), 4u);
}
@ -77,13 +84,17 @@ TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayStaticSize) {
auto* sem = Sem().Get(s);
ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 36u);
EXPECT_EQ(sem->SizeNoPadding(), 36u);
EXPECT_EQ(sem->Align(), 4u);
ASSERT_EQ(sem->Members().size(), 3u);
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 4u);
EXPECT_EQ(sem->Members()[0]->Size(), 12u);
EXPECT_EQ(sem->Members()[1]->Offset(), 12u);
EXPECT_EQ(sem->Members()[1]->Align(), 4u);
EXPECT_EQ(sem->Members()[1]->Size(), 20u);
EXPECT_EQ(sem->Members()[2]->Offset(), 32u);
EXPECT_EQ(sem->Members()[2]->Align(), 4u);
EXPECT_EQ(sem->Members()[2]->Size(), 4u);
}
@ -99,13 +110,17 @@ TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayStaticSize) {
auto* sem = Sem().Get(s);
ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 136u);
EXPECT_EQ(sem->SizeNoPadding(), 136u);
EXPECT_EQ(sem->Align(), 4u);
ASSERT_EQ(sem->Members().size(), 3u);
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 4u);
EXPECT_EQ(sem->Members()[0]->Size(), 24u);
EXPECT_EQ(sem->Members()[1]->Offset(), 24u);
EXPECT_EQ(sem->Members()[1]->Align(), 4u);
EXPECT_EQ(sem->Members()[1]->Size(), 80u);
EXPECT_EQ(sem->Members()[2]->Offset(), 104u);
EXPECT_EQ(sem->Members()[2]->Align(), 4u);
EXPECT_EQ(sem->Members()[2]->Size(), 32u);
}
@ -119,9 +134,11 @@ TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayRuntimeSized) {
auto* sem = Sem().Get(s);
ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 4u);
EXPECT_EQ(sem->SizeNoPadding(), 4u);
EXPECT_EQ(sem->Align(), 4u);
ASSERT_EQ(sem->Members().size(), 1u);
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 4u);
EXPECT_EQ(sem->Members()[0]->Size(), 4u);
}
@ -135,9 +152,11 @@ TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayRuntimeSized) {
auto* sem = Sem().Get(s);
ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 32u);
EXPECT_EQ(sem->SizeNoPadding(), 32u);
EXPECT_EQ(sem->Align(), 4u);
ASSERT_EQ(sem->Members().size(), 1u);
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 4u);
EXPECT_EQ(sem->Members()[0]->Size(), 32u);
}
@ -153,9 +172,11 @@ TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayOfExplicitStrideArray) {
auto* sem = Sem().Get(s);
ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 384u);
EXPECT_EQ(sem->SizeNoPadding(), 384u);
EXPECT_EQ(sem->Align(), 4u);
ASSERT_EQ(sem->Members().size(), 1u);
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 4u);
EXPECT_EQ(sem->Members()[0]->Size(), 384u);
}
@ -175,9 +196,11 @@ TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayOfStructure) {
auto* sem = Sem().Get(s);
ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 576u);
EXPECT_EQ(sem->SizeNoPadding(), 576u);
EXPECT_EQ(sem->Align(), 16u);
ASSERT_EQ(sem->Members().size(), 1u);
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 16u);
EXPECT_EQ(sem->Members()[0]->Size(), 576u);
}
@ -193,13 +216,17 @@ TEST_F(ResolverStructLayoutTest, Vector) {
auto* sem = Sem().Get(s);
ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 48u);
EXPECT_EQ(sem->SizeNoPadding(), 48u);
EXPECT_EQ(sem->Align(), 16u);
ASSERT_EQ(sem->Members().size(), 3u);
EXPECT_EQ(sem->Members()[0]->Offset(), 0u); // vec2
EXPECT_EQ(sem->Members()[0]->Align(), 8u);
EXPECT_EQ(sem->Members()[0]->Size(), 8u);
EXPECT_EQ(sem->Members()[1]->Offset(), 16u); // vec3
EXPECT_EQ(sem->Members()[1]->Align(), 16u);
EXPECT_EQ(sem->Members()[1]->Size(), 12u);
EXPECT_EQ(sem->Members()[2]->Offset(), 32u); // vec4
EXPECT_EQ(sem->Members()[2]->Align(), 16u);
EXPECT_EQ(sem->Members()[2]->Size(), 16u);
}
@ -221,25 +248,35 @@ TEST_F(ResolverStructLayoutTest, Matrix) {
auto* sem = Sem().Get(s);
ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 368u);
EXPECT_EQ(sem->SizeNoPadding(), 368u);
EXPECT_EQ(sem->Align(), 16u);
ASSERT_EQ(sem->Members().size(), 9u);
EXPECT_EQ(sem->Members()[0]->Offset(), 0u); // mat2x2
EXPECT_EQ(sem->Members()[0]->Align(), 8u);
EXPECT_EQ(sem->Members()[0]->Size(), 16u);
EXPECT_EQ(sem->Members()[1]->Offset(), 16u); // mat2x3
EXPECT_EQ(sem->Members()[1]->Align(), 16u);
EXPECT_EQ(sem->Members()[1]->Size(), 32u);
EXPECT_EQ(sem->Members()[2]->Offset(), 48u); // mat2x4
EXPECT_EQ(sem->Members()[2]->Align(), 16u);
EXPECT_EQ(sem->Members()[2]->Size(), 32u);
EXPECT_EQ(sem->Members()[3]->Offset(), 80u); // mat3x2
EXPECT_EQ(sem->Members()[3]->Align(), 8u);
EXPECT_EQ(sem->Members()[3]->Size(), 24u);
EXPECT_EQ(sem->Members()[4]->Offset(), 112u); // mat3x3
EXPECT_EQ(sem->Members()[4]->Align(), 16u);
EXPECT_EQ(sem->Members()[4]->Size(), 48u);
EXPECT_EQ(sem->Members()[5]->Offset(), 160u); // mat3x4
EXPECT_EQ(sem->Members()[5]->Align(), 16u);
EXPECT_EQ(sem->Members()[5]->Size(), 48u);
EXPECT_EQ(sem->Members()[6]->Offset(), 208u); // mat4x2
EXPECT_EQ(sem->Members()[6]->Align(), 8u);
EXPECT_EQ(sem->Members()[6]->Size(), 32u);
EXPECT_EQ(sem->Members()[7]->Offset(), 240u); // mat4x3
EXPECT_EQ(sem->Members()[7]->Align(), 16u);
EXPECT_EQ(sem->Members()[7]->Size(), 64u);
EXPECT_EQ(sem->Members()[8]->Offset(), 304u); // mat4x4
EXPECT_EQ(sem->Members()[8]->Align(), 16u);
EXPECT_EQ(sem->Members()[8]->Size(), 64u);
}
@ -258,13 +295,17 @@ TEST_F(ResolverStructLayoutTest, NestedStruct) {
auto* sem = Sem().Get(s);
ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 80u);
EXPECT_EQ(sem->SizeNoPadding(), 68u);
EXPECT_EQ(sem->Align(), 16u);
ASSERT_EQ(sem->Members().size(), 3u);
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 4u);
EXPECT_EQ(sem->Members()[0]->Size(), 4u);
EXPECT_EQ(sem->Members()[1]->Offset(), 16u);
EXPECT_EQ(sem->Members()[1]->Align(), 16u);
EXPECT_EQ(sem->Members()[1]->Size(), 48u);
EXPECT_EQ(sem->Members()[2]->Offset(), 64u);
EXPECT_EQ(sem->Members()[2]->Align(), 4u);
EXPECT_EQ(sem->Members()[2]->Size(), 4u);
}
@ -286,15 +327,20 @@ TEST_F(ResolverStructLayoutTest, SizeDecorations) {
auto* sem = Sem().Get(s);
ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 76u);
EXPECT_EQ(sem->SizeNoPadding(), 76u);
EXPECT_EQ(sem->Align(), 4u);
ASSERT_EQ(sem->Members().size(), 4u);
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 4u);
EXPECT_EQ(sem->Members()[0]->Size(), 4u);
EXPECT_EQ(sem->Members()[1]->Offset(), 4u);
EXPECT_EQ(sem->Members()[1]->Align(), 4u);
EXPECT_EQ(sem->Members()[1]->Size(), 8u);
EXPECT_EQ(sem->Members()[2]->Offset(), 12u);
EXPECT_EQ(sem->Members()[2]->Align(), 4u);
EXPECT_EQ(sem->Members()[2]->Size(), 32u);
EXPECT_EQ(sem->Members()[3]->Offset(), 44u);
EXPECT_EQ(sem->Members()[3]->Align(), 4u);
EXPECT_EQ(sem->Members()[3]->Size(), 32u);
}
@ -316,18 +362,41 @@ TEST_F(ResolverStructLayoutTest, AlignDecorations) {
auto* sem = Sem().Get(s);
ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 96u);
EXPECT_EQ(sem->SizeNoPadding(), 68u);
EXPECT_EQ(sem->Align(), 32u);
ASSERT_EQ(sem->Members().size(), 4u);
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 4u);
EXPECT_EQ(sem->Members()[0]->Size(), 4u);
EXPECT_EQ(sem->Members()[1]->Offset(), 8u);
EXPECT_EQ(sem->Members()[1]->Align(), 8u);
EXPECT_EQ(sem->Members()[1]->Size(), 4u);
EXPECT_EQ(sem->Members()[2]->Offset(), 16u);
EXPECT_EQ(sem->Members()[2]->Align(), 16u);
EXPECT_EQ(sem->Members()[2]->Size(), 32u);
EXPECT_EQ(sem->Members()[3]->Offset(), 64u);
EXPECT_EQ(sem->Members()[3]->Align(), 32u);
EXPECT_EQ(sem->Members()[3]->Size(), 4u);
}
TEST_F(ResolverStructLayoutTest, StructWithLotsOfPadding) {
auto* s = Structure("S", {
Member("a", ty.i32(), {MemberAlign(1024)}),
});
ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s);
ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 1024u);
EXPECT_EQ(sem->SizeNoPadding(), 4u);
EXPECT_EQ(sem->Align(), 1024u);
ASSERT_EQ(sem->Members().size(), 1u);
EXPECT_EQ(sem->Members()[0]->Offset(), 0u);
EXPECT_EQ(sem->Members()[0]->Align(), 1024u);
EXPECT_EQ(sem->Members()[0]->Size(), 4u);
}
} // namespace
} // namespace resolver
} // namespace tint

View File

@ -23,8 +23,13 @@ namespace semantic {
Struct::Struct(type::Struct* type,
StructMemberList members,
uint32_t align,
uint32_t size)
: type_(type), members_(std::move(members)), align_(align), size_(size) {}
uint32_t size,
uint32_t size_no_padding)
: type_(type),
members_(std::move(members)),
align_(align),
size_(size),
size_no_padding_(size_no_padding) {}
Struct::~Struct() = default;

View File

@ -46,10 +46,13 @@ class Struct : public Castable<Struct, Node> {
/// @param members the structure members
/// @param align the byte alignment of the structure
/// @param size the byte size of the structure
/// @param size_no_padding size of the members without the end of structure
/// alignment padding
Struct(type::Struct* type,
StructMemberList members,
uint32_t align,
uint32_t size);
uint32_t size,
uint32_t size_no_padding);
/// Destructor
~Struct() override;
@ -72,11 +75,16 @@ class Struct : public Castable<Struct, Node> {
/// decoration.
uint32_t Size() const { return size_; }
/// @returns the byte size of the members without the end of structure
/// alignment padding
uint32_t SizeNoPadding() const { return size_no_padding_; }
private:
type::Struct* const type_;
StructMemberList const members_;
uint32_t const align_;
uint32_t const size_;
uint32_t const size_no_padding_;
};
/// StructMember holds the semantic information for structure members.