[ir] Validate that uniform and storage vars have host-shareable types
Move the IsHostShareable() helper from the WGSL validator into
core::type::Type*, using flags to avoid re-computing it on every call.
Fixed: 409840687
Change-Id: I1edd77da419211c09c23e5ba324c3b082f0b8010
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/236077
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index 2a4c3a4..e41a411 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -2552,9 +2552,15 @@
}
}
+ if (mv->AddressSpace() == AddressSpace::kStorage) {
+ if (mv->StoreType() && !mv->StoreType()->IsHostShareable()) {
+ AddError(var) << "vars in the 'storage' address space must be host-shareable";
+ return;
+ }
+ }
+
if (mv->AddressSpace() == AddressSpace::kUniform) {
- // TODO(409840687): Add host-shareable check.
- if (!mv->StoreType()->IsConstructible()) {
+ if (!mv->StoreType()->IsConstructible() || !mv->StoreType()->IsHostShareable()) {
AddError(var)
<< "vars in the 'uniform' address space must be host-shareable and constructible";
return;
diff --git a/src/tint/lang/core/ir/validator_value_test.cc b/src/tint/lang/core/ir/validator_value_test.cc
index 7c7d111..1b3abb2 100644
--- a/src/tint/lang/core/ir/validator_value_test.cc
+++ b/src/tint/lang/core/ir/validator_value_test.cc
@@ -455,6 +455,37 @@
)")) << res.Failure();
}
+TEST_F(IR_ValidatorTest, Var_Uniform_NotHostShareable) {
+ auto* v = b.Var<uniform, bool>();
+ v->SetBindingPoint(0, 0);
+ mod.root_block->Append(v);
+
+ auto res = ir::Validate(mod);
+ ASSERT_NE(res, Success);
+ EXPECT_THAT(
+ res.Failure().reason,
+ testing::HasSubstr(
+ R"(:2:33 error: var: vars in the 'uniform' address space must be host-shareable and constructible
+ %1:ptr<uniform, bool, read> = var undef @binding_point(0, 0)
+ ^^^
+)")) << res.Failure();
+}
+
+TEST_F(IR_ValidatorTest, Var_Storage_NotHostShareable) {
+ auto* v = b.Var<storage, bool, read>();
+ v->SetBindingPoint(0, 0);
+ mod.root_block->Append(v);
+
+ auto res = ir::Validate(mod);
+ ASSERT_NE(res, Success);
+ EXPECT_THAT(res.Failure().reason,
+ testing::HasSubstr(
+ R"(:2:33 error: var: vars in the 'storage' address space must be host-shareable
+ %1:ptr<storage, bool, read> = var undef @binding_point(0, 0)
+ ^^^
+)")) << res.Failure();
+}
+
TEST_F(IR_ValidatorTest, Var_MultipleIOAnnotations) {
auto* v = b.Var<AddressSpace::kIn, vec4<f32>>();
IOAttributes attr;
diff --git a/src/tint/lang/core/type/BUILD.bazel b/src/tint/lang/core/type/BUILD.bazel
index b98f9b7..7771174 100644
--- a/src/tint/lang/core/type/BUILD.bazel
+++ b/src/tint/lang/core/type/BUILD.bazel
@@ -164,6 +164,7 @@
"i32_test.cc",
"i8_test.cc",
"input_attachment_test.cc",
+ "is_host_shareable_test.cc",
"manager_test.cc",
"matrix_test.cc",
"multisampled_texture_test.cc",
diff --git a/src/tint/lang/core/type/BUILD.cmake b/src/tint/lang/core/type/BUILD.cmake
index 91058d3..5d458a6 100644
--- a/src/tint/lang/core/type/BUILD.cmake
+++ b/src/tint/lang/core/type/BUILD.cmake
@@ -165,6 +165,7 @@
lang/core/type/i32_test.cc
lang/core/type/i8_test.cc
lang/core/type/input_attachment_test.cc
+ lang/core/type/is_host_shareable_test.cc
lang/core/type/manager_test.cc
lang/core/type/matrix_test.cc
lang/core/type/multisampled_texture_test.cc
diff --git a/src/tint/lang/core/type/BUILD.gn b/src/tint/lang/core/type/BUILD.gn
index 103e228..9737eb1 100644
--- a/src/tint/lang/core/type/BUILD.gn
+++ b/src/tint/lang/core/type/BUILD.gn
@@ -165,6 +165,7 @@
"i32_test.cc",
"i8_test.cc",
"input_attachment_test.cc",
+ "is_host_shareable_test.cc",
"manager_test.cc",
"matrix_test.cc",
"multisampled_texture_test.cc",
diff --git a/src/tint/lang/core/type/array.cc b/src/tint/lang/core/type/array.cc
index 2def0fe..3548e83 100644
--- a/src/tint/lang/core/type/array.cc
+++ b/src/tint/lang/core/type/array.cc
@@ -58,6 +58,9 @@
flags.Add(Flag::kFixedFootprint);
}
}
+ if (element->IsHostShareable()) {
+ flags.Add(Flag::kHostShareable);
+ }
return flags;
}
diff --git a/src/tint/lang/core/type/atomic.cc b/src/tint/lang/core/type/atomic.cc
index a683f24..d72476d 100644
--- a/src/tint/lang/core/type/atomic.cc
+++ b/src/tint/lang/core/type/atomic.cc
@@ -43,6 +43,7 @@
core::type::Flags{
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
+ Flag::kHostShareable,
}),
subtype_(subtype) {
TINT_ASSERT(!subtype->Is<Reference>());
diff --git a/src/tint/lang/core/type/f16.cc b/src/tint/lang/core/type/f16.cc
index a73f394..0ee753d 100644
--- a/src/tint/lang/core/type/f16.cc
+++ b/src/tint/lang/core/type/f16.cc
@@ -39,6 +39,7 @@
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
+ Flag::kHostShareable,
}) {}
F16::~F16() = default;
diff --git a/src/tint/lang/core/type/f32.cc b/src/tint/lang/core/type/f32.cc
index 30153f1..a4cba58 100644
--- a/src/tint/lang/core/type/f32.cc
+++ b/src/tint/lang/core/type/f32.cc
@@ -39,6 +39,7 @@
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
+ Flag::kHostShareable,
}) {}
F32::~F32() = default;
diff --git a/src/tint/lang/core/type/i32.cc b/src/tint/lang/core/type/i32.cc
index d1d02ea..4942b48 100644
--- a/src/tint/lang/core/type/i32.cc
+++ b/src/tint/lang/core/type/i32.cc
@@ -39,6 +39,7 @@
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
+ Flag::kHostShareable,
}) {}
I32::~I32() = default;
diff --git a/src/tint/lang/core/type/is_host_shareable_test.cc b/src/tint/lang/core/type/is_host_shareable_test.cc
new file mode 100644
index 0000000..47d2d40
--- /dev/null
+++ b/src/tint/lang/core/type/is_host_shareable_test.cc
@@ -0,0 +1,171 @@
+// Copyright 2021 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/core/type/array.h"
+#include "src/tint/lang/core/type/bool.h"
+#include "src/tint/lang/core/type/f16.h"
+#include "src/tint/lang/core/type/f32.h"
+#include "src/tint/lang/core/type/helper_test.h"
+#include "src/tint/lang/core/type/i32.h"
+#include "src/tint/lang/core/type/manager.h"
+#include "src/tint/lang/core/type/matrix.h"
+#include "src/tint/lang/core/type/pointer.h"
+#include "src/tint/lang/core/type/u32.h"
+#include "src/tint/lang/core/type/vector.h"
+#include "src/tint/lang/core/type/void.h"
+#include "src/tint/utils/symbol/symbol_table.h"
+
+namespace tint::core::type {
+namespace {
+
+class TypeIsHostShareableTest : public TestHelper {
+ protected:
+ Manager ty;
+ GenerationID id;
+ SymbolTable st{id};
+};
+
+TEST_F(TypeIsHostShareableTest, Void) {
+ EXPECT_FALSE(ty.void_()->IsHostShareable());
+}
+
+TEST_F(TypeIsHostShareableTest, Bool) {
+ EXPECT_FALSE(ty.bool_()->IsHostShareable());
+}
+
+TEST_F(TypeIsHostShareableTest, NumericScalar) {
+ EXPECT_TRUE(ty.i32()->IsHostShareable());
+ EXPECT_TRUE(ty.u32()->IsHostShareable());
+ EXPECT_TRUE(ty.f32()->IsHostShareable());
+ EXPECT_TRUE(ty.f16()->IsHostShareable());
+}
+
+TEST_F(TypeIsHostShareableTest, NumericVector) {
+ EXPECT_TRUE(ty.vec2<i32>()->IsHostShareable());
+ EXPECT_TRUE(ty.vec3<i32>()->IsHostShareable());
+ EXPECT_TRUE(ty.vec4<i32>()->IsHostShareable());
+ EXPECT_TRUE(ty.vec2<u32>()->IsHostShareable());
+ EXPECT_TRUE(ty.vec3<u32>()->IsHostShareable());
+ EXPECT_TRUE(ty.vec4<u32>()->IsHostShareable());
+ EXPECT_TRUE(ty.vec2<f32>()->IsHostShareable());
+ EXPECT_TRUE(ty.vec3<f32>()->IsHostShareable());
+ EXPECT_TRUE(ty.vec4<f32>()->IsHostShareable());
+ EXPECT_TRUE(ty.vec2<f16>()->IsHostShareable());
+ EXPECT_TRUE(ty.vec3<f16>()->IsHostShareable());
+ EXPECT_TRUE(ty.vec4<f16>()->IsHostShareable());
+}
+
+TEST_F(TypeIsHostShareableTest, BoolVector) {
+ EXPECT_FALSE(ty.vec2<bool>()->IsHostShareable());
+ EXPECT_FALSE(ty.vec3<bool>()->IsHostShareable());
+ EXPECT_FALSE(ty.vec4<bool>()->IsHostShareable());
+ EXPECT_FALSE(ty.vec2<bool>()->IsHostShareable());
+ EXPECT_FALSE(ty.vec3<bool>()->IsHostShareable());
+ EXPECT_FALSE(ty.vec4<bool>()->IsHostShareable());
+ EXPECT_FALSE(ty.vec2<bool>()->IsHostShareable());
+ EXPECT_FALSE(ty.vec3<bool>()->IsHostShareable());
+ EXPECT_FALSE(ty.vec4<bool>()->IsHostShareable());
+}
+
+TEST_F(TypeIsHostShareableTest, Matrix) {
+ EXPECT_TRUE(ty.mat2x2<f32>()->IsHostShareable());
+ EXPECT_TRUE(ty.mat3x2<f32>()->IsHostShareable());
+ EXPECT_TRUE(ty.mat4x2<f32>()->IsHostShareable());
+ EXPECT_TRUE(ty.mat2x2<f32>()->IsHostShareable());
+ EXPECT_TRUE(ty.mat3x2<f32>()->IsHostShareable());
+ EXPECT_TRUE(ty.mat4x2<f32>()->IsHostShareable());
+ EXPECT_TRUE(ty.mat2x2<f32>()->IsHostShareable());
+ EXPECT_TRUE(ty.mat3x2<f32>()->IsHostShareable());
+ EXPECT_TRUE(ty.mat4x2<f32>()->IsHostShareable());
+
+ EXPECT_TRUE(ty.mat2x2<f16>()->IsHostShareable());
+ EXPECT_TRUE(ty.mat3x2<f16>()->IsHostShareable());
+ EXPECT_TRUE(ty.mat4x2<f16>()->IsHostShareable());
+ EXPECT_TRUE(ty.mat2x2<f16>()->IsHostShareable());
+ EXPECT_TRUE(ty.mat3x2<f16>()->IsHostShareable());
+ EXPECT_TRUE(ty.mat4x2<f16>()->IsHostShareable());
+ EXPECT_TRUE(ty.mat2x2<f16>()->IsHostShareable());
+ EXPECT_TRUE(ty.mat3x2<f16>()->IsHostShareable());
+ EXPECT_TRUE(ty.mat4x2<f16>()->IsHostShareable());
+}
+
+TEST_F(TypeIsHostShareableTest, Pointer) {
+ auto* ptr = ty.ptr(core::AddressSpace::kPrivate, ty.i32());
+ EXPECT_FALSE(ptr->IsHostShareable());
+}
+
+TEST_F(TypeIsHostShareableTest, Atomic) {
+ EXPECT_TRUE(ty.atomic<i32>()->IsHostShareable());
+ EXPECT_TRUE(ty.atomic<u32>()->IsHostShareable());
+}
+
+TEST_F(TypeIsHostShareableTest, Array_FixedSized) {
+ EXPECT_TRUE((ty.array<i32, 5>()->IsHostShareable()));
+ EXPECT_FALSE((ty.array<bool, 5>()->IsHostShareable()));
+}
+
+TEST_F(TypeIsHostShareableTest, Array_RuntimeSized) {
+ EXPECT_TRUE(ty.array<i32>()->IsHostShareable());
+ EXPECT_FALSE(ty.array<bool>()->IsHostShareable());
+}
+
+TEST_F(TypeIsHostShareableTest, Struct_HostShareable) {
+ auto* inner = ty.Struct(st.New(), tint::Vector{
+ Manager::StructMemberDesc{st.New(), ty.i32()},
+ Manager::StructMemberDesc{st.New(), ty.u32()},
+ Manager::StructMemberDesc{st.New(), ty.f32()},
+ Manager::StructMemberDesc{st.New(), ty.vec3<f32>()},
+ Manager::StructMemberDesc{st.New(), ty.mat4x2<f32>()},
+ Manager::StructMemberDesc{st.New(), ty.array<f32, 4>()},
+ });
+ auto* outer = ty.Struct(st.New(), tint::Vector{
+ Manager::StructMemberDesc{st.New(), inner},
+ });
+ EXPECT_TRUE(inner->IsConstructible());
+ EXPECT_TRUE(inner->IsHostShareable());
+ EXPECT_TRUE(outer->IsHostShareable());
+}
+
+TEST_F(TypeIsHostShareableTest, Struct_NotHostShareable) {
+ auto* inner = ty.Struct(st.New(), tint::Vector{
+ Manager::StructMemberDesc{st.New(), ty.i32()},
+ Manager::StructMemberDesc{st.New(), ty.u32()},
+ Manager::StructMemberDesc{st.New(), ty.f32()},
+ Manager::StructMemberDesc{st.New(), ty.bool_()},
+ Manager::StructMemberDesc{st.New(), ty.vec3<f32>()},
+ Manager::StructMemberDesc{st.New(), ty.mat4x2<f32>()},
+ Manager::StructMemberDesc{st.New(), ty.array<f32, 4>()},
+ });
+ auto* outer = ty.Struct(st.New(), tint::Vector{
+ Manager::StructMemberDesc{st.New(), inner},
+ });
+ EXPECT_FALSE(inner->IsHostShareable());
+ EXPECT_FALSE(outer->IsHostShareable());
+}
+
+} // namespace
+} // namespace tint::core::type
diff --git a/src/tint/lang/core/type/matrix.cc b/src/tint/lang/core/type/matrix.cc
index a811a8f..b53395f 100644
--- a/src/tint/lang/core/type/matrix.cc
+++ b/src/tint/lang/core/type/matrix.cc
@@ -44,6 +44,7 @@
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
+ Flag::kHostShareable,
}),
subtype_(column_type->Type()),
column_type_(column_type),
diff --git a/src/tint/lang/core/type/struct.cc b/src/tint/lang/core/type/struct.cc
index 3c481c9..6a8d872 100644
--- a/src/tint/lang/core/type/struct.cc
+++ b/src/tint/lang/core/type/struct.cc
@@ -51,6 +51,7 @@
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
+ Flag::kHostShareable,
};
for (auto* member : members) {
if (!member->Type()->IsConstructible()) {
@@ -62,6 +63,9 @@
if (!member->Type()->HasCreationFixedFootprint()) {
flags.Remove(Flag::kCreationFixedFootprint);
}
+ if (!member->Type()->IsHostShareable()) {
+ flags.Remove(Flag::kHostShareable);
+ }
}
return flags;
}
diff --git a/src/tint/lang/core/type/type.h b/src/tint/lang/core/type/type.h
index daa98f9..eef83fd 100644
--- a/src/tint/lang/core/type/type.h
+++ b/src/tint/lang/core/type/type.h
@@ -58,6 +58,9 @@
/// Type has a fixed footprint.
/// @see https://www.w3.org/TR/WGSL/#fixed-footprint-types
kFixedFootprint,
+ /// Type is host-shareable.
+ /// @see https://www.w3.org/TR/WGSL/#host-shareable
+ kHostShareable,
};
/// An alias to tint::EnumSet<Flag>
@@ -129,6 +132,10 @@
/// @see https://www.w3.org/TR/WGSL/#fixed-footprint-types
inline bool HasFixedFootprint() const { return flags_.Contains(Flag::kFixedFootprint); }
+ /// @returns true if type is host-shareable
+ /// https://www.w3.org/TR/WGSL/#host-shareable
+ inline bool IsHostShareable() const { return flags_.Contains(Flag::kHostShareable); }
+
/// @returns true if the type is a scalar
bool IsScalar() const;
/// @returns true if this type is a float scalar
diff --git a/src/tint/lang/core/type/u32.cc b/src/tint/lang/core/type/u32.cc
index 409e1fb..c1b2910 100644
--- a/src/tint/lang/core/type/u32.cc
+++ b/src/tint/lang/core/type/u32.cc
@@ -39,6 +39,7 @@
Flag::kConstructable,
Flag::kCreationFixedFootprint,
Flag::kFixedFootprint,
+ Flag::kHostShareable,
}) {}
U32::~U32() = default;
diff --git a/src/tint/lang/core/type/vector.cc b/src/tint/lang/core/type/vector.cc
index a837c83..5662735 100644
--- a/src/tint/lang/core/type/vector.cc
+++ b/src/tint/lang/core/type/vector.cc
@@ -37,13 +37,24 @@
namespace tint::core::type {
+namespace {
+
+core::type::Flags FlagsFrom(const Type* element) {
+ core::type::Flags flags{
+ Flag::kConstructable,
+ Flag::kCreationFixedFootprint,
+ Flag::kFixedFootprint,
+ };
+ if (element->IsHostShareable()) {
+ flags.Add(Flag::kHostShareable);
+ }
+ return flags;
+}
+
+} // namespace
+
Vector::Vector(type::Type const* subtype, uint32_t width, bool packed /* = false */)
- : Base(Hash(tint::TypeCode::Of<Vector>().bits, width, subtype, packed),
- core::type::Flags{
- Flag::kConstructable,
- Flag::kCreationFixedFootprint,
- Flag::kFixedFootprint,
- }),
+ : Base(Hash(tint::TypeCode::Of<Vector>().bits, width, subtype, packed), FlagsFrom(subtype)),
subtype_(subtype),
width_(width),
packed_(packed) {
diff --git a/src/tint/lang/wgsl/resolver/BUILD.bazel b/src/tint/lang/wgsl/resolver/BUILD.bazel
index 720a77d..8899f2d 100644
--- a/src/tint/lang/wgsl/resolver/BUILD.bazel
+++ b/src/tint/lang/wgsl/resolver/BUILD.bazel
@@ -133,7 +133,6 @@
"increment_decrement_validation_test.cc",
"inferred_type_test.cc",
"input_attachments_extension_test.cc",
- "is_host_shareable_test.cc",
"is_storeable_test.cc",
"language_features_test.cc",
"load_test.cc",
diff --git a/src/tint/lang/wgsl/resolver/BUILD.cmake b/src/tint/lang/wgsl/resolver/BUILD.cmake
index bc4b6b7..863543b 100644
--- a/src/tint/lang/wgsl/resolver/BUILD.cmake
+++ b/src/tint/lang/wgsl/resolver/BUILD.cmake
@@ -134,7 +134,6 @@
lang/wgsl/resolver/increment_decrement_validation_test.cc
lang/wgsl/resolver/inferred_type_test.cc
lang/wgsl/resolver/input_attachments_extension_test.cc
- lang/wgsl/resolver/is_host_shareable_test.cc
lang/wgsl/resolver/is_storeable_test.cc
lang/wgsl/resolver/language_features_test.cc
lang/wgsl/resolver/load_test.cc
diff --git a/src/tint/lang/wgsl/resolver/BUILD.gn b/src/tint/lang/wgsl/resolver/BUILD.gn
index a69dcdf..592731e 100644
--- a/src/tint/lang/wgsl/resolver/BUILD.gn
+++ b/src/tint/lang/wgsl/resolver/BUILD.gn
@@ -134,7 +134,6 @@
"increment_decrement_validation_test.cc",
"inferred_type_test.cc",
"input_attachments_extension_test.cc",
- "is_host_shareable_test.cc",
"is_storeable_test.cc",
"language_features_test.cc",
"load_test.cc",
diff --git a/src/tint/lang/wgsl/resolver/is_host_shareable_test.cc b/src/tint/lang/wgsl/resolver/is_host_shareable_test.cc
deleted file mode 100644
index 1f3a603..0000000
--- a/src/tint/lang/wgsl/resolver/is_host_shareable_test.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2021 The Dawn & Tint Authors
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice, this
-// list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-//
-// 3. Neither the name of the copyright holder nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "src/tint/lang/wgsl/resolver/resolver.h"
-
-#include "gmock/gmock.h"
-#include "src/tint/lang/core/type/atomic.h"
-#include "src/tint/lang/wgsl/resolver/resolver_helper_test.h"
-#include "src/tint/lang/wgsl/sem/array.h"
-
-namespace tint::resolver {
-namespace {
-
-using ResolverIsHostShareable = ResolverTest;
-
-TEST_F(ResolverIsHostShareable, Void) {
- EXPECT_FALSE(r()->IsHostShareable(create<core::type::Void>()));
-}
-
-TEST_F(ResolverIsHostShareable, Bool) {
- EXPECT_FALSE(r()->IsHostShareable(create<core::type::Bool>()));
-}
-
-TEST_F(ResolverIsHostShareable, NumericScalar) {
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::I32>()));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::U32>()));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::F32>()));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::F16>()));
-}
-
-TEST_F(ResolverIsHostShareable, NumericVector) {
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::I32>(), 2u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::I32>(), 3u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::I32>(), 4u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::U32>(), 2u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::U32>(), 3u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::U32>(), 4u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::F32>(), 2u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::F32>(), 3u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::F32>(), 4u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::F16>(), 2u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::F16>(), 3u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::F16>(), 4u)));
-}
-
-TEST_F(ResolverIsHostShareable, BoolVector) {
- EXPECT_FALSE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::Bool>(), 2u)));
- EXPECT_FALSE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::Bool>(), 3u)));
- EXPECT_FALSE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::Bool>(), 4u)));
- EXPECT_FALSE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::Bool>(), 2u)));
- EXPECT_FALSE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::Bool>(), 3u)));
- EXPECT_FALSE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::Bool>(), 4u)));
- EXPECT_FALSE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::Bool>(), 2u)));
- EXPECT_FALSE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::Bool>(), 3u)));
- EXPECT_FALSE(r()->IsHostShareable(create<core::type::Vector>(create<core::type::Bool>(), 4u)));
-}
-
-TEST_F(ResolverIsHostShareable, Matrix) {
- auto* vec2_f32 = create<core::type::Vector>(create<core::type::F32>(), 2u);
- auto* vec3_f32 = create<core::type::Vector>(create<core::type::F32>(), 3u);
- auto* vec4_f32 = create<core::type::Vector>(create<core::type::F32>(), 4u);
- auto* vec2_f16 = create<core::type::Vector>(create<core::type::F16>(), 2u);
- auto* vec3_f16 = create<core::type::Vector>(create<core::type::F16>(), 3u);
- auto* vec4_f16 = create<core::type::Vector>(create<core::type::F16>(), 4u);
-
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec2_f32, 2u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec2_f32, 3u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec2_f32, 4u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec3_f32, 2u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec3_f32, 3u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec3_f32, 4u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec4_f32, 2u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec4_f32, 3u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec4_f32, 4u)));
-
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec2_f16, 2u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec2_f16, 3u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec2_f16, 4u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec3_f16, 2u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec3_f16, 3u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec3_f16, 4u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec4_f16, 2u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec4_f16, 3u)));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Matrix>(vec4_f16, 4u)));
-}
-
-TEST_F(ResolverIsHostShareable, Pointer) {
- auto* ptr = create<core::type::Pointer>(core::AddressSpace::kPrivate, create<core::type::I32>(),
- core::Access::kReadWrite);
- EXPECT_FALSE(r()->IsHostShareable(ptr));
-}
-
-TEST_F(ResolverIsHostShareable, Atomic) {
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Atomic>(create<core::type::I32>())));
- EXPECT_TRUE(r()->IsHostShareable(create<core::type::Atomic>(create<core::type::U32>())));
-}
-
-TEST_F(ResolverIsHostShareable, ArraySizedOfHostShareable) {
- auto* arr = create<sem::Array>(create<core::type::I32>(),
- create<core::type::ConstantArrayCount>(5u), 4u, 20u, 4u, 4u);
- EXPECT_TRUE(r()->IsHostShareable(arr));
-}
-
-TEST_F(ResolverIsHostShareable, ArrayUnsizedOfHostShareable) {
- auto* arr = create<sem::Array>(create<core::type::I32>(),
- create<core::type::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
- EXPECT_TRUE(r()->IsHostShareable(arr));
-}
-
-// Note: Structure tests covered in host_shareable_validation_test.cc
-
-} // namespace
-} // namespace tint::resolver
diff --git a/src/tint/lang/wgsl/resolver/resolver.cc b/src/tint/lang/wgsl/resolver/resolver.cc
index d2edc57..e7f3631 100644
--- a/src/tint/lang/wgsl/resolver/resolver.cc
+++ b/src/tint/lang/wgsl/resolver/resolver.cc
@@ -5046,7 +5046,7 @@
return false;
}
- if (core::IsHostShareable(address_space) && !validator_.IsHostShareable(ty)) {
+ if (core::IsHostShareable(address_space) && !ty->IsHostShareable()) {
AddError(usage) << "type " << style::Type(sem_.TypeNameOf(ty))
<< " cannot be used in address space " << style::Enum(address_space)
<< " as it is non-host-shareable";
diff --git a/src/tint/lang/wgsl/resolver/resolver.h b/src/tint/lang/wgsl/resolver/resolver.h
index deb039e..9d031f9 100644
--- a/src/tint/lang/wgsl/resolver/resolver.h
+++ b/src/tint/lang/wgsl/resolver/resolver.h
@@ -129,12 +129,6 @@
/// @returns true if the given type is storable
bool IsStorable(const core::type::Type* type) const { return validator_.IsStorable(type); }
- /// @param type the given type
- /// @returns true if the given type is host-shareable
- bool IsHostShareable(const core::type::Type* type) const {
- return validator_.IsHostShareable(type);
- }
-
/// @returns the validator for testing
const Validator* GetValidatorForTesting() const { return &validator_; }
diff --git a/src/tint/lang/wgsl/resolver/validator.cc b/src/tint/lang/wgsl/resolver/validator.cc
index 4598a10..432c4d2 100644
--- a/src/tint/lang/wgsl/resolver/validator.cc
+++ b/src/tint/lang/wgsl/resolver/validator.cc
@@ -243,27 +243,6 @@
[&](Default) { return type->Is<core::type::Scalar>(); });
}
-// https://gpuweb.github.io/gpuweb/wgsl.html#host-shareable-types
-bool Validator::IsHostShareable(const core::type::Type* type) const {
- if (type->IsAnyOf<core::type::I32, core::type::U32, core::type::F32, core::type::F16>()) {
- return true;
- }
- return Switch(
- type, //
- [&](const core::type::Vector* vec) { return IsHostShareable(vec->Type()); },
- [&](const core::type::Matrix* mat) { return IsHostShareable(mat->Type()); },
- [&](const sem::Array* arr) { return IsHostShareable(arr->ElemType()); },
- [&](const core::type::Struct* str) {
- for (auto* member : str->Members()) {
- if (!IsHostShareable(member->Type())) {
- return false;
- }
- }
- return true;
- },
- [&](const core::type::Atomic* atomic) { return IsHostShareable(atomic->Type()); });
-}
-
// https://gpuweb.github.io/gpuweb/wgsl.html#storable-types
bool Validator::IsStorable(const core::type::Type* type) const {
return IsPlain(type) ||
diff --git a/src/tint/lang/wgsl/resolver/validator.h b/src/tint/lang/wgsl/resolver/validator.h
index 16c57c0..3955832 100644
--- a/src/tint/lang/wgsl/resolver/validator.h
+++ b/src/tint/lang/wgsl/resolver/validator.h
@@ -170,10 +170,6 @@
/// @returns true if the given type is storable
bool IsStorable(const core::type::Type* type) const;
- /// @param type the given type
- /// @returns true if the given type is host-shareable
- bool IsHostShareable(const core::type::Type* type) const;
-
/// Validates the enabled extensions
/// @param enables the extension enables
/// @returns true on success, false otherwise.