[ir][spirv-writer] De-dup depth texture types

Depth textures are always emitted as sampled textures, so we need to
de-dup them. Use a helper function for this and also use it for the
sampler de-duping.

Bug: tint:1906
Change-Id: Ifa64b7ba76062952ae66705c585698cc8d0ebd47
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/141229
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/writer/spirv/ir/generator_impl_ir.cc b/src/tint/writer/spirv/ir/generator_impl_ir.cc
index 63e7980..024aa59 100644
--- a/src/tint/writer/spirv/ir/generator_impl_ir.cc
+++ b/src/tint/writer/spirv/ir/generator_impl_ir.cc
@@ -127,6 +127,29 @@
     }
 }
 
+const type::Type* DedupType(const type::Type* ty, type::Manager& types) {
+    return Switch(
+        ty,
+
+        // Depth textures are always declared as sampled textures.
+        [&](const type::DepthTexture* depth) {
+            return types.Get<type::SampledTexture>(depth->dim(), types.f32());
+        },
+        [&](const type::DepthMultisampledTexture* depth) {
+            return types.Get<type::MultisampledTexture>(depth->dim(), types.f32());
+        },
+
+        // Both sampler types are the same in SPIR-V.
+        [&](const type::Sampler* s) -> const type::Type* {
+            if (s->IsComparison()) {
+                return types.Get<type::Sampler>(type::SamplerKind::kSampler);
+            }
+            return s;
+        },
+
+        [&](Default) { return ty; });
+}
+
 }  // namespace
 
 GeneratorImplIr::GeneratorImplIr(ir::Module* module, bool zero_init_workgroup_mem)
@@ -303,7 +326,7 @@
 
 uint32_t GeneratorImplIr::Type(const type::Type* ty,
                                builtin::AddressSpace addrspace /* = kUndefined */) {
-    return types_.GetOrCreate(ty, [&] {
+    return types_.GetOrCreate(DedupType(ty, ir_->Types()), [&] {
         auto id = module_.NextId();
         Switch(
             ty,  //
@@ -351,17 +374,7 @@
             },
             [&](const type::Struct* str) { EmitStructType(id, str, addrspace); },
             [&](const type::Texture* tex) { EmitTextureType(id, tex); },
-            [&](const type::Sampler* s) {
-                module_.PushType(spv::Op::OpTypeSampler, {id});
-
-                // Register both of the sampler types, as they're the same in SPIR-V.
-                if (s->kind() == type::SamplerKind::kSampler) {
-                    types_.Add(
-                        ir_->Types().Get<type::Sampler>(type::SamplerKind::kComparisonSampler), id);
-                } else {
-                    types_.Add(ir_->Types().Get<type::Sampler>(type::SamplerKind::kSampler), id);
-                }
-            },
+            [&](const type::Sampler*) { module_.PushType(spv::Op::OpTypeSampler, {id}); },
             [&](Default) {
                 TINT_ICE(Writer, diagnostics_) << "unhandled type: " << ty->FriendlyName();
             });
diff --git a/src/tint/writer/spirv/ir/generator_impl_ir_type_test.cc b/src/tint/writer/spirv/ir/generator_impl_ir_type_test.cc
index 4284884..b59ad90 100644
--- a/src/tint/writer/spirv/ir/generator_impl_ir_type_test.cc
+++ b/src/tint/writer/spirv/ir/generator_impl_ir_type_test.cc
@@ -291,6 +291,18 @@
                     TextureCase{"%1 = OpTypeImage %float Cube 0 0 0 1 Unknown", Dim::kCube},
                     TextureCase{"%1 = OpTypeImage %float Cube 0 1 0 1 Unknown", Dim::kCubeArray}));
 
+TEST_F(SpvGeneratorImplTest, Type_DepthTexture_DedupWithSampledTexture) {
+    generator_.Type(ty.Get<type::SampledTexture>(Dim::k2d, ty.f32()));
+    generator_.Type(ty.Get<type::DepthTexture>(Dim::k2d));
+
+    ASSERT_TRUE(Generate()) << Error() << output_;
+    EXPECT_EQ(DumpTypes(), R"(%2 = OpTypeFloat 32
+%1 = OpTypeImage %2 2D 0 0 0 1 Unknown
+%4 = OpTypeVoid
+%5 = OpTypeFunction %4
+)");
+}
+
 TEST_F(SpvGeneratorImplTest, Type_DepthMultiSampledTexture) {
     generator_.Type(ty.Get<type::DepthMultisampledTexture>(Dim::k2d));
 
@@ -298,6 +310,18 @@
     EXPECT_INST("%1 = OpTypeImage %float 2D 0 0 1 1 Unknown");
 }
 
+TEST_F(SpvGeneratorImplTest, Type_DepthMultisampledTexture_DedupWithMultisampledTexture) {
+    generator_.Type(ty.Get<type::MultisampledTexture>(Dim::k2d, ty.f32()));
+    generator_.Type(ty.Get<type::DepthMultisampledTexture>(Dim::k2d));
+
+    ASSERT_TRUE(Generate()) << Error() << output_;
+    EXPECT_EQ(DumpTypes(), R"(%2 = OpTypeFloat 32
+%1 = OpTypeImage %2 2D 0 0 1 1 Unknown
+%4 = OpTypeVoid
+%5 = OpTypeFunction %4
+)");
+}
+
 using Format = builtin::TexelFormat;
 struct StorageTextureCase {
     std::string result;