Immediately call fence and map callbacks on device loss.
This is more in line with what happens in dawn_wire and Blink's WebGPU implementation. It also allows fixing the Fence-related DeviceLost tests to destroy the mock fence callback on destruction, which in turns fixes a crash on dawn_end2end_tests exit on MSVC x64 debug. Bug: dawn:602 Change-Id: I277e7fa284a573854ed46576602d5f6819db1357 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/38526 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Auto-Submit: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
2df77f4325
commit
c1d3a66bd2
|
@ -35,7 +35,10 @@ namespace dawn_native {
|
|||
: buffer(std::move(buffer)), id(id) {
|
||||
}
|
||||
void Finish() override {
|
||||
buffer->OnMapRequestCompleted(id);
|
||||
buffer->OnMapRequestCompleted(id, WGPUBufferMapAsyncStatus_Success);
|
||||
}
|
||||
void HandleDeviceLoss() override {
|
||||
buffer->OnMapRequestCompleted(id, WGPUBufferMapAsyncStatus_DeviceLost);
|
||||
}
|
||||
~MapRequestTask() override = default;
|
||||
|
||||
|
@ -537,8 +540,8 @@ namespace dawn_native {
|
|||
mState = BufferState::Destroyed;
|
||||
}
|
||||
|
||||
void BufferBase::OnMapRequestCompleted(MapRequestID mapID) {
|
||||
CallMapCallback(mapID, WGPUBufferMapAsyncStatus_Success);
|
||||
void BufferBase::OnMapRequestCompleted(MapRequestID mapID, WGPUBufferMapAsyncStatus status) {
|
||||
CallMapCallback(mapID, status);
|
||||
}
|
||||
|
||||
bool BufferBase::IsDataInitialized() const {
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace dawn_native {
|
|||
wgpu::BufferUsage GetUsage() const;
|
||||
|
||||
MaybeError MapAtCreation();
|
||||
void OnMapRequestCompleted(MapRequestID mapID);
|
||||
void OnMapRequestCompleted(MapRequestID mapID, WGPUBufferMapAsyncStatus status);
|
||||
|
||||
MaybeError ValidateCanUseOnQueueNow() const;
|
||||
|
||||
|
|
|
@ -240,6 +240,8 @@ namespace dawn_native {
|
|||
|
||||
// The device was lost, call the application callback.
|
||||
if (type == InternalErrorType::DeviceLost && mDeviceLostCallback != nullptr) {
|
||||
mDefaultQueue->HandleDeviceLoss();
|
||||
|
||||
mDeviceLostCallback(message, mDeviceLostUserdata);
|
||||
mDeviceLostCallback = nullptr;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,10 @@ namespace dawn_native {
|
|||
: fence(std::move(fence)), value(value) {
|
||||
}
|
||||
void Finish() override {
|
||||
fence->SetCompletedValue(value);
|
||||
fence->SetCompletedValue(value, WGPUFenceCompletionStatus_Success);
|
||||
}
|
||||
void HandleDeviceLoss() override {
|
||||
fence->SetCompletedValue(value, WGPUFenceCompletionStatus_DeviceLost);
|
||||
}
|
||||
~FenceInFlight() override = default;
|
||||
|
||||
|
@ -116,18 +119,14 @@ namespace dawn_native {
|
|||
mSignalValue = signalValue;
|
||||
}
|
||||
|
||||
void Fence::SetCompletedValue(FenceAPISerial completedValue) {
|
||||
void Fence::SetCompletedValue(FenceAPISerial completedValue, WGPUFenceCompletionStatus status) {
|
||||
ASSERT(!IsError());
|
||||
ASSERT(completedValue <= mSignalValue);
|
||||
ASSERT(completedValue > mCompletedValue);
|
||||
mCompletedValue = completedValue;
|
||||
|
||||
for (auto& request : mRequests.IterateUpTo(mCompletedValue)) {
|
||||
if (GetDevice()->IsLost()) {
|
||||
request.completionCallback(WGPUFenceCompletionStatus_DeviceLost, request.userdata);
|
||||
} else {
|
||||
request.completionCallback(WGPUFenceCompletionStatus_Success, request.userdata);
|
||||
}
|
||||
request.completionCallback(status, request.userdata);
|
||||
}
|
||||
mRequests.ClearUpTo(mCompletedValue);
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace dawn_native {
|
|||
friend class QueueBase;
|
||||
friend struct FenceInFlight;
|
||||
void SetSignaledValue(FenceAPISerial signalValue);
|
||||
void SetCompletedValue(FenceAPISerial completedValue);
|
||||
void SetCompletedValue(FenceAPISerial completedValue, WGPUFenceCompletionStatus status);
|
||||
void UpdateFenceOnComplete(Fence* fence, FenceAPISerial value);
|
||||
|
||||
private:
|
||||
|
|
|
@ -192,6 +192,13 @@ namespace dawn_native {
|
|||
mTasksInFlight.ClearUpTo(finishedSerial);
|
||||
}
|
||||
|
||||
void QueueBase::HandleDeviceLoss() {
|
||||
for (auto& task : mTasksInFlight.IterateAll()) {
|
||||
task->HandleDeviceLoss();
|
||||
}
|
||||
mTasksInFlight.Clear();
|
||||
}
|
||||
|
||||
Fence* QueueBase::CreateFence(const FenceDescriptor* descriptor) {
|
||||
if (GetDevice()->ConsumedError(ValidateCreateFence(descriptor))) {
|
||||
return Fence::MakeError(GetDevice());
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace dawn_native {
|
|||
struct TaskInFlight {
|
||||
virtual ~TaskInFlight();
|
||||
virtual void Finish() = 0;
|
||||
virtual void HandleDeviceLoss() = 0;
|
||||
};
|
||||
|
||||
static QueueBase* MakeError(DeviceBase* device);
|
||||
|
@ -52,6 +53,7 @@ namespace dawn_native {
|
|||
|
||||
void TrackTask(std::unique_ptr<TaskInFlight> task, ExecutionSerial serial);
|
||||
void Tick(ExecutionSerial finishedSerial);
|
||||
void HandleDeviceLoss();
|
||||
|
||||
protected:
|
||||
QueueBase(DeviceBase* device);
|
||||
|
|
|
@ -65,6 +65,7 @@ class DeviceLostTest : public DawnTest {
|
|||
|
||||
void TearDown() override {
|
||||
mockDeviceLostCallback = nullptr;
|
||||
mockFenceOnCompletionCallback = nullptr;
|
||||
DawnTest::TearDown();
|
||||
}
|
||||
|
||||
|
@ -449,8 +450,8 @@ TEST_P(DeviceLostTest, FenceOnCompletionFails) {
|
|||
ASSERT_DEVICE_ERROR(fence.OnCompletion(2u, ToMockFenceOnCompletionFails, nullptr));
|
||||
ASSERT_DEVICE_ERROR(device.Tick());
|
||||
|
||||
// completed value should not have changed from initial value
|
||||
EXPECT_EQ(fence.GetCompletedValue(), 0u);
|
||||
// completed value is the last value signaled (all previous GPU operations are as if completed)
|
||||
EXPECT_EQ(fence.GetCompletedValue(), 2u);
|
||||
}
|
||||
|
||||
// Test that Fence::OnCompletion callbacks with device lost status when device is lost after calling
|
||||
|
@ -469,7 +470,7 @@ TEST_P(DeviceLostTest, FenceOnCompletionBeforeLossFails) {
|
|||
SetCallbackAndLoseForTesting();
|
||||
ASSERT_DEVICE_ERROR(device.Tick());
|
||||
|
||||
EXPECT_EQ(fence.GetCompletedValue(), 0u);
|
||||
EXPECT_EQ(fence.GetCompletedValue(), 2u);
|
||||
}
|
||||
|
||||
// Regression test for the Null backend not properly setting the completedSerial when
|
||||
|
|
Loading…
Reference in New Issue