Simplify the device lifecycle.

What was previously the Device's loss status is now a state that also
contains the "being created" state. Its transitions are entirely
handled in the frontend which enforces somewhat uniform lifecycles
between backends.

The backend devices' ShutDownImpl() function is now guaranteed to be
called only during the destructor, which leads to further simplification.
Previously Destroy() could also be called when the device was first
lost. This require complications because, for example, a WGPUBuffer
could still exist, and would want to call some resource allocator
service after the call to Destroy(). Now destruction of the device's
backing API objects is deferred to the destructor. (that's ok as long
as the application can't submit any more work).

WaitForCompletion is now guaranteed to be called before ShutDownImpl() iff
the call to DeviceBase::Initialize was succesful and the backing device
not lost. The idea is that after DeviceBase::Initialize, the GPU can
have some work enqueued and we need to wait for it to complete before
deleting backing API objects. In the future we might also have backend
be reentrant, using WebGPU itself to implement parts of the backend.
Reentrant calls would only be allowed after DeviceBase::Initialize.

Also the DynamicUploader that was special-cased in all backends is
now handled entirely by the frontend.

Bug: dawn:373

Change-Id: I985417d67727ea3bc11849c999c5ef0e02403223
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/18801
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Corentin Wallez
2020-04-07 16:19:47 +00:00
committed by Commit Bot service account
parent 7dbfc91d30
commit 73ea1f1106
12 changed files with 185 additions and 151 deletions

View File

@@ -16,7 +16,6 @@
#include "dawn_native/BackendConnection.h"
#include "dawn_native/Commands.h"
#include "dawn_native/DynamicUploader.h"
#include "dawn_native/ErrorData.h"
#include "dawn_native/Instance.h"
#include "dawn_native/Surface.h"
@@ -86,10 +85,7 @@ namespace dawn_native { namespace null {
}
Device::~Device() {
BaseDestructor();
// This assert is in the destructor rather than Device::Destroy() because it needs to make
// sure buffers have been destroyed before the device.
ASSERT(mMemoryUsage == 0);
ShutDownBase();
}
MaybeError Device::Initialize() {
@@ -182,12 +178,13 @@ namespace dawn_native { namespace null {
return std::move(stagingBuffer);
}
void Device::Destroy() {
ASSERT(mLossStatus != LossStatus::AlreadyLost);
mDynamicUploader = nullptr;
void Device::ShutDownImpl() {
ASSERT(GetState() == State::Disconnected);
// Clear pending operations before checking mMemoryUsage because some operations keep a
// reference to Buffers.
mPendingOperations.clear();
ASSERT(mMemoryUsage == 0);
}
MaybeError Device::WaitForIdleForDestruction() {

View File

@@ -138,7 +138,7 @@ namespace dawn_native { namespace null {
TextureBase* texture,
const TextureViewDescriptor* descriptor) override;
void Destroy() override;
void ShutDownImpl() override;
MaybeError WaitForIdleForDestruction() override;
Serial mCompletedSerial = 0;