Validate CommmandBuffers aren't ended mid pass.
Also adds regression tests.
BUG=chromium:914566
BUG=chromium:914641
Change-Id: Ic1f9f2440580c3598831c8b2d1310e81aa944133
Reviewed-on: https://dawn-review.googlesource.com/c/3321
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_native/CommandBuffer.cpp b/src/dawn_native/CommandBuffer.cpp
index c9e6c25..97b5678 100644
--- a/src/dawn_native/CommandBuffer.cpp
+++ b/src/dawn_native/CommandBuffer.cpp
@@ -364,6 +364,10 @@
// Implementation of the command buffer validation that can be precomputed before submit
MaybeError CommandBufferBuilder::ValidateGetResult() {
+ if (mEncodingState != EncodingState::TopLevel) {
+ return DAWN_VALIDATION_ERROR("Command buffer recording ended mid-pass");
+ }
+
MoveToIterator();
mIterator.Reset();
@@ -502,6 +506,7 @@
}
}
+ UNREACHABLE();
return DAWN_VALIDATION_ERROR("Unfinished compute pass");
}
@@ -609,6 +614,7 @@
}
}
+ UNREACHABLE();
return DAWN_VALIDATION_ERROR("Unfinished render pass");
}
diff --git a/src/tests/unittests/validation/CommandBufferValidationTests.cpp b/src/tests/unittests/validation/CommandBufferValidationTests.cpp
index 8655449..017d4fc 100644
--- a/src/tests/unittests/validation/CommandBufferValidationTests.cpp
+++ b/src/tests/unittests/validation/CommandBufferValidationTests.cpp
@@ -25,10 +25,11 @@
.GetResult();
}
-// Tests for basic render pass usage
-TEST_F(CommandBufferValidationTest, RenderPass) {
- auto renderpass = CreateSimpleRenderPass();
+// Test that a command buffer cannot be ended mid render pass
+TEST_F(CommandBufferValidationTest, EndedMidRenderPass) {
+ dawn::RenderPassDescriptor renderpass = CreateSimpleRenderPass();
+ // Control case, command buffer ended after the pass is ended.
{
dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder());
dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpass);
@@ -36,11 +37,52 @@
builder.GetResult();
}
+ // Error case, command buffer ended mid-pass.
{
dawn::CommandBufferBuilder builder = AssertWillBeError(device.CreateCommandBufferBuilder());
dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpass);
builder.GetResult();
}
+
+ // Error case, command buffer ended mid-pass. Trying to use encoders after GetResult
+ // should fail too.
+ {
+ dawn::CommandBufferBuilder builder = AssertWillBeError(device.CreateCommandBufferBuilder());
+ dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpass);
+ builder.GetResult();
+ // TODO(cwallez@chromium.org) this should probably be a device error, but currently it
+ // produces a builder error.
+ pass.EndPass();
+ }
+}
+
+// Test that a command buffer cannot be ended mid compute pass
+TEST_F(CommandBufferValidationTest, EndedMidComputePass) {
+ // Control case, command buffer ended after the pass is ended.
+ {
+ dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder());
+ dawn::ComputePassEncoder pass = builder.BeginComputePass();
+ pass.EndPass();
+ builder.GetResult();
+ }
+
+ // Error case, command buffer ended mid-pass.
+ {
+ dawn::CommandBufferBuilder builder = AssertWillBeError(device.CreateCommandBufferBuilder());
+ dawn::ComputePassEncoder pass = builder.BeginComputePass();
+ builder.GetResult();
+ }
+
+ // Error case, command buffer ended mid-pass. Trying to use encoders after GetResult
+ // should fail too.
+ {
+ dawn::CommandBufferBuilder builder = AssertWillBeError(device.CreateCommandBufferBuilder());
+ dawn::ComputePassEncoder pass = builder.BeginComputePass();
+ builder.GetResult();
+ // TODO(cwallez@chromium.org) this should probably be a device error, but currently it
+ // produces a builder error.
+ pass.EndPass();
+ }
}
// Test that using a single buffer in multiple read usages in the same pass is allowed.