Add type::Type::FriendlyName()
Gives a WGSL-like string for the given type.
Also cleans up some code in IntrinsicTable.
Change-Id: I89a2fadb5291b49dcbf43371bb970eef74670e2c
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/40605
Auto-Submit: Ben Clayton <bclayton@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/intrinsic_table.cc b/src/intrinsic_table.cc
index 3598372..0c99427 100644
--- a/src/intrinsic_table.cc
+++ b/src/intrinsic_table.cc
@@ -1240,69 +1240,6 @@
}
return ss.str();
}
-/// TODO(bclayton): This really does not belong here. It would be nice if
-/// type::Type::type_name() returned these strings.
-/// @returns a human readable string for the type `ty`.
-std::string TypeName(type::Type* ty) {
- ty = ty->UnwrapAll();
- if (ty->Is<type::F32>()) {
- return "f32";
- }
- if (ty->Is<type::U32>()) {
- return "u32";
- }
- if (ty->Is<type::I32>()) {
- return "i32";
- }
- if (ty->Is<type::Bool>()) {
- return "bool";
- }
- if (ty->Is<type::Void>()) {
- return "void";
- }
- if (auto* ptr = ty->As<type::Pointer>()) {
- return "ptr<" + TypeName(ptr->type()) + ">";
- }
- if (auto* vec = ty->As<type::Vector>()) {
- return "vec" + std::to_string(vec->size()) + "<" + TypeName(vec->type()) +
- ">";
- }
- if (auto* mat = ty->As<type::Matrix>()) {
- return "mat" + std::to_string(mat->columns()) + "x" +
- std::to_string(mat->rows()) + "<" + TypeName(mat->type()) + ">";
- }
- if (auto* tex = ty->As<type::SampledTexture>()) {
- std::stringstream ss;
- ss << "texture_" << tex->dim() << "<" << TypeName(tex->type()) << ">";
- return ss.str();
- }
- if (auto* tex = ty->As<type::MultisampledTexture>()) {
- std::stringstream ss;
- ss << "texture_multisampled_" << tex->dim() << "<" << TypeName(tex->type())
- << ">";
- return ss.str();
- }
- if (auto* tex = ty->As<type::DepthTexture>()) {
- std::stringstream ss;
- ss << "texture_depth_" << tex->dim();
- return ss.str();
- }
- if (auto* tex = ty->As<type::StorageTexture>()) {
- std::stringstream ss;
- ss << "texture_storage_" << tex->dim() << "<" << tex->image_format() << ">";
- return ss.str();
- }
- if (auto* sampler = ty->As<type::Sampler>()) {
- switch (sampler->kind()) {
- case type::SamplerKind::kSampler:
- return "sampler";
- case type::SamplerKind::kComparisonSampler:
- return "sampler_comparison";
- }
- return "sampler";
- }
- return ty->type_name();
-}
IntrinsicTable::Result Impl::Lookup(
ProgramBuilder& builder,
@@ -1345,7 +1282,7 @@
ss << ", ";
}
first = false;
- ss << TypeName(arg);
+ ss << arg->UnwrapAll()->FriendlyName(builder.Symbols());
}
}
ss << ")" << std::endl;
diff --git a/src/type/access_control_type.cc b/src/type/access_control_type.cc
index 9125cc8..4d96e89 100644
--- a/src/type/access_control_type.cc
+++ b/src/type/access_control_type.cc
@@ -50,6 +50,24 @@
return name + subtype_->type_name();
}
+std::string AccessControl::FriendlyName(const SymbolTable& symbols) const {
+ std::ostringstream out;
+ out << "[[access(";
+ switch (access_) {
+ case ast::AccessControl::kReadOnly:
+ out << "read";
+ break;
+ case ast::AccessControl::kWriteOnly:
+ out << "write";
+ break;
+ case ast::AccessControl::kReadWrite:
+ out << "read_write";
+ break;
+ }
+ out << ")]] " << subtype_->FriendlyName(symbols);
+ return out.str();
+}
+
uint64_t AccessControl::MinBufferBindingSize(MemoryLayout mem_layout) const {
return subtype_->MinBufferBindingSize(mem_layout);
}
diff --git a/src/type/access_control_type.h b/src/type/access_control_type.h
index 3e0da48..7dce8bd 100644
--- a/src/type/access_control_type.h
+++ b/src/type/access_control_type.h
@@ -49,6 +49,11 @@
/// @returns the name for this type
std::string type_name() const override;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
/// @param mem_layout type of memory layout to use in calculation.
/// @returns minimum size required for this type, in bytes.
/// 0 for non-host shareable types.
diff --git a/src/type/access_control_type_test.cc b/src/type/access_control_type_test.cc
index 893eb8b..d398fca 100644
--- a/src/type/access_control_type_test.cc
+++ b/src/type/access_control_type_test.cc
@@ -97,6 +97,21 @@
EXPECT_EQ(at.type_name(), "__access_control_read_write__i32");
}
+TEST_F(AccessControlTest, FriendlyNameReadOnly) {
+ AccessControl at{ast::AccessControl::kReadOnly, ty.i32()};
+ EXPECT_EQ(at.FriendlyName(Symbols()), "[[access(read)]] i32");
+}
+
+TEST_F(AccessControlTest, FriendlyNameWriteOnly) {
+ AccessControl at{ast::AccessControl::kWriteOnly, ty.i32()};
+ EXPECT_EQ(at.FriendlyName(Symbols()), "[[access(write)]] i32");
+}
+
+TEST_F(AccessControlTest, FriendlyNameReadWrite) {
+ AccessControl at{ast::AccessControl::kReadWrite, ty.i32()};
+ EXPECT_EQ(at.FriendlyName(Symbols()), "[[access(read_write)]] i32");
+}
+
TEST_F(AccessControlTest, MinBufferBindingSizeU32) {
U32 u32;
AccessControl at{ast::AccessControl::kReadOnly, &u32};
diff --git a/src/type/alias_type.cc b/src/type/alias_type.cc
index cd89bda..95fffe2 100644
--- a/src/type/alias_type.cc
+++ b/src/type/alias_type.cc
@@ -37,6 +37,10 @@
return "__alias_" + symbol_.to_str() + subtype_->type_name();
}
+std::string Alias::FriendlyName(const SymbolTable& symbols) const {
+ return symbols.NameFor(symbol_);
+}
+
uint64_t Alias::MinBufferBindingSize(MemoryLayout mem_layout) const {
return subtype_->MinBufferBindingSize(mem_layout);
}
diff --git a/src/type/alias_type.h b/src/type/alias_type.h
index c1f858d..57e44d9 100644
--- a/src/type/alias_type.h
+++ b/src/type/alias_type.h
@@ -43,6 +43,11 @@
/// @returns the type_name for this type
std::string type_name() const override;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
/// @param mem_layout type of memory layout to use in calculation.
/// @returns minimum size required for this type, in bytes.
/// 0 for non-host shareable types.
diff --git a/src/type/alias_type_test.cc b/src/type/alias_type_test.cc
index a404918..d39b201 100644
--- a/src/type/alias_type_test.cc
+++ b/src/type/alias_type_test.cc
@@ -69,6 +69,11 @@
EXPECT_EQ(at->type_name(), "__alias_tint_symbol_1__i32");
}
+TEST_F(AliasTest, FriendlyName) {
+ auto* at = ty.alias("Particle", ty.i32());
+ EXPECT_EQ(at->FriendlyName(Symbols()), "Particle");
+}
+
TEST_F(AliasTest, UnwrapIfNeeded_Alias) {
auto* a = ty.alias("a_type", ty.u32());
EXPECT_EQ(a->symbol(), Symbol(1));
diff --git a/src/type/array_type.cc b/src/type/array_type.cc
index ce90ad4..549b88f 100644
--- a/src/type/array_type.cc
+++ b/src/type/array_type.cc
@@ -95,6 +95,19 @@
return type_name;
}
+std::string Array::FriendlyName(const SymbolTable& symbols) const {
+ std::ostringstream out;
+ if (has_array_stride()) {
+ out << "[[stride(" << array_stride() << ")]] ";
+ }
+ out << "array<" << subtype_->FriendlyName(symbols);
+ if (!IsRuntimeArray()) {
+ out << ", " << size_;
+ }
+ out << ">";
+ return out.str();
+}
+
Array* Array::Clone(CloneContext* ctx) const {
return ctx->dst->create<Array>(ctx->Clone(subtype_), size_,
ctx->Clone(decorations()));
diff --git a/src/type/array_type.h b/src/type/array_type.h
index 404fa3b..1fccc27 100644
--- a/src/type/array_type.h
+++ b/src/type/array_type.h
@@ -69,6 +69,11 @@
/// @returns the name for the type
std::string type_name() const override;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
diff --git a/src/type/array_type_test.cc b/src/type/array_type_test.cc
index 54bc12a..85c0655 100644
--- a/src/type/array_type_test.cc
+++ b/src/type/array_type_test.cc
@@ -80,6 +80,22 @@
EXPECT_EQ(arr.type_name(), "__array__i32");
}
+TEST_F(ArrayTest, FriendlyNameRuntimeSized) {
+ Array arr{ty.i32(), 0, ast::ArrayDecorationList{}};
+ EXPECT_EQ(arr.FriendlyName(Symbols()), "array<i32>");
+}
+
+TEST_F(ArrayTest, FriendlyNameStaticSized) {
+ Array arr{ty.i32(), 5, ast::ArrayDecorationList{}};
+ EXPECT_EQ(arr.FriendlyName(Symbols()), "array<i32, 5>");
+}
+
+TEST_F(ArrayTest, FriendlyNameWithStride) {
+ Array arr{ty.i32(), 5,
+ ast::ArrayDecorationList{create<ast::StrideDecoration>(32)}};
+ EXPECT_EQ(arr.FriendlyName(Symbols()), "[[stride(32)]] array<i32, 5>");
+}
+
TEST_F(ArrayTest, TypeName_RuntimeArray) {
I32 i32;
Array arr{&i32, 3, ast::ArrayDecorationList{}};
diff --git a/src/type/bool_type.cc b/src/type/bool_type.cc
index 5b97dec..e548fde 100644
--- a/src/type/bool_type.cc
+++ b/src/type/bool_type.cc
@@ -32,6 +32,10 @@
return "__bool";
}
+std::string Bool::FriendlyName(const SymbolTable&) const {
+ return "bool";
+}
+
Bool* Bool::Clone(CloneContext* ctx) const {
return ctx->dst->create<Bool>();
}
diff --git a/src/type/bool_type.h b/src/type/bool_type.h
index cc35062..97863c5 100644
--- a/src/type/bool_type.h
+++ b/src/type/bool_type.h
@@ -40,6 +40,11 @@
/// @returns the name for this type
std::string type_name() const override;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
diff --git a/src/type/bool_type_test.cc b/src/type/bool_type_test.cc
index 552857b..49a18f1 100644
--- a/src/type/bool_type_test.cc
+++ b/src/type/bool_type_test.cc
@@ -55,6 +55,11 @@
EXPECT_EQ(b.type_name(), "__bool");
}
+TEST_F(BoolTest, FriendlyName) {
+ Bool b;
+ EXPECT_EQ(b.FriendlyName(Symbols()), "bool");
+}
+
TEST_F(BoolTest, MinBufferBindingSize) {
Bool b;
EXPECT_EQ(0u, b.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
diff --git a/src/type/depth_texture_type.cc b/src/type/depth_texture_type.cc
index c3cb32e..57f4b21 100644
--- a/src/type/depth_texture_type.cc
+++ b/src/type/depth_texture_type.cc
@@ -51,6 +51,12 @@
return out.str();
}
+std::string DepthTexture::FriendlyName(const SymbolTable&) const {
+ std::ostringstream out;
+ out << "texture_depth_" << dim();
+ return out.str();
+}
+
DepthTexture* DepthTexture::Clone(CloneContext* ctx) const {
return ctx->dst->create<DepthTexture>(dim());
}
diff --git a/src/type/depth_texture_type.h b/src/type/depth_texture_type.h
index 43eed57..2cff86c 100644
--- a/src/type/depth_texture_type.h
+++ b/src/type/depth_texture_type.h
@@ -35,6 +35,11 @@
/// @returns the name for this type
std::string type_name() const override;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
diff --git a/src/type/depth_texture_type_test.cc b/src/type/depth_texture_type_test.cc
index 26be3e9..7303930 100644
--- a/src/type/depth_texture_type_test.cc
+++ b/src/type/depth_texture_type_test.cc
@@ -71,6 +71,11 @@
EXPECT_EQ(d.type_name(), "__depth_texture_cube");
}
+TEST_F(DepthTextureTest, FriendlyName) {
+ DepthTexture d(TextureDimension::kCube);
+ EXPECT_EQ(d.FriendlyName(Symbols()), "texture_depth_cube");
+}
+
TEST_F(DepthTextureTest, MinBufferBindingSize) {
DepthTexture d(TextureDimension::kCube);
EXPECT_EQ(0u, d.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
diff --git a/src/type/f32_type.cc b/src/type/f32_type.cc
index 976a549..e9b341a 100644
--- a/src/type/f32_type.cc
+++ b/src/type/f32_type.cc
@@ -32,6 +32,10 @@
return "__f32";
}
+std::string F32::FriendlyName(const SymbolTable&) const {
+ return "f32";
+}
+
uint64_t F32::MinBufferBindingSize(MemoryLayout) const {
return 4;
}
diff --git a/src/type/f32_type.h b/src/type/f32_type.h
index 55e4224..50e990d 100644
--- a/src/type/f32_type.h
+++ b/src/type/f32_type.h
@@ -34,6 +34,11 @@
/// @returns the name for this type
std::string type_name() const override;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
/// @param mem_layout type of memory layout to use in calculation.
/// @returns minimum size required for this type, in bytes.
/// 0 for non-host shareable types.
diff --git a/src/type/f32_type_test.cc b/src/type/f32_type_test.cc
index 7a25dc7..92fca64 100644
--- a/src/type/f32_type_test.cc
+++ b/src/type/f32_type_test.cc
@@ -55,6 +55,11 @@
EXPECT_EQ(f.type_name(), "__f32");
}
+TEST_F(F32Test, FriendlyName) {
+ F32 f;
+ EXPECT_EQ(f.FriendlyName(Symbols()), "f32");
+}
+
TEST_F(F32Test, MinBufferBindingSize) {
F32 f;
EXPECT_EQ(4u, f.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
diff --git a/src/type/i32_type.cc b/src/type/i32_type.cc
index ded1932..d3f72ec 100644
--- a/src/type/i32_type.cc
+++ b/src/type/i32_type.cc
@@ -32,6 +32,10 @@
return "__i32";
}
+std::string I32::FriendlyName(const SymbolTable&) const {
+ return "i32";
+}
+
uint64_t I32::MinBufferBindingSize(MemoryLayout) const {
return 4;
}
diff --git a/src/type/i32_type.h b/src/type/i32_type.h
index cb4421f..e688a0c 100644
--- a/src/type/i32_type.h
+++ b/src/type/i32_type.h
@@ -34,6 +34,11 @@
/// @returns the name for this type
std::string type_name() const override;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
/// @param mem_layout type of memory layout to use in calculation.
/// @returns minimum size required for this type, in bytes.
/// 0 for non-host shareable types.
diff --git a/src/type/i32_type_test.cc b/src/type/i32_type_test.cc
index 0fa098a..60df02f 100644
--- a/src/type/i32_type_test.cc
+++ b/src/type/i32_type_test.cc
@@ -55,6 +55,11 @@
EXPECT_EQ(i.type_name(), "__i32");
}
+TEST_F(I32Test, FriendlyName) {
+ I32 i;
+ EXPECT_EQ(i.FriendlyName(Symbols()), "i32");
+}
+
TEST_F(I32Test, MinBufferBindingSize) {
I32 i;
EXPECT_EQ(4u, i.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
diff --git a/src/type/matrix_type.cc b/src/type/matrix_type.cc
index f32b396..c678f4e 100644
--- a/src/type/matrix_type.cc
+++ b/src/type/matrix_type.cc
@@ -43,6 +43,13 @@
subtype_->type_name();
}
+std::string Matrix::FriendlyName(const SymbolTable& symbols) const {
+ std::ostringstream out;
+ out << "mat" << columns_ << "x" << rows_ << "<"
+ << subtype_->FriendlyName(symbols) << ">";
+ return out.str();
+}
+
uint64_t Matrix::MinBufferBindingSize(MemoryLayout mem_layout) const {
Vector vec(subtype_, rows_);
return (columns_ - 1) * vec.BaseAlignment(mem_layout) +
diff --git a/src/type/matrix_type.h b/src/type/matrix_type.h
index d37a115..f76d578 100644
--- a/src/type/matrix_type.h
+++ b/src/type/matrix_type.h
@@ -44,6 +44,11 @@
/// @returns the name for this type
std::string type_name() const override;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
/// @param mem_layout type of memory layout to use in calculation.
/// @returns minimum size required for this type, in bytes.
/// 0 for non-host shareable types.
diff --git a/src/type/matrix_type_test.cc b/src/type/matrix_type_test.cc
index c1b6c43..e7b6227 100644
--- a/src/type/matrix_type_test.cc
+++ b/src/type/matrix_type_test.cc
@@ -65,6 +65,11 @@
EXPECT_EQ(m.type_name(), "__mat_2_3__i32");
}
+TEST_F(MatrixTest, FriendlyName) {
+ Matrix m{ty.i32(), 3, 2};
+ EXPECT_EQ(m.FriendlyName(Symbols()), "mat2x3<i32>");
+}
+
TEST_F(MatrixTest, MinBufferBindingSize4x2) {
I32 i32;
Matrix m{&i32, 4, 2};
diff --git a/src/type/multisampled_texture_type.cc b/src/type/multisampled_texture_type.cc
index e9d415d..f647016 100644
--- a/src/type/multisampled_texture_type.cc
+++ b/src/type/multisampled_texture_type.cc
@@ -40,6 +40,14 @@
return out.str();
}
+std::string MultisampledTexture::FriendlyName(
+ const SymbolTable& symbols) const {
+ std::ostringstream out;
+ out << "texture_multisampled_" << dim() << "<" << type_->FriendlyName(symbols)
+ << ">";
+ return out.str();
+}
+
MultisampledTexture* MultisampledTexture::Clone(CloneContext* ctx) const {
return ctx->dst->create<MultisampledTexture>(dim(), ctx->Clone(type_));
}
diff --git a/src/type/multisampled_texture_type.h b/src/type/multisampled_texture_type.h
index afe7d6b..78c4073 100644
--- a/src/type/multisampled_texture_type.h
+++ b/src/type/multisampled_texture_type.h
@@ -39,6 +39,11 @@
/// @returns the name for this type
std::string type_name() const override;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
diff --git a/src/type/multisampled_texture_type_test.cc b/src/type/multisampled_texture_type_test.cc
index 788d7df..d4ac2ee 100644
--- a/src/type/multisampled_texture_type_test.cc
+++ b/src/type/multisampled_texture_type_test.cc
@@ -82,6 +82,11 @@
EXPECT_EQ(s.type_name(), "__multisampled_texture_3d__f32");
}
+TEST_F(MultisampledTextureTest, FriendlyName) {
+ MultisampledTexture s(TextureDimension::k3d, ty.f32());
+ EXPECT_EQ(s.FriendlyName(Symbols()), "texture_multisampled_3d<f32>");
+}
+
TEST_F(MultisampledTextureTest, MinBufferBindingSize) {
F32 f32;
MultisampledTexture s(TextureDimension::k3d, &f32);
diff --git a/src/type/pointer_type.cc b/src/type/pointer_type.cc
index 8ac4a94..ec564ec 100644
--- a/src/type/pointer_type.cc
+++ b/src/type/pointer_type.cc
@@ -31,6 +31,16 @@
return out.str();
}
+std::string Pointer::FriendlyName(const SymbolTable& symbols) const {
+ std::ostringstream out;
+ out << "ptr<";
+ if (storage_class_ != ast::StorageClass::kNone) {
+ out << storage_class_ << ", ";
+ }
+ out << subtype_->FriendlyName(symbols) << ">";
+ return out.str();
+}
+
Pointer::Pointer(Pointer&&) = default;
Pointer::~Pointer() = default;
diff --git a/src/type/pointer_type.h b/src/type/pointer_type.h
index bf64785..9df8e73 100644
--- a/src/type/pointer_type.h
+++ b/src/type/pointer_type.h
@@ -43,6 +43,11 @@
/// @returns the name for this type
std::string type_name() const override;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
diff --git a/src/type/pointer_type_test.cc b/src/type/pointer_type_test.cc
index 7b6c6a8..dd48053 100644
--- a/src/type/pointer_type_test.cc
+++ b/src/type/pointer_type_test.cc
@@ -64,6 +64,16 @@
EXPECT_EQ(p.type_name(), "__ptr_workgroup__i32");
}
+TEST_F(PointerTest, FriendlyNameWithStorageClass) {
+ Pointer p{ty.i32(), ast::StorageClass::kWorkgroup};
+ EXPECT_EQ(p.FriendlyName(Symbols()), "ptr<workgroup, i32>");
+}
+
+TEST_F(PointerTest, FriendlyNameWithoutStorageClass) {
+ Pointer p{ty.i32(), ast::StorageClass::kNone};
+ EXPECT_EQ(p.FriendlyName(Symbols()), "ptr<i32>");
+}
+
} // namespace
} // namespace type
} // namespace tint
diff --git a/src/type/sampled_texture_type.cc b/src/type/sampled_texture_type.cc
index a63577b..bd4fb5c 100644
--- a/src/type/sampled_texture_type.cc
+++ b/src/type/sampled_texture_type.cc
@@ -40,6 +40,12 @@
return out.str();
}
+std::string SampledTexture::FriendlyName(const SymbolTable& symbols) const {
+ std::ostringstream out;
+ out << "texture_" << dim() << "<" << type_->FriendlyName(symbols) << ">";
+ return out.str();
+}
+
SampledTexture* SampledTexture::Clone(CloneContext* ctx) const {
return ctx->dst->create<SampledTexture>(dim(), ctx->Clone(type_));
}
diff --git a/src/type/sampled_texture_type.h b/src/type/sampled_texture_type.h
index 3211050..fc03f72 100644
--- a/src/type/sampled_texture_type.h
+++ b/src/type/sampled_texture_type.h
@@ -39,6 +39,11 @@
/// @returns the name for this type
std::string type_name() const override;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
diff --git a/src/type/sampled_texture_type_test.cc b/src/type/sampled_texture_type_test.cc
index a80312f..7eee0fa 100644
--- a/src/type/sampled_texture_type_test.cc
+++ b/src/type/sampled_texture_type_test.cc
@@ -80,6 +80,11 @@
EXPECT_EQ(s.type_name(), "__sampled_texture_3d__f32");
}
+TEST_F(SampledTextureTest, FriendlyName) {
+ SampledTexture s(TextureDimension::k3d, ty.f32());
+ EXPECT_EQ(s.FriendlyName(Symbols()), "texture_3d<f32>");
+}
+
TEST_F(SampledTextureTest, MinBufferBindingSize) {
F32 f32;
SampledTexture s(TextureDimension::kCube, &f32);
diff --git a/src/type/sampler_type.cc b/src/type/sampler_type.cc
index bff290b..01579ca 100644
--- a/src/type/sampler_type.cc
+++ b/src/type/sampler_type.cc
@@ -45,6 +45,10 @@
(kind_ == SamplerKind::kSampler ? "sampler" : "comparison");
}
+std::string Sampler::FriendlyName(const SymbolTable&) const {
+ return kind_ == SamplerKind::kSampler ? "sampler" : "sampler_comparison";
+}
+
Sampler* Sampler::Clone(CloneContext* ctx) const {
return ctx->dst->create<Sampler>(kind_);
}
diff --git a/src/type/sampler_type.h b/src/type/sampler_type.h
index 8c71128..486446b 100644
--- a/src/type/sampler_type.h
+++ b/src/type/sampler_type.h
@@ -51,6 +51,11 @@
/// @returns the name for this type
std::string type_name() const override;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
diff --git a/src/type/sampler_type_test.cc b/src/type/sampler_type_test.cc
index 2648300..2b3184b 100644
--- a/src/type/sampler_type_test.cc
+++ b/src/type/sampler_type_test.cc
@@ -72,6 +72,16 @@
EXPECT_EQ(s.type_name(), "__sampler_comparison");
}
+TEST_F(SamplerTest, FriendlyNameSampler) {
+ Sampler s{SamplerKind::kSampler};
+ EXPECT_EQ(s.FriendlyName(Symbols()), "sampler");
+}
+
+TEST_F(SamplerTest, FriendlyNameComparisonSampler) {
+ Sampler s{SamplerKind::kComparisonSampler};
+ EXPECT_EQ(s.FriendlyName(Symbols()), "sampler_comparison");
+}
+
TEST_F(SamplerTest, MinBufferBindingSize) {
Sampler s{SamplerKind::kSampler};
EXPECT_EQ(0u, s.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
diff --git a/src/type/storage_texture_type.cc b/src/type/storage_texture_type.cc
index 91be1ad..14f86aa 100644
--- a/src/type/storage_texture_type.cc
+++ b/src/type/storage_texture_type.cc
@@ -156,6 +156,12 @@
return out.str();
}
+std::string StorageTexture::FriendlyName(const SymbolTable&) const {
+ std::ostringstream out;
+ out << "texture_storage_" << dim() << "<" << image_format_ << ">";
+ return out.str();
+}
+
StorageTexture* StorageTexture::Clone(CloneContext* ctx) const {
return ctx->dst->create<StorageTexture>(dim(), image_format_,
ctx->Clone(subtype_));
diff --git a/src/type/storage_texture_type.h b/src/type/storage_texture_type.h
index cff03e2..7342c57 100644
--- a/src/type/storage_texture_type.h
+++ b/src/type/storage_texture_type.h
@@ -87,6 +87,11 @@
/// @returns the name for this type
std::string type_name() const override;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type
diff --git a/src/type/storage_texture_type_test.cc b/src/type/storage_texture_type_test.cc
index 95c498a..bbacb47 100644
--- a/src/type/storage_texture_type_test.cc
+++ b/src/type/storage_texture_type_test.cc
@@ -94,6 +94,15 @@
EXPECT_EQ(s->type_name(), "__storage_texture_2d_array_rgba32float");
}
+TEST_F(StorageTextureTest, FriendlyName) {
+ auto* subtype =
+ StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, Types());
+ auto* s = create<StorageTexture>(TextureDimension::k2dArray,
+ ImageFormat::kRgba32Float, subtype);
+ EXPECT_EQ(s->FriendlyName(Symbols()),
+ "texture_storage_2d_array<rgba32float>");
+}
+
TEST_F(StorageTextureTest, F32) {
auto* subtype =
type::StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, Types());
diff --git a/src/type/struct_type.cc b/src/type/struct_type.cc
index 39efc95..05ba4c7 100644
--- a/src/type/struct_type.cc
+++ b/src/type/struct_type.cc
@@ -40,6 +40,10 @@
return "__struct_" + symbol_.to_str();
}
+std::string Struct::FriendlyName(const SymbolTable& symbols) const {
+ return symbols.NameFor(symbol_);
+}
+
uint64_t Struct::MinBufferBindingSize(MemoryLayout mem_layout) const {
if (!struct_->members().size()) {
return 0;
diff --git a/src/type/struct_type.h b/src/type/struct_type.h
index 63fcaa2..eb0c37d 100644
--- a/src/type/struct_type.h
+++ b/src/type/struct_type.h
@@ -48,6 +48,11 @@
/// @returns the name for the type
std::string type_name() const override;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
/// @param mem_layout type of memory layout to use in calculation.
/// @returns minimum size required for this type, in bytes.
/// 0 for non-host shareable types.
diff --git a/src/type/struct_type_test.cc b/src/type/struct_type_test.cc
index e1e7fa0..4419587 100644
--- a/src/type/struct_type_test.cc
+++ b/src/type/struct_type_test.cc
@@ -73,6 +73,13 @@
EXPECT_EQ(s->type_name(), "__struct_tint_symbol_1");
}
+TEST_F(StructTypeTest, FriendlyName) {
+ auto* impl =
+ create<ast::Struct>(ast::StructMemberList{}, ast::StructDecorationList{});
+ auto* s = ty.struct_("my_struct", impl);
+ EXPECT_EQ(s->FriendlyName(Symbols()), "my_struct");
+}
+
TEST_F(StructTypeTest, MinBufferBindingSize) {
auto* str = create<ast::Struct>(
ast::StructMemberList{Member("foo", ty.u32(), {MemberOffset(0)}),
diff --git a/src/type/type.h b/src/type/type.h
index 2834e7b..7c747c9 100644
--- a/src/type/type.h
+++ b/src/type/type.h
@@ -24,6 +24,7 @@
// Forward declarations
class ProgramBuilder;
+class SymbolTable;
namespace type {
@@ -45,6 +46,11 @@
/// @returns the name for this type. The type name is unique over all types.
virtual std::string type_name() const = 0;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ virtual std::string FriendlyName(const SymbolTable& symbols) const = 0;
+
/// @param mem_layout type of memory layout to use in calculation.
/// @returns minimum size required for this type, in bytes.
/// 0 for non-host shareable types.
diff --git a/src/type/u32_type.cc b/src/type/u32_type.cc
index 0736b05..b97fde6 100644
--- a/src/type/u32_type.cc
+++ b/src/type/u32_type.cc
@@ -32,6 +32,10 @@
return "__u32";
}
+std::string U32::FriendlyName(const SymbolTable&) const {
+ return "u32";
+}
+
uint64_t U32::MinBufferBindingSize(MemoryLayout) const {
return 4;
}
diff --git a/src/type/u32_type.h b/src/type/u32_type.h
index 77d1eda..7e92a3a 100644
--- a/src/type/u32_type.h
+++ b/src/type/u32_type.h
@@ -34,6 +34,11 @@
/// @returns the name for th type
std::string type_name() const override;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
/// @param mem_layout type of memory layout to use in calculation.
/// @returns minimum size required for this type, in bytes.
/// 0 for non-host shareable types.
diff --git a/src/type/u32_type_test.cc b/src/type/u32_type_test.cc
index e0390ce..b9de713 100644
--- a/src/type/u32_type_test.cc
+++ b/src/type/u32_type_test.cc
@@ -56,6 +56,11 @@
EXPECT_EQ(u.type_name(), "__u32");
}
+TEST_F(U32Test, FriendlyName) {
+ U32 u;
+ EXPECT_EQ(u.FriendlyName(Symbols()), "u32");
+}
+
TEST_F(U32Test, MinBufferBindingSize) {
U32 u;
EXPECT_EQ(4u, u.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
diff --git a/src/type/vector_type.cc b/src/type/vector_type.cc
index 96e3b16..84cdf24 100644
--- a/src/type/vector_type.cc
+++ b/src/type/vector_type.cc
@@ -38,6 +38,12 @@
return "__vec_" + std::to_string(size_) + subtype_->type_name();
}
+std::string Vector::FriendlyName(const SymbolTable& symbols) const {
+ std::ostringstream out;
+ out << "vec" << size_ << "<" << subtype_->FriendlyName(symbols) << ">";
+ return out.str();
+}
+
uint64_t Vector::MinBufferBindingSize(MemoryLayout mem_layout) const {
return size_ * subtype_->MinBufferBindingSize(mem_layout);
}
diff --git a/src/type/vector_type.h b/src/type/vector_type.h
index e9f1af5..88e41f2 100644
--- a/src/type/vector_type.h
+++ b/src/type/vector_type.h
@@ -41,6 +41,11 @@
/// @returns the name for th type
std::string type_name() const override;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
/// @param mem_layout type of memory layout to use in calculation.
/// @returns minimum size required for this type, in bytes.
/// 0 for non-host shareable types.
diff --git a/src/type/vector_type_test.cc b/src/type/vector_type_test.cc
index 20656d7..51dfa4b 100644
--- a/src/type/vector_type_test.cc
+++ b/src/type/vector_type_test.cc
@@ -64,6 +64,11 @@
EXPECT_EQ(v.type_name(), "__vec_3__i32");
}
+TEST_F(VectorTest, FriendlyName) {
+ auto* v = ty.vec3<f32>();
+ EXPECT_EQ(v->FriendlyName(Symbols()), "vec3<f32>");
+}
+
TEST_F(VectorTest, MinBufferBindingSizeVec2) {
I32 i32;
Vector v{&i32, 2};
diff --git a/src/type/void_type.cc b/src/type/void_type.cc
index fe2a1a6..342c5ec 100644
--- a/src/type/void_type.cc
+++ b/src/type/void_type.cc
@@ -32,6 +32,10 @@
return "__void";
}
+std::string Void::FriendlyName(const SymbolTable&) const {
+ return "void";
+}
+
Void* Void::Clone(CloneContext* ctx) const {
return ctx->dst->create<Void>();
}
diff --git a/src/type/void_type.h b/src/type/void_type.h
index 1207808..406b36b 100644
--- a/src/type/void_type.h
+++ b/src/type/void_type.h
@@ -34,6 +34,11 @@
/// @returns the name for this type
std::string type_name() const override;
+ /// @param symbols the program's symbol table
+ /// @returns the name for this type that closely resembles how it would be
+ /// declared in WGSL.
+ std::string FriendlyName(const SymbolTable& symbols) const override;
+
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
/// @param ctx the clone context
/// @return the newly cloned type