sem: Use UniqueAllocator for types
Add a Hash() and Equals() methods to sem::Type. Have sem::Manager (which should be called sem::TypeManager) derive from utils::UniqueAllocator. This now uses the Hash() and Equals() for uniquely constructing semantic types instead of building strings and comparing those. Bug: tint:1383 Change-Id: I5e3229bd087391ac594d333a0ab4232cfcddf54d Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/82743 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
a0eac2a492
commit
4391975f72
|
@ -47,6 +47,11 @@ class Any : public Castable<Any, sem::Type> {
|
|||
public:
|
||||
Any() = default;
|
||||
~Any() override = default;
|
||||
|
||||
// Stub implementations for sem::Type conformance.
|
||||
size_t Hash() const override { return 0; }
|
||||
bool Equals(const sem::Type&) const override { return false; }
|
||||
|
||||
std::string type_name() const override { return "<any>"; }
|
||||
std::string FriendlyName(const SymbolTable&) const override {
|
||||
return "<any>";
|
||||
|
@ -429,11 +434,11 @@ bool match_array(const sem::Type* ty, const sem::Type*& T) {
|
|||
|
||||
const sem::Array* build_array(MatchState& state, const sem::Type* el) {
|
||||
return state.builder.create<sem::Array>(el,
|
||||
/* count */ 0,
|
||||
/* align */ 0,
|
||||
/* size */ 0,
|
||||
/* stride */ 0,
|
||||
/* stride_implicit */ 0);
|
||||
/* count */ 0u,
|
||||
/* align */ 0u,
|
||||
/* size */ 0u,
|
||||
/* stride */ 0u,
|
||||
/* stride_implicit */ 0u);
|
||||
}
|
||||
|
||||
bool match_ptr(const sem::Type* ty, Number& S, const sem::Type*& T, Number& A) {
|
||||
|
|
|
@ -60,7 +60,7 @@ TEST_F(BuiltinTableTest, MismatchF32) {
|
|||
TEST_F(BuiltinTableTest, MatchU32) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* u32 = create<sem::U32>();
|
||||
auto* vec2_f32 = create<sem::Vector>(f32, 2);
|
||||
auto* vec2_f32 = create<sem::Vector>(f32, 2u);
|
||||
auto* result = table->Lookup(BuiltinType::kUnpack2x16float, {u32}, Source{});
|
||||
ASSERT_NE(result, nullptr) << Diagnostics().str();
|
||||
ASSERT_EQ(Diagnostics().str(), "");
|
||||
|
@ -80,7 +80,7 @@ TEST_F(BuiltinTableTest, MismatchU32) {
|
|||
TEST_F(BuiltinTableTest, MatchI32) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* i32 = create<sem::I32>();
|
||||
auto* vec4_f32 = create<sem::Vector>(f32, 4);
|
||||
auto* vec4_f32 = create<sem::Vector>(f32, 4u);
|
||||
auto* tex = create<sem::SampledTexture>(ast::TextureDimension::k1d, f32);
|
||||
auto* result =
|
||||
table->Lookup(BuiltinType::kTextureLoad, {tex, i32, i32}, Source{});
|
||||
|
@ -226,7 +226,7 @@ TEST_F(BuiltinTableTest, MismatchPointer) {
|
|||
}
|
||||
|
||||
TEST_F(BuiltinTableTest, MatchArray) {
|
||||
auto* arr = create<sem::Array>(create<sem::U32>(), 0, 4, 4, 4, 4);
|
||||
auto* arr = create<sem::Array>(create<sem::U32>(), 0u, 4u, 4u, 4u, 4u);
|
||||
auto* arr_ptr = create<sem::Pointer>(arr, ast::StorageClass::kStorage,
|
||||
ast::Access::kReadWrite);
|
||||
auto* result = table->Lookup(BuiltinType::kArrayLength, {arr_ptr}, Source{});
|
||||
|
@ -249,8 +249,8 @@ TEST_F(BuiltinTableTest, MismatchArray) {
|
|||
|
||||
TEST_F(BuiltinTableTest, MatchSampler) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* vec2_f32 = create<sem::Vector>(f32, 2);
|
||||
auto* vec4_f32 = create<sem::Vector>(f32, 4);
|
||||
auto* vec2_f32 = create<sem::Vector>(f32, 2u);
|
||||
auto* vec4_f32 = create<sem::Vector>(f32, 4u);
|
||||
auto* tex = create<sem::SampledTexture>(ast::TextureDimension::k2d, f32);
|
||||
auto* sampler = create<sem::Sampler>(ast::SamplerKind::kSampler);
|
||||
auto* result = table->Lookup(BuiltinType::kTextureSample,
|
||||
|
@ -270,7 +270,7 @@ TEST_F(BuiltinTableTest, MatchSampler) {
|
|||
|
||||
TEST_F(BuiltinTableTest, MismatchSampler) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* vec2_f32 = create<sem::Vector>(f32, 2);
|
||||
auto* vec2_f32 = create<sem::Vector>(f32, 2u);
|
||||
auto* tex = create<sem::SampledTexture>(ast::TextureDimension::k2d, f32);
|
||||
auto* result = table->Lookup(BuiltinType::kTextureSample,
|
||||
{tex, f32, vec2_f32}, Source{});
|
||||
|
@ -281,8 +281,8 @@ TEST_F(BuiltinTableTest, MismatchSampler) {
|
|||
TEST_F(BuiltinTableTest, MatchSampledTexture) {
|
||||
auto* i32 = create<sem::I32>();
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* vec2_i32 = create<sem::Vector>(i32, 2);
|
||||
auto* vec4_f32 = create<sem::Vector>(f32, 4);
|
||||
auto* vec2_i32 = create<sem::Vector>(i32, 2u);
|
||||
auto* vec4_f32 = create<sem::Vector>(f32, 4u);
|
||||
auto* tex = create<sem::SampledTexture>(ast::TextureDimension::k2d, f32);
|
||||
auto* result =
|
||||
table->Lookup(BuiltinType::kTextureLoad, {tex, vec2_i32, i32}, Source{});
|
||||
|
@ -302,8 +302,8 @@ TEST_F(BuiltinTableTest, MatchSampledTexture) {
|
|||
TEST_F(BuiltinTableTest, MatchMultisampledTexture) {
|
||||
auto* i32 = create<sem::I32>();
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* vec2_i32 = create<sem::Vector>(i32, 2);
|
||||
auto* vec4_f32 = create<sem::Vector>(f32, 4);
|
||||
auto* vec2_i32 = create<sem::Vector>(i32, 2u);
|
||||
auto* vec4_f32 = create<sem::Vector>(f32, 4u);
|
||||
auto* tex = create<sem::MultisampledTexture>(ast::TextureDimension::k2d, f32);
|
||||
auto* result =
|
||||
table->Lookup(BuiltinType::kTextureLoad, {tex, vec2_i32, i32}, Source{});
|
||||
|
@ -323,7 +323,7 @@ TEST_F(BuiltinTableTest, MatchMultisampledTexture) {
|
|||
TEST_F(BuiltinTableTest, MatchDepthTexture) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* i32 = create<sem::I32>();
|
||||
auto* vec2_i32 = create<sem::Vector>(i32, 2);
|
||||
auto* vec2_i32 = create<sem::Vector>(i32, 2u);
|
||||
auto* tex = create<sem::DepthTexture>(ast::TextureDimension::k2d);
|
||||
auto* result =
|
||||
table->Lookup(BuiltinType::kTextureLoad, {tex, vec2_i32, i32}, Source{});
|
||||
|
@ -343,7 +343,7 @@ TEST_F(BuiltinTableTest, MatchDepthTexture) {
|
|||
TEST_F(BuiltinTableTest, MatchDepthMultisampledTexture) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* i32 = create<sem::I32>();
|
||||
auto* vec2_i32 = create<sem::Vector>(i32, 2);
|
||||
auto* vec2_i32 = create<sem::Vector>(i32, 2u);
|
||||
auto* tex = create<sem::DepthMultisampledTexture>(ast::TextureDimension::k2d);
|
||||
auto* result =
|
||||
table->Lookup(BuiltinType::kTextureLoad, {tex, vec2_i32, i32}, Source{});
|
||||
|
@ -363,8 +363,8 @@ TEST_F(BuiltinTableTest, MatchDepthMultisampledTexture) {
|
|||
TEST_F(BuiltinTableTest, MatchExternalTexture) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* i32 = create<sem::I32>();
|
||||
auto* vec2_i32 = create<sem::Vector>(i32, 2);
|
||||
auto* vec4_f32 = create<sem::Vector>(f32, 4);
|
||||
auto* vec2_i32 = create<sem::Vector>(i32, 2u);
|
||||
auto* vec4_f32 = create<sem::Vector>(f32, 4u);
|
||||
auto* tex = create<sem::ExternalTexture>();
|
||||
auto* result =
|
||||
table->Lookup(BuiltinType::kTextureLoad, {tex, vec2_i32}, Source{});
|
||||
|
@ -382,8 +382,8 @@ TEST_F(BuiltinTableTest, MatchExternalTexture) {
|
|||
TEST_F(BuiltinTableTest, MatchWOStorageTexture) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* i32 = create<sem::I32>();
|
||||
auto* vec2_i32 = create<sem::Vector>(i32, 2);
|
||||
auto* vec4_f32 = create<sem::Vector>(f32, 4);
|
||||
auto* vec2_i32 = create<sem::Vector>(i32, 2u);
|
||||
auto* vec4_f32 = create<sem::Vector>(f32, 4u);
|
||||
auto* subtype =
|
||||
sem::StorageTexture::SubtypeFor(ast::TexelFormat::kR32Float, Types());
|
||||
auto* tex = create<sem::StorageTexture>(ast::TextureDimension::k2d,
|
||||
|
@ -408,7 +408,7 @@ TEST_F(BuiltinTableTest, MatchWOStorageTexture) {
|
|||
TEST_F(BuiltinTableTest, MismatchTexture) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* i32 = create<sem::I32>();
|
||||
auto* vec2_i32 = create<sem::Vector>(i32, 2);
|
||||
auto* vec2_i32 = create<sem::Vector>(i32, 2u);
|
||||
auto* result =
|
||||
table->Lookup(BuiltinType::kTextureLoad, {f32, vec2_i32}, Source{});
|
||||
ASSERT_EQ(result, nullptr);
|
||||
|
@ -452,7 +452,7 @@ TEST_F(BuiltinTableTest, MismatchOpenType) {
|
|||
|
||||
TEST_F(BuiltinTableTest, MatchOpenSizeVector) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* vec2_f32 = create<sem::Vector>(f32, 2);
|
||||
auto* vec2_f32 = create<sem::Vector>(f32, 2u);
|
||||
auto* result = table->Lookup(BuiltinType::kClamp,
|
||||
{vec2_f32, vec2_f32, vec2_f32}, Source{});
|
||||
ASSERT_NE(result, nullptr) << Diagnostics().str();
|
||||
|
@ -468,7 +468,7 @@ TEST_F(BuiltinTableTest, MatchOpenSizeVector) {
|
|||
TEST_F(BuiltinTableTest, MismatchOpenSizeVector) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* u32 = create<sem::U32>();
|
||||
auto* vec2_f32 = create<sem::Vector>(f32, 2);
|
||||
auto* vec2_f32 = create<sem::Vector>(f32, 2u);
|
||||
auto* result =
|
||||
table->Lookup(BuiltinType::kClamp, {vec2_f32, u32, vec2_f32}, Source{});
|
||||
ASSERT_EQ(result, nullptr);
|
||||
|
@ -477,8 +477,8 @@ TEST_F(BuiltinTableTest, MismatchOpenSizeVector) {
|
|||
|
||||
TEST_F(BuiltinTableTest, MatchOpenSizeMatrix) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* vec3_f32 = create<sem::Vector>(f32, 3);
|
||||
auto* mat3_f32 = create<sem::Matrix>(vec3_f32, 3);
|
||||
auto* vec3_f32 = create<sem::Vector>(f32, 3u);
|
||||
auto* mat3_f32 = create<sem::Matrix>(vec3_f32, 3u);
|
||||
auto* result = table->Lookup(BuiltinType::kDeterminant, {mat3_f32}, Source{});
|
||||
ASSERT_NE(result, nullptr) << Diagnostics().str();
|
||||
ASSERT_EQ(Diagnostics().str(), "");
|
||||
|
@ -490,8 +490,8 @@ TEST_F(BuiltinTableTest, MatchOpenSizeMatrix) {
|
|||
|
||||
TEST_F(BuiltinTableTest, MismatchOpenSizeMatrix) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* vec2_f32 = create<sem::Vector>(f32, 2);
|
||||
auto* mat3x2_f32 = create<sem::Matrix>(vec2_f32, 3);
|
||||
auto* vec2_f32 = create<sem::Vector>(f32, 2u);
|
||||
auto* mat3x2_f32 = create<sem::Matrix>(vec2_f32, 3u);
|
||||
auto* result =
|
||||
table->Lookup(BuiltinType::kDeterminant, {mat3x2_f32}, Source{});
|
||||
ASSERT_EQ(result, nullptr);
|
||||
|
@ -578,7 +578,7 @@ TEST_F(BuiltinTableTest, OverloadOrderByMatchingParameter) {
|
|||
|
||||
TEST_F(BuiltinTableTest, SameOverloadReturnsSameBuiltinPointer) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* vec2_f32 = create<sem::Vector>(create<sem::F32>(), 2);
|
||||
auto* vec2_f32 = create<sem::Vector>(create<sem::F32>(), 2u);
|
||||
auto* bool_ = create<sem::Bool>();
|
||||
auto* a = table->Lookup(BuiltinType::kSelect, {f32, f32, bool_}, Source{});
|
||||
ASSERT_NE(a, nullptr) << Diagnostics().str();
|
||||
|
|
|
@ -142,7 +142,7 @@ INSTANTIATE_TEST_SUITE_P(ResolverTest,
|
|||
TEST_F(ResolverInferredTypeTest, InferArray_Pass) {
|
||||
auto* type = ty.array(ty.u32(), 10);
|
||||
auto* expected_type =
|
||||
create<sem::Array>(create<sem::U32>(), 10, 4, 4 * 10, 4, 4);
|
||||
create<sem::Array>(create<sem::U32>(), 10u, 4u, 4u * 10u, 4u, 4u);
|
||||
|
||||
auto* ctor_expr = Construct(type);
|
||||
auto* var = Var("a", nullptr, ast::StorageClass::kFunction, ctor_expr);
|
||||
|
@ -159,8 +159,8 @@ TEST_F(ResolverInferredTypeTest, InferStruct_Pass) {
|
|||
auto* expected_type = create<sem::Struct>(
|
||||
str, str->name,
|
||||
sem::StructMemberList{create<sem::StructMember>(
|
||||
member, member->symbol, create<sem::I32>(), 0, 0, 0, 4)},
|
||||
0, 4, 4);
|
||||
member, member->symbol, create<sem::I32>(), 0u, 0u, 0u, 4u)},
|
||||
0u, 4u, 4u);
|
||||
|
||||
auto* ctor_expr = Construct(ty.Of(str));
|
||||
|
||||
|
|
|
@ -39,52 +39,61 @@ TEST_F(ResolverIsHostShareable, NumericScalar) {
|
|||
}
|
||||
|
||||
TEST_F(ResolverIsHostShareable, NumericVector) {
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Vector>(create<sem::I32>(), 2)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Vector>(create<sem::I32>(), 3)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Vector>(create<sem::I32>(), 4)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Vector>(create<sem::U32>(), 2)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Vector>(create<sem::U32>(), 3)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Vector>(create<sem::U32>(), 4)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Vector>(create<sem::F32>(), 2)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Vector>(create<sem::F32>(), 3)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Vector>(create<sem::F32>(), 4)));
|
||||
EXPECT_TRUE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::I32>(), 2u)));
|
||||
EXPECT_TRUE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::I32>(), 3u)));
|
||||
EXPECT_TRUE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::I32>(), 4u)));
|
||||
EXPECT_TRUE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::U32>(), 2u)));
|
||||
EXPECT_TRUE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::U32>(), 3u)));
|
||||
EXPECT_TRUE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::U32>(), 4u)));
|
||||
EXPECT_TRUE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::F32>(), 2u)));
|
||||
EXPECT_TRUE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::F32>(), 3u)));
|
||||
EXPECT_TRUE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::F32>(), 4u)));
|
||||
}
|
||||
|
||||
TEST_F(ResolverIsHostShareable, BoolVector) {
|
||||
EXPECT_FALSE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 2)));
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 2u)));
|
||||
EXPECT_FALSE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 3)));
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 3u)));
|
||||
EXPECT_FALSE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 4)));
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 4u)));
|
||||
EXPECT_FALSE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 2)));
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 2u)));
|
||||
EXPECT_FALSE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 3)));
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 3u)));
|
||||
EXPECT_FALSE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 4)));
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 4u)));
|
||||
EXPECT_FALSE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 2)));
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 2u)));
|
||||
EXPECT_FALSE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 3)));
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 3u)));
|
||||
EXPECT_FALSE(
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 4)));
|
||||
r()->IsHostShareable(create<sem::Vector>(create<sem::Bool>(), 4u)));
|
||||
}
|
||||
|
||||
TEST_F(ResolverIsHostShareable, Matrix) {
|
||||
auto* vec2 = create<sem::Vector>(create<sem::F32>(), 2);
|
||||
auto* vec3 = create<sem::Vector>(create<sem::F32>(), 3);
|
||||
auto* vec4 = create<sem::Vector>(create<sem::F32>(), 4);
|
||||
auto* vec2 = create<sem::Vector>(create<sem::F32>(), 2u);
|
||||
auto* vec3 = create<sem::Vector>(create<sem::F32>(), 3u);
|
||||
auto* vec4 = create<sem::Vector>(create<sem::F32>(), 4u);
|
||||
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec2, 2)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec2, 3)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec2, 4)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec3, 2)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec3, 3)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec3, 4)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec4, 2)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec4, 3)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec4, 4)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec2, 2u)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec2, 3u)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec2, 4u)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec3, 2u)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec3, 3u)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec3, 4u)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec4, 2u)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec4, 3u)));
|
||||
EXPECT_TRUE(r()->IsHostShareable(create<sem::Matrix>(vec4, 4u)));
|
||||
}
|
||||
|
||||
TEST_F(ResolverIsHostShareable, Pointer) {
|
||||
|
@ -99,12 +108,12 @@ TEST_F(ResolverIsHostShareable, Atomic) {
|
|||
}
|
||||
|
||||
TEST_F(ResolverIsHostShareable, ArraySizedOfHostShareable) {
|
||||
auto* arr = create<sem::Array>(create<sem::I32>(), 5, 4, 20, 4, 4);
|
||||
auto* arr = create<sem::Array>(create<sem::I32>(), 5u, 4u, 20u, 4u, 4u);
|
||||
EXPECT_TRUE(r()->IsHostShareable(arr));
|
||||
}
|
||||
|
||||
TEST_F(ResolverIsHostShareable, ArrayUnsizedOfHostShareable) {
|
||||
auto* arr = create<sem::Array>(create<sem::I32>(), 0, 4, 4, 4, 4);
|
||||
auto* arr = create<sem::Array>(create<sem::I32>(), 0u, 4u, 4u, 4u, 4u);
|
||||
EXPECT_TRUE(r()->IsHostShareable(arr));
|
||||
}
|
||||
|
||||
|
|
|
@ -36,30 +36,30 @@ TEST_F(ResolverIsStorableTest, Scalar) {
|
|||
}
|
||||
|
||||
TEST_F(ResolverIsStorableTest, Vector) {
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::I32>(), 2)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::I32>(), 3)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::I32>(), 4)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::U32>(), 2)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::U32>(), 3)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::U32>(), 4)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::F32>(), 2)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::F32>(), 3)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::F32>(), 4)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::I32>(), 2u)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::I32>(), 3u)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::I32>(), 4u)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::U32>(), 2u)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::U32>(), 3u)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::U32>(), 4u)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::F32>(), 2u)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::F32>(), 3u)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Vector>(create<sem::F32>(), 4u)));
|
||||
}
|
||||
|
||||
TEST_F(ResolverIsStorableTest, Matrix) {
|
||||
auto* vec2 = create<sem::Vector>(create<sem::F32>(), 2);
|
||||
auto* vec3 = create<sem::Vector>(create<sem::F32>(), 3);
|
||||
auto* vec4 = create<sem::Vector>(create<sem::F32>(), 4);
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec2, 2)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec2, 3)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec2, 4)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec3, 2)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec3, 3)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec3, 4)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec4, 2)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec4, 3)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec4, 4)));
|
||||
auto* vec2 = create<sem::Vector>(create<sem::F32>(), 2u);
|
||||
auto* vec3 = create<sem::Vector>(create<sem::F32>(), 3u);
|
||||
auto* vec4 = create<sem::Vector>(create<sem::F32>(), 4u);
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec2, 2u)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec2, 3u)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec2, 4u)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec3, 2u)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec3, 3u)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec3, 4u)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec4, 2u)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec4, 3u)));
|
||||
EXPECT_TRUE(r()->IsStorable(create<sem::Matrix>(vec4, 4u)));
|
||||
}
|
||||
|
||||
TEST_F(ResolverIsStorableTest, Pointer) {
|
||||
|
@ -74,12 +74,12 @@ TEST_F(ResolverIsStorableTest, Atomic) {
|
|||
}
|
||||
|
||||
TEST_F(ResolverIsStorableTest, ArraySizedOfStorable) {
|
||||
auto* arr = create<sem::Array>(create<sem::I32>(), 5, 4, 20, 4, 4);
|
||||
auto* arr = create<sem::Array>(create<sem::I32>(), 5u, 4u, 20u, 4u, 4u);
|
||||
EXPECT_TRUE(r()->IsStorable(arr));
|
||||
}
|
||||
|
||||
TEST_F(ResolverIsStorableTest, ArrayUnsizedOfStorable) {
|
||||
auto* arr = create<sem::Array>(create<sem::I32>(), 0, 4, 4, 4, 4);
|
||||
auto* arr = create<sem::Array>(create<sem::I32>(), 0u, 4u, 4u, 4u, 4u);
|
||||
EXPECT_TRUE(r()->IsStorable(arr));
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ using i32 = ProgramBuilder::i32;
|
|||
using u32 = ProgramBuilder::u32;
|
||||
using f32 = ProgramBuilder::f32;
|
||||
|
||||
template <int N, typename T>
|
||||
template <uint32_t N, typename T>
|
||||
struct vec {};
|
||||
|
||||
template <typename T>
|
||||
|
@ -138,7 +138,7 @@ using vec3 = vec<3, T>;
|
|||
template <typename T>
|
||||
using vec4 = vec<4, T>;
|
||||
|
||||
template <int N, int M, typename T>
|
||||
template <uint32_t N, uint32_t M, typename T>
|
||||
struct mat {};
|
||||
|
||||
template <typename T>
|
||||
|
@ -156,7 +156,7 @@ using mat3x3 = mat<3, 3, T>;
|
|||
template <typename T>
|
||||
using mat4x4 = mat<4, 4, T>;
|
||||
|
||||
template <int N, typename T>
|
||||
template <uint32_t N, typename T>
|
||||
struct array {};
|
||||
|
||||
template <typename TO, int ID = 0>
|
||||
|
@ -271,7 +271,7 @@ struct DataType<f32> {
|
|||
};
|
||||
|
||||
/// Helper for building vector types and expressions
|
||||
template <int N, typename T>
|
||||
template <uint32_t N, typename T>
|
||||
struct DataType<vec<N, T>> {
|
||||
/// true as vectors are a composite type
|
||||
static constexpr bool is_composite = true;
|
||||
|
@ -300,7 +300,7 @@ struct DataType<vec<N, T>> {
|
|||
static inline ast::ExpressionList ExprArgs(ProgramBuilder& b,
|
||||
int elem_value) {
|
||||
ast::ExpressionList args;
|
||||
for (int i = 0; i < N; i++) {
|
||||
for (uint32_t i = 0; i < N; i++) {
|
||||
args.emplace_back(DataType<T>::Expr(b, elem_value));
|
||||
}
|
||||
return args;
|
||||
|
@ -308,7 +308,7 @@ struct DataType<vec<N, T>> {
|
|||
};
|
||||
|
||||
/// Helper for building matrix types and expressions
|
||||
template <int N, int M, typename T>
|
||||
template <uint32_t N, uint32_t M, typename T>
|
||||
struct DataType<mat<N, M, T>> {
|
||||
/// true as matrices are a composite type
|
||||
static constexpr bool is_composite = true;
|
||||
|
@ -338,7 +338,7 @@ struct DataType<mat<N, M, T>> {
|
|||
static inline ast::ExpressionList ExprArgs(ProgramBuilder& b,
|
||||
int elem_value) {
|
||||
ast::ExpressionList args;
|
||||
for (int i = 0; i < N; i++) {
|
||||
for (uint32_t i = 0; i < N; i++) {
|
||||
args.emplace_back(DataType<vec<M, T>>::Expr(b, elem_value));
|
||||
}
|
||||
return args;
|
||||
|
@ -421,7 +421,7 @@ struct DataType<ptr<T>> {
|
|||
};
|
||||
|
||||
/// Helper for building array types and expressions
|
||||
template <int N, typename T>
|
||||
template <uint32_t N, typename T>
|
||||
struct DataType<array<N, T>> {
|
||||
/// true as arrays are a composite type
|
||||
static constexpr bool is_composite = true;
|
||||
|
@ -457,7 +457,7 @@ struct DataType<array<N, T>> {
|
|||
static inline ast::ExpressionList ExprArgs(ProgramBuilder& b,
|
||||
int elem_value) {
|
||||
ast::ExpressionList args;
|
||||
for (int i = 0; i < N; i++) {
|
||||
for (uint32_t i = 0; i < N; i++) {
|
||||
args.emplace_back(DataType<T>::Expr(b, elem_value));
|
||||
}
|
||||
return args;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <string>
|
||||
|
||||
#include "src/tint/debug.h"
|
||||
#include "src/tint/utils/hash.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::Array);
|
||||
|
||||
|
@ -40,6 +41,21 @@ Array::Array(const Type* element,
|
|||
TINT_ASSERT(Semantic, element_);
|
||||
}
|
||||
|
||||
size_t Array::Hash() const {
|
||||
return utils::Hash(TypeInfo::Of<Array>().full_hashcode, count_, align_, size_,
|
||||
stride_);
|
||||
}
|
||||
|
||||
bool Array::Equals(const sem::Type& other) const {
|
||||
if (auto* o = other.As<Array>()) {
|
||||
// Note: implicit_stride is not part of the type_name string as this is
|
||||
// derived from the element type
|
||||
return o->element_ == element_ && o->count_ == count_ &&
|
||||
o->align_ == align_ && o->size_ == size_ && o->stride_ == stride_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Array::IsConstructible() const {
|
||||
return constructible_;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,13 @@ class Array : public Castable<Array, Type> {
|
|||
uint32_t stride,
|
||||
uint32_t implicit_stride);
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @return the array element type
|
||||
Type const* ElemType() const { return element_; }
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "src/tint/program_builder.h"
|
||||
#include "src/tint/sem/reference_type.h"
|
||||
#include "src/tint/utils/hash.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::Atomic);
|
||||
|
||||
|
@ -26,6 +27,17 @@ Atomic::Atomic(const sem::Type* subtype) : subtype_(subtype) {
|
|||
TINT_ASSERT(AST, !subtype->Is<Reference>());
|
||||
}
|
||||
|
||||
size_t Atomic::Hash() const {
|
||||
return utils::Hash(TypeInfo::Of<Atomic>().full_hashcode, subtype_);
|
||||
}
|
||||
|
||||
bool Atomic::Equals(const sem::Type& other) const {
|
||||
if (auto* o = other.As<Atomic>()) {
|
||||
return o->subtype_ == subtype_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Atomic::type_name() const {
|
||||
std::ostringstream out;
|
||||
out << "__atomic" << subtype_->type_name();
|
||||
|
|
|
@ -33,6 +33,13 @@ class Atomic : public Castable<Atomic, Type> {
|
|||
Atomic(Atomic&&);
|
||||
~Atomic() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the atomic type
|
||||
const sem::Type* Type() const { return subtype_; }
|
||||
|
||||
|
|
|
@ -27,6 +27,14 @@ Bool::Bool(Bool&&) = default;
|
|||
|
||||
Bool::~Bool() = default;
|
||||
|
||||
size_t Bool::Hash() const {
|
||||
return TypeInfo::Of<Bool>().full_hashcode;
|
||||
}
|
||||
|
||||
bool Bool::Equals(const Type& other) const {
|
||||
return other.Is<Bool>();
|
||||
}
|
||||
|
||||
std::string Bool::type_name() const {
|
||||
return "__bool";
|
||||
}
|
||||
|
|
|
@ -37,6 +37,13 @@ class Bool : public Castable<Bool, Type> {
|
|||
Bool(Bool&&);
|
||||
~Bool() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the name for this type
|
||||
std::string type_name() const override;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "src/tint/sem/depth_multisampled_texture_type.h"
|
||||
|
||||
#include "src/tint/program_builder.h"
|
||||
#include "src/tint/utils/hash.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::DepthMultisampledTexture);
|
||||
|
||||
|
@ -38,6 +39,18 @@ DepthMultisampledTexture::DepthMultisampledTexture(DepthMultisampledTexture&&) =
|
|||
|
||||
DepthMultisampledTexture::~DepthMultisampledTexture() = default;
|
||||
|
||||
size_t DepthMultisampledTexture::Hash() const {
|
||||
return utils::Hash(TypeInfo::Of<DepthMultisampledTexture>().full_hashcode,
|
||||
dim());
|
||||
}
|
||||
|
||||
bool DepthMultisampledTexture::Equals(const sem::Type& other) const {
|
||||
if (auto* o = other.As<DepthMultisampledTexture>()) {
|
||||
return o->dim() == dim();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string DepthMultisampledTexture::type_name() const {
|
||||
std::ostringstream out;
|
||||
out << "__depth_multisampled_texture_" << dim();
|
||||
|
|
|
@ -33,6 +33,13 @@ class DepthMultisampledTexture
|
|||
DepthMultisampledTexture(DepthMultisampledTexture&&);
|
||||
~DepthMultisampledTexture() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the name for this type
|
||||
std::string type_name() const override;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "src/tint/sem/depth_texture_type.h"
|
||||
|
||||
#include "src/tint/program_builder.h"
|
||||
#include "src/tint/utils/hash.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::DepthTexture);
|
||||
|
||||
|
@ -39,6 +40,17 @@ DepthTexture::DepthTexture(DepthTexture&&) = default;
|
|||
|
||||
DepthTexture::~DepthTexture() = default;
|
||||
|
||||
size_t DepthTexture::Hash() const {
|
||||
return utils::Hash(TypeInfo::Of<DepthTexture>().full_hashcode, dim());
|
||||
}
|
||||
|
||||
bool DepthTexture::Equals(const sem::Type& other) const {
|
||||
if (auto* o = other.As<DepthTexture>()) {
|
||||
return o->dim() == dim();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string DepthTexture::type_name() const {
|
||||
std::ostringstream out;
|
||||
out << "__depth_texture_" << dim();
|
||||
|
|
|
@ -32,6 +32,13 @@ class DepthTexture : public Castable<DepthTexture, Texture> {
|
|||
DepthTexture(DepthTexture&&);
|
||||
~DepthTexture() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the name for this type
|
||||
std::string type_name() const override;
|
||||
|
||||
|
|
|
@ -27,6 +27,14 @@ ExternalTexture::ExternalTexture(ExternalTexture&&) = default;
|
|||
|
||||
ExternalTexture::~ExternalTexture() = default;
|
||||
|
||||
size_t ExternalTexture::Hash() const {
|
||||
return TypeInfo::Of<ExternalTexture>().full_hashcode;
|
||||
}
|
||||
|
||||
bool ExternalTexture::Equals(const sem::Type& other) const {
|
||||
return other.Is<ExternalTexture>();
|
||||
}
|
||||
|
||||
std::string ExternalTexture::type_name() const {
|
||||
return "__external_texture";
|
||||
}
|
||||
|
|
|
@ -32,6 +32,13 @@ class ExternalTexture : public Castable<ExternalTexture, Texture> {
|
|||
ExternalTexture(ExternalTexture&&);
|
||||
~ExternalTexture() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the name for this type
|
||||
std::string type_name() const override;
|
||||
|
||||
|
|
|
@ -27,6 +27,14 @@ F32::F32(F32&&) = default;
|
|||
|
||||
F32::~F32() = default;
|
||||
|
||||
size_t F32::Hash() const {
|
||||
return TypeInfo::Of<F32>().full_hashcode;
|
||||
}
|
||||
|
||||
bool F32::Equals(const Type& other) const {
|
||||
return other.Is<F32>();
|
||||
}
|
||||
|
||||
std::string F32::type_name() const {
|
||||
return "__f32";
|
||||
}
|
||||
|
|
|
@ -31,6 +31,13 @@ class F32 : public Castable<F32, Type> {
|
|||
F32(F32&&);
|
||||
~F32() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the name for this type
|
||||
std::string type_name() const override;
|
||||
|
||||
|
|
|
@ -27,6 +27,14 @@ I32::I32(I32&&) = default;
|
|||
|
||||
I32::~I32() = default;
|
||||
|
||||
size_t I32::Hash() const {
|
||||
return TypeInfo::Of<I32>().full_hashcode;
|
||||
}
|
||||
|
||||
bool I32::Equals(const Type& other) const {
|
||||
return other.Is<I32>();
|
||||
}
|
||||
|
||||
std::string I32::type_name() const {
|
||||
return "__i32";
|
||||
}
|
||||
|
|
|
@ -31,6 +31,13 @@ class I32 : public Castable<I32, Type> {
|
|||
I32(I32&&);
|
||||
~I32() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the name for this type
|
||||
std::string type_name() const override;
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "src/tint/program_builder.h"
|
||||
#include "src/tint/sem/vector_type.h"
|
||||
#include "src/tint/utils/hash.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::Matrix);
|
||||
|
||||
|
@ -37,6 +38,19 @@ Matrix::Matrix(Matrix&&) = default;
|
|||
|
||||
Matrix::~Matrix() = default;
|
||||
|
||||
size_t Matrix::Hash() const {
|
||||
return utils::Hash(TypeInfo::Of<Vector>().full_hashcode, rows_, columns_,
|
||||
column_type_);
|
||||
}
|
||||
|
||||
bool Matrix::Equals(const Type& other) const {
|
||||
if (auto* v = other.As<Matrix>()) {
|
||||
return v->rows_ == rows_ && v->columns_ == columns_ &&
|
||||
v->column_type_ == column_type_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Matrix::type_name() const {
|
||||
return "__mat_" + std::to_string(rows_) + "_" + std::to_string(columns_) +
|
||||
subtype_->type_name();
|
||||
|
|
|
@ -36,6 +36,13 @@ class Matrix : public Castable<Matrix, Type> {
|
|||
Matrix(Matrix&&);
|
||||
~Matrix() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the type of the matrix
|
||||
const Type* type() const { return subtype_; }
|
||||
/// @returns the number of rows in the matrix
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "src/tint/sem/multisampled_texture_type.h"
|
||||
|
||||
#include "src/tint/program_builder.h"
|
||||
#include "src/tint/utils/hash.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::MultisampledTexture);
|
||||
|
||||
|
@ -31,6 +32,18 @@ MultisampledTexture::MultisampledTexture(MultisampledTexture&&) = default;
|
|||
|
||||
MultisampledTexture::~MultisampledTexture() = default;
|
||||
|
||||
size_t MultisampledTexture::Hash() const {
|
||||
return utils::Hash(TypeInfo::Of<MultisampledTexture>().full_hashcode, dim(),
|
||||
type_);
|
||||
}
|
||||
|
||||
bool MultisampledTexture::Equals(const sem::Type& other) const {
|
||||
if (auto* o = other.As<MultisampledTexture>()) {
|
||||
return o->dim() == dim() && o->type_ == type_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string MultisampledTexture::type_name() const {
|
||||
std::ostringstream out;
|
||||
out << "__multisampled_texture_" << dim() << type_->type_name();
|
||||
|
|
|
@ -33,6 +33,13 @@ class MultisampledTexture : public Castable<MultisampledTexture, Texture> {
|
|||
MultisampledTexture(MultisampledTexture&&);
|
||||
~MultisampledTexture() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the subtype of the sampled texture
|
||||
const Type* type() const { return type_; }
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "src/tint/program_builder.h"
|
||||
#include "src/tint/sem/reference_type.h"
|
||||
#include "src/tint/utils/hash.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::Pointer);
|
||||
|
||||
|
@ -30,6 +31,19 @@ Pointer::Pointer(const Type* subtype,
|
|||
TINT_ASSERT(Semantic, access != ast::Access::kUndefined);
|
||||
}
|
||||
|
||||
size_t Pointer::Hash() const {
|
||||
return utils::Hash(TypeInfo::Of<Pointer>().full_hashcode, storage_class_,
|
||||
subtype_, access_);
|
||||
}
|
||||
|
||||
bool Pointer::Equals(const sem::Type& other) const {
|
||||
if (auto* o = other.As<Pointer>()) {
|
||||
return o->storage_class_ == storage_class_ && o->subtype_ == subtype_ &&
|
||||
o->access_ == access_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Pointer::type_name() const {
|
||||
std::ostringstream out;
|
||||
out << "__ptr_" << storage_class_ << subtype_->type_name() << "__" << access_;
|
||||
|
|
|
@ -39,6 +39,13 @@ class Pointer : public Castable<Pointer, Type> {
|
|||
Pointer(Pointer&&);
|
||||
~Pointer() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the pointee type
|
||||
const Type* StoreType() const { return subtype_; }
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "src/tint/sem/reference_type.h"
|
||||
|
||||
#include "src/tint/program_builder.h"
|
||||
#include "src/tint/utils/hash.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::Reference);
|
||||
|
||||
|
@ -29,6 +30,19 @@ Reference::Reference(const Type* subtype,
|
|||
TINT_ASSERT(Semantic, access != ast::Access::kUndefined);
|
||||
}
|
||||
|
||||
size_t Reference::Hash() const {
|
||||
return utils::Hash(TypeInfo::Of<Reference>().full_hashcode, storage_class_,
|
||||
subtype_, access_);
|
||||
}
|
||||
|
||||
bool Reference::Equals(const sem::Type& other) const {
|
||||
if (auto* o = other.As<Reference>()) {
|
||||
return o->storage_class_ == storage_class_ && o->subtype_ == subtype_ &&
|
||||
o->access_ == access_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Reference::type_name() const {
|
||||
std::ostringstream out;
|
||||
out << "__ref_" << storage_class_ << subtype_->type_name() << "__" << access_;
|
||||
|
|
|
@ -39,6 +39,13 @@ class Reference : public Castable<Reference, Type> {
|
|||
Reference(Reference&&);
|
||||
~Reference() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the pointee type
|
||||
const Type* StoreType() const { return subtype_; }
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "src/tint/sem/sampled_texture_type.h"
|
||||
|
||||
#include "src/tint/program_builder.h"
|
||||
#include "src/tint/utils/hash.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::SampledTexture);
|
||||
|
||||
|
@ -30,6 +31,18 @@ SampledTexture::SampledTexture(SampledTexture&&) = default;
|
|||
|
||||
SampledTexture::~SampledTexture() = default;
|
||||
|
||||
size_t SampledTexture::Hash() const {
|
||||
return utils::Hash(TypeInfo::Of<SampledTexture>().full_hashcode, dim(),
|
||||
type_);
|
||||
}
|
||||
|
||||
bool SampledTexture::Equals(const sem::Type& other) const {
|
||||
if (auto* o = other.As<SampledTexture>()) {
|
||||
return o->dim() == dim() && o->type_ == type_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string SampledTexture::type_name() const {
|
||||
std::ostringstream out;
|
||||
out << "__sampled_texture_" << dim() << type_->type_name();
|
||||
|
|
|
@ -33,6 +33,13 @@ class SampledTexture : public Castable<SampledTexture, Texture> {
|
|||
SampledTexture(SampledTexture&&);
|
||||
~SampledTexture() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the subtype of the sampled texture
|
||||
Type* type() const { return const_cast<Type*>(type_); }
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "src/tint/sem/sampler_type.h"
|
||||
|
||||
#include "src/tint/program_builder.h"
|
||||
#include "src/tint/utils/hash.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::Sampler);
|
||||
|
||||
|
@ -27,6 +28,17 @@ Sampler::Sampler(Sampler&&) = default;
|
|||
|
||||
Sampler::~Sampler() = default;
|
||||
|
||||
size_t Sampler::Hash() const {
|
||||
return utils::Hash(TypeInfo::Of<Sampler>().full_hashcode, kind_);
|
||||
}
|
||||
|
||||
bool Sampler::Equals(const sem::Type& other) const {
|
||||
if (auto* o = other.As<Sampler>()) {
|
||||
return o->kind_ == kind_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Sampler::type_name() const {
|
||||
return std::string("__sampler_") +
|
||||
(kind_ == ast::SamplerKind::kSampler ? "sampler" : "comparison");
|
||||
|
|
|
@ -33,6 +33,13 @@ class Sampler : public Castable<Sampler, Type> {
|
|||
Sampler(Sampler&&);
|
||||
~Sampler() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the sampler type
|
||||
ast::SamplerKind kind() const { return kind_; }
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ using ArrayTest = TestHelper;
|
|||
|
||||
TEST_F(ArrayTest, CreateSizedArray) {
|
||||
U32 u32;
|
||||
auto* arr = create<Array>(&u32, 2, 4, 8, 32, 16);
|
||||
auto* arr = create<Array>(&u32, 2u, 4u, 8u, 32u, 16u);
|
||||
EXPECT_EQ(arr->ElemType(), &u32);
|
||||
EXPECT_EQ(arr->Count(), 2u);
|
||||
EXPECT_EQ(arr->Align(), 4u);
|
||||
|
@ -36,7 +36,7 @@ TEST_F(ArrayTest, CreateSizedArray) {
|
|||
|
||||
TEST_F(ArrayTest, CreateRuntimeArray) {
|
||||
U32 u32;
|
||||
auto* arr = create<Array>(&u32, 0, 4, 8, 32, 32);
|
||||
auto* arr = create<Array>(&u32, 0u, 4u, 8u, 32u, 32u);
|
||||
EXPECT_EQ(arr->ElemType(), &u32);
|
||||
EXPECT_EQ(arr->Count(), 0u);
|
||||
EXPECT_EQ(arr->Align(), 4u);
|
||||
|
@ -49,33 +49,33 @@ TEST_F(ArrayTest, CreateRuntimeArray) {
|
|||
|
||||
TEST_F(ArrayTest, TypeName) {
|
||||
I32 i32;
|
||||
auto* arr = create<Array>(&i32, 2, 0, 4, 4, 4);
|
||||
auto* arr = create<Array>(&i32, 2u, 0u, 4u, 4u, 4u);
|
||||
EXPECT_EQ(arr->type_name(), "__array__i32_count_2_align_0_size_4_stride_4");
|
||||
}
|
||||
|
||||
TEST_F(ArrayTest, FriendlyNameRuntimeSized) {
|
||||
auto* arr = create<Array>(create<I32>(), 0, 0, 4, 4, 4);
|
||||
auto* arr = create<Array>(create<I32>(), 0u, 0u, 4u, 4u, 4u);
|
||||
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32>");
|
||||
}
|
||||
|
||||
TEST_F(ArrayTest, FriendlyNameStaticSized) {
|
||||
auto* arr = create<Array>(create<I32>(), 5, 4, 20, 4, 4);
|
||||
auto* arr = create<Array>(create<I32>(), 5u, 4u, 20u, 4u, 4u);
|
||||
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, 5>");
|
||||
}
|
||||
|
||||
TEST_F(ArrayTest, FriendlyNameRuntimeSizedNonImplicitStride) {
|
||||
auto* arr = create<Array>(create<I32>(), 0, 0, 4, 8, 4);
|
||||
auto* arr = create<Array>(create<I32>(), 0u, 0u, 4u, 8u, 4u);
|
||||
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(8) array<i32>");
|
||||
}
|
||||
|
||||
TEST_F(ArrayTest, FriendlyNameStaticSizedNonImplicitStride) {
|
||||
auto* arr = create<Array>(create<I32>(), 5, 4, 20, 8, 4);
|
||||
auto* arr = create<Array>(create<I32>(), 5u, 4u, 20u, 8u, 4u);
|
||||
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(8) array<i32, 5>");
|
||||
}
|
||||
|
||||
TEST_F(ArrayTest, TypeName_RuntimeArray) {
|
||||
I32 i32;
|
||||
auto* arr = create<Array>(&i32, 2, 4, 8, 16, 16);
|
||||
auto* arr = create<Array>(&i32, 2u, 4u, 8u, 16u, 16u);
|
||||
EXPECT_EQ(arr->type_name(), "__array__i32_count_2_align_4_size_8_stride_16");
|
||||
}
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@ TEST_F(StructTest, Creation) {
|
|||
create<ast::Struct>(name, ast::StructMemberList{}, ast::AttributeList{});
|
||||
auto* ptr = impl;
|
||||
auto* s =
|
||||
create<sem::Struct>(impl, impl->name, StructMemberList{}, 4 /* align */,
|
||||
8 /* size */, 16 /* size_no_padding */);
|
||||
create<sem::Struct>(impl, impl->name, StructMemberList{}, 4u /* align */,
|
||||
8u /* size */, 16u /* size_no_padding */);
|
||||
EXPECT_EQ(s->Declaration(), ptr);
|
||||
EXPECT_EQ(s->Align(), 4u);
|
||||
EXPECT_EQ(s->Size(), 8u);
|
||||
|
@ -41,8 +41,8 @@ TEST_F(StructTest, TypeName) {
|
|||
auto* impl =
|
||||
create<ast::Struct>(name, ast::StructMemberList{}, ast::AttributeList{});
|
||||
auto* s =
|
||||
create<sem::Struct>(impl, impl->name, StructMemberList{}, 4 /* align */,
|
||||
4 /* size */, 4 /* size_no_padding */);
|
||||
create<sem::Struct>(impl, impl->name, StructMemberList{}, 4u /* align */,
|
||||
4u /* size */, 4u /* size_no_padding */);
|
||||
EXPECT_EQ(s->type_name(), "__struct_$1");
|
||||
}
|
||||
|
||||
|
@ -51,8 +51,8 @@ TEST_F(StructTest, FriendlyName) {
|
|||
auto* impl =
|
||||
create<ast::Struct>(name, ast::StructMemberList{}, ast::AttributeList{});
|
||||
auto* s =
|
||||
create<sem::Struct>(impl, impl->name, StructMemberList{}, 4 /* align */,
|
||||
4 /* size */, 4 /* size_no_padding */);
|
||||
create<sem::Struct>(impl, impl->name, StructMemberList{}, 4u /* align */,
|
||||
4u /* size */, 4u /* size_no_padding */);
|
||||
EXPECT_EQ(s->FriendlyName(Symbols()), "my_struct");
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "src/tint/sem/storage_texture_type.h"
|
||||
|
||||
#include "src/tint/program_builder.h"
|
||||
#include "src/tint/utils/hash.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::StorageTexture);
|
||||
|
||||
|
@ -31,6 +32,19 @@ StorageTexture::StorageTexture(StorageTexture&&) = default;
|
|||
|
||||
StorageTexture::~StorageTexture() = default;
|
||||
|
||||
size_t StorageTexture::Hash() const {
|
||||
return utils::Hash(TypeInfo::Of<StorageTexture>().full_hashcode, dim(),
|
||||
texel_format_, access_);
|
||||
}
|
||||
|
||||
bool StorageTexture::Equals(const sem::Type& other) const {
|
||||
if (auto* o = other.As<StorageTexture>()) {
|
||||
return o->dim() == dim() && o->texel_format_ == texel_format_ &&
|
||||
o->access_ == access_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string StorageTexture::type_name() const {
|
||||
std::ostringstream out;
|
||||
out << "__storage_texture_" << dim() << "_" << texel_format_ << "_"
|
||||
|
|
|
@ -43,6 +43,13 @@ class StorageTexture : public Castable<StorageTexture, Texture> {
|
|||
StorageTexture(StorageTexture&&);
|
||||
~StorageTexture() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the storage subtype
|
||||
Type* type() const { return subtype_; }
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "src/tint/ast/struct_member.h"
|
||||
#include "src/tint/symbol_table.h"
|
||||
#include "src/tint/utils/hash.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::Struct);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::StructMember);
|
||||
|
@ -51,6 +52,17 @@ Struct::Struct(const ast::Struct* declaration,
|
|||
|
||||
Struct::~Struct() = default;
|
||||
|
||||
size_t Struct::Hash() const {
|
||||
return utils::Hash(TypeInfo::Of<Struct>().full_hashcode, name_);
|
||||
}
|
||||
|
||||
bool Struct::Equals(const sem::Type& other) const {
|
||||
if (auto* o = other.As<Struct>()) {
|
||||
return o->name_ == name_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const StructMember* Struct::FindMember(Symbol name) const {
|
||||
for (auto* member : members_) {
|
||||
if (member->Declaration()->symbol == name) {
|
||||
|
|
|
@ -74,6 +74,13 @@ class Struct : public Castable<Struct, Type> {
|
|||
/// Destructor
|
||||
~Struct() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the struct
|
||||
const ast::Struct* Declaration() const { return declaration_; }
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef SRC_TINT_SEM_TYPE_H_
|
||||
#define SRC_TINT_SEM_TYPE_H_
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/sem/node.h"
|
||||
|
@ -37,6 +38,13 @@ class Type : public Castable<Type, Node> {
|
|||
Type(Type&&);
|
||||
~Type() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
virtual size_t Hash() const = 0;
|
||||
|
||||
/// @returns true if the this type is equal to the given type
|
||||
virtual bool Equals(const Type&) const = 0;
|
||||
|
||||
/// [DEPRECATED]
|
||||
/// @returns the name for this type. The type name is unique over all types.
|
||||
virtual std::string type_name() const = 0;
|
||||
|
||||
|
@ -115,4 +123,27 @@ class Type : public Castable<Type, Node> {
|
|||
} // namespace sem
|
||||
} // namespace tint
|
||||
|
||||
namespace std {
|
||||
|
||||
/// std::hash specialization for tint::sem::Type
|
||||
template <>
|
||||
struct hash<tint::sem::Type> {
|
||||
/// @param type the type to obtain a hash from
|
||||
/// @returns the hash of the semantic type
|
||||
size_t operator()(const tint::sem::Type& type) const { return type.Hash(); }
|
||||
};
|
||||
|
||||
/// std::equal_to specialization for tint::sem::Type
|
||||
template <>
|
||||
struct equal_to<tint::sem::Type> {
|
||||
/// @param a the first type to compare
|
||||
/// @param b the second type to compare
|
||||
/// @returns true if the two types are equal
|
||||
bool operator()(const tint::sem::Type& a, const tint::sem::Type& b) const {
|
||||
return a.Equals(b);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // SRC_TINT_SEM_TYPE_H_
|
||||
|
|
|
@ -20,16 +20,15 @@
|
|||
#include <utility>
|
||||
|
||||
#include "src/tint/sem/type.h"
|
||||
#include "src/tint/utils/block_allocator.h"
|
||||
#include "src/tint/utils/unique_allocator.h"
|
||||
|
||||
namespace tint {
|
||||
namespace sem {
|
||||
namespace tint::sem {
|
||||
|
||||
/// The type manager holds all the pointers to the known types.
|
||||
class Manager {
|
||||
class Manager : public utils::UniqueAllocator<Type> {
|
||||
public:
|
||||
/// Iterator is the type returned by begin() and end()
|
||||
using Iterator = utils::BlockAllocator<sem::Type>::ConstIterator;
|
||||
using Iterator = utils::BlockAllocator<Type>::ConstIterator;
|
||||
|
||||
/// Constructor
|
||||
Manager();
|
||||
|
@ -45,24 +44,6 @@ class Manager {
|
|||
/// Destructor
|
||||
~Manager();
|
||||
|
||||
/// Get the given type `T` from the type manager
|
||||
/// @param args the arguments to pass to the type constructor
|
||||
/// @return the pointer to the registered type
|
||||
template <typename T, typename... ARGS>
|
||||
T* Get(ARGS&&... args) {
|
||||
// Note: We do not use std::forward here, as we may need to use the
|
||||
// arguments again for the call to Create<T>() below.
|
||||
auto name = T(args...).type_name();
|
||||
auto it = by_name_.find(name);
|
||||
if (it != by_name_.end()) {
|
||||
return static_cast<T*>(it->second);
|
||||
}
|
||||
|
||||
auto* type = types_.Create<T>(std::forward<ARGS>(args)...);
|
||||
by_name_.emplace(name, type);
|
||||
return type;
|
||||
}
|
||||
|
||||
/// Wrap returns a new Manager created with the types of `inner`.
|
||||
/// The Manager returned by Wrap is intended to temporarily extend the types
|
||||
/// of an existing immutable Manager.
|
||||
|
@ -74,27 +55,16 @@ class Manager {
|
|||
/// @return the Manager that wraps `inner`
|
||||
static Manager Wrap(const Manager& inner) {
|
||||
Manager out;
|
||||
out.by_name_ = inner.by_name_;
|
||||
out.items = inner.items;
|
||||
return out;
|
||||
}
|
||||
|
||||
/// Returns the type map
|
||||
/// @returns the mapping from name string to type.
|
||||
const std::unordered_map<std::string, sem::Type*>& types() const {
|
||||
return by_name_;
|
||||
}
|
||||
|
||||
/// @returns an iterator to the beginning of the types
|
||||
Iterator begin() const { return types_.Objects().begin(); }
|
||||
Iterator begin() const { return allocator.Objects().begin(); }
|
||||
/// @returns an iterator to the end of the types
|
||||
Iterator end() const { return types_.Objects().end(); }
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, sem::Type*> by_name_;
|
||||
utils::BlockAllocator<sem::Type> types_;
|
||||
Iterator end() const { return allocator.Objects().end(); }
|
||||
};
|
||||
|
||||
} // namespace sem
|
||||
} // namespace tint
|
||||
} // namespace tint::sem
|
||||
|
||||
#endif // SRC_TINT_SEM_TYPE_MANAGER_H_
|
||||
|
|
|
@ -27,6 +27,14 @@ U32::~U32() = default;
|
|||
|
||||
U32::U32(U32&&) = default;
|
||||
|
||||
size_t U32::Hash() const {
|
||||
return TypeInfo::Of<U32>().full_hashcode;
|
||||
}
|
||||
|
||||
bool U32::Equals(const Type& other) const {
|
||||
return other.Is<U32>();
|
||||
}
|
||||
|
||||
std::string U32::type_name() const {
|
||||
return "__u32";
|
||||
}
|
||||
|
|
|
@ -31,6 +31,13 @@ class U32 : public Castable<U32, Type> {
|
|||
U32(U32&&);
|
||||
~U32() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the name for th type
|
||||
std::string type_name() const override;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "src/tint/sem/vector_type.h"
|
||||
|
||||
#include "src/tint/program_builder.h"
|
||||
#include "src/tint/utils/hash.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::Vector);
|
||||
|
||||
|
@ -31,6 +32,17 @@ Vector::Vector(Vector&&) = default;
|
|||
|
||||
Vector::~Vector() = default;
|
||||
|
||||
size_t Vector::Hash() const {
|
||||
return utils::Hash(TypeInfo::Of<Vector>().full_hashcode, width_, subtype_);
|
||||
}
|
||||
|
||||
bool Vector::Equals(const Type& other) const {
|
||||
if (auto* v = other.As<Vector>()) {
|
||||
return v->width_ == width_ && v->subtype_ == subtype_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Vector::type_name() const {
|
||||
return "__vec_" + std::to_string(width_) + subtype_->type_name();
|
||||
}
|
||||
|
|
|
@ -33,6 +33,13 @@ class Vector : public Castable<Vector, Type> {
|
|||
Vector(Vector&&);
|
||||
~Vector() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the type of the vector elements
|
||||
const Type* type() const { return subtype_; }
|
||||
|
||||
|
|
|
@ -30,13 +30,13 @@ TEST_F(VectorTest, Creation) {
|
|||
|
||||
TEST_F(VectorTest, TypeName) {
|
||||
auto* i32 = create<I32>();
|
||||
auto* v = create<Vector>(i32, 3);
|
||||
auto* v = create<Vector>(i32, 3u);
|
||||
EXPECT_EQ(v->type_name(), "__vec_3__i32");
|
||||
}
|
||||
|
||||
TEST_F(VectorTest, FriendlyName) {
|
||||
auto* f32 = create<F32>();
|
||||
auto* v = create<Vector>(f32, 3);
|
||||
auto* v = create<Vector>(f32, 3u);
|
||||
EXPECT_EQ(v->FriendlyName(Symbols()), "vec3<f32>");
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,14 @@ Void::Void(Void&&) = default;
|
|||
|
||||
Void::~Void() = default;
|
||||
|
||||
size_t Void::Hash() const {
|
||||
return TypeInfo::Of<Void>().full_hashcode;
|
||||
}
|
||||
|
||||
bool Void::Equals(const Type& other) const {
|
||||
return other.Is<Void>();
|
||||
}
|
||||
|
||||
std::string Void::type_name() const {
|
||||
return "__void";
|
||||
}
|
||||
|
|
|
@ -31,6 +31,13 @@ class Void : public Castable<Void, Type> {
|
|||
Void(Void&&);
|
||||
~Void() override;
|
||||
|
||||
/// @returns a hash of the type.
|
||||
size_t Hash() const override;
|
||||
|
||||
/// @param other the other type to compare against
|
||||
/// @returns true if the this type is equal to the given type
|
||||
bool Equals(const Type& other) const override;
|
||||
|
||||
/// @returns the name for this type
|
||||
std::string type_name() const override;
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ TEST_F(CreateASTTypeForTest, Matrix) {
|
|||
|
||||
TEST_F(CreateASTTypeForTest, Vector) {
|
||||
auto* vec = create([](ProgramBuilder& b) {
|
||||
return b.create<sem::Vector>(b.create<sem::F32>(), 2);
|
||||
return b.create<sem::Vector>(b.create<sem::F32>(), 2u);
|
||||
});
|
||||
ASSERT_TRUE(vec->Is<ast::Vector>());
|
||||
ASSERT_TRUE(vec->As<ast::Vector>()->type->Is<ast::F32>());
|
||||
|
@ -78,7 +78,7 @@ TEST_F(CreateASTTypeForTest, Vector) {
|
|||
|
||||
TEST_F(CreateASTTypeForTest, ArrayImplicitStride) {
|
||||
auto* arr = create([](ProgramBuilder& b) {
|
||||
return b.create<sem::Array>(b.create<sem::F32>(), 2, 4, 4, 32u, 32u);
|
||||
return b.create<sem::Array>(b.create<sem::F32>(), 2u, 4u, 4u, 32u, 32u);
|
||||
});
|
||||
ASSERT_TRUE(arr->Is<ast::Array>());
|
||||
ASSERT_TRUE(arr->As<ast::Array>()->type->Is<ast::F32>());
|
||||
|
@ -91,7 +91,7 @@ TEST_F(CreateASTTypeForTest, ArrayImplicitStride) {
|
|||
|
||||
TEST_F(CreateASTTypeForTest, ArrayNonImplicitStride) {
|
||||
auto* arr = create([](ProgramBuilder& b) {
|
||||
return b.create<sem::Array>(b.create<sem::F32>(), 2, 4, 4, 64u, 32u);
|
||||
return b.create<sem::Array>(b.create<sem::F32>(), 2u, 4u, 4u, 64u, 32u);
|
||||
});
|
||||
ASSERT_TRUE(arr->Is<ast::Array>());
|
||||
ASSERT_TRUE(arr->As<ast::Array>()->type->Is<ast::F32>());
|
||||
|
@ -110,8 +110,8 @@ TEST_F(CreateASTTypeForTest, Struct) {
|
|||
auto* str = create([](ProgramBuilder& b) {
|
||||
auto* decl = b.Structure("S", {}, {});
|
||||
return b.create<sem::Struct>(decl, decl->name, sem::StructMemberList{},
|
||||
4 /* align */, 4 /* size */,
|
||||
4 /* size_no_padding */);
|
||||
4u /* align */, 4u /* size */,
|
||||
4u /* size_no_padding */);
|
||||
});
|
||||
ASSERT_TRUE(str->Is<ast::TypeName>());
|
||||
EXPECT_EQ(ast_type_builder.Symbols().NameFor(str->As<ast::TypeName>()->name),
|
||||
|
|
|
@ -34,37 +34,49 @@ class UniqueAllocator {
|
|||
/// @return a pointer to an instance of `T` with the provided arguments.
|
||||
/// If an existing instance of `T` has been constructed, then the same
|
||||
/// pointer is returned.
|
||||
template <typename... ARGS>
|
||||
T* Get(ARGS&&... args) {
|
||||
template <typename TYPE = T, typename... ARGS>
|
||||
TYPE* Get(ARGS&&... args) {
|
||||
// Create a temporary T instance on the stack so that we can hash it, and
|
||||
// use it for equality lookup for the std::unordered_set. If the item is not
|
||||
// found in the set, then we create the persisted instance with the
|
||||
// allocator.
|
||||
T key{args...};
|
||||
TYPE key{args...};
|
||||
auto hash = HASH{}(key);
|
||||
auto it = items.find(Entry{hash, &key});
|
||||
if (it != items.end()) {
|
||||
return it->ptr;
|
||||
return static_cast<TYPE*>(it->ptr);
|
||||
}
|
||||
auto* ptr = allocator.Create(std::forward<ARGS>(args)...);
|
||||
auto* ptr = allocator.template Create<TYPE>(std::forward<ARGS>(args)...);
|
||||
items.emplace_hint(it, Entry{hash, ptr});
|
||||
return ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
/// Entry is used as the entry to the unordered_set
|
||||
struct Entry {
|
||||
/// The pre-calculated hash of the entry
|
||||
size_t hash;
|
||||
/// Tge pointer to the unique object
|
||||
T* ptr;
|
||||
};
|
||||
struct Hasher {
|
||||
size_t operator()(Entry e) const { return e.hash; }
|
||||
};
|
||||
/// Comparator is the hashing and equality function used by the unordered_set
|
||||
struct Comparator {
|
||||
/// Hashing function
|
||||
/// @param e the entry
|
||||
/// @returns the hash of the entry
|
||||
size_t operator()(Entry e) const { return e.hash; }
|
||||
|
||||
/// Equality function
|
||||
/// @param a the first entry to compare
|
||||
/// @param b the second entry to compare
|
||||
/// @returns true if the two entries are equal
|
||||
bool operator()(Entry a, Entry b) const { return EQUAL{}(*a.ptr, *b.ptr); }
|
||||
};
|
||||
|
||||
/// The block allocator used to allocate the unique objects
|
||||
BlockAllocator<T> allocator;
|
||||
std::unordered_set<Entry, Hasher, Comparator> items;
|
||||
/// The unordered_set of unique item entries
|
||||
std::unordered_set<Entry, Comparator, Comparator> items;
|
||||
};
|
||||
|
||||
} // namespace tint::utils
|
||||
|
|
|
@ -122,8 +122,8 @@ TEST_F(GlslGeneratorImplTest_Type, EmitType_I32) {
|
|||
|
||||
TEST_F(GlslGeneratorImplTest_Type, EmitType_Matrix) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* vec3 = create<sem::Vector>(f32, 3);
|
||||
auto* mat2x3 = create<sem::Matrix>(vec3, 2);
|
||||
auto* vec3 = create<sem::Vector>(f32, 3u);
|
||||
auto* mat2x3 = create<sem::Matrix>(vec3, 2u);
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
|
@ -224,7 +224,7 @@ TEST_F(GlslGeneratorImplTest_Type, EmitType_U32) {
|
|||
|
||||
TEST_F(GlslGeneratorImplTest_Type, EmitType_Vector) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* vec3 = create<sem::Vector>(f32, 3);
|
||||
auto* vec3 = create<sem::Vector>(f32, 3u);
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
|
|
|
@ -122,8 +122,8 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_I32) {
|
|||
|
||||
TEST_F(HlslGeneratorImplTest_Type, EmitType_Matrix) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* vec3 = create<sem::Vector>(f32, 3);
|
||||
auto* mat2x3 = create<sem::Matrix>(vec3, 2);
|
||||
auto* vec3 = create<sem::Vector>(f32, 3u);
|
||||
auto* mat2x3 = create<sem::Matrix>(vec3, 2u);
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
|
@ -241,7 +241,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_U32) {
|
|||
|
||||
TEST_F(HlslGeneratorImplTest_Type, EmitType_Vector) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* vec3 = create<sem::Vector>(f32, 3);
|
||||
auto* vec3 = create<sem::Vector>(f32, 3u);
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
|
|
|
@ -177,8 +177,8 @@ TEST_F(MslGeneratorImplTest, EmitType_I32) {
|
|||
|
||||
TEST_F(MslGeneratorImplTest, EmitType_Matrix) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* vec3 = create<sem::Vector>(f32, 3);
|
||||
auto* mat2x3 = create<sem::Matrix>(vec3, 2);
|
||||
auto* vec3 = create<sem::Vector>(f32, 3u);
|
||||
auto* mat2x3 = create<sem::Matrix>(vec3, 2u);
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
|
@ -708,7 +708,7 @@ TEST_F(MslGeneratorImplTest, EmitType_U32) {
|
|||
|
||||
TEST_F(MslGeneratorImplTest, EmitType_Vector) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* vec3 = create<sem::Vector>(f32, 3);
|
||||
auto* vec3 = create<sem::Vector>(f32, 3u);
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
|
|
|
@ -516,7 +516,7 @@ bool Builder::GenerateExecutionModes(const ast::Function* func, uint32_t id) {
|
|||
has_overridable_workgroup_size_ = true;
|
||||
|
||||
auto* vec3_u32 =
|
||||
builder_.create<sem::Vector>(builder_.create<sem::U32>(), 3);
|
||||
builder_.create<sem::Vector>(builder_.create<sem::U32>(), 3u);
|
||||
uint32_t vec3_u32_type_id = GenerateTypeIfNeeded(vec3_u32);
|
||||
if (vec3_u32_type_id == 0) {
|
||||
return 0;
|
||||
|
@ -2712,7 +2712,7 @@ bool Builder::GenerateTextureBuiltin(const sem::Call* call,
|
|||
if (texture_type
|
||||
->IsAnyOf<sem::DepthTexture, sem::DepthMultisampledTexture>()) {
|
||||
auto* f32 = builder_.create<sem::F32>();
|
||||
auto* spirv_result_type = builder_.create<sem::Vector>(f32, 4);
|
||||
auto* spirv_result_type = builder_.create<sem::Vector>(f32, 4u);
|
||||
auto spirv_result = result_op();
|
||||
post_emission = [=] {
|
||||
return push_function_inst(
|
||||
|
@ -3996,9 +3996,7 @@ bool Builder::GenerateTextureType(const sem::Texture* texture,
|
|||
[&](const sem::StorageTexture* t) {
|
||||
return GenerateTypeIfNeeded(t->type());
|
||||
},
|
||||
[&](Default) {
|
||||
return 0u;
|
||||
});
|
||||
[&](Default) { return 0u; });
|
||||
if (type_id == 0u) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -208,8 +208,8 @@ TEST_F(BuilderTest_Type, ReturnsGeneratedI32) {
|
|||
|
||||
TEST_F(BuilderTest_Type, GenerateMatrix) {
|
||||
auto* f32 = create<sem::F32>();
|
||||
auto* vec3 = create<sem::Vector>(f32, 3);
|
||||
auto* mat2x3 = create<sem::Matrix>(vec3, 2);
|
||||
auto* vec3 = create<sem::Vector>(f32, 3u);
|
||||
auto* mat2x3 = create<sem::Matrix>(vec3, 2u);
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
|
@ -226,8 +226,8 @@ TEST_F(BuilderTest_Type, GenerateMatrix) {
|
|||
|
||||
TEST_F(BuilderTest_Type, ReturnsGeneratedMatrix) {
|
||||
auto* i32 = create<sem::I32>();
|
||||
auto* col = create<sem::Vector>(i32, 4);
|
||||
auto* mat = create<sem::Matrix>(col, 3);
|
||||
auto* col = create<sem::Vector>(i32, 4u);
|
||||
auto* mat = create<sem::Matrix>(col, 3u);
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
|
@ -469,7 +469,7 @@ TEST_F(BuilderTest_Type, ReturnsGeneratedU32) {
|
|||
}
|
||||
|
||||
TEST_F(BuilderTest_Type, GenerateVector) {
|
||||
auto* vec = create<sem::Vector>(create<sem::F32>(), 3);
|
||||
auto* vec = create<sem::Vector>(create<sem::F32>(), 3u);
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
|
@ -485,7 +485,7 @@ TEST_F(BuilderTest_Type, GenerateVector) {
|
|||
|
||||
TEST_F(BuilderTest_Type, ReturnsGeneratedVector) {
|
||||
auto* i32 = create<sem::I32>();
|
||||
auto* vec = create<sem::Vector>(i32, 3);
|
||||
auto* vec = create<sem::Vector>(i32, 3u);
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
|
|
Loading…
Reference in New Issue