Validate EndPass isn't called more than once.

BUG=chromium:918254

Change-Id: I24db2f459bae7c0644a54472e56159ff8f5ab955
Reviewed-on: https://dawn-review.googlesource.com/c/3621
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Yunchao He <yunchao.he@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_native/ProgrammablePassEncoder.cpp b/src/dawn_native/ProgrammablePassEncoder.cpp
index 355e9f3..fdfcf42 100644
--- a/src/dawn_native/ProgrammablePassEncoder.cpp
+++ b/src/dawn_native/ProgrammablePassEncoder.cpp
@@ -29,6 +29,10 @@
     }
 
     void ProgrammablePassEncoder::EndPass() {
+        if (mTopLevelBuilder->ConsumedError(ValidateCanRecordCommands())) {
+            return;
+        }
+
         mTopLevelBuilder->PassEnded();
         mAllocator = nullptr;
     }
diff --git a/src/tests/unittests/validation/CommandBufferValidationTests.cpp b/src/tests/unittests/validation/CommandBufferValidationTests.cpp
index a5c1634..339bfbe 100644
--- a/src/tests/unittests/validation/CommandBufferValidationTests.cpp
+++ b/src/tests/unittests/validation/CommandBufferValidationTests.cpp
@@ -85,6 +85,52 @@
     }
 }
 
+// Test that a render pass cannot be ended twice
+TEST_F(CommandBufferValidationTest, RenderPassEndedTwice) {
+    dawn::RenderPassDescriptor renderpass = CreateSimpleRenderPass();
+
+    // Control case, pass is ended once
+    {
+        dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder());
+        dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpass);
+        pass.EndPass();
+        builder.GetResult();
+    }
+
+    // Error case, pass ended twice
+    {
+        dawn::CommandBufferBuilder builder = AssertWillBeError(device.CreateCommandBufferBuilder());
+        dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpass);
+        pass.EndPass();
+        // TODO(cwallez@chromium.org) this should probably be a device error, but currently it
+        // produces a builder error.
+        pass.EndPass();
+        builder.GetResult();
+    }
+}
+
+// Test that a compute pass cannot be ended twice
+TEST_F(CommandBufferValidationTest, ComputePassEndedTwice) {
+    // Control case, pass is ended once.
+    {
+        dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder());
+        dawn::ComputePassEncoder pass = builder.BeginComputePass();
+        pass.EndPass();
+        builder.GetResult();
+    }
+
+    // Error case, pass ended twice
+    {
+        dawn::CommandBufferBuilder builder = AssertWillBeError(device.CreateCommandBufferBuilder());
+        dawn::ComputePassEncoder pass = builder.BeginComputePass();
+        pass.EndPass();
+        // TODO(cwallez@chromium.org) this should probably be a device error, but currently it
+        // produces a builder error.
+        pass.EndPass();
+        builder.GetResult();
+    }
+}
+
 // Test that using a single buffer in multiple read usages in the same pass is allowed.
 TEST_F(CommandBufferValidationTest, BufferWithMultipleReadUsage) {
     // Create a buffer used as both vertex and index buffer.