// Copyright 2019 The Dawn Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "dawn_native/ErrorScope.h" #include "common/Assert.h" namespace dawn::native { namespace { wgpu::ErrorType ErrorFilterToErrorType(wgpu::ErrorFilter filter) { switch (filter) { case wgpu::ErrorFilter::Validation: return wgpu::ErrorType::Validation; case wgpu::ErrorFilter::OutOfMemory: return wgpu::ErrorType::OutOfMemory; } UNREACHABLE(); } } // namespace ErrorScope::ErrorScope(wgpu::ErrorFilter errorFilter) : mMatchedErrorType(ErrorFilterToErrorType(errorFilter)) { } wgpu::ErrorType ErrorScope::GetErrorType() const { return mCapturedError; } const char* ErrorScope::GetErrorMessage() const { return mErrorMessage.c_str(); } void ErrorScopeStack::Push(wgpu::ErrorFilter filter) { mScopes.push_back(ErrorScope(filter)); } ErrorScope ErrorScopeStack::Pop() { ASSERT(!mScopes.empty()); ErrorScope scope = std::move(mScopes.back()); mScopes.pop_back(); return scope; } bool ErrorScopeStack::Empty() const { return mScopes.empty(); } bool ErrorScopeStack::HandleError(wgpu::ErrorType type, const char* message) { for (auto it = mScopes.rbegin(); it != mScopes.rend(); ++it) { if (it->mMatchedErrorType != type) { // Error filter does not match. Move on to the next scope. continue; } // Filter matches. // Record the error if the scope doesn't have one yet. if (it->mCapturedError == wgpu::ErrorType::NoError) { it->mCapturedError = type; it->mErrorMessage = message; } if (type == wgpu::ErrorType::DeviceLost) { if (it->mCapturedError != wgpu::ErrorType::DeviceLost) { // DeviceLost overrides any other error that is not a DeviceLost. it->mCapturedError = type; it->mErrorMessage = message; } } else { // Errors that are not device lost are captured and stop propogating. return true; } } // The error was not captured. return false; } } // namespace dawn::native