Also use ExternalImageDescriptor in D3D12 and Metal Backends

Bug: chromium:1036080
Change-Id: I358b0441c168ca075b09ab028c2f6d9df2a44d59
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/16240
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Natasha Lee <natlee@microsoft.com>
diff --git a/src/dawn_native/DawnNative.cpp b/src/dawn_native/DawnNative.cpp
index b39b9f2..6e3272b 100644
--- a/src/dawn_native/DawnNative.cpp
+++ b/src/dawn_native/DawnNative.cpp
@@ -171,4 +171,8 @@
         return GetProcMapNamesForTestingInternal();
     }
 
+    ExternalImageDescriptor::ExternalImageDescriptor(ExternalImageDescriptorType type)
+        : type(type) {
+    }
+
 }  // namespace dawn_native
diff --git a/src/dawn_native/d3d12/D3D12Backend.cpp b/src/dawn_native/d3d12/D3D12Backend.cpp
index 2db62da..4e57b54 100644
--- a/src/dawn_native/d3d12/D3D12Backend.cpp
+++ b/src/dawn_native/d3d12/D3D12Backend.cpp
@@ -46,15 +46,27 @@
         return static_cast<WGPUTextureFormat>(impl->GetPreferredFormat());
     }
 
+    ExternalImageDescriptorDXGISharedHandle::ExternalImageDescriptorDXGISharedHandle()
+        : ExternalImageDescriptor(ExternalImageDescriptorType::DXGISharedHandle) {
+    }
+
+    WGPUTexture WrapSharedHandle(WGPUDevice device,
+                                 const ExternalImageDescriptorDXGISharedHandle* descriptor) {
+        Device* backendDevice = reinterpret_cast<Device*>(device);
+        TextureBase* texture = backendDevice->WrapSharedHandle(descriptor, descriptor->sharedHandle,
+                                                               descriptor->acquireMutexKey);
+        return reinterpret_cast<WGPUTexture>(texture);
+    }
+
     WGPUTexture WrapSharedHandle(WGPUDevice device,
                                  const WGPUTextureDescriptor* descriptor,
                                  HANDLE sharedHandle,
                                  uint64_t acquireMutexKey) {
         Device* backendDevice = reinterpret_cast<Device*>(device);
-        const TextureDescriptor* backendDescriptor =
-            reinterpret_cast<const TextureDescriptor*>(descriptor);
+        ExternalImageDescriptorDXGISharedHandle externalDescriptor = {};
+        externalDescriptor.cTextureDescriptor = descriptor;
         TextureBase* texture =
-            backendDevice->WrapSharedHandle(backendDescriptor, sharedHandle, acquireMutexKey);
+            backendDevice->WrapSharedHandle(&externalDescriptor, sharedHandle, acquireMutexKey);
         return reinterpret_cast<WGPUTexture>(texture);
     }
 }}  // namespace dawn_native::d3d12
diff --git a/src/dawn_native/d3d12/DeviceD3D12.cpp b/src/dawn_native/d3d12/DeviceD3D12.cpp
index 085dffd..5ec7537 100644
--- a/src/dawn_native/d3d12/DeviceD3D12.cpp
+++ b/src/dawn_native/d3d12/DeviceD3D12.cpp
@@ -312,7 +312,7 @@
                                                          initialUsage);
     }
 
-    TextureBase* Device::WrapSharedHandle(const TextureDescriptor* descriptor,
+    TextureBase* Device::WrapSharedHandle(const ExternalImageDescriptor* descriptor,
                                           HANDLE sharedHandle,
                                           uint64_t acquireMutexKey) {
         TextureBase* dawnTexture;
diff --git a/src/dawn_native/d3d12/DeviceD3D12.h b/src/dawn_native/d3d12/DeviceD3D12.h
index 4817102..311f150 100644
--- a/src/dawn_native/d3d12/DeviceD3D12.h
+++ b/src/dawn_native/d3d12/DeviceD3D12.h
@@ -98,7 +98,7 @@
 
         ShaderVisibleDescriptorAllocator* GetShaderVisibleDescriptorAllocator() const;
 
-        TextureBase* WrapSharedHandle(const TextureDescriptor* descriptor,
+        TextureBase* WrapSharedHandle(const ExternalImageDescriptor* descriptor,
                                       HANDLE sharedHandle,
                                       uint64_t acquireMutexKey);
         ResultOrError<ComPtr<IDXGIKeyedMutex>> CreateKeyedMutexForTexture(
diff --git a/src/dawn_native/d3d12/TextureD3D12.cpp b/src/dawn_native/d3d12/TextureD3D12.cpp
index fa1cc2c..0165232 100644
--- a/src/dawn_native/d3d12/TextureD3D12.cpp
+++ b/src/dawn_native/d3d12/TextureD3D12.cpp
@@ -280,13 +280,16 @@
     }
 
     ResultOrError<TextureBase*> Texture::Create(Device* device,
-                                                const TextureDescriptor* descriptor,
+                                                const ExternalImageDescriptor* descriptor,
                                                 HANDLE sharedHandle,
                                                 uint64_t acquireMutexKey) {
+        const TextureDescriptor* textureDescriptor =
+            reinterpret_cast<const TextureDescriptor*>(descriptor->cTextureDescriptor);
+
         Ref<Texture> dawnTexture =
-            AcquireRef(new Texture(device, descriptor, TextureState::OwnedExternal));
-        DAWN_TRY(
-            dawnTexture->InitializeAsExternalTexture(descriptor, sharedHandle, acquireMutexKey));
+            AcquireRef(new Texture(device, textureDescriptor, TextureState::OwnedExternal));
+        DAWN_TRY(dawnTexture->InitializeAsExternalTexture(textureDescriptor, sharedHandle,
+                                                          acquireMutexKey));
         return dawnTexture.Detach();
     }
 
diff --git a/src/dawn_native/d3d12/TextureD3D12.h b/src/dawn_native/d3d12/TextureD3D12.h
index 332ab5a..3bbbeb4 100644
--- a/src/dawn_native/d3d12/TextureD3D12.h
+++ b/src/dawn_native/d3d12/TextureD3D12.h
@@ -18,6 +18,7 @@
 #include "common/Serial.h"
 #include "dawn_native/Texture.h"
 
+#include "dawn_native/DawnNative.h"
 #include "dawn_native/d3d12/ResourceHeapAllocationD3D12.h"
 #include "dawn_native/d3d12/d3d12_platform.h"
 
@@ -36,7 +37,7 @@
         static ResultOrError<TextureBase*> Create(Device* device,
                                                   const TextureDescriptor* descriptor);
         static ResultOrError<TextureBase*> Create(Device* device,
-                                                  const TextureDescriptor* descriptor,
+                                                  const ExternalImageDescriptor* descriptor,
                                                   HANDLE sharedHandle,
                                                   uint64_t acquireMutexKey);
         Texture(Device* device,
diff --git a/src/dawn_native/metal/DeviceMTL.h b/src/dawn_native/metal/DeviceMTL.h
index d881ea0..6fa5b72 100644
--- a/src/dawn_native/metal/DeviceMTL.h
+++ b/src/dawn_native/metal/DeviceMTL.h
@@ -55,7 +55,7 @@
 
         MapRequestTracker* GetMapTracker() const;
 
-        TextureBase* CreateTextureWrappingIOSurface(const TextureDescriptor* descriptor,
+        TextureBase* CreateTextureWrappingIOSurface(const ExternalImageDescriptor* descriptor,
                                                     IOSurfaceRef ioSurface,
                                                     uint32_t plane);
         void WaitForCommandsToBeScheduled();
diff --git a/src/dawn_native/metal/DeviceMTL.mm b/src/dawn_native/metal/DeviceMTL.mm
index d449d48..8869b68 100644
--- a/src/dawn_native/metal/DeviceMTL.mm
+++ b/src/dawn_native/metal/DeviceMTL.mm
@@ -269,13 +269,16 @@
         return {};
     }
 
-    TextureBase* Device::CreateTextureWrappingIOSurface(const TextureDescriptor* descriptor,
+    TextureBase* Device::CreateTextureWrappingIOSurface(const ExternalImageDescriptor* descriptor,
                                                         IOSurfaceRef ioSurface,
                                                         uint32_t plane) {
-        if (ConsumedError(ValidateTextureDescriptor(this, descriptor))) {
+        const TextureDescriptor* textureDescriptor =
+            reinterpret_cast<const TextureDescriptor*>(descriptor->cTextureDescriptor);
+        if (ConsumedError(ValidateTextureDescriptor(this, textureDescriptor))) {
             return nullptr;
         }
-        if (ConsumedError(ValidateIOSurfaceCanBeWrapped(this, descriptor, ioSurface, plane))) {
+        if (ConsumedError(
+                ValidateIOSurfaceCanBeWrapped(this, textureDescriptor, ioSurface, plane))) {
             return nullptr;
         }
 
diff --git a/src/dawn_native/metal/MetalBackend.mm b/src/dawn_native/metal/MetalBackend.mm
index 22b583a..ac65399 100644
--- a/src/dawn_native/metal/MetalBackend.mm
+++ b/src/dawn_native/metal/MetalBackend.mm
@@ -27,14 +27,27 @@
         return device->GetMTLDevice();
     }
 
+    ExternalImageDescriptorIOSurface::ExternalImageDescriptorIOSurface()
+        : ExternalImageDescriptor(ExternalImageDescriptorType::IOSurface) {
+    }
+
+    WGPUTexture WrapIOSurface(WGPUDevice cDevice,
+                              const ExternalImageDescriptorIOSurface* cDescriptor) {
+        Device* device = reinterpret_cast<Device*>(cDevice);
+        TextureBase* texture = device->CreateTextureWrappingIOSurface(
+            cDescriptor, cDescriptor->ioSurface, cDescriptor->plane);
+        return reinterpret_cast<WGPUTexture>(texture);
+    }
+
     WGPUTexture WrapIOSurface(WGPUDevice cDevice,
                               const WGPUTextureDescriptor* cDescriptor,
                               IOSurfaceRef ioSurface,
                               uint32_t plane) {
         Device* device = reinterpret_cast<Device*>(cDevice);
-        const TextureDescriptor* descriptor =
-            reinterpret_cast<const TextureDescriptor*>(cDescriptor);
-        TextureBase* texture = device->CreateTextureWrappingIOSurface(descriptor, ioSurface, plane);
+        ExternalImageDescriptorIOSurface descriptor = {};
+        descriptor.cTextureDescriptor = cDescriptor;
+        TextureBase* texture =
+            device->CreateTextureWrappingIOSurface(&descriptor, ioSurface, plane);
         return reinterpret_cast<WGPUTexture>(texture);
     }
 
diff --git a/src/dawn_native/metal/TextureMTL.h b/src/dawn_native/metal/TextureMTL.h
index 1929459..0b18089 100644
--- a/src/dawn_native/metal/TextureMTL.h
+++ b/src/dawn_native/metal/TextureMTL.h
@@ -19,6 +19,7 @@
 
 #include <IOSurface/IOSurfaceRef.h>
 #import <Metal/Metal.h>
+#include "dawn_native/DawnNative.h"
 
 namespace dawn_native { namespace metal {
 
@@ -35,7 +36,7 @@
         Texture(Device* device, const TextureDescriptor* descriptor);
         Texture(Device* device, const TextureDescriptor* descriptor, id<MTLTexture> mtlTexture);
         Texture(Device* device,
-                const TextureDescriptor* descriptor,
+                const ExternalImageDescriptor* descriptor,
                 IOSurfaceRef ioSurface,
                 uint32_t plane);
         ~Texture();
diff --git a/src/dawn_native/metal/TextureMTL.mm b/src/dawn_native/metal/TextureMTL.mm
index 23ca25f..fbaf1fc 100644
--- a/src/dawn_native/metal/TextureMTL.mm
+++ b/src/dawn_native/metal/TextureMTL.mm
@@ -335,11 +335,14 @@
     }
 
     Texture::Texture(Device* device,
-                     const TextureDescriptor* descriptor,
+                     const ExternalImageDescriptor* descriptor,
                      IOSurfaceRef ioSurface,
                      uint32_t plane)
-        : TextureBase(device, descriptor, TextureState::OwnedInternal) {
-        MTLTextureDescriptor* mtlDesc = CreateMetalTextureDescriptor(descriptor);
+        : TextureBase(device,
+                      reinterpret_cast<const TextureDescriptor*>(descriptor->cTextureDescriptor),
+                      TextureState::OwnedInternal) {
+        MTLTextureDescriptor* mtlDesc = CreateMetalTextureDescriptor(
+            reinterpret_cast<const TextureDescriptor*>(descriptor->cTextureDescriptor));
         mtlDesc.storageMode = kIOSurfaceStorageMode;
         mMtlTexture = [device->GetMTLDevice() newTextureWithDescriptor:mtlDesc
                                                              iosurface:ioSurface
diff --git a/src/dawn_native/vulkan/DeviceVk.h b/src/dawn_native/vulkan/DeviceVk.h
index 7175710..a4445f2 100644
--- a/src/dawn_native/vulkan/DeviceVk.h
+++ b/src/dawn_native/vulkan/DeviceVk.h
@@ -36,7 +36,6 @@
     class Adapter;
     class BufferUploader;
     class DescriptorSetService;
-    struct ExternalImageDescriptor;
     class FencedDeleter;
     class MapRequestTracker;
     class RenderPassCache;
diff --git a/src/dawn_native/vulkan/TextureVk.h b/src/dawn_native/vulkan/TextureVk.h
index f904452..2c898ff 100644
--- a/src/dawn_native/vulkan/TextureVk.h
+++ b/src/dawn_native/vulkan/TextureVk.h
@@ -26,7 +26,6 @@
 
     struct CommandRecordingContext;
     class Device;
-    struct ExternalImageDescriptor;
 
     VkFormat VulkanImageFormat(const Device* device, wgpu::TextureFormat format);
     VkImageUsageFlags VulkanImageUsage(wgpu::TextureUsage usage, const Format& format);
diff --git a/src/dawn_native/vulkan/VulkanBackend.cpp b/src/dawn_native/vulkan/VulkanBackend.cpp
index 2a9361f..f24d8ca 100644
--- a/src/dawn_native/vulkan/VulkanBackend.cpp
+++ b/src/dawn_native/vulkan/VulkanBackend.cpp
@@ -60,10 +60,6 @@
     }
 
 #ifdef DAWN_PLATFORM_LINUX
-    ExternalImageDescriptor::ExternalImageDescriptor(ExternalImageDescriptorType type)
-        : type(type) {
-    }
-
     ExternalImageDescriptorFD::ExternalImageDescriptorFD(ExternalImageDescriptorType type)
         : ExternalImageDescriptor(type) {
     }
diff --git a/src/include/dawn_native/D3D12Backend.h b/src/include/dawn_native/D3D12Backend.h
index de12d64..1506e91 100644
--- a/src/include/dawn_native/D3D12Backend.h
+++ b/src/include/dawn_native/D3D12Backend.h
@@ -30,6 +30,18 @@
     DAWN_NATIVE_EXPORT WGPUTextureFormat
     GetNativeSwapChainPreferredFormat(const DawnSwapChainImplementation* swapChain);
 
+    struct DAWN_NATIVE_EXPORT ExternalImageDescriptorDXGISharedHandle : ExternalImageDescriptor {
+      public:
+        ExternalImageDescriptorDXGISharedHandle();
+
+        HANDLE sharedHandle;
+        uint64_t acquireMutexKey;
+    };
+
+    // Note: SharedHandle must be a handle to a texture object.
+    DAWN_NATIVE_EXPORT WGPUTexture
+    WrapSharedHandle(WGPUDevice device, const ExternalImageDescriptorDXGISharedHandle* descriptor);
+
     // Note: SharedHandle must be a handle to a texture object.
     DAWN_NATIVE_EXPORT WGPUTexture WrapSharedHandle(WGPUDevice device,
                                                     const WGPUTextureDescriptor* descriptor,
diff --git a/src/include/dawn_native/DawnNative.h b/src/include/dawn_native/DawnNative.h
index 0230cca..0a6a286 100644
--- a/src/include/dawn_native/DawnNative.h
+++ b/src/include/dawn_native/DawnNative.h
@@ -185,6 +185,24 @@
     DAWN_NATIVE_EXPORT uint64_t AcquireErrorInjectorCallCount();
     DAWN_NATIVE_EXPORT void InjectErrorAt(uint64_t index);
 
+    // The different types of ExternalImageDescriptors
+    enum ExternalImageDescriptorType {
+        OpaqueFD,
+        DmaBuf,
+        IOSurface,
+        DXGISharedHandle,
+    };
+
+    // Common properties of external images
+    struct DAWN_NATIVE_EXPORT ExternalImageDescriptor {
+      public:
+        const ExternalImageDescriptorType type;
+        const WGPUTextureDescriptor* cTextureDescriptor;  // Must match image creation params
+        bool isCleared;  // Sets whether the texture will be cleared before use
+
+      protected:
+        ExternalImageDescriptor(ExternalImageDescriptorType type);
+    };
 }  // namespace dawn_native
 
 #endif  // DAWNNATIVE_DAWNNATIVE_H_
diff --git a/src/include/dawn_native/MetalBackend.h b/src/include/dawn_native/MetalBackend.h
index 6e07c05..7ed458e 100644
--- a/src/include/dawn_native/MetalBackend.h
+++ b/src/include/dawn_native/MetalBackend.h
@@ -33,6 +33,17 @@
 #endif  //__OBJC__
 
 namespace dawn_native { namespace metal {
+    struct DAWN_NATIVE_EXPORT ExternalImageDescriptorIOSurface : ExternalImageDescriptor {
+      public:
+        ExternalImageDescriptorIOSurface();
+
+        IOSurfaceRef ioSurface;
+        uint32_t plane;
+    };
+
+    DAWN_NATIVE_EXPORT WGPUTexture
+    WrapIOSurface(WGPUDevice device, const ExternalImageDescriptorIOSurface* descriptor);
+
     DAWN_NATIVE_EXPORT WGPUTexture WrapIOSurface(WGPUDevice device,
                                                  const WGPUTextureDescriptor* descriptor,
                                                  IOSurfaceRef ioSurface,
diff --git a/src/include/dawn_native/VulkanBackend.h b/src/include/dawn_native/VulkanBackend.h
index 005a655..b144e4e 100644
--- a/src/include/dawn_native/VulkanBackend.h
+++ b/src/include/dawn_native/VulkanBackend.h
@@ -23,26 +23,6 @@
 #include <vector>
 
 namespace dawn_native { namespace vulkan {
-
-    // The different types of ExternalImageDescriptors
-    enum ExternalImageDescriptorType {
-#ifdef __linux__
-        OpaqueFD,
-        DmaBuf,
-#endif  // __linux__
-    };
-
-    // Common properties of external images
-    struct DAWN_NATIVE_EXPORT ExternalImageDescriptor {
-      public:
-        const ExternalImageDescriptorType type;           // Must match the subclass
-        const WGPUTextureDescriptor* cTextureDescriptor;  // Must match image creation params
-        bool isCleared;  // Sets whether the texture will be cleared before use
-
-      protected:
-        ExternalImageDescriptor(ExternalImageDescriptorType type);
-    };
-
     DAWN_NATIVE_EXPORT VkInstance GetInstance(WGPUDevice device);
 
     DAWN_NATIVE_EXPORT PFN_vkVoidFunction GetInstanceProcAddr(WGPUDevice device, const char* pName);
diff --git a/src/tests/end2end/D3D12ResourceWrappingTests.cpp b/src/tests/end2end/D3D12ResourceWrappingTests.cpp
index cbc7413..4aced27 100644
--- a/src/tests/end2end/D3D12ResourceWrappingTests.cpp
+++ b/src/tests/end2end/D3D12ResourceWrappingTests.cpp
@@ -102,9 +102,13 @@
                 &sharedHandle);
             ASSERT_EQ(hr, S_OK);
 
-            WGPUTexture texture = dawn_native::d3d12::WrapSharedHandle(
-                device.Get(), reinterpret_cast<const WGPUTextureDescriptor*>(dawnDescriptor),
-                sharedHandle, 0);
+            dawn_native::d3d12::ExternalImageDescriptorDXGISharedHandle externDesc;
+            externDesc.cTextureDescriptor =
+                reinterpret_cast<const WGPUTextureDescriptor*>(dawnDescriptor);
+            externDesc.sharedHandle = sharedHandle;
+            externDesc.acquireMutexKey = 0;
+            WGPUTexture texture = dawn_native::d3d12::WrapSharedHandle(device.Get(), &externDesc);
+
             // Now that we've created all of our resources, we can close the handle
             // since we no longer need it.
             ::CloseHandle(sharedHandle);
@@ -329,9 +333,12 @@
         hr = dxgiKeyedMutex->ReleaseSync(1);
         ASSERT_EQ(hr, S_OK);
 
-        WGPUTexture dawnTexture = dawn_native::d3d12::WrapSharedHandle(
-            device.Get(), reinterpret_cast<const WGPUTextureDescriptor*>(dawnDescriptor),
-            sharedHandle, 1);
+        dawn_native::d3d12::ExternalImageDescriptorDXGISharedHandle externDesc;
+        externDesc.cTextureDescriptor =
+            reinterpret_cast<const WGPUTextureDescriptor*>(dawnDescriptor);
+        externDesc.sharedHandle = sharedHandle;
+        externDesc.acquireMutexKey = 1;
+        WGPUTexture dawnTexture = dawn_native::d3d12::WrapSharedHandle(device.Get(), &externDesc);
 
         *dawnTextureOut = wgpu::Texture::Acquire(dawnTexture);
         *d3d11TextureOut = d3d11Texture.Detach();
diff --git a/src/tests/end2end/IOSurfaceWrappingTests.cpp b/src/tests/end2end/IOSurfaceWrappingTests.cpp
index cc0b203..1119309 100644
--- a/src/tests/end2end/IOSurfaceWrappingTests.cpp
+++ b/src/tests/end2end/IOSurfaceWrappingTests.cpp
@@ -96,9 +96,12 @@
         wgpu::Texture WrapIOSurface(const wgpu::TextureDescriptor* descriptor,
                                     IOSurfaceRef ioSurface,
                                     uint32_t plane) {
-            WGPUTexture texture = dawn_native::metal::WrapIOSurface(
-                device.Get(), reinterpret_cast<const WGPUTextureDescriptor*>(descriptor), ioSurface,
-                plane);
+            dawn_native::metal::ExternalImageDescriptorIOSurface externDesc;
+            externDesc.cTextureDescriptor =
+                reinterpret_cast<const WGPUTextureDescriptor*>(descriptor);
+            externDesc.ioSurface = ioSurface;
+            externDesc.plane = plane;
+            WGPUTexture texture = dawn_native::metal::WrapIOSurface(device.Get(), &externDesc);
             return wgpu::Texture::Acquire(texture);
         }
     };