[merge m92] Add releaseMutexKey to ExternalImageAccessDescriptorDXGIKeyedMutex

This allows the client to specify a different release key for the keyed
mutex than the default of acquire key + 1. If the release key is the
sentinel value of UINT64_MAX, it's set to acquire key + 1. Once Chromium
transitions to always specifying the release key, it will be made a
required parameter and the default behavior will be removed.

Bug: chromium:1213977
Change-Id: I327f7157bb7ff23cf216e43043568ce7c6f38a60
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/53880
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Sunny Sachanandani <sunnyps@chromium.org>
(cherry picked from commit cabd60d991487b64ddc99dc283b9fa2090d668e9)
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/55603
Commit-Queue: Austin Eng <enga@chromium.org>
Auto-Submit: Sunny Sachanandani <sunnyps@chromium.org>
diff --git a/src/dawn_native/d3d12/D3D12Backend.cpp b/src/dawn_native/d3d12/D3D12Backend.cpp
index 5fc2e24..a363757 100644
--- a/src/dawn_native/d3d12/D3D12Backend.cpp
+++ b/src/dawn_native/d3d12/D3D12Backend.cpp
@@ -84,9 +84,16 @@
         textureDescriptor.mipLevelCount = mMipLevelCount;
         textureDescriptor.sampleCount = mSampleCount;
 
+        // Set the release key to acquire key + 1 if not set. This allows supporting the old keyed
+        // mutex protocol during the transition to making this a required parameter.
+        ExternalMutexSerial releaseMutexKey =
+            (descriptor->releaseMutexKey != UINT64_MAX)
+                ? ExternalMutexSerial(descriptor->releaseMutexKey)
+                : ExternalMutexSerial(descriptor->acquireMutexKey + 1);
+
         Ref<TextureBase> texture = backendDevice->CreateExternalTexture(
             &textureDescriptor, mD3D12Resource, ExternalMutexSerial(descriptor->acquireMutexKey),
-            descriptor->isSwapChainTexture, descriptor->isInitialized);
+            releaseMutexKey, descriptor->isSwapChainTexture, descriptor->isInitialized);
         return reinterpret_cast<WGPUTexture>(texture.Detach());
     }
 
diff --git a/src/dawn_native/d3d12/DeviceD3D12.cpp b/src/dawn_native/d3d12/DeviceD3D12.cpp
index 43c35cc..24ca1af 100644
--- a/src/dawn_native/d3d12/DeviceD3D12.cpp
+++ b/src/dawn_native/d3d12/DeviceD3D12.cpp
@@ -447,13 +447,14 @@
     Ref<TextureBase> Device::CreateExternalTexture(const TextureDescriptor* descriptor,
                                                    ComPtr<ID3D12Resource> d3d12Texture,
                                                    ExternalMutexSerial acquireMutexKey,
+                                                   ExternalMutexSerial releaseMutexKey,
                                                    bool isSwapChainTexture,
                                                    bool isInitialized) {
         Ref<Texture> dawnTexture;
-        if (ConsumedError(
-                Texture::CreateExternalImage(this, descriptor, std::move(d3d12Texture),
-                                             acquireMutexKey, isSwapChainTexture, isInitialized),
-                &dawnTexture)) {
+        if (ConsumedError(Texture::CreateExternalImage(this, descriptor, std::move(d3d12Texture),
+                                                       acquireMutexKey, releaseMutexKey,
+                                                       isSwapChainTexture, isInitialized),
+                          &dawnTexture)) {
             return nullptr;
         }
         return {dawnTexture};
diff --git a/src/dawn_native/d3d12/DeviceD3D12.h b/src/dawn_native/d3d12/DeviceD3D12.h
index 915430c..024bc50 100644
--- a/src/dawn_native/d3d12/DeviceD3D12.h
+++ b/src/dawn_native/d3d12/DeviceD3D12.h
@@ -125,6 +125,7 @@
         Ref<TextureBase> CreateExternalTexture(const TextureDescriptor* descriptor,
                                                ComPtr<ID3D12Resource> d3d12Texture,
                                                ExternalMutexSerial acquireMutexKey,
+                                               ExternalMutexSerial releaseMutexKey,
                                                bool isSwapChainTexture,
                                                bool isInitialized);
         ResultOrError<ComPtr<IDXGIKeyedMutex>> CreateKeyedMutexForTexture(
diff --git a/src/dawn_native/d3d12/TextureD3D12.cpp b/src/dawn_native/d3d12/TextureD3D12.cpp
index ac7c396..7e72f4d 100644
--- a/src/dawn_native/d3d12/TextureD3D12.cpp
+++ b/src/dawn_native/d3d12/TextureD3D12.cpp
@@ -422,12 +422,14 @@
                                                              const TextureDescriptor* descriptor,
                                                              ComPtr<ID3D12Resource> d3d12Texture,
                                                              ExternalMutexSerial acquireMutexKey,
+                                                             ExternalMutexSerial releaseMutexKey,
                                                              bool isSwapChainTexture,
                                                              bool isInitialized) {
         Ref<Texture> dawnTexture =
             AcquireRef(new Texture(device, descriptor, TextureState::OwnedExternal));
         DAWN_TRY(dawnTexture->InitializeAsExternalTexture(descriptor, std::move(d3d12Texture),
-                                                          acquireMutexKey, isSwapChainTexture));
+                                                          acquireMutexKey, releaseMutexKey,
+                                                          isSwapChainTexture));
 
         // Importing a multi-planar format must be initialized. This is required because
         // a shared multi-planar format cannot be initialized by Dawn.
@@ -454,6 +456,7 @@
     MaybeError Texture::InitializeAsExternalTexture(const TextureDescriptor* descriptor,
                                                     ComPtr<ID3D12Resource> d3d12Texture,
                                                     ExternalMutexSerial acquireMutexKey,
+                                                    ExternalMutexSerial releaseMutexKey,
                                                     bool isSwapChainTexture) {
         Device* dawnDevice = ToBackend(GetDevice());
 
@@ -464,6 +467,7 @@
                               "D3D12 acquiring shared mutex"));
 
         mAcquireMutexKey = acquireMutexKey;
+        mReleaseMutexKey = releaseMutexKey;
         mDxgiKeyedMutex = std::move(dxgiKeyedMutex);
         mSwapChainTexture = isSwapChainTexture;
 
@@ -529,7 +533,7 @@
         // When creating the ResourceHeapAllocation, the resource heap is set to nullptr because the
         // texture is owned externally. The texture's owning entity must remain responsible for
         // memory management.
-        mResourceAllocation = { info, 0, std::move(d3d12Texture), nullptr };
+        mResourceAllocation = {info, 0, std::move(d3d12Texture), nullptr};
         return {};
     }
 
@@ -570,7 +574,7 @@
         mSwapChainTexture = false;
 
         if (mDxgiKeyedMutex != nullptr) {
-            mDxgiKeyedMutex->ReleaseSync(uint64_t(mAcquireMutexKey) + 1);
+            mDxgiKeyedMutex->ReleaseSync(uint64_t(mReleaseMutexKey));
             device->ReleaseKeyedMutexForTexture(std::move(mDxgiKeyedMutex));
         }
     }
@@ -790,18 +794,17 @@
         // This transitions assume it is a 2D texture
         ASSERT(GetDimension() == wgpu::TextureDimension::e2D);
 
-        mSubresourceStateAndDecay.Merge(
-            textureUsages, [&](const SubresourceRange& mergeRange, StateAndDecay* state,
-                               wgpu::TextureUsage usage) {
-                // Skip if this subresource is not used during the current pass
-                if (usage == wgpu::TextureUsage::None) {
-                    return;
-                }
+        mSubresourceStateAndDecay.Merge(textureUsages, [&](const SubresourceRange& mergeRange,
+                                                           StateAndDecay* state,
+                                                           wgpu::TextureUsage usage) {
+            // Skip if this subresource is not used during the current pass
+            if (usage == wgpu::TextureUsage::None) {
+                return;
+            }
 
-                D3D12_RESOURCE_STATES newState = D3D12TextureUsage(usage, GetFormat());
-                TransitionSubresourceRange(barriers, mergeRange, state, newState,
-                                           pendingCommandSerial);
-            });
+            D3D12_RESOURCE_STATES newState = D3D12TextureUsage(usage, GetFormat());
+            TransitionSubresourceRange(barriers, mergeRange, state, newState, pendingCommandSerial);
+        });
     }
 
     D3D12_RENDER_TARGET_VIEW_DESC Texture::GetRTVDescriptor(uint32_t mipLevel,
@@ -871,7 +874,6 @@
     MaybeError Texture::ClearTexture(CommandRecordingContext* commandContext,
                                      const SubresourceRange& range,
                                      TextureBase::ClearValue clearValue) {
-
         ID3D12GraphicsCommandList* commandList = commandContext->GetCommandList();
 
         Device* device = ToBackend(GetDevice());
diff --git a/src/dawn_native/d3d12/TextureD3D12.h b/src/dawn_native/d3d12/TextureD3D12.h
index c7a652d..d760c1e 100644
--- a/src/dawn_native/d3d12/TextureD3D12.h
+++ b/src/dawn_native/d3d12/TextureD3D12.h
@@ -43,6 +43,7 @@
                                                                const TextureDescriptor* descriptor,
                                                                ComPtr<ID3D12Resource> d3d12Texture,
                                                                ExternalMutexSerial acquireMutexKey,
+                                                               ExternalMutexSerial releaseMutexKey,
                                                                bool isSwapChainTexture,
                                                                bool isInitialized);
         static ResultOrError<Ref<Texture>> Create(Device* device,
@@ -89,6 +90,7 @@
         MaybeError InitializeAsExternalTexture(const TextureDescriptor* descriptor,
                                                ComPtr<ID3D12Resource> d3d12Texture,
                                                ExternalMutexSerial acquireMutexKey,
+                                               ExternalMutexSerial releaseMutexKey,
                                                bool isSwapChainTexture);
         MaybeError InitializeAsSwapChainTexture(ComPtr<ID3D12Resource> d3d12Texture);
 
@@ -123,6 +125,7 @@
         bool mSwapChainTexture = false;
 
         ExternalMutexSerial mAcquireMutexKey = ExternalMutexSerial(0);
+        ExternalMutexSerial mReleaseMutexKey = ExternalMutexSerial(0);
         ComPtr<IDXGIKeyedMutex> mDxgiKeyedMutex;
     };
 
diff --git a/src/include/dawn_native/D3D12Backend.h b/src/include/dawn_native/D3D12Backend.h
index b85a988..e545ee1 100644
--- a/src/include/dawn_native/D3D12Backend.h
+++ b/src/include/dawn_native/D3D12Backend.h
@@ -56,6 +56,8 @@
         : ExternalImageAccessDescriptor {
       public:
         uint64_t acquireMutexKey;
+        // Release key will be set to acquireMutexKey + 1 if set to sentinel value UINT64_MAX.
+        uint64_t releaseMutexKey = UINT64_MAX;
         bool isSwapChainTexture = false;
     };