EncodingContext: Forward the backtrace of stored errors.

This makes error messages from command buffers more useful because they
keep the whole stack trace instead of just showing that the error was
created in the CommandBuffer::Finish call.

Bug: dawn:632
Change-Id: I23e66045c3caa1ad086003a04eed78c40aefc562
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/49885
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2021-05-05 17:37:43 +00:00 committed by Commit Bot service account
parent c8f0b6d633
commit d98b3076f5
3 changed files with 14 additions and 21 deletions

View File

@ -815,7 +815,7 @@ namespace dawn_native {
void CommandEncoder::APIInjectValidationError(const char* message) {
if (mEncodingContext.CheckCurrentEncoder(this)) {
mEncodingContext.HandleError(InternalErrorType::Validation, message);
mEncodingContext.HandleError(DAWN_VALIDATION_ERROR(message));
}
}

View File

@ -53,18 +53,17 @@ namespace dawn_native {
}
}
void EncodingContext::HandleError(InternalErrorType type, const char* message) {
void EncodingContext::HandleError(std::unique_ptr<ErrorData> error) {
if (!IsFinished()) {
// Encoding should only generate validation errors.
ASSERT(type == InternalErrorType::Validation);
ASSERT(error->GetType() == InternalErrorType::Validation);
// If the encoding context is not finished, errors are deferred until
// Finish() is called.
if (!mGotError) {
mGotError = true;
mErrorMessage = message;
if (mError == nullptr) {
mError = std::move(error);
}
} else {
mDevice->HandleError(type, message);
mDevice->HandleError(error->GetType(), error->GetMessage().c_str());
}
}
@ -129,8 +128,8 @@ namespace dawn_native {
mCurrentEncoder = nullptr;
mTopLevelEncoder = nullptr;
if (mGotError) {
return DAWN_VALIDATION_ERROR(mErrorMessage);
if (mError != nullptr) {
return std::move(mError);
}
if (currentEncoder != topLevelEncoder) {
return DAWN_VALIDATION_ERROR("Command buffer recording ended mid-pass");

View File

@ -39,15 +39,11 @@ namespace dawn_native {
CommandIterator* GetIterator();
// Functions to handle encoder errors
void HandleError(InternalErrorType type, const char* message);
inline void ConsumeError(std::unique_ptr<ErrorData> error) {
HandleError(error->GetType(), error->GetMessage().c_str());
}
void HandleError(std::unique_ptr<ErrorData> error);
inline bool ConsumedError(MaybeError maybeError) {
if (DAWN_UNLIKELY(maybeError.IsError())) {
ConsumeError(maybeError.AcquireError());
HandleError(maybeError.AcquireError());
return true;
}
return false;
@ -57,11 +53,10 @@ namespace dawn_native {
if (DAWN_UNLIKELY(encoder != mCurrentEncoder)) {
if (mCurrentEncoder != mTopLevelEncoder) {
// The top level encoder was used when a pass encoder was current.
HandleError(InternalErrorType::Validation,
"Command cannot be recorded inside a pass");
HandleError(DAWN_VALIDATION_ERROR("Command cannot be recorded inside a pass"));
} else {
HandleError(InternalErrorType::Validation,
"Recording in an error or already ended pass encoder");
HandleError(DAWN_VALIDATION_ERROR(
"Recording in an error or already ended pass encoder"));
}
return false;
}
@ -113,8 +108,7 @@ namespace dawn_native {
bool mWasMovedToIterator = false;
bool mWereCommandsAcquired = false;
bool mGotError = false;
std::string mErrorMessage;
std::unique_ptr<ErrorData> mError;
};
} // namespace dawn_native