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>
This commit is contained in:
Corentin Wallez 2018-12-15 10:34:42 +00:00 committed by Commit Bot service account
parent e018292bed
commit 28c1fba1c0
2 changed files with 51 additions and 3 deletions

View File

@ -364,6 +364,10 @@ namespace dawn_native {
// 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 @@ namespace dawn_native {
}
}
UNREACHABLE();
return DAWN_VALIDATION_ERROR("Unfinished compute pass");
}
@ -609,6 +614,7 @@ namespace dawn_native {
}
}
UNREACHABLE();
return DAWN_VALIDATION_ERROR("Unfinished render pass");
}

View File

@ -25,10 +25,11 @@ TEST_F(CommandBufferValidationTest, Empty) {
.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 @@ TEST_F(CommandBufferValidationTest, RenderPass) {
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.