Improve validation errors for encoders
Improves the validation messages in ComputePassEncoder.cpp,
ProgrammablePassEncoder.cpp, RenderBundleEncoder.cpp, and
EncodingContext.cpp/h to give them more contextual information.
Bug: dawn:563
Change-Id: I3807c30fb0de8e766fbc35b98ef9c059f9d441ee
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/67603
Commit-Queue: Brandon Jones <bajones@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn_native/EncodingContext.cpp b/src/dawn_native/EncodingContext.cpp
index 2724291..9122d83 100644
--- a/src/dawn_native/EncodingContext.cpp
+++ b/src/dawn_native/EncodingContext.cpp
@@ -24,7 +24,7 @@
namespace dawn_native {
- EncodingContext::EncodingContext(DeviceBase* device, const ObjectBase* initialEncoder)
+ EncodingContext::EncodingContext(DeviceBase* device, const ApiObjectBase* initialEncoder)
: mDevice(device), mTopLevelEncoder(initialEncoder), mCurrentEncoder(initialEncoder) {
}
@@ -87,7 +87,7 @@
}
}
- void EncodingContext::EnterPass(const ObjectBase* passEncoder) {
+ void EncodingContext::EnterPass(const ApiObjectBase* passEncoder) {
// Assert we're at the top level.
ASSERT(mCurrentEncoder == mTopLevelEncoder);
ASSERT(passEncoder != nullptr);
@@ -95,7 +95,7 @@
mCurrentEncoder = passEncoder;
}
- MaybeError EncodingContext::ExitRenderPass(const ObjectBase* passEncoder,
+ MaybeError EncodingContext::ExitRenderPass(const ApiObjectBase* passEncoder,
RenderPassResourceUsageTracker usageTracker,
CommandEncoder* commandEncoder,
IndirectDrawMetadata indirectDrawMetadata) {
@@ -121,7 +121,7 @@
return {};
}
- void EncodingContext::ExitComputePass(const ObjectBase* passEncoder,
+ void EncodingContext::ExitComputePass(const ApiObjectBase* passEncoder,
ComputePassResourceUsage usages) {
ASSERT(mCurrentEncoder != mTopLevelEncoder);
ASSERT(mCurrentEncoder == passEncoder);
@@ -130,6 +130,15 @@
mComputePassUsages.push_back(std::move(usages));
}
+ void EncodingContext::EnsurePassExited(const ApiObjectBase* passEncoder) {
+ if (mCurrentEncoder != mTopLevelEncoder && mCurrentEncoder == passEncoder) {
+ // The current pass encoder is being deleted. Implicitly end the pass with an error.
+ mCurrentEncoder = mTopLevelEncoder;
+ HandleError(DAWN_FORMAT_VALIDATION_ERROR(
+ "Command buffer recording ended before %s was ended.", passEncoder));
+ }
+ }
+
const RenderPassUsages& EncodingContext::GetRenderPassUsages() const {
ASSERT(!mWereRenderPassUsagesAcquired);
return mRenderPassUsages;
@@ -161,12 +170,10 @@
}
MaybeError EncodingContext::Finish() {
- if (IsFinished()) {
- return DAWN_VALIDATION_ERROR("Command encoding already finished");
- }
+ DAWN_INVALID_IF(IsFinished(), "Command encoding already finished.");
- const void* currentEncoder = mCurrentEncoder;
- const void* topLevelEncoder = mTopLevelEncoder;
+ const ApiObjectBase* currentEncoder = mCurrentEncoder;
+ const ApiObjectBase* topLevelEncoder = mTopLevelEncoder;
// Even if finish validation fails, it is now invalid to call any encoding commands,
// so we clear the encoders. Note: mTopLevelEncoder == nullptr is used as a flag for
@@ -178,9 +185,8 @@
if (mError != nullptr) {
return std::move(mError);
}
- if (currentEncoder != topLevelEncoder) {
- return DAWN_VALIDATION_ERROR("Command buffer recording ended mid-pass");
- }
+ DAWN_INVALID_IF(currentEncoder != topLevelEncoder,
+ "Command buffer recording ended before %s was ended.", currentEncoder);
return {};
}