D3D12: Handle state promotion and decay for simultaneous access textures

This patch enables the state promotion and decay for simultaneous
access textures on D3D12 backends. When Dawn acquires a D3D11 shared
texture, that texture will have the flag
D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS. With this patch we can
skip many transition barriers added before.

Fixed: dawn:697
Change-Id: Id64402362921ae57d3a2a36839a9b49814a1ae18
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/145720
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/dawn/native/d3d12/CommandRecordingContext.cpp b/src/dawn/native/d3d12/CommandRecordingContext.cpp
index 72f29b4..b8ca153 100644
--- a/src/dawn/native/d3d12/CommandRecordingContext.cpp
+++ b/src/dawn/native/d3d12/CommandRecordingContext.cpp
@@ -67,13 +67,8 @@
 
 MaybeError CommandRecordingContext::ExecuteCommandList(Device* device) {
     if (IsOpen()) {
-        // Shared textures must be transitioned to common state after the last usage in order
-        // for them to be used by other APIs like D3D11. We ensure this by transitioning to the
-        // common state right before command list submission. TransitionUsageNow itself ensures
-        // no unnecessary transitions happen if the resources is already in the common state.
         for (Texture* texture : mSharedTextures) {
             DAWN_TRY(texture->SynchronizeImportedTextureBeforeUse());
-            texture->TrackAllUsageAndTransitionNow(this, D3D12_RESOURCE_STATE_COMMON);
         }
 
         MaybeError error =
diff --git a/src/dawn/native/d3d12/TextureD3D12.cpp b/src/dawn/native/d3d12/TextureD3D12.cpp
index bcc7886..f3efb60 100644
--- a/src/dawn/native/d3d12/TextureD3D12.cpp
+++ b/src/dawn/native/d3d12/TextureD3D12.cpp
@@ -216,6 +216,7 @@
 
     D3D12_RESOURCE_DESC desc = d3d12Texture->GetDesc();
     mD3D12ResourceFlags = desc.Flags;
+    ASSERT(mD3D12ResourceFlags & D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS);
 
     AllocationInfo info;
     info.mMethod = AllocationMethod::kExternal;
@@ -338,6 +339,8 @@
 }
 
 ResultOrError<ExecutionSerial> Texture::EndAccess() {
+    ASSERT(mD3D12ResourceFlags & D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS);
+
     Device* device = ToBackend(GetDevice());
     // Synchronize if texture access wasn't synchronized already due to ExecuteCommandLists.
     if (!mSignalFenceValue.has_value()) {
@@ -433,17 +436,6 @@
     TrackUsageAndTransitionNow(commandContext, D3D12TextureUsage(usage, GetFormat()), range);
 }
 
-void Texture::TrackAllUsageAndTransitionNow(CommandRecordingContext* commandContext,
-                                            wgpu::TextureUsage usage) {
-    TrackUsageAndTransitionNow(commandContext, D3D12TextureUsage(usage, GetFormat()),
-                               GetAllSubresources());
-}
-
-void Texture::TrackAllUsageAndTransitionNow(CommandRecordingContext* commandContext,
-                                            D3D12_RESOURCE_STATES newState) {
-    TrackUsageAndTransitionNow(commandContext, newState, GetAllSubresources());
-}
-
 void Texture::TrackUsageAndTransitionNow(CommandRecordingContext* commandContext,
                                          D3D12_RESOURCE_STATES newState,
                                          const SubresourceRange& range) {
@@ -513,6 +505,7 @@
     // Update the tracked state.
     state->lastState = newState;
 
+    // All simultaneous-access textures are qualified for an implicit promotion.
     // Destination states that qualify for an implicit promotion for a
     // non-simultaneous-access texture: NON_PIXEL_SHADER_RESOURCE,
     // PIXEL_SHADER_RESOURCE, COPY_SRC, COPY_DEST.
@@ -522,7 +515,8 @@
             D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
 
         if (lastState == D3D12_RESOURCE_STATE_COMMON) {
-            if (IsSubset(newState, kD3D12PromotableReadOnlyStates)) {
+            if (IsSubset(newState, kD3D12PromotableReadOnlyStates) ||
+                mD3D12ResourceFlags & D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS) {
                 // Implicit texture state decays can only occur when the texture was implicitly
                 // transitioned to a read-only state. isValidToDecay is needed to differentiate
                 // between resources that were implictly or explicitly transitioned to a
diff --git a/src/dawn/native/d3d12/TextureD3D12.h b/src/dawn/native/d3d12/TextureD3D12.h
index 4af3620..47bcd8e 100644
--- a/src/dawn/native/d3d12/TextureD3D12.h
+++ b/src/dawn/native/d3d12/TextureD3D12.h
@@ -90,10 +90,6 @@
     void TrackUsageAndTransitionNow(CommandRecordingContext* commandContext,
                                     D3D12_RESOURCE_STATES newState,
                                     const SubresourceRange& range);
-    void TrackAllUsageAndTransitionNow(CommandRecordingContext* commandContext,
-                                       wgpu::TextureUsage usage);
-    void TrackAllUsageAndTransitionNow(CommandRecordingContext* commandContext,
-                                       D3D12_RESOURCE_STATES newState);
 
   private:
     using Base = d3d::Texture;