diff --git a/src/dawn/native/EncodingContext.h b/src/dawn/native/EncodingContext.h index 4a44eec591..17bfe326eb 100644 --- a/src/dawn/native/EncodingContext.h +++ b/src/dawn/native/EncodingContext.h @@ -24,6 +24,7 @@ #include "dawn/native/Error.h" #include "dawn/native/ErrorData.h" #include "dawn/native/IndirectDrawMetadata.h" +#include "dawn/native/ObjectType_autogen.h" #include "dawn/native/PassResourceUsageTracker.h" #include "dawn/native/dawn_platform.h" @@ -89,6 +90,16 @@ class EncodingContext { HandleError(DAWN_VALIDATION_ERROR( "Command cannot be recorded while %s is locked and %s is currently open.", mTopLevelEncoder, mCurrentEncoder)); + } else if (mTopLevelEncoder == nullptr) { + // Note: mTopLevelEncoder == nullptr is used as a flag for if Finish() has been + // called. + if (encoder->GetType() == ObjectType::CommandEncoder || + encoder->GetType() == ObjectType::RenderBundleEncoder) { + HandleError(DAWN_VALIDATION_ERROR("%s is already finished.", encoder)); + } else { + HandleError(DAWN_VALIDATION_ERROR("Parent encoder of %s is already finished.", + encoder)); + } } else { HandleError(DAWN_VALIDATION_ERROR("Recording in an error %s.", encoder)); } diff --git a/src/dawn/tests/unittests/validation/CommandBufferValidationTests.cpp b/src/dawn/tests/unittests/validation/CommandBufferValidationTests.cpp index cc8ca34b89..ab139ed5d6 100644 --- a/src/dawn/tests/unittests/validation/CommandBufferValidationTests.cpp +++ b/src/dawn/tests/unittests/validation/CommandBufferValidationTests.cpp @@ -58,7 +58,8 @@ TEST_F(CommandBufferValidationTest, EndedMidRenderPass) { ASSERT_DEVICE_ERROR( encoder.Finish(), HasSubstr("Command buffer recording ended before [RenderPassEncoder] was ended.")); - ASSERT_DEVICE_ERROR(pass.End(), HasSubstr("Recording in an error [RenderPassEncoder].")); + ASSERT_DEVICE_ERROR( + pass.End(), HasSubstr("Parent encoder of [RenderPassEncoder] is already finished.")); } } @@ -89,7 +90,8 @@ TEST_F(CommandBufferValidationTest, EndedMidComputePass) { ASSERT_DEVICE_ERROR( encoder.Finish(), HasSubstr("Command buffer recording ended before [ComputePassEncoder] was ended.")); - ASSERT_DEVICE_ERROR(pass.End(), HasSubstr("Recording in an error [ComputePassEncoder].")); + ASSERT_DEVICE_ERROR( + pass.End(), HasSubstr("Parent encoder of [ComputePassEncoder] is already finished.")); } } @@ -223,7 +225,8 @@ TEST_F(CommandBufferValidationTest, CallsAfterASuccessfulFinish) { wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); encoder.Finish(); - ASSERT_DEVICE_ERROR(encoder.CopyBufferToBuffer(copyBuffer, 0, copyBuffer, 0, 0)); + ASSERT_DEVICE_ERROR(encoder.CopyBufferToBuffer(copyBuffer, 0, copyBuffer, 0, 0), + HasSubstr("[CommandEncoder] is already finished.")); } // Test that encoding command after a failed finish produces an error @@ -244,7 +247,8 @@ TEST_F(CommandBufferValidationTest, CallsAfterAFailedFinish) { encoder.CopyBufferToBuffer(buffer, 0, buffer, 0, 0); ASSERT_DEVICE_ERROR(encoder.Finish()); - ASSERT_DEVICE_ERROR(encoder.CopyBufferToBuffer(copyBuffer, 0, copyBuffer, 0, 0)); + ASSERT_DEVICE_ERROR(encoder.CopyBufferToBuffer(copyBuffer, 0, copyBuffer, 0, 0), + HasSubstr("[CommandEncoder] is already finished.")); } // Test that passes which are de-referenced prior to ending still allow the correct errors to be