Tint: Add support for input_attachment_index in inspector.

Bug: 341117913
Change-Id: Ie7d6bd2018abc33cf5019e7b4f418caf76b335d9
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/189841
Commit-Queue: Quyen Le <lehoangquyen@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/cmd/common/helper.cc b/src/tint/cmd/common/helper.cc
index 0fd37f8..606dd69 100644
--- a/src/tint/cmd/common/helper.cc
+++ b/src/tint/cmd/common/helper.cc
@@ -498,6 +498,8 @@
             return "DepthMultisampledTexture";
         case tint::inspector::ResourceBinding::ResourceType::kExternalTexture:
             return "ExternalTexture";
+        case tint::inspector::ResourceBinding::ResourceType::kInputAttachment:
+            return "InputAttachment";
     }
 
     return "Unknown";
diff --git a/src/tint/lang/wgsl/helpers/flatten_bindings.cc b/src/tint/lang/wgsl/helpers/flatten_bindings.cc
index b0565cb..ae136a9 100644
--- a/src/tint/lang/wgsl/helpers/flatten_bindings.cc
+++ b/src/tint/lang/wgsl/helpers/flatten_bindings.cc
@@ -73,6 +73,9 @@
                 case tint::inspector::ResourceBinding::ResourceType::kExternalTexture:
                     binding_points.emplace(src, BindingPoint{0, next_texture_idx++});
                     break;
+                case tint::inspector::ResourceBinding::ResourceType::kInputAttachment:
+                    // flattening is not supported for input attachments.
+                    TINT_UNREACHABLE();
             }
         }
     }
diff --git a/src/tint/lang/wgsl/inspector/inspector.cc b/src/tint/lang/wgsl/inspector/inspector.cc
index 9857271..8902806 100644
--- a/src/tint/lang/wgsl/inspector/inspector.cc
+++ b/src/tint/lang/wgsl/inspector/inspector.cc
@@ -42,6 +42,7 @@
 #include "src/tint/lang/core/type/f16.h"
 #include "src/tint/lang/core/type/f32.h"
 #include "src/tint/lang/core/type/i32.h"
+#include "src/tint/lang/core/type/input_attachment.h"
 #include "src/tint/lang/core/type/matrix.h"
 #include "src/tint/lang/core/type/multisampled_texture.h"
 #include "src/tint/lang/core/type/sampled_texture.h"
@@ -55,6 +56,7 @@
 #include "src/tint/lang/wgsl/ast/float_literal_expression.h"
 #include "src/tint/lang/wgsl/ast/id_attribute.h"
 #include "src/tint/lang/wgsl/ast/identifier.h"
+#include "src/tint/lang/wgsl/ast/input_attachment_index_attribute.h"
 #include "src/tint/lang/wgsl/ast/int_literal_expression.h"
 #include "src/tint/lang/wgsl/ast/interpolate_attribute.h"
 #include "src/tint/lang/wgsl/ast/location_attribute.h"
@@ -339,6 +341,7 @@
              &Inspector::GetDepthTextureResourceBindings,
              &Inspector::GetDepthMultisampledTextureResourceBindings,
              &Inspector::GetExternalTextureResourceBindings,
+             &Inspector::GetInputAttachmentResourceBindings,
          }) {
         AppendResourceBindings(&result, (this->*fn)(entry_point));
     }
@@ -504,6 +507,45 @@
                                       ResourceBinding::ResourceType::kExternalTexture);
 }
 
+std::vector<ResourceBinding> Inspector::GetInputAttachmentResourceBindings(
+    const std::string& entry_point) {
+    auto* func = FindEntryPointByName(entry_point);
+    if (!func) {
+        return {};
+    }
+
+    std::vector<ResourceBinding> result;
+    auto* func_sem = program_.Sem().Get(func);
+    for (auto& ref : func_sem->TransitivelyReferencedVariablesOfType(
+             &tint::TypeInfo::Of<core::type::InputAttachment>())) {
+        auto* var = ref.first;
+        auto binding_info = ref.second;
+
+        ResourceBinding entry;
+        entry.resource_type = ResourceBinding::ResourceType::kInputAttachment;
+        entry.bind_group = binding_info.group;
+        entry.binding = binding_info.binding;
+
+        auto* sem_var = var->As<sem::GlobalVariable>();
+        TINT_ASSERT(sem_var);
+        TINT_ASSERT(sem_var->Attributes().input_attachment_index);
+        entry.input_attachmnt_index = sem_var->Attributes().input_attachment_index.value();
+
+        auto* input_attachment_type = var->Type()->UnwrapRef()->As<core::type::InputAttachment>();
+        auto* base_type = input_attachment_type->type();
+        entry.sampled_kind = BaseTypeToSampledKind(base_type);
+
+        entry.variable_name = var->Declaration()->name->symbol.Name();
+
+        entry.dim =
+            TypeTextureDimensionToResourceBindingTextureDimension(input_attachment_type->dim());
+
+        result.push_back(entry);
+    }
+
+    return result;
+}
+
 VectorRef<SamplerTexturePair> Inspector::GetSamplerTextureUses(const std::string& entry_point) {
     auto* func = FindEntryPointByName(entry_point);
     if (!func) {
diff --git a/src/tint/lang/wgsl/inspector/inspector.h b/src/tint/lang/wgsl/inspector/inspector.h
index 736b2da..e91de8d 100644
--- a/src/tint/lang/wgsl/inspector/inspector.h
+++ b/src/tint/lang/wgsl/inspector/inspector.h
@@ -131,6 +131,13 @@
     /// @returns vector of all of the bindings for external textures.
     std::vector<ResourceBinding> GetExternalTextureResourceBindings(const std::string& entry_point);
 
+    /// Gathers all the resource bindings of the input attachment type for the given
+    /// entry point.
+    /// @param entry_point name of the entry point to get information about.
+    /// texture type.
+    /// @returns vector of all of the bindings for input attachments.
+    std::vector<ResourceBinding> GetInputAttachmentResourceBindings(const std::string& entry_point);
+
     /// @param entry_point name of the entry point to get information about.
     /// @returns vector of all of the sampler/texture sampling pairs that are used
     /// by that entry point.
diff --git a/src/tint/lang/wgsl/inspector/inspector_test.cc b/src/tint/lang/wgsl/inspector/inspector_test.cc
index 3dd5661..ca4c4cb 100644
--- a/src/tint/lang/wgsl/inspector/inspector_test.cc
+++ b/src/tint/lang/wgsl/inspector/inspector_test.cc
@@ -2075,6 +2075,66 @@
     EXPECT_EQ(3u, result[8].binding);
 }
 
+TEST_F(InspectorGetResourceBindingsTest, InputAttachment) {
+    // enable chromium_internal_input_attachments;
+    // @group(0) @binding(1) @input_attachment_index(3)
+    // var input_tex1 : input_attachment<f32>;
+    //
+    // @group(4) @binding(3) @input_attachment_index(1)
+    // var input_tex2 : input_attachment<i32>;
+    //
+    // fn f1() -> vec4f {
+    //    return inputAttachmentLoad(input_tex1);
+    // }
+    //
+    // fn f2() -> vec4i {
+    //    return inputAttachmentLoad(input_tex2);
+    // }
+
+    Enable(Source{{12, 34}}, wgsl::Extension::kChromiumInternalInputAttachments);
+
+    GlobalVar("input_tex1", ty.input_attachment(ty.Of<f32>()),
+              Vector{Group(0_u), Binding(1_u), InputAttachmentIndex(3_u)});
+    GlobalVar("input_tex2", ty.input_attachment(ty.Of<i32>()),
+              Vector{Group(4_u), Binding(3_u), InputAttachmentIndex(1_u)});
+
+    Func("f1", Empty, ty.vec4<f32>(),
+         Vector{
+             Return(Call("inputAttachmentLoad", "input_tex1")),
+         });
+    Func("f2", Empty, ty.vec4<i32>(),
+         Vector{
+             Return(Call("inputAttachmentLoad", "input_tex2")),
+         });
+
+    MakeCallerBodyFunction("main",
+                           Vector{
+                               std::string("f1"),
+                               std::string("f2"),
+                           },
+                           Vector{
+                               Stage(ast::PipelineStage::kFragment),
+                           });
+
+    Inspector& inspector = Build();
+
+    auto result = inspector.GetResourceBindings("main");
+    ASSERT_FALSE(inspector.has_error()) << inspector.error();
+    ASSERT_EQ(2u, result.size());
+
+    EXPECT_EQ(ResourceBinding::ResourceType::kInputAttachment, result[0].resource_type);
+    EXPECT_EQ(0u, result[0].bind_group);
+    EXPECT_EQ(1u, result[0].binding);
+    EXPECT_EQ(3u, result[0].input_attachmnt_index);
+    EXPECT_EQ(inspector::ResourceBinding::SampledKind::kFloat, result[0].sampled_kind);
+
+    EXPECT_EQ(ResourceBinding::ResourceType::kInputAttachment, result[1].resource_type);
+    EXPECT_EQ(4u, result[1].bind_group);
+    EXPECT_EQ(3u, result[1].binding);
+    EXPECT_EQ(1u, result[1].input_attachmnt_index);
+    EXPECT_EQ(inspector::ResourceBinding::SampledKind::kSInt, result[1].sampled_kind);
+}
+
 TEST_F(InspectorGetUniformBufferResourceBindingsTest, MissingEntryPoint) {
     Inspector& inspector = Build();
 
diff --git a/src/tint/lang/wgsl/inspector/resource_binding.h b/src/tint/lang/wgsl/inspector/resource_binding.h
index 1c1f801..a62819b 100644
--- a/src/tint/lang/wgsl/inspector/resource_binding.h
+++ b/src/tint/lang/wgsl/inspector/resource_binding.h
@@ -98,7 +98,8 @@
         kReadWriteStorageTexture,
         kDepthTexture,
         kDepthMultisampledTexture,
-        kExternalTexture
+        kExternalTexture,
+        kInputAttachment,
     };
 
     /// Type of resource that is bound.
@@ -107,6 +108,8 @@
     uint32_t bind_group;
     /// Identifier to identify this binding within the bind group
     uint32_t binding;
+    /// Input attachment index. Only available for input attachments.
+    uint32_t input_attachmnt_index;
     /// Size for this binding, in bytes, if defined.
     uint64_t size;
     /// Size for this binding without trailing structure padding, in bytes, if