D3D12: Reference all signatures when destroying pipeline layout

This patch implements PipelineLayoutD3D12::DestroyImpl() where we
call ReferenceUntilUnused() to all the root and command signatures
so that they won't be destroyed when they are referenced by GPU
operations in-flight on command queue.

BUG=dawn:1422
TEST=dawn_end2end_tests

Change-Id: I54df7b53645c9beaaa2e7b74aef54e0f6d37c440
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/90940
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
diff --git a/src/dawn/native/d3d12/PipelineLayoutD3D12.cpp b/src/dawn/native/d3d12/PipelineLayoutD3D12.cpp
index b710069..91505c1 100644
--- a/src/dawn/native/d3d12/PipelineLayoutD3D12.cpp
+++ b/src/dawn/native/d3d12/PipelineLayoutD3D12.cpp
@@ -275,6 +275,27 @@
     return {};
 }
 
+void PipelineLayout::DestroyImpl() {
+    PipelineLayoutBase::DestroyImpl();
+
+    Device* device = ToBackend(GetDevice());
+    device->ReferenceUntilUnused(mRootSignature);
+
+    // The ID3D12CommandSignature object should not be referenced by GPU operations in-flight on
+    // Command Queue when it is being deleted. According to D3D12 debug layer, "it is not safe to
+    // final-release objects that may have GPU operations pending. This can result in application
+    // instability (921)".
+    if (mDispatchIndirectCommandSignatureWithNumWorkgroups.Get()) {
+        device->ReferenceUntilUnused(mDispatchIndirectCommandSignatureWithNumWorkgroups);
+    }
+    if (mDrawIndirectCommandSignatureWithInstanceVertexOffsets.Get()) {
+        device->ReferenceUntilUnused(mDrawIndirectCommandSignatureWithInstanceVertexOffsets);
+    }
+    if (mDrawIndexedIndirectCommandSignatureWithInstanceVertexOffsets.Get()) {
+        device->ReferenceUntilUnused(mDrawIndexedIndirectCommandSignatureWithInstanceVertexOffsets);
+    }
+}
+
 uint32_t PipelineLayout::GetCbvUavSrvRootParameterIndex(BindGroupIndex group) const {
     ASSERT(group < kMaxBindGroupsTyped);
     return mCbvUavSrvRootParameterInfo[group];
diff --git a/src/dawn/native/d3d12/PipelineLayoutD3D12.h b/src/dawn/native/d3d12/PipelineLayoutD3D12.h
index 69d9095..5e5360e 100644
--- a/src/dawn/native/d3d12/PipelineLayoutD3D12.h
+++ b/src/dawn/native/d3d12/PipelineLayoutD3D12.h
@@ -85,6 +85,8 @@
     ~PipelineLayout() override = default;
     using PipelineLayoutBase::PipelineLayoutBase;
     MaybeError Initialize();
+    void DestroyImpl() override;
+
     ityp::array<BindGroupIndex, uint32_t, kMaxBindGroups> mCbvUavSrvRootParameterInfo;
     ityp::array<BindGroupIndex, uint32_t, kMaxBindGroups> mSamplerRootParameterInfo;
     ityp::array<BindGroupIndex,