dawn::native: Check that ExternalTexture bindings are ExternalTextures

The code was checking the equivalence in one direction but not the
other, leading to a case where passing a TextureView instead of an
ExternalTexture passed validation and lead to crashes in the backends.

Bug: chromium:1343099
Change-Id: I428252796df375e7cf3a6df1a03192d65364e370
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/95944
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Shrek Shao <shrekshao@google.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/dawn/native/BindGroup.cpp b/src/dawn/native/BindGroup.cpp
index 802213c..0d3af77 100644
--- a/src/dawn/native/BindGroup.cpp
+++ b/src/dawn/native/BindGroup.cpp
@@ -301,6 +301,12 @@
                 device, entry, externalTextureBindingEntry,
                 descriptor->layout->GetExternalTextureBindingExpansionMap()));
             continue;
+        } else {
+            DAWN_INVALID_IF(descriptor->layout->GetExternalTextureBindingExpansionMap().count(
+                                BindingNumber(entry.binding)),
+                            "entries[%u] is not an ExternalTexture when the layout contains an "
+                            "ExternalTexture entry.",
+                            i);
         }
 
         const BindingInfo& bindingInfo = descriptor->layout->GetBindingInfo(bindingIndex);
diff --git a/src/dawn/tests/unittests/validation/ExternalTextureTests.cpp b/src/dawn/tests/unittests/validation/ExternalTextureTests.cpp
index 246ce5b..6f6aebc 100644
--- a/src/dawn/tests/unittests/validation/ExternalTextureTests.cpp
+++ b/src/dawn/tests/unittests/validation/ExternalTextureTests.cpp
@@ -541,6 +541,22 @@
     }
 }
 
+// Regression test for crbug.com/1343099 where BindGroup validation let other binding types be used
+// for external texture bindings.
+TEST_F(ExternalTextureTest, TextureViewBindingDoesntMatch) {
+    wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
+        device, {{0, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout}});
+
+    wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
+    wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
+
+    // The bug was that this passed validation and crashed inside the backends with a null
+    // dereference. It passed validation because the number of bindings matched (1 == 1) and that
+    // the validation didn't check that an external texture binding was required, fell back to
+    // checking for the binding type of entry 0 that had been decayed to be a sampled texture view.
+    ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, bgl, {{0, texture.CreateView()}}));
+}
+
 // Ensure that bind group validation catches error external textures.
 TEST_F(ExternalTextureTest, UseErrorExternalTextureInBindGroup) {
     // Control case should succeed.