Call ExecutePendingCommandContext() in ExternalImageDXGIImpl::Destroy()

Before destroying ExternalImageDXGI we should execute all the pending
commands before calling NextSerial(), or the device will be lost as
the CommandAllocator will be destroyed before the pending commands are
executed.

Bug: dawn:576
Test: dawn_end2end_tests
Change-Id: I6e291586cd78a7e0feaf2f8dfee87a289ec27f77
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/100100
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Jiawei Shao 2022-08-26 03:08:28 +00:00 committed by Dawn LUCI CQ
parent 2d239c4945
commit 8b99a54b26
2 changed files with 23 additions and 0 deletions

View File

@ -64,6 +64,7 @@ void ExternalImageDXGIImpl::Destroy() {
RemoveFromList(); RemoveFromList();
// Keep fence alive until any pending signal calls are done on the GPU. // Keep fence alive until any pending signal calls are done on the GPU.
mBackendDevice->ConsumedError(mBackendDevice->ExecutePendingCommandContext());
mBackendDevice->ConsumedError(mBackendDevice->NextSerial()); mBackendDevice->ConsumedError(mBackendDevice->NextSerial());
mBackendDevice->ReferenceUntilUnused(mD3D12Fence.Get()); mBackendDevice->ReferenceUntilUnused(mD3D12Fence.Get());
mBackendDevice = nullptr; mBackendDevice = nullptr;

View File

@ -849,6 +849,28 @@ TEST_P(D3D12SharedHandleUsageTests, DisallowExternalImageAfterDestroyDevice) {
EXPECT_EQ(texture, nullptr); EXPECT_EQ(texture, nullptr);
} }
// Verify there is no error generated when we destroy an external image with CommandRecordingContext
// open.
TEST_P(D3D12SharedHandleUsageTests, CallWriteBufferBeforeDestroyingExternalImage) {
DAWN_TEST_UNSUPPORTED_IF(UsesWire());
wgpu::Texture texture;
ComPtr<ID3D11Texture2D> d3d11Texture;
std::unique_ptr<dawn::native::d3d12::ExternalImageDXGI> externalImage;
WrapSharedHandle(&baseDawnDescriptor, &baseD3dDescriptor, &texture, &d3d11Texture,
&externalImage, /*fenceSignalValue=*/1);
// In utils::CreateBufferFromData() we will call queue.WriteBuffer(), which will make a
// recording context pending.
constexpr uint32_t kExpected = 1u;
wgpu::Buffer buffer = utils::CreateBufferFromData(
device, wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst, {kExpected});
externalImage = nullptr;
EXPECT_BUFFER_U32_EQ(kExpected, buffer, 0);
}
DAWN_INSTANTIATE_TEST_P(D3D12SharedHandleValidation, DAWN_INSTANTIATE_TEST_P(D3D12SharedHandleValidation,
{D3D12Backend()}, {D3D12Backend()},
{SyncMode::kKeyedMutex, SyncMode::kFence}); {SyncMode::kKeyedMutex, SyncMode::kFence});