Report error immediately if pass ends twice
The previous code reports error till command encoder finish.
This change also updates webgpu-cts expectations.txt accordingly.
Bug: dawn:1578
Change-Id: I1fe758a02d9cfdb1440e3cabf10aea0bd60b9c59
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/116842
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Yunchao He <yunchao.he@intel.com>
diff --git a/src/dawn/native/ComputePassEncoder.cpp b/src/dawn/native/ComputePassEncoder.cpp
index 0480753..d3c6a5c 100644
--- a/src/dawn/native/ComputePassEncoder.cpp
+++ b/src/dawn/native/ComputePassEncoder.cpp
@@ -150,6 +150,13 @@
}
void ComputePassEncoder::APIEnd() {
+ if (mEnded && IsValidationEnabled()) {
+ GetDevice()->ConsumedError(DAWN_VALIDATION_ERROR("%s was already ended.", this));
+ return;
+ }
+
+ mEnded = true;
+
if (mEncodingContext->TryEncode(
this,
[&](CommandAllocator* allocator) -> MaybeError {
diff --git a/src/dawn/native/EncodingContext.h b/src/dawn/native/EncodingContext.h
index 3614a09..4a44eec 100644
--- a/src/dawn/native/EncodingContext.h
+++ b/src/dawn/native/EncodingContext.h
@@ -86,11 +86,11 @@
if (DAWN_UNLIKELY(encoder != mCurrentEncoder)) {
if (mCurrentEncoder != mTopLevelEncoder) {
// The top level encoder was used when a pass encoder was current.
- HandleError(DAWN_VALIDATION_ERROR("Command cannot be recorded while %s is active.",
- mCurrentEncoder));
+ HandleError(DAWN_VALIDATION_ERROR(
+ "Command cannot be recorded while %s is locked and %s is currently open.",
+ mTopLevelEncoder, mCurrentEncoder));
} else {
- HandleError(
- DAWN_VALIDATION_ERROR("Recording in an error or already ended %s.", encoder));
+ HandleError(DAWN_VALIDATION_ERROR("Recording in an error %s.", encoder));
}
return false;
}
diff --git a/src/dawn/native/ProgrammableEncoder.h b/src/dawn/native/ProgrammableEncoder.h
index 0aa53d1..25b730f 100644
--- a/src/dawn/native/ProgrammableEncoder.h
+++ b/src/dawn/native/ProgrammableEncoder.h
@@ -59,6 +59,8 @@
uint64_t mDebugGroupStackSize = 0;
+ bool mEnded = false;
+
private:
const bool mValidationEnabled;
};
diff --git a/src/dawn/native/RenderPassEncoder.cpp b/src/dawn/native/RenderPassEncoder.cpp
index cc3de8d..3b5a062 100644
--- a/src/dawn/native/RenderPassEncoder.cpp
+++ b/src/dawn/native/RenderPassEncoder.cpp
@@ -136,6 +136,13 @@
}
void RenderPassEncoder::APIEnd() {
+ if (mEnded && IsValidationEnabled()) {
+ GetDevice()->ConsumedError(DAWN_VALIDATION_ERROR("%s was already ended.", this));
+ return;
+ }
+
+ mEnded = true;
+
mEncodingContext->TryEncode(
this,
[&](CommandAllocator* allocator) -> MaybeError {
diff --git a/src/dawn/tests/unittests/validation/CommandBufferValidationTests.cpp b/src/dawn/tests/unittests/validation/CommandBufferValidationTests.cpp
index dc45bc0..cc8ca34 100644
--- a/src/dawn/tests/unittests/validation/CommandBufferValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/CommandBufferValidationTests.cpp
@@ -58,8 +58,7 @@
ASSERT_DEVICE_ERROR(
encoder.Finish(),
HasSubstr("Command buffer recording ended before [RenderPassEncoder] was ended."));
- ASSERT_DEVICE_ERROR(
- pass.End(), HasSubstr("Recording in an error or already ended [RenderPassEncoder]."));
+ ASSERT_DEVICE_ERROR(pass.End(), HasSubstr("Recording in an error [RenderPassEncoder]."));
}
}
@@ -90,8 +89,7 @@
ASSERT_DEVICE_ERROR(
encoder.Finish(),
HasSubstr("Command buffer recording ended before [ComputePassEncoder] was ended."));
- ASSERT_DEVICE_ERROR(
- pass.End(), HasSubstr("Recording in an error or already ended [ComputePassEncoder]."));
+ ASSERT_DEVICE_ERROR(pass.End(), HasSubstr("Recording in an error [ComputePassEncoder]."));
}
}
@@ -112,10 +110,8 @@
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&placeholderRenderPass);
pass.End();
- pass.End();
- ASSERT_DEVICE_ERROR(
- encoder.Finish(),
- HasSubstr("Recording in an error or already ended [RenderPassEncoder]."));
+ ASSERT_DEVICE_ERROR(pass.End(), HasSubstr("[RenderPassEncoder] was already ended."));
+ encoder.Finish();
}
}
@@ -134,10 +130,35 @@
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
pass.End();
- pass.End();
- ASSERT_DEVICE_ERROR(
- encoder.Finish(),
- HasSubstr("Recording in an error or already ended [ComputePassEncoder]."));
+ ASSERT_DEVICE_ERROR(pass.End(), HasSubstr("[ComputePassEncoder] was already ended."));
+ encoder.Finish();
+ }
+}
+
+// Test that a pass cannot be ended again in another pass
+TEST_F(CommandBufferValidationTest, PassEndedAgainMidAnotherPass) {
+ // Error case, render pass ended again in another render pass
+ {
+ PlaceholderRenderPass placeholderRenderPass(device);
+
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ wgpu::RenderPassEncoder pass0 = encoder.BeginRenderPass(&placeholderRenderPass);
+ pass0.End();
+ wgpu::RenderPassEncoder pass1 = encoder.BeginRenderPass(&placeholderRenderPass);
+ ASSERT_DEVICE_ERROR(pass0.End(), HasSubstr("[RenderPassEncoder] was already ended."));
+ pass1.End();
+ encoder.Finish();
+ }
+
+ // Error case, compute pass ended again in another compute pass
+ {
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ wgpu::ComputePassEncoder pass0 = encoder.BeginComputePass();
+ pass0.End();
+ wgpu::ComputePassEncoder pass1 = encoder.BeginComputePass();
+ ASSERT_DEVICE_ERROR(pass0.End(), HasSubstr("[ComputePassEncoder] was already ended."));
+ pass1.End();
+ encoder.Finish();
}
}
diff --git a/webgpu-cts/expectations.txt b/webgpu-cts/expectations.txt
index c383204..1f33c92 100644
--- a/webgpu-cts/expectations.txt
+++ b/webgpu-cts/expectations.txt
@@ -406,7 +406,7 @@
crbug.com/dawn/0000 webgpu:api,validation,buffer,mapping:mapAsync,state,mappingPending: [ Failure ]
crbug.com/dawn/0000 webgpu:api,validation,createBindGroupLayout:multisampled_validation:viewDimension="2d" [ Failure ]
crbug.com/dawn/0000 webgpu:api,validation,createBindGroupLayout:multisampled_validation:viewDimension="_undef_" [ Failure ]
-crbug.com/dawn/0000 webgpu:api,validation,encoding,encoder_state:pass_end_twice: [ Failure ]
+crbug.com/dawn/0000 webgpu:api,validation,encoding,encoder_state:pass_end_invalid_order:* [ Failure ]
crbug.com/dawn/0000 [ nvidia-0x2184 target-cpu-64 ubuntu ] webgpu:shader,execution,expression,binary,i32_arithmetic:remainder:inputSource="storage_r";vectorize="_undef_" [ Failure ]
crbug.com/dawn/0000 [ nvidia-0x2184 target-cpu-64 ubuntu ] webgpu:shader,execution,expression,binary,i32_arithmetic:remainder:inputSource="storage_r";vectorize=2 [ Failure ]
crbug.com/dawn/0000 [ nvidia-0x2184 target-cpu-64 ubuntu ] webgpu:shader,execution,expression,binary,i32_arithmetic:remainder:inputSource="storage_r";vectorize=3 [ Failure ]