Reset bind group aspect in SetBindGroup

Change-Id: Ic123578764266a913a3a9a814d5b6c01f47d4ff9
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/22860
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Idan Raiter <idanr@google.com>
diff --git a/src/dawn_native/CommandBufferStateTracker.cpp b/src/dawn_native/CommandBufferStateTracker.cpp
index 88197f3..ff99d7b 100644
--- a/src/dawn_native/CommandBufferStateTracker.cpp
+++ b/src/dawn_native/CommandBufferStateTracker.cpp
@@ -144,6 +144,7 @@
 
     void CommandBufferStateTracker::SetBindGroup(uint32_t index, BindGroupBase* bindgroup) {
         mBindgroups[index] = bindgroup;
+        mAspects.reset(VALIDATION_ASPECT_BIND_GROUPS);
     }
 
     void CommandBufferStateTracker::SetIndexBuffer() {
diff --git a/src/tests/unittests/validation/BindGroupValidationTests.cpp b/src/tests/unittests/validation/BindGroupValidationTests.cpp
index a08dfc4..571c8ee 100644
--- a/src/tests/unittests/validation/BindGroupValidationTests.cpp
+++ b/src/tests/unittests/validation/BindGroupValidationTests.cpp
@@ -883,6 +883,55 @@
     TestComputePassBindGroup(bindGroup, offsets.data(), 3, true);
 }
 
+// Setting bind group after a draw / dispatch should re-verify the layout is compatible
+TEST_F(SetBindGroupValidationTest, VerifyGroupIfChangedAfterAction) {
+    // Set up the bind group
+    wgpu::Buffer uniformBuffer = CreateBuffer(kBufferSize, wgpu::BufferUsage::Uniform);
+    wgpu::Buffer storageBuffer = CreateBuffer(kBufferSize, wgpu::BufferUsage::Storage);
+    wgpu::Buffer readonlyStorageBuffer = CreateBuffer(kBufferSize, wgpu::BufferUsage::Storage);
+    wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, mBindGroupLayout,
+                                                     {{0, uniformBuffer, 0, kBindingSize},
+                                                      {1, uniformBuffer, 0, kBindingSize},
+                                                      {2, storageBuffer, 0, kBindingSize},
+                                                      {3, readonlyStorageBuffer, 0, kBindingSize}});
+
+    std::array<uint32_t, 3> offsets = {512, 256, 0};
+
+    // Set up bind group that is incompatible
+    wgpu::BindGroupLayout invalidLayout = utils::MakeBindGroupLayout(
+        device, {{0, wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment,
+                  wgpu::BindingType::StorageBuffer}});
+    wgpu::BindGroup invalidGroup =
+        utils::MakeBindGroup(device, invalidLayout, {{0, storageBuffer, 0, kBindingSize}});
+
+    {
+        wgpu::ComputePipeline computePipeline = CreateComputePipeline();
+        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
+        wgpu::ComputePassEncoder computePassEncoder = commandEncoder.BeginComputePass();
+        computePassEncoder.SetPipeline(computePipeline);
+        computePassEncoder.SetBindGroup(0, bindGroup, 3, offsets.data());
+        computePassEncoder.Dispatch(1);
+        computePassEncoder.SetBindGroup(0, invalidGroup, 0, nullptr);
+        computePassEncoder.Dispatch(1);
+        computePassEncoder.EndPass();
+        ASSERT_DEVICE_ERROR(commandEncoder.Finish());
+    }
+    {
+        wgpu::RenderPipeline renderPipeline = CreateRenderPipeline();
+        DummyRenderPass renderPass(device);
+
+        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
+        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
+        renderPassEncoder.SetPipeline(renderPipeline);
+        renderPassEncoder.SetBindGroup(0, bindGroup, 3, offsets.data());
+        renderPassEncoder.Draw(3);
+        renderPassEncoder.SetBindGroup(0, invalidGroup, 0, nullptr);
+        renderPassEncoder.Draw(3);
+        renderPassEncoder.EndPass();
+        ASSERT_DEVICE_ERROR(commandEncoder.Finish());
+    }
+}
+
 // Test cases that test dynamic offsets count mismatch with bind group layout.
 TEST_F(SetBindGroupValidationTest, DynamicOffsetsMismatch) {
     // Set up bind group.