[tint][ir] Serialize struct types
Change-Id: I9564415b2dcf021b688fc915f0ab3a0a25e5be4d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/164882
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/lang/core/ir/binary/decode.cc b/src/tint/lang/core/ir/binary/decode.cc
index ca40071..14d7285 100644
--- a/src/tint/lang/core/ir/binary/decode.cc
+++ b/src/tint/lang/core/ir/binary/decode.cc
@@ -315,6 +315,8 @@
return CreateTypeMatrix(type_in.matrix());
case pb::Type::KindCase::kPointer:
return CreateTypePointer(type_in.pointer());
+ case pb::Type::KindCase::kStruct:
+ return CreateTypeStruct(type_in.struct_());
case pb::Type::KindCase::kArray:
return CreateTypeArray(type_in.array());
case pb::Type::KindCase::kAtomic:
@@ -366,6 +368,55 @@
return mod_out_.Types().ptr(address_space, store_ty, access);
}
+ const type::Struct* CreateTypeStruct(const pb::TypeStruct& struct_in) {
+ Vector<const core::type::StructMember*, 8> members_out;
+ uint32_t offset = 0;
+ for (auto& member_in : struct_in.member()) {
+ auto symbol = mod_out_.symbols.Register(member_in.name());
+ auto* type = Type(member_in.type());
+ auto index = static_cast<uint32_t>(members_out.Length());
+ auto align = member_in.align();
+ auto size = member_in.size();
+ core::type::StructMemberAttributes attributes_out{};
+ if (member_in.has_attributes()) {
+ auto& attributes_in = member_in.attributes();
+ if (attributes_in.has_location()) {
+ attributes_out.location = attributes_in.location();
+ }
+ if (attributes_in.has_index()) {
+ attributes_out.index = attributes_in.index();
+ }
+ if (attributes_in.has_color()) {
+ attributes_out.color = attributes_in.color();
+ }
+ if (attributes_in.has_builtin()) {
+ attributes_out.builtin = BuiltinValue(attributes_in.builtin());
+ }
+ if (attributes_in.has_interpolation()) {
+ auto& interpolation_in = attributes_in.interpolation();
+ attributes_out.interpolation = core::Interpolation{
+ InterpolationType(interpolation_in.type()),
+ InterpolationSampling::kUndefined,
+ };
+ if (interpolation_in.has_sampling()) {
+ attributes_out.interpolation->sampling =
+ InterpolationSampling(interpolation_in.sampling());
+ }
+ }
+ if (attributes_in.has_invariant()) {
+ attributes_out.invariant = attributes_in.invariant();
+ }
+ }
+ offset = RoundUp(align, offset);
+ auto* member_out = mod_out_.Types().Get<core::type::StructMember>(
+ symbol, type, index, offset, align, size, std::move(attributes_out));
+ offset += size;
+ members_out.Push(member_out);
+ }
+ auto name = mod_out_.symbols.Register(struct_in.name());
+ return mod_out_.Types().Struct(name, std::move(members_out));
+ }
+
const type::Array* CreateTypeArray(const pb::TypeArray& array_in) {
auto* element = Type(array_in.element());
uint32_t stride = static_cast<uint32_t>(array_in.stride());
@@ -576,6 +627,75 @@
return core::ir::BinaryOp::kAdd;
}
}
+
+ core::InterpolationType InterpolationType(pb::InterpolationType in) {
+ switch (in) {
+ case pb::InterpolationType::flat:
+ return core::InterpolationType::kFlat;
+ case pb::InterpolationType::linear:
+ return core::InterpolationType::kLinear;
+ case pb::InterpolationType::perspective:
+ return core::InterpolationType::kPerspective;
+ default:
+ break;
+ }
+ TINT_ICE() << "invalid InterpolationType: " << in;
+ return core::InterpolationType::kFlat;
+ }
+
+ core::InterpolationSampling InterpolationSampling(pb::InterpolationSampling in) {
+ switch (in) {
+ case pb::InterpolationSampling::center:
+ return core::InterpolationSampling::kCenter;
+ case pb::InterpolationSampling::centroid:
+ return core::InterpolationSampling::kCentroid;
+ case pb::InterpolationSampling::sample:
+ return core::InterpolationSampling::kSample;
+ default:
+ break;
+ }
+ TINT_ICE() << "invalid InterpolationSampling: " << in;
+ return core::InterpolationSampling::kCenter;
+ }
+
+ core::BuiltinValue BuiltinValue(pb::BuiltinValue in) {
+ switch (in) {
+ case pb::BuiltinValue::point_size:
+ return core::BuiltinValue::kPointSize;
+ case pb::BuiltinValue::frag_depth:
+ return core::BuiltinValue::kFragDepth;
+ case pb::BuiltinValue::front_facing:
+ return core::BuiltinValue::kFrontFacing;
+ case pb::BuiltinValue::global_invocation_id:
+ return core::BuiltinValue::kGlobalInvocationId;
+ case pb::BuiltinValue::instance_index:
+ return core::BuiltinValue::kInstanceIndex;
+ case pb::BuiltinValue::local_invocation_id:
+ return core::BuiltinValue::kLocalInvocationId;
+ case pb::BuiltinValue::local_invocation_index:
+ return core::BuiltinValue::kLocalInvocationIndex;
+ case pb::BuiltinValue::num_workgroups:
+ return core::BuiltinValue::kNumWorkgroups;
+ case pb::BuiltinValue::position:
+ return core::BuiltinValue::kPosition;
+ case pb::BuiltinValue::sample_index:
+ return core::BuiltinValue::kSampleIndex;
+ case pb::BuiltinValue::sample_mask:
+ return core::BuiltinValue::kSampleMask;
+ case pb::BuiltinValue::subgroup_invocation_id:
+ return core::BuiltinValue::kSubgroupInvocationId;
+ case pb::BuiltinValue::subgroup_size:
+ return core::BuiltinValue::kSubgroupSize;
+ case pb::BuiltinValue::vertex_index:
+ return core::BuiltinValue::kVertexIndex;
+ case pb::BuiltinValue::workgroup_id:
+ return core::BuiltinValue::kWorkgroupId;
+ default:
+ break;
+ }
+ TINT_ICE() << "invalid BuiltinValue: " << in;
+ return core::BuiltinValue::kPointSize;
+ }
};
} // namespace
diff --git a/src/tint/lang/core/ir/binary/encode.cc b/src/tint/lang/core/ir/binary/encode.cc
index ab18fe9..be11d5b 100644
--- a/src/tint/lang/core/ir/binary/encode.cc
+++ b/src/tint/lang/core/ir/binary/encode.cc
@@ -29,6 +29,8 @@
#include <utility>
+#include "src/tint/lang/core/builtin_fn.h"
+#include "src/tint/lang/core/builtin_value.h"
#include "src/tint/lang/core/constant/composite.h"
#include "src/tint/lang/core/constant/scalar.h"
#include "src/tint/lang/core/constant/splat.h"
@@ -240,6 +242,7 @@
[&](const core::type::Vector* v) { TypeVector(*type_out.mutable_vector(), v); },
[&](const core::type::Matrix* m) { TypeMatrix(*type_out.mutable_matrix(), m); },
[&](const core::type::Pointer* m) { TypePointer(*type_out.mutable_pointer(), m); },
+ [&](const core::type::Struct* s) { TypeStruct(*type_out.mutable_struct_(), s); },
[&](const core::type::Array* m) { TypeArray(*type_out.mutable_array(), m); },
TINT_ICE_ON_NO_MATCH);
@@ -265,6 +268,42 @@
pointer_out.set_access(Access(pointer_in->Access()));
}
+ void TypeStruct(pb::TypeStruct& struct_out, const core::type::Struct* struct_in) {
+ struct_out.set_name(struct_in->Name().Name());
+ for (auto* member_in : struct_in->Members()) {
+ auto& member_out = *struct_out.add_member();
+ member_out.set_name(member_in->Name().Name());
+ member_out.set_type(Type(member_in->Type()));
+ member_out.set_size(member_in->Size());
+ member_out.set_align(member_in->Align());
+
+ auto& attrs_in = member_in->Attributes();
+ if (attrs_in.location) {
+ member_out.mutable_attributes()->set_location(*attrs_in.location);
+ }
+ if (attrs_in.index) {
+ member_out.mutable_attributes()->set_index(*attrs_in.index);
+ }
+ if (attrs_in.color) {
+ member_out.mutable_attributes()->set_color(*attrs_in.color);
+ }
+ if (attrs_in.builtin) {
+ member_out.mutable_attributes()->set_builtin(BuiltinValue(*attrs_in.builtin));
+ }
+ if (auto& interpolation_in = attrs_in.interpolation) {
+ auto& interpolation_out = *member_out.mutable_attributes()->mutable_interpolation();
+ interpolation_out.set_type(InterpolationType(interpolation_in->type));
+ if (interpolation_in->sampling != InterpolationSampling::kUndefined) {
+ interpolation_out.set_sampling(
+ InterpolationSampling(interpolation_in->sampling));
+ }
+ }
+ if (attrs_in.invariant) {
+ member_out.mutable_attributes()->set_invariant(true);
+ }
+ }
+ }
+
void TypeArray(pb::TypeArray& array_out, const core::type::Array* array_in) {
array_out.set_element(Type(array_in->ElemType()));
array_out.set_stride(array_in->Stride());
@@ -458,6 +497,75 @@
TINT_ICE() << "invalid BinaryOp: " << in;
return pb::BinaryOp::add_;
}
+
+ pb::InterpolationType InterpolationType(core::InterpolationType in) {
+ switch (in) {
+ case core::InterpolationType::kFlat:
+ return pb::InterpolationType::flat;
+ case core::InterpolationType::kLinear:
+ return pb::InterpolationType::linear;
+ case core::InterpolationType::kPerspective:
+ return pb::InterpolationType::perspective;
+ default:
+ break;
+ }
+ TINT_ICE() << "invalid InterpolationType: " << in;
+ return pb::InterpolationType::flat;
+ }
+
+ pb::InterpolationSampling InterpolationSampling(core::InterpolationSampling in) {
+ switch (in) {
+ case core::InterpolationSampling::kCenter:
+ return pb::InterpolationSampling::center;
+ case core::InterpolationSampling::kCentroid:
+ return pb::InterpolationSampling::centroid;
+ case core::InterpolationSampling::kSample:
+ return pb::InterpolationSampling::sample;
+ default:
+ break;
+ }
+ TINT_ICE() << "invalid InterpolationSampling: " << in;
+ return pb::InterpolationSampling::center;
+ }
+
+ pb::BuiltinValue BuiltinValue(core::BuiltinValue in) {
+ switch (in) {
+ case core::BuiltinValue::kPointSize:
+ return pb::BuiltinValue::point_size;
+ case core::BuiltinValue::kFragDepth:
+ return pb::BuiltinValue::frag_depth;
+ case core::BuiltinValue::kFrontFacing:
+ return pb::BuiltinValue::front_facing;
+ case core::BuiltinValue::kGlobalInvocationId:
+ return pb::BuiltinValue::global_invocation_id;
+ case core::BuiltinValue::kInstanceIndex:
+ return pb::BuiltinValue::instance_index;
+ case core::BuiltinValue::kLocalInvocationId:
+ return pb::BuiltinValue::local_invocation_id;
+ case core::BuiltinValue::kLocalInvocationIndex:
+ return pb::BuiltinValue::local_invocation_index;
+ case core::BuiltinValue::kNumWorkgroups:
+ return pb::BuiltinValue::num_workgroups;
+ case core::BuiltinValue::kPosition:
+ return pb::BuiltinValue::position;
+ case core::BuiltinValue::kSampleIndex:
+ return pb::BuiltinValue::sample_index;
+ case core::BuiltinValue::kSampleMask:
+ return pb::BuiltinValue::sample_mask;
+ case core::BuiltinValue::kSubgroupInvocationId:
+ return pb::BuiltinValue::subgroup_invocation_id;
+ case core::BuiltinValue::kSubgroupSize:
+ return pb::BuiltinValue::subgroup_size;
+ case core::BuiltinValue::kVertexIndex:
+ return pb::BuiltinValue::vertex_index;
+ case core::BuiltinValue::kWorkgroupId:
+ return pb::BuiltinValue::workgroup_id;
+ default:
+ break;
+ }
+ TINT_ICE() << "invalid BuiltinValue: " << in;
+ return pb::BuiltinValue::point_size;
+ }
};
} // namespace
diff --git a/src/tint/lang/core/ir/binary/ir.proto b/src/tint/lang/core/ir/binary/ir.proto
index fff8d02..fc272de 100644
--- a/src/tint/lang/core/ir/binary/ir.proto
+++ b/src/tint/lang/core/ir/binary/ir.proto
@@ -48,7 +48,8 @@
TypeMatrix matrix = 3;
TypeArray array = 4;
TypePointer pointer = 5;
- uint32 atomic = 6; // Module.types
+ TypeStruct struct = 6;
+ uint32 atomic = 7; // Module.types
// TODO: textures, samplers
}
}
@@ -86,6 +87,19 @@
AccessControl access = 3;
}
+message TypeStruct {
+ string name = 1;
+ repeated TypeStructMember member = 2;
+}
+
+message TypeStructMember {
+ string name = 1;
+ uint32 type = 2;
+ uint32 size = 3;
+ uint32 align = 4;
+ optional AttributesStructMember attributes = 5;
+}
+
////////////////////////////////////////////////////////////////////////////////
// Values
////////////////////////////////////////////////////////////////////////////////
@@ -244,6 +258,23 @@
}
////////////////////////////////////////////////////////////////////////////////
+// Attributes
+////////////////////////////////////////////////////////////////////////////////
+message AttributesStructMember {
+ optional uint32 location = 1;
+ optional uint32 index = 2;
+ optional uint32 color = 3;
+ optional BuiltinValue builtin = 4;
+ optional AttributesInterpolation interpolation = 5;
+ optional bool invariant = 6;
+}
+
+message AttributesInterpolation {
+ InterpolationType type = 1;
+ optional InterpolationSampling sampling = 2;
+}
+
+////////////////////////////////////////////////////////////////////////////////
// Enums
////////////////////////////////////////////////////////////////////////////////
enum AddressSpace {
@@ -286,3 +317,151 @@
shift_left = 14;
shift_right = 15;
}
+
+enum InterpolationType {
+ flat = 0;
+ linear = 1;
+ perspective = 2;
+}
+
+enum InterpolationSampling {
+ center = 0;
+ centroid = 1;
+ sample = 2;
+}
+
+enum BuiltinValue {
+ point_size = 0;
+ frag_depth = 1;
+ front_facing = 2;
+ global_invocation_id = 3;
+ instance_index = 4;
+ local_invocation_id = 5;
+ local_invocation_index = 6;
+ num_workgroups = 7;
+ position = 8;
+ sample_index = 9;
+ sample_mask = 10;
+ subgroup_invocation_id = 11;
+ subgroup_size = 12;
+ vertex_index = 13;
+ workgroup_id = 14;
+}
+
+enum BuiltinFn {
+ abs = 0;
+ acos = 1;
+ acosh = 2;
+ all = 3;
+ any = 4;
+ array_length = 5;
+ asin = 6;
+ asinh = 7;
+ atan = 8;
+ atan2 = 9;
+ atanh = 10;
+ ceil = 11;
+ clamp = 12;
+ cos = 13;
+ cosh = 14;
+ count_leading_zeros = 15;
+ count_one_bits = 16;
+ count_trailing_zeros = 17;
+ cross = 18;
+ degrees = 19;
+ determinant = 20;
+ distance = 21;
+ dot = 22;
+ dot4i8_packed = 23;
+ dot4u8_packed = 24;
+ dpdx = 25;
+ dpdx_coarse = 26;
+ dpdx_fine = 27;
+ dpdy = 28;
+ dpdy_coarse = 29;
+ dpdy_fine = 30;
+ exp = 31;
+ exp2 = 32;
+ extract_bits = 33;
+ face_forward = 34;
+ first_leading_bit = 35;
+ first_trailing_bit = 36;
+ floor = 37;
+ fma = 38;
+ fract = 39;
+ frexp = 40;
+ fwidth = 41;
+ fwidth_coarse = 42;
+ fwidth_fine = 43;
+ insert_bits = 44;
+ inverse_sqrt = 45;
+ ldexp = 46;
+ length = 47;
+ log = 48;
+ log2 = 49;
+ max = 50;
+ min = 51;
+ mix = 52;
+ modf = 53;
+ normalize = 54;
+ pack2x16_float = 55;
+ pack2x16_snorm = 56;
+ pack2x16_unorm = 57;
+ pack4x8_snorm = 58;
+ pack4x8_unorm = 59;
+ pow = 60;
+ quantize_to_f16 = 61;
+ radians = 62;
+ reflect = 63;
+ refract = 64;
+ reverse_bits = 65;
+ round = 66;
+ saturate = 67;
+ select = 68;
+ sign = 69;
+ sin = 70;
+ sinh = 71;
+ smoothstep = 72;
+ sqrt = 73;
+ step = 74;
+ storage_barrier = 75;
+ tan = 76;
+ tanh = 77;
+ transpose = 78;
+ trunc = 79;
+ unpack2x16_float = 80;
+ unpack2x16_snorm = 81;
+ unpack2x16_unorm = 82;
+ unpack4x8_snorm = 83;
+ unpack4x8_unorm = 84;
+ workgroup_barrier = 85;
+ texture_barrier = 86;
+ texture_dimensions = 87;
+ texture_gather = 88;
+ texture_gather_compare = 89;
+ texture_num_layers = 90;
+ texture_num_levels = 91;
+ texture_num_samples = 92;
+ texture_sample = 93;
+ texture_sample_bias = 94;
+ texture_sample_compare = 95;
+ texture_sample_compare_level = 96;
+ texture_sample_grad = 97;
+ texture_sample_level = 98;
+ texture_sample_base_clamp_to_edge = 99;
+ texture_store = 100;
+ texture_load = 101;
+ atomic_load = 102;
+ atomic_store = 103;
+ atomic_add = 104;
+ atomic_sub = 105;
+ atomic_max = 106;
+ atomic_min = 107;
+ atomic_and = 108;
+ atomic_or = 109;
+ atomic_xor = 110;
+ atomic_exchange = 111;
+ atomic_compare_exchange_weak = 112;
+ subgroup_ballot = 113;
+ subgroup_broadcast = 114;
+}
diff --git a/src/tint/lang/core/ir/binary/roundtrip_test.cc b/src/tint/lang/core/ir/binary/roundtrip_test.cc
index 57ade4e..120eff7 100644
--- a/src/tint/lang/core/ir/binary/roundtrip_test.cc
+++ b/src/tint/lang/core/ir/binary/roundtrip_test.cc
@@ -87,6 +87,7 @@
});
RUN_TEST();
}
+
////////////////////////////////////////////////////////////////////////////////
// Functions
////////////////////////////////////////////////////////////////////////////////
@@ -123,6 +124,115 @@
}
////////////////////////////////////////////////////////////////////////////////
+// Types
+////////////////////////////////////////////////////////////////////////////////
+TEST_F(IRBinaryRoundtripTest, bool) {
+ b.Append(b.ir.root_block, [&] { b.Var<private_, bool>(); });
+ RUN_TEST();
+}
+
+TEST_F(IRBinaryRoundtripTest, i32) {
+ b.Append(b.ir.root_block, [&] { b.Var<private_, i32>(); });
+ RUN_TEST();
+}
+
+TEST_F(IRBinaryRoundtripTest, u32) {
+ b.Append(b.ir.root_block, [&] { b.Var<private_, u32>(); });
+ RUN_TEST();
+}
+
+TEST_F(IRBinaryRoundtripTest, f32) {
+ b.Append(b.ir.root_block, [&] { b.Var<private_, f32>(); });
+ RUN_TEST();
+}
+
+TEST_F(IRBinaryRoundtripTest, f16) {
+ b.Append(b.ir.root_block, [&] { b.Var<private_, f16>(); });
+ RUN_TEST();
+}
+
+TEST_F(IRBinaryRoundtripTest, vec2_f32) {
+ b.Append(b.ir.root_block, [&] { b.Var<private_, vec2<f32>>(); });
+ RUN_TEST();
+}
+
+TEST_F(IRBinaryRoundtripTest, vec3_i32) {
+ b.Append(b.ir.root_block, [&] { b.Var<private_, vec3<i32>>(); });
+ RUN_TEST();
+}
+
+TEST_F(IRBinaryRoundtripTest, vec4_bool) {
+ b.Append(b.ir.root_block, [&] { b.Var<private_, vec4<bool>>(); });
+ RUN_TEST();
+}
+
+TEST_F(IRBinaryRoundtripTest, mat4x2_f32) {
+ b.Append(b.ir.root_block, [&] { b.Var<private_, vec4<mat4x2<f32>>>(); });
+ RUN_TEST();
+}
+
+TEST_F(IRBinaryRoundtripTest, mat2x4_f16) {
+ b.Append(b.ir.root_block, [&] { b.Var<private_, vec4<mat2x4<f16>>>(); });
+ RUN_TEST();
+}
+
+TEST_F(IRBinaryRoundtripTest, ptr_function_f32_read_write) {
+ auto p = b.FunctionParam<ptr<function, f32, read_write>>("p");
+ auto* fn = b.Function("Function", ty.void_());
+ fn->SetParams({p});
+ b.Append(fn->Block(), [&] { b.Return(fn); });
+ RUN_TEST();
+}
+
+TEST_F(IRBinaryRoundtripTest, ptr_workgroup_i32_read) {
+ auto p = b.FunctionParam<ptr<workgroup, i32, read>>("p");
+ auto* fn = b.Function("Function", ty.void_());
+ fn->SetParams({p});
+ b.Append(fn->Block(), [&] { b.Return(fn); });
+ RUN_TEST();
+}
+
+TEST_F(IRBinaryRoundtripTest, struct) {
+ Vector members{
+ ty.Get<core::type::StructMember>(b.ir.symbols.New("a"), ty.i32(), /* index */ 0u,
+ /* offset */ 0u, /* align */ 4u, /* size */ 4u,
+ type::StructMemberAttributes{}),
+ ty.Get<core::type::StructMember>(b.ir.symbols.New("b"), ty.f32(), /* index */ 1u,
+ /* offset */ 4u, /* align */ 4u, /* size */ 32u,
+ type::StructMemberAttributes{}),
+ ty.Get<core::type::StructMember>(b.ir.symbols.New("c"), ty.u32(), /* index */ 2u,
+ /* offset */ 36u, /* align */ 4u, /* size */ 4u,
+ type::StructMemberAttributes{}),
+ ty.Get<core::type::StructMember>(b.ir.symbols.New("d"), ty.u32(), /* index */ 3u,
+ /* offset */ 64u, /* align */ 32u, /* size */ 4u,
+ type::StructMemberAttributes{}),
+ };
+ auto* S = ty.Struct(b.ir.symbols.New("S"), std::move(members));
+ b.Append(b.ir.root_block, [&] { b.Var(ty.ptr<function, read_write>(S)); });
+ RUN_TEST();
+}
+
+TEST_F(IRBinaryRoundtripTest, StructMemberAttributes) {
+ type::StructMemberAttributes attrs{};
+ attrs.location = 1;
+ attrs.index = 2;
+ attrs.color = 3;
+ attrs.builtin = core::BuiltinValue::kFragDepth;
+ attrs.interpolation = core::Interpolation{
+ core::InterpolationType::kLinear,
+ core::InterpolationSampling::kCentroid,
+ };
+ attrs.invariant = true;
+ Vector members{
+ ty.Get<core::type::StructMember>(b.ir.symbols.New("a"), ty.i32(), /* index */ 0u,
+ /* offset */ 0u, /* align */ 4u, /* size */ 4u, attrs),
+ };
+ auto* S = ty.Struct(b.ir.symbols.New("S"), std::move(members));
+ b.Append(b.ir.root_block, [&] { b.Var(ty.ptr<function, read_write>(S)); });
+ RUN_TEST();
+}
+
+////////////////////////////////////////////////////////////////////////////////
// Instructions
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRBinaryRoundtripTest, Return) {
diff --git a/src/tint/lang/core/type/manager.cc b/src/tint/lang/core/type/manager.cc
index a3473ca..50c1a39 100644
--- a/src/tint/lang/core/type/manager.cc
+++ b/src/tint/lang/core/type/manager.cc
@@ -192,8 +192,18 @@
return Get<core::type::Pointer>(address_space, subtype, access);
}
+core::type::Struct* Manager::Struct(Symbol name, VectorRef<const StructMember*> members) {
+ uint32_t max_align = 0u;
+ for (const auto& m : members) {
+ max_align = std::max(max_align, m->Align());
+ }
+ uint32_t size = members.Back()->Offset() + members.Back()->Size();
+ return Get<core::type::Struct>(name, std::move(members), max_align,
+ tint::RoundUp(max_align, size), size);
+}
+
core::type::Struct* Manager::Struct(Symbol name, VectorRef<StructMemberDesc> md) {
- tint::Vector<const core::type::StructMember*, 4> members;
+ tint::Vector<const StructMember*, 4> members;
uint32_t current_size = 0u;
uint32_t max_align = 0u;
for (const auto& m : md) {
@@ -205,8 +215,8 @@
current_size = offset + m.type->Size();
max_align = std::max(max_align, align);
}
- return Get<core::type::Struct>(name, members, max_align, tint::RoundUp(max_align, current_size),
- current_size);
+ return Get<core::type::Struct>(name, std::move(members), max_align,
+ tint::RoundUp(max_align, current_size), current_size);
}
} // namespace tint::core::type
diff --git a/src/tint/lang/core/type/manager.h b/src/tint/lang/core/type/manager.h
index 8f361da..d88e084 100644
--- a/src/tint/lang/core/type/manager.h
+++ b/src/tint/lang/core/type/manager.h
@@ -451,6 +451,12 @@
/// Create a new structure declaration.
/// @param name the name of the structure
+ /// @param members the list of structure members
+ /// @returns the structure type
+ core::type::Struct* Struct(Symbol name, VectorRef<const StructMember*> members);
+
+ /// Create a new structure declaration.
+ /// @param name the name of the structure
/// @param members the list of structure member descriptors
/// @returns the structure type
core::type::Struct* Struct(Symbol name, VectorRef<StructMemberDesc> members);