Release D3D12 command queue in Device::DestroyImpl

Repeatedly creating and destroying WebGPU devices in a loop causes
large amounts of memory to pile up in the GPU process. Much of this
memory comes from the D3D12 command queue.

Releasing the command queue early in DestroyImpl before the destructor
runs goes a long way towards relieving the memory pressure.

Bug: chromium:1377789
Change-Id: I3ff9a5f6cb3ea3136e41079343532cbe732b6cc4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/111280
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Rafael Cintron <rafael.cintron@microsoft.com>
This commit is contained in:
Rafael Cintron 2022-11-24 01:10:35 +00:00 committed by Dawn LUCI CQ
parent 9ba5f9e2c6
commit 36317d9839
2 changed files with 13 additions and 1 deletions

View File

@ -859,6 +859,10 @@ void Device::DestroyImpl() {
ASSERT(mUsedComObjectRefs.Empty()); ASSERT(mUsedComObjectRefs.Empty());
ASSERT(!mPendingCommands.IsOpen()); ASSERT(!mPendingCommands.IsOpen());
// Now that we've cleared out pending work from the queue, we can safely release it and reclaim
// memory.
mCommandQueue.Reset();
} }
ShaderVisibleDescriptorAllocator* Device::GetViewShaderVisibleDescriptorAllocator() const { ShaderVisibleDescriptorAllocator* Device::GetViewShaderVisibleDescriptorAllocator() const {

View File

@ -156,7 +156,7 @@ TEST_P(DestroyTest, TextureSubmitDestroySubmit) {
} }
// Attempting to set an object label after it has been destroyed should not cause an error. // Attempting to set an object label after it has been destroyed should not cause an error.
TEST_P(DestroyTest, DestroyThenSetLabel) { TEST_P(DestroyTest, DestroyObjectThenSetLabel) {
DAWN_TEST_UNSUPPORTED_IF(UsesWire()); DAWN_TEST_UNSUPPORTED_IF(UsesWire());
std::string label = "test"; std::string label = "test";
wgpu::BufferDescriptor descriptor; wgpu::BufferDescriptor descriptor;
@ -167,6 +167,14 @@ TEST_P(DestroyTest, DestroyThenSetLabel) {
buffer.SetLabel(label.c_str()); buffer.SetLabel(label.c_str());
} }
// Attempting to set a device label after it has been destroyed should not cause an error.
TEST_P(DestroyTest, DestroyDeviceThenSetLabel) {
DAWN_TEST_UNSUPPORTED_IF(UsesWire());
std::string label = "test";
device.Destroy();
device.SetLabel(label.c_str());
}
// Device destroy before buffer submit will result in error. // Device destroy before buffer submit will result in error.
TEST_P(DestroyTest, DestroyDeviceBeforeSubmit) { TEST_P(DestroyTest, DestroyDeviceBeforeSubmit) {
// TODO(crbug.com/dawn/628) Add more comprehensive tests with destroy and backends. // TODO(crbug.com/dawn/628) Add more comprehensive tests with destroy and backends.