[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;