Fix incorrect return status of Create*PipelineAsync when device is lost

This patch fixes the incorrect return status of Create*PipelineAsync
when device is lost by explicitly calling and clearing all the
Create*PipelineAsync callbacks in DeviceBase::HandleError() when the
device is lost.

BUG=dawn:529
TEST=dawn_end2end_tests

Change-Id: I67a8047b2e5a54f6f85c5a4cbcf420b744ac0d5c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/49080
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
This commit is contained in:
Jiawei Shao 2021-04-27 09:33:26 +00:00 committed by Commit Bot service account
parent cf569e2c58
commit 045a02adc0
4 changed files with 30 additions and 5 deletions

View File

@ -128,13 +128,9 @@ namespace dawn_native {
mCreatePipelineAsyncTasksInFlight.ClearUpTo(finishedSerial);
for (auto& task : tasks) {
if (mDevice->IsLost()) {
task->HandleDeviceLoss();
} else {
task->Finish();
}
}
}
void CreatePipelineAsyncTracker::ClearForShutDown() {
for (auto& task : mCreatePipelineAsyncTasksInFlight.IterateAll()) {
@ -143,4 +139,11 @@ namespace dawn_native {
mCreatePipelineAsyncTasksInFlight.Clear();
}
void CreatePipelineAsyncTracker::ClearForDeviceLoss() {
for (auto& task : mCreatePipelineAsyncTasksInFlight.IterateAll()) {
task->HandleDeviceLoss();
}
mCreatePipelineAsyncTasksInFlight.Clear();
}
} // namespace dawn_native

View File

@ -80,6 +80,7 @@ namespace dawn_native {
void TrackTask(std::unique_ptr<CreatePipelineAsyncTaskBase> task, ExecutionSerial serial);
void Tick(ExecutionSerial finishedSerial);
void ClearForShutDown();
void ClearForDeviceLoss();
private:
DeviceBase* mDevice;

View File

@ -238,6 +238,7 @@ namespace dawn_native {
}
mQueue->HandleDeviceLoss();
mCreatePipelineAsyncTracker->ClearForDeviceLoss();
// Still forward device loss errors to the error scopes so they all reject.
mErrorScopeStack->HandleError(ToWGPUErrorType(type), message);

View File

@ -554,6 +554,26 @@ TEST_P(DeviceLostTest, DeviceLostDoesntCallUncapturedError) {
device.LoseForTesting();
}
// Test that WGPUCreatePipelineAsyncStatus_DeviceLost can be correctly returned when device is lost
// before the callback of Create*PipelineAsync() is called.
TEST_P(DeviceLostTest, DeviceLostBeforeCreatePipelineAsyncCallback) {
wgpu::ShaderModule csModule = utils::CreateShaderModule(device, R"(
[[stage(compute)]] fn main() {
})");
wgpu::ComputePipelineDescriptor descriptor;
descriptor.computeStage.module = csModule;
descriptor.computeStage.entryPoint = "main";
auto callback = [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline returnPipeline,
const char* message, void* userdata) {
EXPECT_EQ(WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_DeviceLost, status);
};
device.CreateComputePipelineAsync(&descriptor, callback, nullptr);
SetCallbackAndLoseForTesting();
}
DAWN_INSTANTIATE_TEST(DeviceLostTest,
D3D12Backend(),
MetalBackend(),