Separate device lost from internal errors.
The effect to the user is the same, the Dawn device gets lost. However we need to make the difference internally because when the backend device is lost we can clean up immediately. On the contrary on internal errors, the backend device is still alive and processing commands so we need to gracefully shut it down. Bug: dawn:269 Change-Id: Ie13b33a4f9ac2e1f5f98b3723d83cf1c6205c988 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/17965 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
3da19b843f
commit
a0afd31585
|
@ -32,7 +32,7 @@
|
|||
{"value": 0, "name": "discrete GPU"},
|
||||
{"value": 1, "name": "integrated GPU"},
|
||||
{"value": 2, "name": "CPU"},
|
||||
{"value": 3, "name": "Unknown"}
|
||||
{"value": 3, "name": "unknown"}
|
||||
]
|
||||
},
|
||||
"address mode": {
|
||||
|
|
|
@ -20,7 +20,7 @@ template<typename T>
|
|||
MaybeError OpenGLFunctionsBase::LoadProc(GetProcAddress getProc, T* memberProc, const char* name) {
|
||||
*memberProc = reinterpret_cast<T>(getProc(name));
|
||||
if (DAWN_UNLIKELY(memberProc == nullptr)) {
|
||||
return DAWN_DEVICE_LOST_ERROR(std::string("Couldn't load GL proc: ") + name);
|
||||
return DAWN_INTERNAL_ERROR(std::string("Couldn't load GL proc: ") + name);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -109,23 +109,41 @@ namespace dawn_native {
|
|||
mLossStatus = LossStatus::AlreadyLost;
|
||||
}
|
||||
|
||||
void DeviceBase::HandleError(wgpu::ErrorType type, const char* message) {
|
||||
if (type == wgpu::ErrorType::DeviceLost) {
|
||||
void DeviceBase::HandleError(InternalErrorType type, const char* message) {
|
||||
// If we receive an internal error, assume the backend can't recover and proceed with
|
||||
// device destruction. We first wait for all previous commands to be completed so that
|
||||
// backend objects can be freed immediately, before handling the loss.
|
||||
if (type == InternalErrorType::Internal) {
|
||||
mLossStatus = LossStatus::BeingLost;
|
||||
// Assert that errors are device loss so that we can continue with destruction.
|
||||
AssertAndIgnoreDeviceLossError(WaitForIdleForDestruction());
|
||||
HandleLoss(message);
|
||||
}
|
||||
// Still forward device loss to error scope so it can reject them all
|
||||
mCurrentErrorScope->HandleError(type, message);
|
||||
|
||||
// The device was lost for real, call the loss handler because all the backend objects are
|
||||
// as if no longer in use.
|
||||
if (type == InternalErrorType::DeviceLost) {
|
||||
HandleLoss(message);
|
||||
}
|
||||
|
||||
// Still forward device loss and internal errors to the error scopes so they all reject.
|
||||
mCurrentErrorScope->HandleError(ToWGPUErrorType(type), message);
|
||||
}
|
||||
|
||||
void DeviceBase::InjectError(wgpu::ErrorType type, const char* message) {
|
||||
if (ConsumedError(ValidateErrorType(type))) {
|
||||
return;
|
||||
}
|
||||
if (DAWN_UNLIKELY(type == wgpu::ErrorType::NoError)) {
|
||||
HandleError(wgpu::ErrorType::Validation, "Invalid injected error NoError");
|
||||
|
||||
// This method should only be used to make error scope reject. For DeviceLost there is the
|
||||
// LoseForTesting function that can be used instead.
|
||||
if (type != wgpu::ErrorType::Validation && type != wgpu::ErrorType::OutOfMemory) {
|
||||
HandleError(InternalErrorType::Validation,
|
||||
"Invalid injected error, must be Validation or OutOfMemory");
|
||||
return;
|
||||
}
|
||||
HandleError(type, message);
|
||||
|
||||
HandleError(FromWGPUErrorType(type), message);
|
||||
}
|
||||
|
||||
void DeviceBase::ConsumeError(std::unique_ptr<ErrorData> error) {
|
||||
|
@ -200,10 +218,7 @@ namespace dawn_native {
|
|||
return;
|
||||
}
|
||||
|
||||
mLossStatus = LossStatus::BeingLost;
|
||||
// Assert that errors are device loss so that we can continue with destruction
|
||||
AssertAndIgnoreDeviceLossError(WaitForIdleForDestruction());
|
||||
HandleError(wgpu::ErrorType::DeviceLost, "Device lost for testing");
|
||||
HandleError(InternalErrorType::Internal, "Device lost for testing");
|
||||
}
|
||||
|
||||
bool DeviceBase::IsLost() const {
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace dawn_native {
|
|||
DeviceBase(AdapterBase* adapter, const DeviceDescriptor* descriptor);
|
||||
virtual ~DeviceBase();
|
||||
|
||||
void HandleError(wgpu::ErrorType type, const char* message);
|
||||
void HandleError(InternalErrorType type, const char* message);
|
||||
|
||||
bool ConsumedError(MaybeError maybeError) {
|
||||
if (DAWN_UNLIKELY(maybeError.IsError())) {
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace dawn_native {
|
|||
}
|
||||
}
|
||||
|
||||
void EncodingContext::HandleError(wgpu::ErrorType type, const char* message) {
|
||||
void EncodingContext::HandleError(InternalErrorType type, const char* message) {
|
||||
if (!IsFinished()) {
|
||||
// If the encoding context is not finished, errors are deferred until
|
||||
// Finish() is called.
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace dawn_native {
|
|||
CommandIterator* GetIterator();
|
||||
|
||||
// Functions to handle encoder errors
|
||||
void HandleError(wgpu::ErrorType type, const char* message);
|
||||
void HandleError(InternalErrorType type, const char* message);
|
||||
|
||||
inline void ConsumeError(std::unique_ptr<ErrorData> error) {
|
||||
HandleError(error->GetType(), error->GetMessage().c_str());
|
||||
|
@ -58,10 +58,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(wgpu::ErrorType::Validation,
|
||||
HandleError(InternalErrorType::Validation,
|
||||
"Command cannot be recorded inside a pass");
|
||||
} else {
|
||||
HandleError(wgpu::ErrorType::Validation,
|
||||
HandleError(InternalErrorType::Validation,
|
||||
"Recording in an error or already ended pass encoder");
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -18,10 +18,43 @@
|
|||
#include "dawn_native/dawn_platform.h"
|
||||
|
||||
namespace dawn_native {
|
||||
|
||||
void AssertAndIgnoreDeviceLossError(MaybeError maybeError) {
|
||||
if (maybeError.IsError()) {
|
||||
std::unique_ptr<ErrorData> errorData = maybeError.AcquireError();
|
||||
ASSERT(errorData->GetType() == wgpu::ErrorType::DeviceLost);
|
||||
ASSERT(errorData->GetType() == InternalErrorType::DeviceLost);
|
||||
}
|
||||
}
|
||||
|
||||
wgpu::ErrorType ToWGPUErrorType(InternalErrorType type) {
|
||||
switch (type) {
|
||||
case InternalErrorType::Validation:
|
||||
return wgpu::ErrorType::Validation;
|
||||
case InternalErrorType::OutOfMemory:
|
||||
return wgpu::ErrorType::OutOfMemory;
|
||||
|
||||
// There is no equivalent of Internal errors in the WebGPU API. Internal errors cause
|
||||
// the device at the API level to be lost, so treat it like a DeviceLost error.
|
||||
case InternalErrorType::Internal:
|
||||
case InternalErrorType::DeviceLost:
|
||||
return wgpu::ErrorType::DeviceLost;
|
||||
|
||||
default:
|
||||
return wgpu::ErrorType::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
InternalErrorType FromWGPUErrorType(wgpu::ErrorType type) {
|
||||
switch (type) {
|
||||
case wgpu::ErrorType::Validation:
|
||||
return InternalErrorType::Validation;
|
||||
case wgpu::ErrorType::OutOfMemory:
|
||||
return InternalErrorType::OutOfMemory;
|
||||
case wgpu::ErrorType::DeviceLost:
|
||||
return InternalErrorType::DeviceLost;
|
||||
default:
|
||||
return InternalErrorType::Internal;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dawn_native
|
||||
|
|
|
@ -22,7 +22,13 @@
|
|||
|
||||
namespace dawn_native {
|
||||
|
||||
enum class InternalErrorType : uint32_t { Validation, DeviceLost, Unimplemented, OutOfMemory };
|
||||
enum class InternalErrorType : uint32_t {
|
||||
Validation,
|
||||
DeviceLost,
|
||||
Internal,
|
||||
Unimplemented,
|
||||
OutOfMemory
|
||||
};
|
||||
|
||||
// MaybeError and ResultOrError are meant to be used as return value for function that are not
|
||||
// expected to, but might fail. The handling of error is potentially much slower than successes.
|
||||
|
@ -40,11 +46,37 @@ namespace dawn_native {
|
|||
//
|
||||
// but shorthand version for specific error types are preferred:
|
||||
// return DAWN_VALIDATION_ERROR("My error message");
|
||||
//
|
||||
// There are different types of errors that should be used for different purpose:
|
||||
//
|
||||
// - Validation: these are errors that show the user did something bad, which causes the
|
||||
// whole call to be a no-op. It's most commonly found in the frontend but there can be some
|
||||
// backend specific validation in non-conformant backends too.
|
||||
//
|
||||
// - Out of memory: creation of a Buffer or Texture failed because there isn't enough memory.
|
||||
// This is similar to validation errors in that the call becomes a no-op and returns an
|
||||
// error object, but is reported separated from validation to the user.
|
||||
//
|
||||
// - Device loss: the backend driver reported that the GPU has been lost, which means all
|
||||
// previous commands magically disappeared and the only thing left to do is clean up.
|
||||
// Note: Device loss should be used rarely and in most case you want to use Internal
|
||||
// instead.
|
||||
//
|
||||
// - Internal: something happened that the backend didn't expect, and it doesn't know
|
||||
// how to recover from that situation. This causes the device to be lost, but is separate
|
||||
// from device loss, because the GPU execution is still happening so we need to clean up
|
||||
// more gracefully.
|
||||
//
|
||||
// - Unimplemented: same as Internal except it puts "unimplemented" in the error message for
|
||||
// more clarity.
|
||||
|
||||
#define DAWN_MAKE_ERROR(TYPE, MESSAGE) \
|
||||
::dawn_native::ErrorData::Create(TYPE, MESSAGE, __FILE__, __func__, __LINE__)
|
||||
#define DAWN_VALIDATION_ERROR(MESSAGE) DAWN_MAKE_ERROR(InternalErrorType::Validation, MESSAGE)
|
||||
#define DAWN_DEVICE_LOST_ERROR(MESSAGE) DAWN_MAKE_ERROR(InternalErrorType::DeviceLost, MESSAGE)
|
||||
#define DAWN_UNIMPLEMENTED_ERROR(MESSAGE) DAWN_MAKE_ERROR(InternalErrorType::Unimplemented, MESSAGE)
|
||||
#define DAWN_INTERNAL_ERROR(MESSAGE) DAWN_MAKE_ERROR(InternalErrorType::Internal, MESSAGE)
|
||||
#define DAWN_UNIMPLEMENTED_ERROR(MESSAGE) \
|
||||
DAWN_MAKE_ERROR(InternalErrorType::Internal, std::string("Unimplemented: ") + MESSAGE)
|
||||
#define DAWN_OUT_OF_MEMORY_ERROR(MESSAGE) DAWN_MAKE_ERROR(InternalErrorType::OutOfMemory, MESSAGE)
|
||||
|
||||
#define DAWN_CONCAT1(x, y) x##y
|
||||
|
@ -84,6 +116,9 @@ namespace dawn_native {
|
|||
// Assert that errors are device loss so that we can continue with destruction
|
||||
void AssertAndIgnoreDeviceLossError(MaybeError maybeError);
|
||||
|
||||
wgpu::ErrorType ToWGPUErrorType(InternalErrorType type);
|
||||
InternalErrorType FromWGPUErrorType(wgpu::ErrorType type);
|
||||
|
||||
} // namespace dawn_native
|
||||
|
||||
#endif // DAWNNATIVE_ERROR_H_
|
||||
|
|
|
@ -42,23 +42,10 @@ namespace dawn_native {
|
|||
mBacktrace.push_back(std::move(record));
|
||||
}
|
||||
|
||||
InternalErrorType ErrorData::GetInternalType() const {
|
||||
InternalErrorType ErrorData::GetType() const {
|
||||
return mType;
|
||||
}
|
||||
|
||||
wgpu::ErrorType ErrorData::GetType() const {
|
||||
switch (mType) {
|
||||
case InternalErrorType::Validation:
|
||||
return wgpu::ErrorType::Validation;
|
||||
case InternalErrorType::OutOfMemory:
|
||||
return wgpu::ErrorType::OutOfMemory;
|
||||
case InternalErrorType::DeviceLost:
|
||||
return wgpu::ErrorType::DeviceLost;
|
||||
default:
|
||||
return wgpu::ErrorType::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& ErrorData::GetMessage() const {
|
||||
return mMessage;
|
||||
}
|
||||
|
|
|
@ -49,8 +49,7 @@ namespace dawn_native {
|
|||
};
|
||||
void AppendBacktrace(const char* file, const char* function, int line);
|
||||
|
||||
InternalErrorType GetInternalType() const;
|
||||
wgpu::ErrorType GetType() const;
|
||||
InternalErrorType GetType() const;
|
||||
const std::string& GetMessage() const;
|
||||
const std::vector<BacktraceRecord>& GetBacktrace() const;
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
const PlatformFunctions* functions = GetBackend()->GetFunctions();
|
||||
if (FAILED(functions->d3d12CreateDevice(GetHardwareAdapter(), D3D_FEATURE_LEVEL_11_0,
|
||||
_uuidof(ID3D12Device), &mD3d12Device))) {
|
||||
return DAWN_DEVICE_LOST_ERROR("D3D12CreateDevice failed");
|
||||
return DAWN_INTERNAL_ERROR("D3D12CreateDevice failed");
|
||||
}
|
||||
|
||||
DXGI_ADAPTER_DESC1 adapterDesc;
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
}
|
||||
|
||||
if (FAILED(functions->createDxgiFactory2(dxgiFactoryFlags, IID_PPV_ARGS(&factory)))) {
|
||||
return DAWN_DEVICE_LOST_ERROR("Failed to create a DXGI factory");
|
||||
return DAWN_INTERNAL_ERROR("Failed to create a DXGI factory");
|
||||
}
|
||||
|
||||
ASSERT(factory != nullptr);
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
}
|
||||
|
||||
std::string message = std::string(context) + " failed with " + std::to_string(result);
|
||||
return DAWN_DEVICE_LOST_ERROR(message);
|
||||
return DAWN_INTERNAL_ERROR(message);
|
||||
}
|
||||
|
||||
MaybeError CheckOutOfMemoryHRESULT(HRESULT result, const char* context) {
|
||||
|
@ -33,4 +33,4 @@ namespace dawn_native { namespace d3d12 {
|
|||
return CheckHRESULT(result, context);
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::d3d12
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
"D3D12SerializeVersionedRootSignature", &error) ||
|
||||
!mD3D12Lib.GetProc(&d3d12CreateVersionedRootSignatureDeserializer,
|
||||
"D3D12CreateVersionedRootSignatureDeserializer", &error)) {
|
||||
return DAWN_DEVICE_LOST_ERROR(error.c_str());
|
||||
return DAWN_INTERNAL_ERROR(error.c_str());
|
||||
}
|
||||
|
||||
return {};
|
||||
|
@ -55,7 +55,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
std::string error;
|
||||
if (!mD3D11Lib.Open("d3d11.dll", &error) ||
|
||||
!mD3D11Lib.GetProc(&d3d11on12CreateDevice, "D3D11On12CreateDevice", &error)) {
|
||||
return DAWN_DEVICE_LOST_ERROR(error.c_str());
|
||||
return DAWN_INTERNAL_ERROR(error.c_str());
|
||||
}
|
||||
|
||||
return {};
|
||||
|
@ -66,7 +66,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
if (!mDXGILib.Open("dxgi.dll", &error) ||
|
||||
!mDXGILib.GetProc(&dxgiGetDebugInterface1, "DXGIGetDebugInterface1", &error) ||
|
||||
!mDXGILib.GetProc(&createDxgiFactory2, "CreateDXGIFactory2", &error)) {
|
||||
return DAWN_DEVICE_LOST_ERROR(error.c_str());
|
||||
return DAWN_INTERNAL_ERROR(error.c_str());
|
||||
}
|
||||
|
||||
return {};
|
||||
|
@ -76,7 +76,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
std::string error;
|
||||
if (!mD3DCompilerLib.Open("d3dcompiler_47.dll", &error) ||
|
||||
!mD3DCompilerLib.GetProc(&d3dCompile, "D3DCompile", &error)) {
|
||||
return DAWN_DEVICE_LOST_ERROR(error.c_str());
|
||||
return DAWN_INTERNAL_ERROR(error.c_str());
|
||||
}
|
||||
|
||||
return {};
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
DawnSwapChainNextTexture next = {};
|
||||
DawnSwapChainError error = im.GetNextTexture(im.userData, &next);
|
||||
if (error) {
|
||||
GetDevice()->HandleError(wgpu::ErrorType::Unknown, error);
|
||||
GetDevice()->HandleError(InternalErrorType::Internal, error);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace dawn_native { namespace metal {
|
|||
}
|
||||
|
||||
if (vendorId == 0) {
|
||||
return DAWN_DEVICE_LOST_ERROR("Failed to find vendor id with the device");
|
||||
return DAWN_INTERNAL_ERROR("Failed to find vendor id with the device");
|
||||
}
|
||||
|
||||
// Set vendor id with 0
|
||||
|
@ -108,7 +108,7 @@ namespace dawn_native { namespace metal {
|
|||
// Get a matching dictionary for the IOGraphicsAccelerator2
|
||||
CFMutableDictionaryRef matchingDict = IORegistryEntryIDMatching([device registryID]);
|
||||
if (matchingDict == nullptr) {
|
||||
return DAWN_DEVICE_LOST_ERROR("Failed to create the matching dict for the device");
|
||||
return DAWN_INTERNAL_ERROR("Failed to create the matching dict for the device");
|
||||
}
|
||||
|
||||
// IOServiceGetMatchingService will consume the reference on the matching dictionary,
|
||||
|
@ -116,7 +116,7 @@ namespace dawn_native { namespace metal {
|
|||
io_registry_entry_t acceleratorEntry =
|
||||
IOServiceGetMatchingService(kIOMasterPortDefault, matchingDict);
|
||||
if (acceleratorEntry == IO_OBJECT_NULL) {
|
||||
return DAWN_DEVICE_LOST_ERROR(
|
||||
return DAWN_INTERNAL_ERROR(
|
||||
"Failed to get the IO registry entry for the accelerator");
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ namespace dawn_native { namespace metal {
|
|||
if (IORegistryEntryGetParentEntry(acceleratorEntry, kIOServicePlane, &deviceEntry) !=
|
||||
kIOReturnSuccess) {
|
||||
IOObjectRelease(acceleratorEntry);
|
||||
return DAWN_DEVICE_LOST_ERROR("Failed to get the IO registry entry for the device");
|
||||
return DAWN_INTERNAL_ERROR("Failed to get the IO registry entry for the device");
|
||||
}
|
||||
|
||||
ASSERT(deviceEntry != IO_OBJECT_NULL);
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace dawn_native { namespace metal {
|
|||
[mtlDevice newComputePipelineStateWithFunction:computeData.function error:&error];
|
||||
if (error != nil) {
|
||||
NSLog(@" error => %@", error);
|
||||
return DAWN_DEVICE_LOST_ERROR("Error creating pipeline state");
|
||||
return DAWN_INTERNAL_ERROR("Error creating pipeline state");
|
||||
}
|
||||
|
||||
// Copy over the local workgroup size as it is passed to dispatch explicitly in Metal
|
||||
|
|
|
@ -391,7 +391,7 @@ namespace dawn_native { namespace metal {
|
|||
[descriptorMTL release];
|
||||
if (error != nil) {
|
||||
NSLog(@" error => %@", error);
|
||||
return DAWN_DEVICE_LOST_ERROR("Error creating rendering pipeline state");
|
||||
return DAWN_INTERNAL_ERROR("Error creating rendering pipeline state");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace dawn_native { namespace metal {
|
|||
|
||||
mMappedPointer = [mBuffer contents];
|
||||
if (mMappedPointer == nullptr) {
|
||||
return DAWN_DEVICE_LOST_ERROR("Unable to map staging buffer.");
|
||||
return DAWN_INTERNAL_ERROR("Unable to map staging buffer.");
|
||||
}
|
||||
|
||||
return {};
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace dawn_native { namespace metal {
|
|||
DawnSwapChainNextTexture next = {};
|
||||
DawnSwapChainError error = im.GetNextTexture(im.userData, &next);
|
||||
if (error) {
|
||||
GetDevice()->HandleError(wgpu::ErrorType::Unknown, error);
|
||||
GetDevice()->HandleError(InternalErrorType::Internal, error);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ namespace dawn_native { namespace null {
|
|||
MaybeError Device::IncrementMemoryUsage(size_t bytes) {
|
||||
static_assert(kMaxMemoryUsage <= std::numeric_limits<size_t>::max() / 2, "");
|
||||
if (bytes > kMaxMemoryUsage || mMemoryUsage + bytes > kMaxMemoryUsage) {
|
||||
return DAWN_DEVICE_LOST_ERROR("Out of memory.");
|
||||
return DAWN_OUT_OF_MEMORY_ERROR("Out of memory.");
|
||||
}
|
||||
mMemoryUsage += bytes;
|
||||
return {};
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace dawn_native { namespace opengl {
|
|||
MaybeError OpenGLFunctions::Initialize(GetProcAddress getProc) {
|
||||
PFNGLGETSTRINGPROC getString = reinterpret_cast<PFNGLGETSTRINGPROC>(getProc("glGetString"));
|
||||
if (getString == nullptr) {
|
||||
return DAWN_DEVICE_LOST_ERROR("Couldn't load glGetString");
|
||||
return DAWN_INTERNAL_ERROR("Couldn't load glGetString");
|
||||
}
|
||||
|
||||
std::string version = reinterpret_cast<const char*>(getString(GL_VERSION));
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace dawn_native { namespace opengl {
|
|||
DawnSwapChainNextTexture next = {};
|
||||
DawnSwapChainError error = im.GetNextTexture(im.userData, &next);
|
||||
if (error) {
|
||||
GetDevice()->HandleError(wgpu::ErrorType::Unknown, error);
|
||||
GetDevice()->HandleError(InternalErrorType::Internal, error);
|
||||
return nullptr;
|
||||
}
|
||||
GLuint nativeTexture = next.texture.u32;
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace dawn_native { namespace vulkan {
|
|||
MaybeError Adapter::Initialize() {
|
||||
DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(*this));
|
||||
if (!mDeviceInfo.maintenance1) {
|
||||
return DAWN_DEVICE_LOST_ERROR(
|
||||
return DAWN_INTERNAL_ERROR(
|
||||
"Dawn requires Vulkan 1.1 or Vulkan 1.0 with KHR_Maintenance1 in order to support "
|
||||
"viewport flipY");
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ namespace dawn_native { namespace vulkan {
|
|||
if (GetInstance()->IsBackendValidationEnabled()) {
|
||||
std::string vkDataDir = GetExecutableDirectory() + DAWN_VK_DATA_DIR;
|
||||
if (!SetEnvironmentVar("VK_LAYER_PATH", vkDataDir.c_str())) {
|
||||
return DAWN_DEVICE_LOST_ERROR("Couldn't set VK_LAYER_PATH");
|
||||
return DAWN_INTERNAL_ERROR("Couldn't set VK_LAYER_PATH");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -94,7 +94,7 @@ namespace dawn_native { namespace vulkan {
|
|||
std::string fullSwiftshaderICDPath =
|
||||
GetExecutableDirectory() + DAWN_SWIFTSHADER_VK_ICD_JSON;
|
||||
if (!SetEnvironmentVar("VK_ICD_FILENAMES", fullSwiftshaderICDPath.c_str())) {
|
||||
return DAWN_DEVICE_LOST_ERROR("Couldn't set VK_ICD_FILENAMES");
|
||||
return DAWN_INTERNAL_ERROR("Couldn't set VK_ICD_FILENAMES");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -112,7 +112,7 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
#endif
|
||||
|
||||
return DAWN_DEVICE_LOST_ERROR("Couldn't load Vulkan");
|
||||
return DAWN_INTERNAL_ERROR("Couldn't load Vulkan");
|
||||
}
|
||||
|
||||
MaybeError Backend::Initialize() {
|
||||
|
|
|
@ -385,7 +385,7 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
|
||||
if (universalQueueFamily == -1) {
|
||||
return DAWN_DEVICE_LOST_ERROR("No universal queue family");
|
||||
return DAWN_INTERNAL_ERROR("No universal queue family");
|
||||
}
|
||||
mQueueFamily = static_cast<uint32_t>(universalQueueFamily);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
mMappedPointer = mAllocation.GetMappedPointer();
|
||||
if (mMappedPointer == nullptr) {
|
||||
return DAWN_DEVICE_LOST_ERROR("Unable to map staging buffer.");
|
||||
return DAWN_INTERNAL_ERROR("Unable to map staging buffer.");
|
||||
}
|
||||
|
||||
return {};
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace dawn_native { namespace vulkan {
|
|||
DawnSwapChainError error = im.GetNextTexture(im.userData, &next);
|
||||
|
||||
if (error) {
|
||||
GetDevice()->HandleError(wgpu::ErrorType::Unknown, error);
|
||||
GetDevice()->HandleError(InternalErrorType::Internal, error);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,8 +73,14 @@ namespace dawn_native { namespace vulkan {
|
|||
if (DAWN_LIKELY(result == VK_SUCCESS)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string message = std::string(context) + " failed with " + VkResultAsString(result);
|
||||
return DAWN_DEVICE_LOST_ERROR(message);
|
||||
|
||||
if (result == VK_ERROR_DEVICE_LOST) {
|
||||
return DAWN_DEVICE_LOST_ERROR(message);
|
||||
} else {
|
||||
return DAWN_INTERNAL_ERROR(message);
|
||||
}
|
||||
}
|
||||
|
||||
MaybeError CheckVkOOMThenSuccessImpl(VkResult result, const char* context) {
|
||||
|
@ -83,10 +89,14 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
|
||||
std::string message = std::string(context) + " failed with " + VkResultAsString(result);
|
||||
|
||||
if (result == VK_ERROR_OUT_OF_DEVICE_MEMORY || result == VK_FAKE_DEVICE_OOM_FOR_TESTING) {
|
||||
return DAWN_OUT_OF_MEMORY_ERROR(message);
|
||||
} else if (result == VK_ERROR_DEVICE_LOST) {
|
||||
return DAWN_DEVICE_LOST_ERROR(message);
|
||||
} else {
|
||||
return DAWN_INTERNAL_ERROR(message);
|
||||
}
|
||||
return DAWN_DEVICE_LOST_ERROR(message);
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
||||
|
|
|
@ -22,12 +22,12 @@ namespace dawn_native { namespace vulkan {
|
|||
#define GET_GLOBAL_PROC(name) \
|
||||
name = reinterpret_cast<decltype(name)>(GetInstanceProcAddr(nullptr, "vk" #name)); \
|
||||
if (name == nullptr) { \
|
||||
return DAWN_DEVICE_LOST_ERROR(std::string("Couldn't get proc vk") + #name); \
|
||||
return DAWN_INTERNAL_ERROR(std::string("Couldn't get proc vk") + #name); \
|
||||
}
|
||||
|
||||
MaybeError VulkanFunctions::LoadGlobalProcs(const DynamicLib& vulkanLib) {
|
||||
if (!vulkanLib.GetProc(&GetInstanceProcAddr, "vkGetInstanceProcAddr")) {
|
||||
return DAWN_DEVICE_LOST_ERROR("Couldn't get vkGetInstanceProcAddr");
|
||||
return DAWN_INTERNAL_ERROR("Couldn't get vkGetInstanceProcAddr");
|
||||
}
|
||||
|
||||
GET_GLOBAL_PROC(CreateInstance);
|
||||
|
@ -44,7 +44,7 @@ namespace dawn_native { namespace vulkan {
|
|||
#define GET_INSTANCE_PROC_BASE(name, procName) \
|
||||
name = reinterpret_cast<decltype(name)>(GetInstanceProcAddr(instance, "vk" #procName)); \
|
||||
if (name == nullptr) { \
|
||||
return DAWN_DEVICE_LOST_ERROR(std::string("Couldn't get proc vk") + #procName); \
|
||||
return DAWN_INTERNAL_ERROR(std::string("Couldn't get proc vk") + #procName); \
|
||||
}
|
||||
|
||||
#define GET_INSTANCE_PROC(name) GET_INSTANCE_PROC_BASE(name, name)
|
||||
|
@ -147,7 +147,7 @@ namespace dawn_native { namespace vulkan {
|
|||
#define GET_DEVICE_PROC(name) \
|
||||
name = reinterpret_cast<decltype(name)>(GetDeviceProcAddr(device, "vk" #name)); \
|
||||
if (name == nullptr) { \
|
||||
return DAWN_DEVICE_LOST_ERROR(std::string("Couldn't get proc vk") + #name); \
|
||||
return DAWN_INTERNAL_ERROR(std::string("Couldn't get proc vk") + #name); \
|
||||
}
|
||||
|
||||
MaybeError VulkanFunctions::LoadDeviceProcs(VkDevice device,
|
||||
|
|
|
@ -93,7 +93,7 @@ namespace dawn_native { namespace vulkan {
|
|||
// incomplete otherwise. This means that both values represent a success.
|
||||
// This is the same for all Enumarte functions
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return DAWN_DEVICE_LOST_ERROR("vkEnumerateInstanceLayerProperties");
|
||||
return DAWN_INTERNAL_ERROR("vkEnumerateInstanceLayerProperties");
|
||||
}
|
||||
|
||||
info.layers.resize(count);
|
||||
|
@ -123,7 +123,7 @@ namespace dawn_native { namespace vulkan {
|
|||
// Gather the info about the instance extensions
|
||||
{
|
||||
if (!EnumerateInstanceExtensions(nullptr, vkFunctions, &info.extensions)) {
|
||||
return DAWN_DEVICE_LOST_ERROR("vkEnumerateInstanceExtensionProperties");
|
||||
return DAWN_INTERNAL_ERROR("vkEnumerateInstanceExtensionProperties");
|
||||
}
|
||||
|
||||
for (const auto& extension : info.extensions) {
|
||||
|
@ -169,7 +169,7 @@ namespace dawn_native { namespace vulkan {
|
|||
std::vector<VkExtensionProperties> layer_extensions;
|
||||
if (!EnumerateInstanceExtensions(kLayerNameFuchsiaImagePipeSwapchain, vkFunctions,
|
||||
&layer_extensions)) {
|
||||
return DAWN_DEVICE_LOST_ERROR("vkEnumerateInstanceExtensionProperties");
|
||||
return DAWN_INTERNAL_ERROR("vkEnumerateInstanceExtensionProperties");
|
||||
}
|
||||
|
||||
for (const auto& extension : layer_extensions) {
|
||||
|
@ -207,7 +207,7 @@ namespace dawn_native { namespace vulkan {
|
|||
VkResult result =
|
||||
VkResult::WrapUnsafe(vkFunctions.EnumeratePhysicalDevices(instance, &count, nullptr));
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return DAWN_DEVICE_LOST_ERROR("vkEnumeratePhysicalDevices");
|
||||
return DAWN_INTERNAL_ERROR("vkEnumeratePhysicalDevices");
|
||||
}
|
||||
|
||||
std::vector<VkPhysicalDevice> physicalDevices(count);
|
||||
|
@ -254,7 +254,7 @@ namespace dawn_native { namespace vulkan {
|
|||
VkResult result = VkResult::WrapUnsafe(
|
||||
vkFunctions.EnumerateDeviceLayerProperties(physicalDevice, &count, nullptr));
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return DAWN_DEVICE_LOST_ERROR("vkEnumerateDeviceLayerProperties");
|
||||
return DAWN_INTERNAL_ERROR("vkEnumerateDeviceLayerProperties");
|
||||
}
|
||||
|
||||
info.layers.resize(count);
|
||||
|
@ -269,7 +269,7 @@ namespace dawn_native { namespace vulkan {
|
|||
VkResult result = VkResult::WrapUnsafe(vkFunctions.EnumerateDeviceExtensionProperties(
|
||||
physicalDevice, nullptr, &count, nullptr));
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return DAWN_DEVICE_LOST_ERROR("vkEnumerateDeviceExtensionProperties");
|
||||
return DAWN_INTERNAL_ERROR("vkEnumerateDeviceExtensionProperties");
|
||||
}
|
||||
|
||||
info.extensions.resize(count);
|
||||
|
@ -357,7 +357,7 @@ namespace dawn_native { namespace vulkan {
|
|||
VkResult result = VkResult::WrapUnsafe(vkFunctions.GetPhysicalDeviceSurfaceFormatsKHR(
|
||||
physicalDevice, surface, &count, nullptr));
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return DAWN_DEVICE_LOST_ERROR("vkGetPhysicalDeviceSurfaceFormatsKHR");
|
||||
return DAWN_INTERNAL_ERROR("vkGetPhysicalDeviceSurfaceFormatsKHR");
|
||||
}
|
||||
|
||||
info.formats.resize(count);
|
||||
|
@ -373,7 +373,7 @@ namespace dawn_native { namespace vulkan {
|
|||
VkResult::WrapUnsafe(vkFunctions.GetPhysicalDeviceSurfacePresentModesKHR(
|
||||
physicalDevice, surface, &count, nullptr));
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return DAWN_DEVICE_LOST_ERROR("vkGetPhysicalDeviceSurfacePresentModesKHR");
|
||||
return DAWN_INTERNAL_ERROR("vkGetPhysicalDeviceSurfacePresentModesKHR");
|
||||
}
|
||||
|
||||
info.presentModes.resize(count);
|
||||
|
|
Loading…
Reference in New Issue