D3D12: Use Texture::Create pattern for swapchain textures

Bug: dawn:269
Change-Id: Ia4b48126c153ddff2feefc1bf04dcc9adc783bd1
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/37421
Auto-Submit: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Rafael Cintron <rafael.cintron@microsoft.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_native/d3d12/DeviceD3D12.cpp b/src/dawn_native/d3d12/DeviceD3D12.cpp
index a03b048..c41c87f 100644
--- a/src/dawn_native/d3d12/DeviceD3D12.cpp
+++ b/src/dawn_native/d3d12/DeviceD3D12.cpp
@@ -446,13 +446,13 @@
                                               HANDLE sharedHandle,
                                               ExternalMutexSerial acquireMutexKey,
                                               bool isSwapChainTexture) {
-        Ref<TextureBase> dawnTexture;
+        Ref<Texture> dawnTexture;
         if (ConsumedError(Texture::Create(this, descriptor, sharedHandle, acquireMutexKey,
                                           isSwapChainTexture),
-                          &dawnTexture))
+                          &dawnTexture)) {
             return nullptr;
-
-        return dawnTexture;
+        }
+        return {dawnTexture};
     }
 
     // We use IDXGIKeyedMutexes to synchronize access between D3D11 and D3D12. D3D11/12 fences
diff --git a/src/dawn_native/d3d12/SwapChainD3D12.cpp b/src/dawn_native/d3d12/SwapChainD3D12.cpp
index 7479805..4d890bf 100644
--- a/src/dawn_native/d3d12/SwapChainD3D12.cpp
+++ b/src/dawn_native/d3d12/SwapChainD3D12.cpp
@@ -36,16 +36,24 @@
     }
 
     TextureBase* SwapChain::GetNextTextureImpl(const TextureDescriptor* descriptor) {
+        DeviceBase* device = GetDevice();
         const auto& im = GetImplementation();
         DawnSwapChainNextTexture next = {};
         DawnSwapChainError error = im.GetNextTexture(im.userData, &next);
         if (error) {
-            GetDevice()->HandleError(InternalErrorType::Internal, error);
+            device->HandleError(InternalErrorType::Internal, error);
             return nullptr;
         }
 
         ComPtr<ID3D12Resource> d3d12Texture = static_cast<ID3D12Resource*>(next.texture.ptr);
-        return new Texture(ToBackend(GetDevice()), descriptor, std::move(d3d12Texture));
+        Ref<Texture> dawnTexture;
+        if (device->ConsumedError(
+                Texture::Create(ToBackend(GetDevice()), descriptor, std::move(d3d12Texture)),
+                &dawnTexture)) {
+            return nullptr;
+        }
+
+        return dawnTexture.Detach();
     }
 
     MaybeError SwapChain::OnBeforePresent(TextureViewBase* view) {
diff --git a/src/dawn_native/d3d12/TextureD3D12.cpp b/src/dawn_native/d3d12/TextureD3D12.cpp
index 0cac08b..675577d 100644
--- a/src/dawn_native/d3d12/TextureD3D12.cpp
+++ b/src/dawn_native/d3d12/TextureD3D12.cpp
@@ -378,19 +378,21 @@
         return {};
     }
 
-    ResultOrError<Ref<TextureBase>> Texture::Create(Device* device,
-                                                    const TextureDescriptor* descriptor) {
+    // static
+    ResultOrError<Ref<Texture>> Texture::Create(Device* device,
+                                                const TextureDescriptor* descriptor) {
         Ref<Texture> dawnTexture =
             AcquireRef(new Texture(device, descriptor, TextureState::OwnedInternal));
         DAWN_TRY(dawnTexture->InitializeAsInternalTexture());
         return std::move(dawnTexture);
     }
 
-    ResultOrError<Ref<TextureBase>> Texture::Create(Device* device,
-                                                    const ExternalImageDescriptor* descriptor,
-                                                    HANDLE sharedHandle,
-                                                    ExternalMutexSerial acquireMutexKey,
-                                                    bool isSwapChainTexture) {
+    // static
+    ResultOrError<Ref<Texture>> Texture::Create(Device* device,
+                                                const ExternalImageDescriptor* descriptor,
+                                                HANDLE sharedHandle,
+                                                ExternalMutexSerial acquireMutexKey,
+                                                bool isSwapChainTexture) {
         const TextureDescriptor* textureDescriptor =
             reinterpret_cast<const TextureDescriptor*>(descriptor->cTextureDescriptor);
 
@@ -403,6 +405,16 @@
         return std::move(dawnTexture);
     }
 
+    // static
+    ResultOrError<Ref<Texture>> Texture::Create(Device* device,
+                                                const TextureDescriptor* descriptor,
+                                                ComPtr<ID3D12Resource> d3d12Texture) {
+        Ref<Texture> dawnTexture =
+            AcquireRef(new Texture(device, descriptor, TextureState::OwnedExternal));
+        DAWN_TRY(dawnTexture->InitializeAsSwapChainTexture(std::move(d3d12Texture)));
+        return std::move(dawnTexture);
+    }
+
     MaybeError Texture::InitializeAsExternalTexture(const TextureDescriptor* descriptor,
                                                     HANDLE sharedHandle,
                                                     ExternalMutexSerial acquireMutexKey,
@@ -485,25 +497,24 @@
         return {};
     }
 
-    Texture::Texture(Device* device, const TextureDescriptor* descriptor, TextureState state)
-        : TextureBase(device, descriptor, state),
-          mSubresourceStateAndDecay(
-              GetSubresourceCount(),
-              {D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_COMMON, kMaxExecutionSerial, false}) {
-    }
-
-    Texture::Texture(Device* device,
-                     const TextureDescriptor* descriptor,
-                     ComPtr<ID3D12Resource> nativeTexture)
-        : Texture(device, descriptor, TextureState::OwnedExternal) {
+    MaybeError Texture::InitializeAsSwapChainTexture(ComPtr<ID3D12Resource> d3d12Texture) {
         AllocationInfo info;
         info.mMethod = AllocationMethod::kExternal;
         // 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(nativeTexture), nullptr};
+        mResourceAllocation = { info, 0, std::move(d3d12Texture), nullptr };
 
         SetIsSubresourceContentInitialized(true, GetAllSubresources());
+
+        return {};
+    }
+
+    Texture::Texture(Device* device, const TextureDescriptor* descriptor, TextureState state)
+        : TextureBase(device, descriptor, state),
+          mSubresourceStateAndDecay(
+              GetSubresourceCount(),
+              {D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_COMMON, kMaxExecutionSerial, false}) {
     }
 
     Texture::~Texture() {
diff --git a/src/dawn_native/d3d12/TextureD3D12.h b/src/dawn_native/d3d12/TextureD3D12.h
index 5d7aab7..79539eb 100644
--- a/src/dawn_native/d3d12/TextureD3D12.h
+++ b/src/dawn_native/d3d12/TextureD3D12.h
@@ -36,16 +36,16 @@
 
     class Texture final : public TextureBase {
       public:
-        static ResultOrError<Ref<TextureBase>> Create(Device* device,
-                                                      const TextureDescriptor* descriptor);
-        static ResultOrError<Ref<TextureBase>> Create(Device* device,
-                                                      const ExternalImageDescriptor* descriptor,
-                                                      HANDLE sharedHandle,
-                                                      ExternalMutexSerial acquireMutexKey,
-                                                      bool isSwapChainTexture);
-        Texture(Device* device,
-                const TextureDescriptor* descriptor,
-                ComPtr<ID3D12Resource> d3d12Texture);
+        static ResultOrError<Ref<Texture>> Create(Device* device,
+                                                  const TextureDescriptor* descriptor);
+        static ResultOrError<Ref<Texture>> Create(Device* device,
+                                                  const ExternalImageDescriptor* descriptor,
+                                                  HANDLE sharedHandle,
+                                                  ExternalMutexSerial acquireMutexKey,
+                                                  bool isSwapChainTexture);
+        static ResultOrError<Ref<Texture>> Create(Device* device,
+                                                  const TextureDescriptor* descriptor,
+                                                  ComPtr<ID3D12Resource> d3d12Texture);
 
         DXGI_FORMAT GetD3D12Format() const;
         ID3D12Resource* GetD3D12Resource() const;
@@ -88,6 +88,7 @@
                                                HANDLE sharedHandle,
                                                ExternalMutexSerial acquireMutexKey,
                                                bool isSwapChainTexture);
+        MaybeError InitializeAsSwapChainTexture(ComPtr<ID3D12Resource> d3d12Texture);
 
         // Dawn API
         void DestroyImpl() override;