From 3e8060b4e353f852349735b1cb59e2de9653fdc6 Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Tue, 9 Feb 2021 18:52:34 +0000 Subject: [PATCH] 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 Commit-Queue: dan sinclair Reviewed-by: dan sinclair --- src/intrinsic_table.cc | 65 +--------------------- src/type/access_control_type.cc | 18 ++++++ src/type/access_control_type.h | 5 ++ src/type/access_control_type_test.cc | 15 +++++ src/type/alias_type.cc | 4 ++ src/type/alias_type.h | 5 ++ src/type/alias_type_test.cc | 5 ++ src/type/array_type.cc | 13 +++++ src/type/array_type.h | 5 ++ src/type/array_type_test.cc | 16 ++++++ src/type/bool_type.cc | 4 ++ src/type/bool_type.h | 5 ++ src/type/bool_type_test.cc | 5 ++ src/type/depth_texture_type.cc | 6 ++ src/type/depth_texture_type.h | 5 ++ src/type/depth_texture_type_test.cc | 5 ++ src/type/f32_type.cc | 4 ++ src/type/f32_type.h | 5 ++ src/type/f32_type_test.cc | 5 ++ src/type/i32_type.cc | 4 ++ src/type/i32_type.h | 5 ++ src/type/i32_type_test.cc | 5 ++ src/type/matrix_type.cc | 7 +++ src/type/matrix_type.h | 5 ++ src/type/matrix_type_test.cc | 5 ++ src/type/multisampled_texture_type.cc | 8 +++ src/type/multisampled_texture_type.h | 5 ++ src/type/multisampled_texture_type_test.cc | 5 ++ src/type/pointer_type.cc | 10 ++++ src/type/pointer_type.h | 5 ++ src/type/pointer_type_test.cc | 10 ++++ src/type/sampled_texture_type.cc | 6 ++ src/type/sampled_texture_type.h | 5 ++ src/type/sampled_texture_type_test.cc | 5 ++ src/type/sampler_type.cc | 4 ++ src/type/sampler_type.h | 5 ++ src/type/sampler_type_test.cc | 10 ++++ src/type/storage_texture_type.cc | 6 ++ src/type/storage_texture_type.h | 5 ++ src/type/storage_texture_type_test.cc | 9 +++ src/type/struct_type.cc | 4 ++ src/type/struct_type.h | 5 ++ src/type/struct_type_test.cc | 7 +++ src/type/type.h | 6 ++ src/type/u32_type.cc | 4 ++ src/type/u32_type.h | 5 ++ src/type/u32_type_test.cc | 5 ++ src/type/vector_type.cc | 6 ++ src/type/vector_type.h | 5 ++ src/type/vector_type_test.cc | 5 ++ src/type/void_type.cc | 4 ++ src/type/void_type.h | 5 ++ 52 files changed, 321 insertions(+), 64 deletions(-) diff --git a/src/intrinsic_table.cc b/src/intrinsic_table.cc index 35983728d7..0c99427daa 100644 --- a/src/intrinsic_table.cc +++ b/src/intrinsic_table.cc @@ -1240,69 +1240,6 @@ std::string Impl::Overload::str() const { } 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()) { - return "f32"; - } - if (ty->Is()) { - return "u32"; - } - if (ty->Is()) { - return "i32"; - } - if (ty->Is()) { - return "bool"; - } - if (ty->Is()) { - return "void"; - } - if (auto* ptr = ty->As()) { - return "ptr<" + TypeName(ptr->type()) + ">"; - } - if (auto* vec = ty->As()) { - return "vec" + std::to_string(vec->size()) + "<" + TypeName(vec->type()) + - ">"; - } - if (auto* mat = ty->As()) { - return "mat" + std::to_string(mat->columns()) + "x" + - std::to_string(mat->rows()) + "<" + TypeName(mat->type()) + ">"; - } - if (auto* tex = ty->As()) { - std::stringstream ss; - ss << "texture_" << tex->dim() << "<" << TypeName(tex->type()) << ">"; - return ss.str(); - } - if (auto* tex = ty->As()) { - std::stringstream ss; - ss << "texture_multisampled_" << tex->dim() << "<" << TypeName(tex->type()) - << ">"; - return ss.str(); - } - if (auto* tex = ty->As()) { - std::stringstream ss; - ss << "texture_depth_" << tex->dim(); - return ss.str(); - } - if (auto* tex = ty->As()) { - std::stringstream ss; - ss << "texture_storage_" << tex->dim() << "<" << tex->image_format() << ">"; - return ss.str(); - } - if (auto* sampler = ty->As()) { - 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 @@ IntrinsicTable::Result Impl::Lookup( 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 9125cc8d75..4d96e896bb 100644 --- a/src/type/access_control_type.cc +++ b/src/type/access_control_type.cc @@ -50,6 +50,24 @@ std::string AccessControl::type_name() const { 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 3e0da4816c..7dce8bd1e6 100644 --- a/src/type/access_control_type.h +++ b/src/type/access_control_type.h @@ -49,6 +49,11 @@ class AccessControl : public Castable { /// @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 893eb8b8d3..d398fcae60 100644 --- a/src/type/access_control_type_test.cc +++ b/src/type/access_control_type_test.cc @@ -97,6 +97,21 @@ TEST_F(AccessControlTest, AccessReadWrite) { 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 cd89bdaee7..95fffe24e3 100644 --- a/src/type/alias_type.cc +++ b/src/type/alias_type.cc @@ -37,6 +37,10 @@ std::string Alias::type_name() const { 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 c1f858d97f..57e44d99bd 100644 --- a/src/type/alias_type.h +++ b/src/type/alias_type.h @@ -43,6 +43,11 @@ class Alias : public Castable { /// @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 a404918049..d39b2014f7 100644 --- a/src/type/alias_type_test.cc +++ b/src/type/alias_type_test.cc @@ -69,6 +69,11 @@ TEST_F(AliasTest, TypeName) { 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 ce90ad4ba3..549b88fb18 100644 --- a/src/type/array_type.cc +++ b/src/type/array_type.cc @@ -95,6 +95,19 @@ std::string Array::type_name() const { 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(ctx->Clone(subtype_), size_, ctx->Clone(decorations())); diff --git a/src/type/array_type.h b/src/type/array_type.h index 404fa3b376..1fccc27e50 100644 --- a/src/type/array_type.h +++ b/src/type/array_type.h @@ -69,6 +69,11 @@ class Array : public Castable { /// @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 54bc12ad70..85c0655bd8 100644 --- a/src/type/array_type_test.cc +++ b/src/type/array_type_test.cc @@ -80,6 +80,22 @@ TEST_F(ArrayTest, TypeName) { EXPECT_EQ(arr.type_name(), "__array__i32"); } +TEST_F(ArrayTest, FriendlyNameRuntimeSized) { + Array arr{ty.i32(), 0, ast::ArrayDecorationList{}}; + EXPECT_EQ(arr.FriendlyName(Symbols()), "array"); +} + +TEST_F(ArrayTest, FriendlyNameStaticSized) { + Array arr{ty.i32(), 5, ast::ArrayDecorationList{}}; + EXPECT_EQ(arr.FriendlyName(Symbols()), "array"); +} + +TEST_F(ArrayTest, FriendlyNameWithStride) { + Array arr{ty.i32(), 5, + ast::ArrayDecorationList{create(32)}}; + EXPECT_EQ(arr.FriendlyName(Symbols()), "[[stride(32)]] array"); +} + 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 5b97decc82..e548fde80b 100644 --- a/src/type/bool_type.cc +++ b/src/type/bool_type.cc @@ -32,6 +32,10 @@ std::string Bool::type_name() const { return "__bool"; } +std::string Bool::FriendlyName(const SymbolTable&) const { + return "bool"; +} + Bool* Bool::Clone(CloneContext* ctx) const { return ctx->dst->create(); } diff --git a/src/type/bool_type.h b/src/type/bool_type.h index cc35062187..97863c53ff 100644 --- a/src/type/bool_type.h +++ b/src/type/bool_type.h @@ -40,6 +40,11 @@ class Bool : public Castable { /// @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 552857b4bc..49a18f1455 100644 --- a/src/type/bool_type_test.cc +++ b/src/type/bool_type_test.cc @@ -55,6 +55,11 @@ TEST_F(BoolTest, TypeName) { 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 c3cb32e88c..57f4b21b72 100644 --- a/src/type/depth_texture_type.cc +++ b/src/type/depth_texture_type.cc @@ -51,6 +51,12 @@ std::string DepthTexture::type_name() const { 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(dim()); } diff --git a/src/type/depth_texture_type.h b/src/type/depth_texture_type.h index 43eed57189..2cff86ce62 100644 --- a/src/type/depth_texture_type.h +++ b/src/type/depth_texture_type.h @@ -35,6 +35,11 @@ class DepthTexture : public Castable { /// @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 26be3e9add..730393011b 100644 --- a/src/type/depth_texture_type_test.cc +++ b/src/type/depth_texture_type_test.cc @@ -71,6 +71,11 @@ TEST_F(DepthTextureTest, TypeName) { 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 976a5497ec..e9b341a998 100644 --- a/src/type/f32_type.cc +++ b/src/type/f32_type.cc @@ -32,6 +32,10 @@ std::string F32::type_name() const { 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 55e4224230..50e990d179 100644 --- a/src/type/f32_type.h +++ b/src/type/f32_type.h @@ -34,6 +34,11 @@ class F32 : public Castable { /// @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 7a25dc7576..92fca648c5 100644 --- a/src/type/f32_type_test.cc +++ b/src/type/f32_type_test.cc @@ -55,6 +55,11 @@ TEST_F(F32Test, TypeName) { 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 ded193288b..d3f72eced5 100644 --- a/src/type/i32_type.cc +++ b/src/type/i32_type.cc @@ -32,6 +32,10 @@ std::string I32::type_name() const { 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 cb4421f8ff..e688a0c8f0 100644 --- a/src/type/i32_type.h +++ b/src/type/i32_type.h @@ -34,6 +34,11 @@ class I32 : public Castable { /// @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 0fa098a989..60df02f74a 100644 --- a/src/type/i32_type_test.cc +++ b/src/type/i32_type_test.cc @@ -55,6 +55,11 @@ TEST_F(I32Test, TypeName) { 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 f32b39682f..c678f4ef1c 100644 --- a/src/type/matrix_type.cc +++ b/src/type/matrix_type.cc @@ -43,6 +43,13 @@ std::string Matrix::type_name() const { 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 d37a115b38..f76d578985 100644 --- a/src/type/matrix_type.h +++ b/src/type/matrix_type.h @@ -44,6 +44,11 @@ class Matrix : public Castable { /// @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 c1b6c43628..e7b6227735 100644 --- a/src/type/matrix_type_test.cc +++ b/src/type/matrix_type_test.cc @@ -65,6 +65,11 @@ TEST_F(MatrixTest, TypeName) { 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"); +} + 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 e9d415dcc1..f647016aea 100644 --- a/src/type/multisampled_texture_type.cc +++ b/src/type/multisampled_texture_type.cc @@ -40,6 +40,14 @@ std::string MultisampledTexture::type_name() const { 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(dim(), ctx->Clone(type_)); } diff --git a/src/type/multisampled_texture_type.h b/src/type/multisampled_texture_type.h index afe7d6ba4a..78c40737d8 100644 --- a/src/type/multisampled_texture_type.h +++ b/src/type/multisampled_texture_type.h @@ -39,6 +39,11 @@ class MultisampledTexture : public Castable { /// @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 788d7df887..d4ac2ee727 100644 --- a/src/type/multisampled_texture_type_test.cc +++ b/src/type/multisampled_texture_type_test.cc @@ -82,6 +82,11 @@ TEST_F(MultisampledTextureTest, TypeName) { 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"); +} + 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 8ac4a94bcc..ec564ece69 100644 --- a/src/type/pointer_type.cc +++ b/src/type/pointer_type.cc @@ -31,6 +31,16 @@ std::string Pointer::type_name() const { 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 bf64785796..9df8e73bb2 100644 --- a/src/type/pointer_type.h +++ b/src/type/pointer_type.h @@ -43,6 +43,11 @@ class Pointer : public Castable { /// @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 7b6c6a87a5..dd48053e22 100644 --- a/src/type/pointer_type_test.cc +++ b/src/type/pointer_type_test.cc @@ -64,6 +64,16 @@ TEST_F(PointerTest, TypeName) { 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"); +} + +TEST_F(PointerTest, FriendlyNameWithoutStorageClass) { + Pointer p{ty.i32(), ast::StorageClass::kNone}; + EXPECT_EQ(p.FriendlyName(Symbols()), "ptr"); +} + } // namespace } // namespace type } // namespace tint diff --git a/src/type/sampled_texture_type.cc b/src/type/sampled_texture_type.cc index a63577ba97..bd4fb5cefd 100644 --- a/src/type/sampled_texture_type.cc +++ b/src/type/sampled_texture_type.cc @@ -40,6 +40,12 @@ std::string SampledTexture::type_name() const { 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(dim(), ctx->Clone(type_)); } diff --git a/src/type/sampled_texture_type.h b/src/type/sampled_texture_type.h index 32110506ca..fc03f72d54 100644 --- a/src/type/sampled_texture_type.h +++ b/src/type/sampled_texture_type.h @@ -39,6 +39,11 @@ class SampledTexture : public Castable { /// @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 a80312f7ba..7eee0faaaf 100644 --- a/src/type/sampled_texture_type_test.cc +++ b/src/type/sampled_texture_type_test.cc @@ -80,6 +80,11 @@ TEST_F(SampledTextureTest, TypeName) { 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"); +} + 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 bff290be8f..01579ca897 100644 --- a/src/type/sampler_type.cc +++ b/src/type/sampler_type.cc @@ -45,6 +45,10 @@ std::string Sampler::type_name() const { (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(kind_); } diff --git a/src/type/sampler_type.h b/src/type/sampler_type.h index 8c71128852..486446be51 100644 --- a/src/type/sampler_type.h +++ b/src/type/sampler_type.h @@ -51,6 +51,11 @@ class Sampler : public Castable { /// @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 2648300349..2b3184b681 100644 --- a/src/type/sampler_type_test.cc +++ b/src/type/sampler_type_test.cc @@ -72,6 +72,16 @@ TEST_F(SamplerTest, TypeName_Comparison) { 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 91be1ad780..14f86aaa68 100644 --- a/src/type/storage_texture_type.cc +++ b/src/type/storage_texture_type.cc @@ -156,6 +156,12 @@ std::string StorageTexture::type_name() const { 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(dim(), image_format_, ctx->Clone(subtype_)); diff --git a/src/type/storage_texture_type.h b/src/type/storage_texture_type.h index cff03e26c3..7342c57c72 100644 --- a/src/type/storage_texture_type.h +++ b/src/type/storage_texture_type.h @@ -87,6 +87,11 @@ class StorageTexture : public Castable { /// @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 95c498a04d..bbacb47298 100644 --- a/src/type/storage_texture_type_test.cc +++ b/src/type/storage_texture_type_test.cc @@ -94,6 +94,15 @@ TEST_F(StorageTextureTest, TypeName) { EXPECT_EQ(s->type_name(), "__storage_texture_2d_array_rgba32float"); } +TEST_F(StorageTextureTest, FriendlyName) { + auto* subtype = + StorageTexture::SubtypeFor(ImageFormat::kRgba32Float, Types()); + auto* s = create(TextureDimension::k2dArray, + ImageFormat::kRgba32Float, subtype); + EXPECT_EQ(s->FriendlyName(Symbols()), + "texture_storage_2d_array"); +} + 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 39efc95739..05ba4c74fb 100644 --- a/src/type/struct_type.cc +++ b/src/type/struct_type.cc @@ -40,6 +40,10 @@ std::string Struct::type_name() const { 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 63fcaa2721..eb0c37dfe8 100644 --- a/src/type/struct_type.h +++ b/src/type/struct_type.h @@ -48,6 +48,11 @@ class Struct : public Castable { /// @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 e1e7fa03bf..44195873f4 100644 --- a/src/type/struct_type_test.cc +++ b/src/type/struct_type_test.cc @@ -73,6 +73,13 @@ TEST_F(StructTypeTest, TypeName) { EXPECT_EQ(s->type_name(), "__struct_tint_symbol_1"); } +TEST_F(StructTypeTest, FriendlyName) { + auto* impl = + create(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::StructMemberList{Member("foo", ty.u32(), {MemberOffset(0)}), diff --git a/src/type/type.h b/src/type/type.h index 2834e7bfc1..7c747c919b 100644 --- a/src/type/type.h +++ b/src/type/type.h @@ -24,6 +24,7 @@ namespace tint { // Forward declarations class ProgramBuilder; +class SymbolTable; namespace type { @@ -45,6 +46,11 @@ class Type : public Castable { /// @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 0736b05cd7..b97fde6d96 100644 --- a/src/type/u32_type.cc +++ b/src/type/u32_type.cc @@ -32,6 +32,10 @@ std::string U32::type_name() const { 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 77d1eda9af..7e92a3a400 100644 --- a/src/type/u32_type.h +++ b/src/type/u32_type.h @@ -34,6 +34,11 @@ class U32 : public Castable { /// @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 e0390ce785..b9de713e23 100644 --- a/src/type/u32_type_test.cc +++ b/src/type/u32_type_test.cc @@ -56,6 +56,11 @@ TEST_F(U32Test, TypeName) { 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 96e3b164ae..84cdf2499e 100644 --- a/src/type/vector_type.cc +++ b/src/type/vector_type.cc @@ -38,6 +38,12 @@ std::string Vector::type_name() const { 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 e9f1af5113..88e41f2fff 100644 --- a/src/type/vector_type.h +++ b/src/type/vector_type.h @@ -41,6 +41,11 @@ class Vector : public Castable { /// @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 20656d763b..51dfa4bb48 100644 --- a/src/type/vector_type_test.cc +++ b/src/type/vector_type_test.cc @@ -64,6 +64,11 @@ TEST_F(VectorTest, TypeName) { EXPECT_EQ(v.type_name(), "__vec_3__i32"); } +TEST_F(VectorTest, FriendlyName) { + auto* v = ty.vec3(); + EXPECT_EQ(v->FriendlyName(Symbols()), "vec3"); +} + 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 fe2a1a6999..342c5ecf0a 100644 --- a/src/type/void_type.cc +++ b/src/type/void_type.cc @@ -32,6 +32,10 @@ std::string Void::type_name() const { return "__void"; } +std::string Void::FriendlyName(const SymbolTable&) const { + return "void"; +} + Void* Void::Clone(CloneContext* ctx) const { return ctx->dst->create(); } diff --git a/src/type/void_type.h b/src/type/void_type.h index 1207808cfb..406b36b19d 100644 --- a/src/type/void_type.h +++ b/src/type/void_type.h @@ -34,6 +34,11 @@ class Void : public Castable { /// @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