diff --git a/src/tint/ast/struct_member_offset_attribute.cc b/src/tint/ast/struct_member_offset_attribute.cc index 48d73336b3..8b9faabaf8 100644 --- a/src/tint/ast/struct_member_offset_attribute.cc +++ b/src/tint/ast/struct_member_offset_attribute.cc @@ -25,8 +25,8 @@ namespace tint::ast { StructMemberOffsetAttribute::StructMemberOffsetAttribute(ProgramID pid, NodeID nid, const Source& src, - uint32_t o) - : Base(pid, nid, src), offset(o) {} + const ast::Expression* exp) + : Base(pid, nid, src), expr(exp) {} StructMemberOffsetAttribute::~StructMemberOffsetAttribute() = default; @@ -37,7 +37,8 @@ std::string StructMemberOffsetAttribute::Name() const { const StructMemberOffsetAttribute* StructMemberOffsetAttribute::Clone(CloneContext* ctx) const { // Clone arguments outside of create() call to have deterministic ordering auto src = ctx->Clone(source); - return ctx->dst->create(src, offset); + auto expr_ = ctx->Clone(expr); + return ctx->dst->create(src, expr_); } } // namespace tint::ast diff --git a/src/tint/ast/struct_member_offset_attribute.h b/src/tint/ast/struct_member_offset_attribute.h index 790927eaa8..632d71ae9b 100644 --- a/src/tint/ast/struct_member_offset_attribute.h +++ b/src/tint/ast/struct_member_offset_attribute.h @@ -18,6 +18,7 @@ #include #include "src/tint/ast/attribute.h" +#include "src/tint/ast/expression.h" namespace tint::ast { @@ -37,8 +38,11 @@ class StructMemberOffsetAttribute final : public Castable(2u); - EXPECT_EQ(2u, d->offset); + auto* d = MemberOffset(2_u); + ASSERT_TRUE(d->expr->Is()); + EXPECT_EQ(2u, d->expr->As()->value); } } // namespace diff --git a/src/tint/ast/struct_member_size_attribute.cc b/src/tint/ast/struct_member_size_attribute.cc index 391907877d..833896decd 100644 --- a/src/tint/ast/struct_member_size_attribute.cc +++ b/src/tint/ast/struct_member_size_attribute.cc @@ -26,8 +26,8 @@ namespace tint::ast { StructMemberSizeAttribute::StructMemberSizeAttribute(ProgramID pid, NodeID nid, const Source& src, - uint32_t sz) - : Base(pid, nid, src), size(sz) {} + const ast::Expression* exp) + : Base(pid, nid, src), expr(exp) {} StructMemberSizeAttribute::~StructMemberSizeAttribute() = default; @@ -38,7 +38,8 @@ std::string StructMemberSizeAttribute::Name() const { const StructMemberSizeAttribute* StructMemberSizeAttribute::Clone(CloneContext* ctx) const { // Clone arguments outside of create() call to have deterministic ordering auto src = ctx->Clone(source); - return ctx->dst->create(src, size); + auto expr_ = ctx->Clone(expr); + return ctx->dst->create(src, expr_); } } // namespace tint::ast diff --git a/src/tint/ast/struct_member_size_attribute.h b/src/tint/ast/struct_member_size_attribute.h index 5649e2eaa3..c048b1fd1a 100644 --- a/src/tint/ast/struct_member_size_attribute.h +++ b/src/tint/ast/struct_member_size_attribute.h @@ -19,6 +19,7 @@ #include #include "src/tint/ast/attribute.h" +#include "src/tint/ast/expression.h" namespace tint::ast { @@ -29,8 +30,11 @@ class StructMemberSizeAttribute final : public Castable(2u); - EXPECT_EQ(2u, d->size); + auto* d = MemberSize(2_u); + ASSERT_TRUE(d->expr->Is()); + EXPECT_EQ(2u, d->expr->As()->value); } } // namespace diff --git a/src/tint/ast/struct_member_test.cc b/src/tint/ast/struct_member_test.cc index 69772f4e14..850be9fbd4 100644 --- a/src/tint/ast/struct_member_test.cc +++ b/src/tint/ast/struct_member_test.cc @@ -18,10 +18,11 @@ namespace tint::ast { namespace { +using namespace tint::number_suffixes; // NOLINT using StructMemberTest = TestHelper; TEST_F(StructMemberTest, Creation) { - auto* st = Member("a", ty.i32(), utils::Vector{MemberSize(4)}); + auto* st = Member("a", ty.i32(), utils::Vector{MemberSize(4_a)}); EXPECT_EQ(st->symbol, Symbol(1, ID())); EXPECT_TRUE(st->type->Is()); EXPECT_EQ(st->attributes.Length(), 1u); @@ -66,7 +67,7 @@ TEST_F(StructMemberTest, Assert_Null_Attribute) { EXPECT_FATAL_FAILURE( { ProgramBuilder b; - b.Member("a", b.ty.i32(), utils::Vector{b.MemberSize(4), nullptr}); + b.Member("a", b.ty.i32(), utils::Vector{b.MemberSize(4_a), nullptr}); }, "internal compiler error"); } @@ -76,7 +77,7 @@ TEST_F(StructMemberTest, Assert_DifferentProgramID_Symbol) { { ProgramBuilder b1; ProgramBuilder b2; - b1.Member(b2.Sym("a"), b1.ty.i32(), utils::Vector{b1.MemberSize(4)}); + b1.Member(b2.Sym("a"), b1.ty.i32(), utils::Vector{b1.MemberSize(4_a)}); }, "internal compiler error"); } @@ -86,7 +87,7 @@ TEST_F(StructMemberTest, Assert_DifferentProgramID_Attribute) { { ProgramBuilder b1; ProgramBuilder b2; - b1.Member("a", b1.ty.i32(), utils::Vector{b2.MemberSize(4)}); + b1.Member("a", b1.ty.i32(), utils::Vector{b2.MemberSize(4_a)}); }, "internal compiler error"); } diff --git a/src/tint/program_builder.h b/src/tint/program_builder.h index ead13e9c9f..c94f5fbd86 100644 --- a/src/tint/program_builder.h +++ b/src/tint/program_builder.h @@ -2251,25 +2251,37 @@ class ProgramBuilder { } /// Creates a ast::StructMemberOffsetAttribute - /// @param val the offset value + /// @param val the offset expression /// @returns the offset attribute pointer - const ast::StructMemberOffsetAttribute* MemberOffset(uint32_t val) { - return create(source_, val); + template + const ast::StructMemberOffsetAttribute* MemberOffset(EXPR&& val) { + return create(source_, Expr(std::forward(val))); + } + + /// Creates a ast::StructMemberOffsetAttribute + /// @param source the source information + /// @param val the offset expression + /// @returns the offset attribute pointer + template + const ast::StructMemberOffsetAttribute* MemberOffset(const Source& source, EXPR&& val) { + return create(source, Expr(std::forward(val))); } /// Creates a ast::StructMemberSizeAttribute /// @param source the source information /// @param val the size value /// @returns the size attribute pointer - const ast::StructMemberSizeAttribute* MemberSize(const Source& source, uint32_t val) { - return create(source, val); + template + const ast::StructMemberSizeAttribute* MemberSize(const Source& source, EXPR&& val) { + return create(source, Expr(std::forward(val))); } /// Creates a ast::StructMemberSizeAttribute /// @param val the size value /// @returns the size attribute pointer - const ast::StructMemberSizeAttribute* MemberSize(uint32_t val) { - return create(source_, val); + template + const ast::StructMemberSizeAttribute* MemberSize(EXPR&& val) { + return create(source_, Expr(std::forward(val))); } /// Creates a ast::StructMemberAlignAttribute @@ -2525,7 +2537,7 @@ class ProgramBuilder { const ast::StructMember* Member(uint32_t offset, NAME&& name, const ast::Type* type) { return create(source_, Sym(std::forward(name)), type, utils::Vector{ - create(offset), + MemberOffset(AInt(offset)), }); } diff --git a/src/tint/reader/spirv/parser_impl.cc b/src/tint/reader/spirv/parser_impl.cc index 37ea5ca3f3..caa2c69173 100644 --- a/src/tint/reader/spirv/parser_impl.cc +++ b/src/tint/reader/spirv/parser_impl.cc @@ -464,7 +464,7 @@ ParserImpl::AttributeList ParserImpl::ConvertMemberDecoration(uint32_t struct_ty return {}; } return { - create(Source{}, decoration[1]), + builder_.MemberOffset(Source{}, AInt(decoration[1])), }; case SpvDecorationNonReadable: // WGSL doesn't have a member decoration for this. Silently drop it. diff --git a/src/tint/reader/spirv/parser_impl_convert_member_decoration_test.cc b/src/tint/reader/spirv/parser_impl_convert_member_decoration_test.cc index cd3e7b5002..767b3337d4 100644 --- a/src/tint/reader/spirv/parser_impl_convert_member_decoration_test.cc +++ b/src/tint/reader/spirv/parser_impl_convert_member_decoration_test.cc @@ -54,7 +54,8 @@ TEST_F(SpvParserTest, ConvertMemberDecoration_Offset) { EXPECT_TRUE(result[0]->Is()); auto* offset_deco = result[0]->As(); ASSERT_NE(offset_deco, nullptr); - EXPECT_EQ(offset_deco->offset, 8u); + ASSERT_TRUE(offset_deco->expr->Is()); + EXPECT_EQ(offset_deco->expr->As()->value, 8u); EXPECT_TRUE(p->error().empty()); } diff --git a/src/tint/reader/wgsl/parser_impl.cc b/src/tint/reader/wgsl/parser_impl.cc index f3b424e71b..2c72d6a0c3 100644 --- a/src/tint/reader/wgsl/parser_impl.cc +++ b/src/tint/reader/wgsl/parser_impl.cc @@ -3566,7 +3566,7 @@ Maybe ParserImpl::attribute() { } match(Token::Type::kComma); - return create(t.source(), val.value); + return builder_.MemberSize(t.source(), AInt(val.value)); }); } diff --git a/src/tint/reader/wgsl/parser_impl_struct_member_attribute_test.cc b/src/tint/reader/wgsl/parser_impl_struct_member_attribute_test.cc index cc6d186d32..9bafaf0f44 100644 --- a/src/tint/reader/wgsl/parser_impl_struct_member_attribute_test.cc +++ b/src/tint/reader/wgsl/parser_impl_struct_member_attribute_test.cc @@ -30,7 +30,8 @@ TEST_F(ParserImplTest, Attribute_Size) { ASSERT_TRUE(member_attr->Is()); auto* o = member_attr->As(); - EXPECT_EQ(o->size, 4u); + ASSERT_TRUE(o->expr->Is()); + EXPECT_EQ(o->expr->As()->value, 4u); } TEST_F(ParserImplTest, Attribute_Size_TrailingComma) { @@ -46,7 +47,8 @@ TEST_F(ParserImplTest, Attribute_Size_TrailingComma) { ASSERT_TRUE(member_attr->Is()); auto* o = member_attr->As(); - EXPECT_EQ(o->size, 4u); + ASSERT_TRUE(o->expr->Is()); + EXPECT_EQ(o->expr->As()->value, 4u); } TEST_F(ParserImplTest, Attribute_Size_MissingLeftParen) { diff --git a/src/tint/reader/wgsl/parser_impl_struct_member_test.cc b/src/tint/reader/wgsl/parser_impl_struct_member_test.cc index fe233fe8a4..6267406571 100644 --- a/src/tint/reader/wgsl/parser_impl_struct_member_test.cc +++ b/src/tint/reader/wgsl/parser_impl_struct_member_test.cc @@ -73,8 +73,11 @@ TEST_F(ParserImplTest, StructMember_ParsesWithSizeAttribute) { EXPECT_EQ(m->symbol, builder.Symbols().Get("a")); EXPECT_TRUE(m->type->Is()); EXPECT_EQ(m->attributes.Length(), 1u); - EXPECT_TRUE(m->attributes[0]->Is()); - EXPECT_EQ(m->attributes[0]->As()->size, 2u); + ASSERT_TRUE(m->attributes[0]->Is()); + auto* s = m->attributes[0]->As(); + + ASSERT_TRUE(s->expr->Is()); + EXPECT_EQ(s->expr->As()->value, 2u); EXPECT_EQ(m->source.range, (Source::Range{{1u, 10u}, {1u, 11u}})); EXPECT_EQ(m->type->source.range, (Source::Range{{1u, 14u}, {1u, 17u}})); @@ -95,7 +98,9 @@ TEST_F(ParserImplTest, StructMember_ParsesWithMultipleattributes) { EXPECT_TRUE(m->type->Is()); EXPECT_EQ(m->attributes.Length(), 2u); ASSERT_TRUE(m->attributes[0]->Is()); - EXPECT_EQ(m->attributes[0]->As()->size, 2u); + auto* size_attr = m->attributes[0]->As(); + ASSERT_TRUE(size_attr->expr->Is()); + EXPECT_EQ(size_attr->expr->As()->value, 2u); ASSERT_TRUE(m->attributes[1]->Is()); auto* attr = m->attributes[1]->As(); diff --git a/src/tint/resolver/attribute_validation_test.cc b/src/tint/resolver/attribute_validation_test.cc index b182f6d85e..e648562012 100644 --- a/src/tint/resolver/attribute_validation_test.cc +++ b/src/tint/resolver/attribute_validation_test.cc @@ -106,9 +106,9 @@ static utils::Vector createAttributes(const Source& so case AttributeKind::kLocation: return {builder.Location(source, 1_a)}; case AttributeKind::kOffset: - return {builder.create(source, 4u)}; + return {builder.MemberOffset(source, 4_a)}; case AttributeKind::kSize: - return {builder.create(source, 16u)}; + return {builder.MemberSize(source, 16_a)}; case AttributeKind::kStage: return {builder.Stage(source, ast::PipelineStage::kCompute)}; case AttributeKind::kStride: diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc index 27dc2199b8..911b66c3e7 100644 --- a/src/tint/resolver/resolver.cc +++ b/src/tint/resolver/resolver.cc @@ -2803,11 +2803,22 @@ sem::Struct* Resolver::Structure(const ast::Struct* str) { if (auto* o = attr->As()) { // Offset attributes are not part of the WGSL spec, but are emitted // by the SPIR-V reader. - if (o->offset < struct_size) { + + auto* materialized = Materialize(Expression(o->expr)); + if (!materialized) { + return nullptr; + } + auto const_value = materialized->ConstantValue(); + if (!const_value) { + AddError("'offset' must be constant expression", o->expr->source); + return nullptr; + } + offset = const_value->As(); + + if (offset < struct_size) { AddError("offsets must be in ascending order", o->source); return nullptr; } - offset = o->offset; align = 1; has_offset_attr = true; } else if (auto* a = attr->As()) { @@ -2829,13 +2840,24 @@ sem::Struct* Resolver::Structure(const ast::Struct* str) { align = const_value->As(); has_align_attr = true; } else if (auto* s = attr->As()) { - if (s->size < size) { + auto* materialized = Materialize(Expression(s->expr)); + if (!materialized) { + return nullptr; + } + auto const_value = materialized->ConstantValue(); + if (!const_value) { + AddError("'size' must be constant expression", s->expr->source); + return nullptr; + } + auto value = const_value->As(); + + if (value < size) { AddError("size must be at least as big as the type's size (" + std::to_string(size) + ")", s->source); return nullptr; } - size = s->size; + size = const_value->As(); has_size_attr = true; } else if (auto* l = attr->As()) { auto* materialize = Materialize(Expression(l->expr)); diff --git a/src/tint/resolver/storage_class_layout_validation_test.cc b/src/tint/resolver/storage_class_layout_validation_test.cc index 8f1b2c1c37..91d0d5d021 100644 --- a/src/tint/resolver/storage_class_layout_validation_test.cc +++ b/src/tint/resolver/storage_class_layout_validation_test.cc @@ -35,7 +35,7 @@ TEST_F(ResolverStorageClassLayoutValidationTest, StorageBuffer_UnalignedMember) Structure(Source{{12, 34}}, "S", utils::Vector{ - Member("a", ty.f32(), utils::Vector{MemberSize(5)}), + Member("a", ty.f32(), utils::Vector{MemberSize(5_a)}), Member(Source{{34, 56}}, "b", ty.f32(), utils::Vector{MemberAlign(1_u)}), }); @@ -65,7 +65,7 @@ TEST_F(ResolverStorageClassLayoutValidationTest, StorageBuffer_UnalignedMember_S Structure(Source{{12, 34}}, "S", utils::Vector{ - Member("a", ty.f32(), utils::Vector{MemberSize(5)}), + Member("a", ty.f32(), utils::Vector{MemberSize(5_a)}), Member(Source{{34, 56}}, "b", ty.f32(), utils::Vector{MemberAlign(4_u)}), }); @@ -227,7 +227,7 @@ TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_MembersOffsetNotM Structure(Source{{12, 34}}, "Inner", utils::Vector{ - Member("scalar", ty.i32(), utils::Vector{MemberAlign(1_u), MemberSize(5)}), + Member("scalar", ty.i32(), utils::Vector{MemberAlign(1_u), MemberSize(5_a)}), }); Structure(Source{{34, 56}}, "Outer", @@ -279,7 +279,7 @@ TEST_F(ResolverStorageClassLayoutValidationTest, Member("a", ty.i32()), Member("b", ty.i32()), Member("c", ty.i32()), - Member("scalar", ty.i32(), utils::Vector{MemberAlign(1_u), MemberSize(5)}), + Member("scalar", ty.i32(), utils::Vector{MemberAlign(1_u), MemberSize(5_a)}), }); Structure(Source{{34, 56}}, "Outer", @@ -327,7 +327,7 @@ TEST_F(ResolverStorageClassLayoutValidationTest, Structure(Source{{12, 34}}, "Inner", utils::Vector{ - Member("scalar", ty.i32(), utils::Vector{MemberAlign(1_u), MemberSize(5)}), + Member("scalar", ty.i32(), utils::Vector{MemberAlign(1_u), MemberSize(5_a)}), }); Structure(Source{{34, 56}}, "Outer", @@ -550,7 +550,7 @@ TEST_F(ResolverStorageClassLayoutValidationTest, PushConstant_UnalignedMember) { Enable(ast::Extension::kChromiumExperimentalPushConstant); Structure( Source{{12, 34}}, "S", - utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(5)}), + utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(5_a)}), Member(Source{{34, 56}}, "b", ty.f32(), utils::Vector{MemberAlign(1_u)})}); GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), ast::StorageClass::kPushConstant); @@ -575,7 +575,7 @@ TEST_F(ResolverStorageClassLayoutValidationTest, PushConstant_Aligned) { // }; // var a : S; Enable(ast::Extension::kChromiumExperimentalPushConstant); - Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(5)}), + Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(5_a)}), Member("b", ty.f32(), utils::Vector{MemberAlign(4_u)})}); GlobalVar("a", ty.type_name("S"), ast::StorageClass::kPushConstant); diff --git a/src/tint/resolver/storage_class_validation_test.cc b/src/tint/resolver/storage_class_validation_test.cc index 8c1a253c4f..cff20c0923 100644 --- a/src/tint/resolver/storage_class_validation_test.cc +++ b/src/tint/resolver/storage_class_validation_test.cc @@ -400,7 +400,7 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferArrayF16_TemporallyBan) Enable(ast::Extension::kF16); auto* s = Structure( - "S", utils::Vector{Member("a", ty.f16(Source{{56, 78}}), utils::Vector{MemberSize(16)})}); + "S", utils::Vector{Member("a", ty.f16(Source{{56, 78}}), utils::Vector{MemberSize(16_a)})}); auto* a = ty.array(ty.Of(s), 3_u); GlobalVar("g", a, ast::StorageClass::kUniform, Binding(0_a), Group(0_a)); @@ -474,7 +474,7 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferArrayF32) { // @size(16) f : f32; // } // var g : array; - auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(16)})}); + auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(16_a)})}); auto* a = ty.array(ty.Of(s), 3_u); GlobalVar(Source{{56, 78}}, "g", a, ast::StorageClass::kUniform, Binding(0_a), Group(0_a)); diff --git a/src/tint/resolver/struct_layout_test.cc b/src/tint/resolver/struct_layout_test.cc index ae3972b04f..5b5ab686e8 100644 --- a/src/tint/resolver/struct_layout_test.cc +++ b/src/tint/resolver/struct_layout_test.cc @@ -460,15 +460,15 @@ TEST_F(ResolverStructLayoutTest, NestedStruct) { TEST_F(ResolverStructLayoutTest, SizeAttributes) { auto* inner = Structure("Inner", utils::Vector{ - Member("a", ty.f32(), utils::Vector{MemberSize(8)}), - Member("b", ty.f32(), utils::Vector{MemberSize(16)}), - Member("c", ty.f32(), utils::Vector{MemberSize(8)}), + Member("a", ty.f32(), utils::Vector{MemberSize(8_a)}), + Member("b", ty.f32(), utils::Vector{MemberSize(16_a)}), + Member("c", ty.f32(), utils::Vector{MemberSize(8_a)}), }); auto* s = Structure("S", utils::Vector{ - Member("a", ty.f32(), utils::Vector{MemberSize(4)}), - Member("b", ty.u32(), utils::Vector{MemberSize(8)}), + Member("a", ty.f32(), utils::Vector{MemberSize(4_a)}), + Member("b", ty.u32(), utils::Vector{MemberSize(8_a)}), Member("c", ty.Of(inner)), - Member("d", ty.i32(), utils::Vector{MemberSize(32)}), + Member("d", ty.i32(), utils::Vector{MemberSize(32_a)}), }); ASSERT_TRUE(r()->Resolve()) << r()->error(); diff --git a/src/tint/resolver/validation_test.cc b/src/tint/resolver/validation_test.cc index 6054cacf4b..90b1664615 100644 --- a/src/tint/resolver/validation_test.cc +++ b/src/tint/resolver/validation_test.cc @@ -1257,7 +1257,7 @@ TEST_F(ResolverValidationTest, ZeroStructMemberAlignAttribute) { TEST_F(ResolverValidationTest, ZeroStructMemberSizeAttribute) { Structure("S", utils::Vector{ - Member("a", ty.f32(), utils::Vector{MemberSize(Source{{12, 34}}, 0)}), + Member("a", ty.f32(), utils::Vector{MemberSize(Source{{12, 34}}, 0_a)}), }); EXPECT_FALSE(r()->Resolve()); @@ -1267,7 +1267,7 @@ TEST_F(ResolverValidationTest, ZeroStructMemberSizeAttribute) { TEST_F(ResolverValidationTest, OffsetAndSizeAttribute) { Structure("S", utils::Vector{ Member(Source{{12, 34}}, "a", ty.f32(), - utils::Vector{MemberOffset(0), MemberSize(4)}), + utils::Vector{MemberOffset(0_a), MemberSize(4_a)}), }); EXPECT_FALSE(r()->Resolve()); @@ -1279,7 +1279,7 @@ TEST_F(ResolverValidationTest, OffsetAndSizeAttribute) { TEST_F(ResolverValidationTest, OffsetAndAlignAttribute) { Structure("S", utils::Vector{ Member(Source{{12, 34}}, "a", ty.f32(), - utils::Vector{MemberOffset(0), MemberAlign(4_u)}), + utils::Vector{MemberOffset(0_a), MemberAlign(4_u)}), }); EXPECT_FALSE(r()->Resolve()); @@ -1291,7 +1291,7 @@ TEST_F(ResolverValidationTest, OffsetAndAlignAttribute) { TEST_F(ResolverValidationTest, OffsetAndAlignAndSizeAttribute) { Structure("S", utils::Vector{ Member(Source{{12, 34}}, "a", ty.f32(), - utils::Vector{MemberOffset(0), MemberAlign(4_u), MemberSize(4)}), + utils::Vector{MemberOffset(0_a), MemberAlign(4_u), MemberSize(4_a)}), }); EXPECT_FALSE(r()->Resolve()); diff --git a/src/tint/transform/decompose_strided_array.cc b/src/tint/transform/decompose_strided_array.cc index 61841f6299..b7fe53c360 100644 --- a/src/tint/transform/decompose_strided_array.cc +++ b/src/tint/transform/decompose_strided_array.cc @@ -73,7 +73,7 @@ void DecomposeStridedArray::Run(CloneContext& ctx, const DataMap&, DataMap&) con auto* member_ty = ctx.Clone(ast->type); auto* member = ctx.dst->Member(kMemberName, member_ty, utils::Vector{ - ctx.dst->MemberSize(arr->Stride()), + ctx.dst->MemberSize(AInt(arr->Stride())), }); ctx.dst->Structure(name, utils::Vector{member}); return name; diff --git a/src/tint/transform/decompose_strided_matrix_test.cc b/src/tint/transform/decompose_strided_matrix_test.cc index c7a8f59534..6bfba7c298 100644 --- a/src/tint/transform/decompose_strided_matrix_test.cc +++ b/src/tint/transform/decompose_strided_matrix_test.cc @@ -71,7 +71,7 @@ TEST_F(DecomposeStridedMatrixTest, ReadUniformMatrix) { "S", utils::Vector{ b.Member("m", b.ty.mat2x2(), utils::Vector{ - b.create(16u), + b.MemberOffset(16_u), b.create(32u), b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute), }), @@ -127,7 +127,7 @@ TEST_F(DecomposeStridedMatrixTest, ReadUniformColumn) { "S", utils::Vector{ b.Member("m", b.ty.mat2x2(), utils::Vector{ - b.create(16u), + b.MemberOffset(16_u), b.create(32u), b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute), }), @@ -180,7 +180,7 @@ TEST_F(DecomposeStridedMatrixTest, ReadUniformMatrix_DefaultStride) { "S", utils::Vector{ b.Member("m", b.ty.mat2x2(), utils::Vector{ - b.create(16u), + b.MemberOffset(16_u), b.create(8u), b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute), }), @@ -233,7 +233,7 @@ TEST_F(DecomposeStridedMatrixTest, ReadStorageMatrix) { "S", utils::Vector{ b.Member("m", b.ty.mat2x2(), utils::Vector{ - b.create(8u), + b.MemberOffset(8_u), b.create(32u), b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute), }), @@ -290,7 +290,7 @@ TEST_F(DecomposeStridedMatrixTest, ReadStorageColumn) { "S", utils::Vector{ b.Member("m", b.ty.mat2x2(), utils::Vector{ - b.create(16u), + b.MemberOffset(16_u), b.create(32u), b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute), }), @@ -344,7 +344,7 @@ TEST_F(DecomposeStridedMatrixTest, WriteStorageMatrix) { "S", utils::Vector{ b.Member("m", b.ty.mat2x2(), utils::Vector{ - b.create(8u), + b.MemberOffset(8_u), b.create(32u), b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute), }), @@ -402,7 +402,7 @@ TEST_F(DecomposeStridedMatrixTest, WriteStorageColumn) { "S", utils::Vector{ b.Member("m", b.ty.mat2x2(), utils::Vector{ - b.create(8u), + b.MemberOffset(8_u), b.create(32u), b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute), }), @@ -461,7 +461,7 @@ TEST_F(DecomposeStridedMatrixTest, ReadWriteViaPointerLets) { "S", utils::Vector{ b.Member("m", b.ty.mat2x2(), utils::Vector{ - b.create(8u), + b.MemberOffset(8_u), b.create(32u), b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute), }), @@ -532,7 +532,7 @@ TEST_F(DecomposeStridedMatrixTest, ReadPrivateMatrix) { "S", utils::Vector{ b.Member("m", b.ty.mat2x2(), utils::Vector{ - b.create(8u), + b.MemberOffset(8_u), b.create(32u), b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute), }), @@ -585,7 +585,7 @@ TEST_F(DecomposeStridedMatrixTest, WritePrivateMatrix) { "S", utils::Vector{ b.Member("m", b.ty.mat2x2(), utils::Vector{ - b.create(8u), + b.MemberOffset(8_u), b.create(32u), b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute), }), diff --git a/src/tint/transform/std140.cc b/src/tint/transform/std140.cc index f46fdea5c8..e6f070b255 100644 --- a/src/tint/transform/std140.cc +++ b/src/tint/transform/std140.cc @@ -246,9 +246,9 @@ struct Std140::State { // The matrix was @size() annotated with a larger size than the // natural size for the matrix. This extra padding needs to be // applied to the last column vector. - attributes.Push( - b.MemberSize(member->Size() - mat->ColumnType()->Size() * - (num_columns - 1))); + attributes.Push(b.MemberSize( + AInt(member->Size() - + mat->ColumnType()->Size() * (num_columns - 1)))); } // Build the member diff --git a/src/tint/writer/glsl/generator_impl_type_test.cc b/src/tint/writer/glsl/generator_impl_type_test.cc index 15c139810b..c2d9109a42 100644 --- a/src/tint/writer/glsl/generator_impl_type_test.cc +++ b/src/tint/writer/glsl/generator_impl_type_test.cc @@ -212,8 +212,8 @@ TEST_F(GlslGeneratorImplTest_Type, EmitType_Struct_NameCollision) { TEST_F(GlslGeneratorImplTest_Type, EmitType_Struct_WithOffsetAttributes) { auto* s = Structure("S", utils::Vector{ - Member("a", ty.i32(), utils::Vector{MemberOffset(0)}), - Member("b", ty.f32(), utils::Vector{MemberOffset(8)}), + Member("a", ty.i32(), utils::Vector{MemberOffset(0_a)}), + Member("b", ty.f32(), utils::Vector{MemberOffset(8_a)}), }); GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate); diff --git a/src/tint/writer/hlsl/generator_impl_type_test.cc b/src/tint/writer/hlsl/generator_impl_type_test.cc index 279eb3fd10..75dac72d4e 100644 --- a/src/tint/writer/hlsl/generator_impl_type_test.cc +++ b/src/tint/writer/hlsl/generator_impl_type_test.cc @@ -221,8 +221,8 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct_NameCollision) { TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct_WithOffsetAttributes) { auto* s = Structure("S", utils::Vector{ - Member("a", ty.i32(), utils::Vector{MemberOffset(0)}), - Member("b", ty.f32(), utils::Vector{MemberOffset(8)}), + Member("a", ty.i32(), utils::Vector{MemberOffset(0_a)}), + Member("b", ty.f32(), utils::Vector{MemberOffset(8_a)}), }); GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate); diff --git a/src/tint/writer/msl/generator_impl_type_test.cc b/src/tint/writer/msl/generator_impl_type_test.cc index a6901b4cb1..c8f4f6d4df 100644 --- a/src/tint/writer/msl/generator_impl_type_test.cc +++ b/src/tint/writer/msl/generator_impl_type_test.cc @@ -254,8 +254,8 @@ TEST_F(MslGeneratorImplTest, EmitType_StructDecl) { TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_NonComposites) { auto* s = Structure( "S", utils::Vector{ - Member("a", ty.i32(), utils::Vector{MemberSize(32)}), - Member("b", ty.f32(), utils::Vector{MemberAlign(128_u), MemberSize(128)}), + Member("a", ty.i32(), utils::Vector{MemberSize(32_a)}), + Member("b", ty.f32(), utils::Vector{MemberAlign(128_u), MemberSize(128_a)}), Member("c", ty.vec2()), Member("d", ty.u32()), Member("e", ty.vec3()), @@ -376,10 +376,11 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_Structures) { }); // inner_y: size(516), align(4) - auto* inner_y = Structure("inner_y", utils::Vector{ - Member("a", ty.i32(), utils::Vector{MemberSize(512)}), - Member("b", ty.f32()), - }); + auto* inner_y = + Structure("inner_y", utils::Vector{ + Member("a", ty.i32(), utils::Vector{MemberSize(512_a)}), + Member("b", ty.f32()), + }); auto* s = Structure("S", utils::Vector{ Member("a", ty.i32()), @@ -595,7 +596,7 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_ArrayVec3DefaultStride) { TEST_F(MslGeneratorImplTest, AttemptTintPadSymbolCollision) { auto* s = Structure("S", utils::Vector{ // uses symbols tint_pad_[0..9] and tint_pad_[20..35] - Member("tint_pad_2", ty.i32(), utils::Vector{MemberSize(32)}), + Member("tint_pad_2", ty.i32(), utils::Vector{MemberSize(32_a)}), Member("tint_pad_20", ty.f32(), utils::Vector{MemberAlign(128_u), MemberSize(128_u)}), Member("tint_pad_33", ty.vec2()), diff --git a/src/tint/writer/wgsl/generator_impl.cc b/src/tint/writer/wgsl/generator_impl.cc index b2fba295d3..83a96d9164 100644 --- a/src/tint/writer/wgsl/generator_impl.cc +++ b/src/tint/writer/wgsl/generator_impl.cc @@ -788,7 +788,11 @@ bool GeneratorImpl::EmitAttributes(std::ostream& out, return true; }, [&](const ast::StructMemberSizeAttribute* size) { - out << "size(" << size->size << ")"; + out << "size("; + if (!EmitExpression(out, size->expr)) { + return false; + } + out << ")"; return true; }, [&](const ast::StructMemberAlignAttribute* align) { diff --git a/src/tint/writer/wgsl/generator_impl_type_test.cc b/src/tint/writer/wgsl/generator_impl_type_test.cc index ef90579c55..f6f39d4a2f 100644 --- a/src/tint/writer/wgsl/generator_impl_type_test.cc +++ b/src/tint/writer/wgsl/generator_impl_type_test.cc @@ -178,8 +178,8 @@ TEST_F(WgslGeneratorImplTest, EmitType_Struct) { TEST_F(WgslGeneratorImplTest, EmitType_StructOffsetDecl) { auto* s = Structure("S", utils::Vector{ - Member("a", ty.i32(), utils::Vector{MemberOffset(8)}), - Member("b", ty.f32(), utils::Vector{MemberOffset(16)}), + Member("a", ty.i32(), utils::Vector{MemberOffset(8_a)}), + Member("b", ty.f32(), utils::Vector{MemberOffset(16_a)}), }); GeneratorImpl& gen = Build(); @@ -199,8 +199,8 @@ TEST_F(WgslGeneratorImplTest, EmitType_StructOffsetDecl) { TEST_F(WgslGeneratorImplTest, EmitType_StructOffsetDecl_WithSymbolCollisions) { auto* s = Structure("S", utils::Vector{ - Member("tint_0_padding", ty.i32(), utils::Vector{MemberOffset(8)}), - Member("tint_2_padding", ty.f32(), utils::Vector{MemberOffset(16)}), + Member("tint_0_padding", ty.i32(), utils::Vector{MemberOffset(8_a)}), + Member("tint_2_padding", ty.f32(), utils::Vector{MemberOffset(16_a)}), }); GeneratorImpl& gen = Build(); @@ -237,8 +237,8 @@ TEST_F(WgslGeneratorImplTest, EmitType_StructAlignDecl) { TEST_F(WgslGeneratorImplTest, EmitType_StructSizeDecl) { auto* s = Structure("S", utils::Vector{ - Member("a", ty.i32(), utils::Vector{MemberSize(16)}), - Member("b", ty.f32(), utils::Vector{MemberSize(32)}), + Member("a", ty.i32(), utils::Vector{MemberSize(16_a)}), + Member("b", ty.f32(), utils::Vector{MemberSize(32_a)}), }); GeneratorImpl& gen = Build();