[ir] Do not wrap structs with @block attribute
Push constant structures already have a block attribute and do not
need to be wrapped, so skip them in the BlockDecoratedStructs
transform.
Change-Id: I1d564b9155cd3a2b7d6d38158b9475d7fed60583
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/209834
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/core/ir/transform/block_decorated_structs.cc b/src/tint/lang/core/ir/transform/block_decorated_structs.cc
index bc8fe39..e026fad 100644
--- a/src/tint/lang/core/ir/transform/block_decorated_structs.cc
+++ b/src/tint/lang/core/ir/transform/block_decorated_structs.cc
@@ -68,12 +68,18 @@
auto* ptr = var->Result(0)->Type()->As<core::type::Pointer>();
auto* store_ty = ptr->StoreType();
- if (auto* str = store_ty->As<core::type::Struct>(); str && !str->HasFixedFootprint()) {
- // We know the original struct will only ever be used as the store type of a buffer, so
- // just mark it as a block-decorated struct.
- // TODO(crbug.com/tint/745): Remove the const_cast.
- const_cast<type::Struct*>(str)->SetStructFlag(type::kBlock);
- continue;
+ if (auto* str = store_ty->As<core::type::Struct>()) {
+ if (str->StructFlags().Contains(type::kBlock)) {
+ // The struct already has a block attribute, so we don't need to do anything here.
+ continue;
+ }
+ if (!str->HasFixedFootprint()) {
+ // We know the original struct will only ever be used as the store type of a buffer,
+ // so just mark it as a block-decorated struct.
+ // TODO(crbug.com/tint/745): Remove the const_cast.
+ const_cast<type::Struct*>(str)->SetStructFlag(type::kBlock);
+ continue;
+ }
}
// The original struct might be used in other places, so create a new block-decorated
diff --git a/src/tint/lang/core/ir/transform/block_decorated_structs_test.cc b/src/tint/lang/core/ir/transform/block_decorated_structs_test.cc
index f85e4dd..6f7ad60 100644
--- a/src/tint/lang/core/ir/transform/block_decorated_structs_test.cc
+++ b/src/tint/lang/core/ir/transform/block_decorated_structs_test.cc
@@ -394,5 +394,47 @@
EXPECT_EQ(expect, str());
}
+TEST_F(IR_BlockDecoratedStructsTest, PushConstantAlreadyHasBlockAttribute) {
+ auto* structure = ty.Struct(mod.symbols.New("MyStruct"), {
+ {mod.symbols.New("i"), ty.i32()},
+ });
+ structure->SetStructFlag(type::kBlock);
+
+ auto* buffer = b.Var(ty.ptr(push_constant, structure));
+ mod.root_block->Append(buffer);
+
+ auto* func = b.Function("foo", ty.i32());
+ b.Append(func->Block(), [&] {
+ auto* val_ptr = b.Access<ptr<push_constant, i32>>(buffer, 0_u);
+ b.Return(func, b.Load(val_ptr));
+ });
+
+ auto* src = R"(
+MyStruct = struct @align(4), @block {
+ i:i32 @offset(0)
+}
+
+$B1: { # root
+ %1:ptr<push_constant, MyStruct, read> = var
+}
+
+%foo = func():i32 {
+ $B2: {
+ %3:ptr<push_constant, i32, read> = access %1, 0u
+ %4:i32 = load %3
+ ret %4
+ }
+}
+)";
+
+ EXPECT_EQ(src, str());
+
+ auto* expect = src;
+
+ Run(BlockDecoratedStructs);
+
+ EXPECT_EQ(expect, str());
+}
+
} // namespace
} // namespace tint::core::ir::transform