diff --git a/src/dawn_native/DawnNative.cpp b/src/dawn_native/DawnNative.cpp
index b166c44..498d9b1 100644
--- a/src/dawn_native/DawnNative.cpp
+++ b/src/dawn_native/DawnNative.cpp
@@ -278,12 +278,20 @@
 
     // ExternalImageDescriptor
 
-    ExternalImageDescriptor::ExternalImageDescriptor(ExternalImageType type) : type(type) {
+    ExternalImageDescriptor::ExternalImageDescriptor(ExternalImageType type) : mType(type) {
+    }
+
+    ExternalImageType ExternalImageDescriptor::GetType() const {
+        return mType;
     }
 
     // ExternalImageExportInfo
 
-    ExternalImageExportInfo::ExternalImageExportInfo(ExternalImageType type) : type(type) {
+    ExternalImageExportInfo::ExternalImageExportInfo(ExternalImageType type) : mType(type) {
+    }
+
+    ExternalImageType ExternalImageExportInfo::GetType() const {
+        return mType;
     }
 
     const char* GetObjectLabelForTesting(void* objectHandle) {
diff --git a/src/dawn_native/vulkan/VulkanBackend.cpp b/src/dawn_native/vulkan/VulkanBackend.cpp
index f15cb8a..f7e3560 100644
--- a/src/dawn_native/vulkan/VulkanBackend.cpp
+++ b/src/dawn_native/vulkan/VulkanBackend.cpp
@@ -83,7 +83,7 @@
 
     WGPUTexture WrapVulkanImage(WGPUDevice device, const ExternalImageDescriptorVk* descriptor) {
 #if defined(DAWN_PLATFORM_LINUX)
-        switch (descriptor->type) {
+        switch (descriptor->GetType()) {
             case ExternalImageType::OpaqueFD:
             case ExternalImageType::DmaBuf: {
                 Device* backendDevice = ToBackend(FromAPI(device));
@@ -108,7 +108,7 @@
             return false;
         }
 #if defined(DAWN_PLATFORM_LINUX)
-        switch (info->type) {
+        switch (info->GetType()) {
             case ExternalImageType::OpaqueFD:
             case ExternalImageType::DmaBuf: {
                 Texture* backendTexture = ToBackend(FromAPI(texture));
diff --git a/src/dawn_native/vulkan/external_memory/MemoryServiceDmaBuf.cpp b/src/dawn_native/vulkan/external_memory/MemoryServiceDmaBuf.cpp
index 2bf8874..8cdd5ba 100644
--- a/src/dawn_native/vulkan/external_memory/MemoryServiceDmaBuf.cpp
+++ b/src/dawn_native/vulkan/external_memory/MemoryServiceDmaBuf.cpp
@@ -144,7 +144,7 @@
         if (!mSupported) {
             return false;
         }
-        if (descriptor->type != ExternalImageType::DmaBuf) {
+        if (descriptor->GetType() != ExternalImageType::DmaBuf) {
             return false;
         }
         const ExternalImageDescriptorDmaBuf* dmaBufDescriptor =
@@ -226,7 +226,7 @@
     ResultOrError<MemoryImportParams> Service::GetMemoryImportParams(
         const ExternalImageDescriptor* descriptor,
         VkImage image) {
-        DAWN_INVALID_IF(descriptor->type != ExternalImageType::DmaBuf,
+        DAWN_INVALID_IF(descriptor->GetType() != ExternalImageType::DmaBuf,
                         "ExternalImageDescriptor is not a ExternalImageDescriptorDmaBuf.");
 
         const ExternalImageDescriptorDmaBuf* dmaBufDescriptor =
@@ -290,7 +290,7 @@
 
     ResultOrError<VkImage> Service::CreateImage(const ExternalImageDescriptor* descriptor,
                                                 const VkImageCreateInfo& baseCreateInfo) {
-        DAWN_INVALID_IF(descriptor->type != ExternalImageType::DmaBuf,
+        DAWN_INVALID_IF(descriptor->GetType() != ExternalImageType::DmaBuf,
                         "ExternalImageDescriptor is not a dma-buf descriptor.");
 
         const ExternalImageDescriptorDmaBuf* dmaBufDescriptor =
diff --git a/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp b/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp
index e8762d2..181a17b 100644
--- a/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp
+++ b/src/dawn_native/vulkan/external_memory/MemoryServiceOpaqueFD.cpp
@@ -90,7 +90,7 @@
     ResultOrError<MemoryImportParams> Service::GetMemoryImportParams(
         const ExternalImageDescriptor* descriptor,
         VkImage image) {
-        DAWN_INVALID_IF(descriptor->type != ExternalImageType::OpaqueFD,
+        DAWN_INVALID_IF(descriptor->GetType() != ExternalImageType::OpaqueFD,
                         "ExternalImageDescriptor is not an OpaqueFD descriptor.");
 
         const ExternalImageDescriptorOpaqueFD* opaqueFDDescriptor =
diff --git a/src/include/dawn_native/DawnNative.h b/src/include/dawn_native/DawnNative.h
index e8a6e13..4850d8c 100644
--- a/src/include/dawn_native/DawnNative.h
+++ b/src/include/dawn_native/DawnNative.h
@@ -217,12 +217,15 @@
     // Common properties of external images
     struct DAWN_NATIVE_EXPORT ExternalImageDescriptor {
       public:
-        const ExternalImageType type;
         const WGPUTextureDescriptor* cTextureDescriptor;  // Must match image creation params
         bool isInitialized;  // Whether the texture is initialized on import
+        ExternalImageType GetType() const;
 
       protected:
         ExternalImageDescriptor(ExternalImageType type);
+
+      private:
+        ExternalImageType mType;
     };
 
     struct DAWN_NATIVE_EXPORT ExternalImageAccessDescriptor {
@@ -233,11 +236,14 @@
 
     struct DAWN_NATIVE_EXPORT ExternalImageExportInfo {
       public:
-        const ExternalImageType type;
         bool isInitialized;  // Whether the texture is initialized after export
+        ExternalImageType GetType() const;
 
       protected:
         ExternalImageExportInfo(ExternalImageType type);
+
+      private:
+        ExternalImageType mType;
     };
 
     DAWN_NATIVE_EXPORT const char* GetObjectLabelForTesting(void* objectHandle);
diff --git a/src/tests/BUILD.gn b/src/tests/BUILD.gn
index 6141875..aab52af 100644
--- a/src/tests/BUILD.gn
+++ b/src/tests/BUILD.gn
@@ -494,7 +494,11 @@
     if (is_chromeos) {
       sources += [ "white_box/VulkanImageWrappingTestsDmaBuf.cpp" ]
     } else if (is_linux) {
-      sources += [ "white_box/VulkanImageWrappingTestsOpaqueFD.cpp" ]
+      sources += [
+        "white_box/VulkanImageWrappingTests.cpp",
+        "white_box/VulkanImageWrappingTests.h",
+        "white_box/VulkanImageWrappingTests_OpaqueFD.cpp",
+      ]
     }
 
     if (dawn_enable_error_injection) {
diff --git a/src/tests/white_box/VulkanImageWrappingTests.cpp b/src/tests/white_box/VulkanImageWrappingTests.cpp
new file mode 100644
index 0000000..7cf1df0
--- /dev/null
+++ b/src/tests/white_box/VulkanImageWrappingTests.cpp
@@ -0,0 +1,793 @@
+// Copyright 2021 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "tests/white_box/VulkanImageWrappingTests.h"
+
+#include "common/Math.h"
+#include "dawn_native/vulkan/AdapterVk.h"
+#include "dawn_native/vulkan/DeviceVk.h"
+#include "tests/DawnTest.h"
+#include "utils/WGPUHelpers.h"
+
+namespace dawn::native { namespace vulkan {
+
+    using ExternalTexture = VulkanImageWrappingTestBackend::ExternalTexture;
+    using ExternalSemaphore = VulkanImageWrappingTestBackend::ExternalSemaphore;
+
+    ExternalImageDescriptorVkForTesting::ExternalImageDescriptorVkForTesting()
+        : ExternalImageDescriptorVk(ExternalImageType::OpaqueFD) {
+    }
+    ExternalImageExportInfoVkForTesting::ExternalImageExportInfoVkForTesting()
+        : ExternalImageExportInfoVk(ExternalImageType::OpaqueFD) {
+    }
+
+    namespace {
+
+        class VulkanImageWrappingTestBase : public DawnTest {
+          protected:
+            std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
+                return {wgpu::FeatureName::DawnInternalUsages};
+            }
+
+          public:
+            void SetUp() override {
+                DawnTest::SetUp();
+                DAWN_TEST_UNSUPPORTED_IF(UsesWire());
+
+                mBackend = VulkanImageWrappingTestBackend::Create(device);
+
+                defaultDescriptor.dimension = wgpu::TextureDimension::e2D;
+                defaultDescriptor.format = wgpu::TextureFormat::RGBA8Unorm;
+                defaultDescriptor.size = {1, 1, 1};
+                defaultDescriptor.sampleCount = 1;
+                defaultDescriptor.mipLevelCount = 1;
+                defaultDescriptor.usage = wgpu::TextureUsage::RenderAttachment |
+                                          wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
+
+                defaultTexture = mBackend->CreateTexture(1, 1, defaultDescriptor.format,
+                                                         defaultDescriptor.usage);
+            }
+
+            void TearDown() override {
+                if (UsesWire()) {
+                    DawnTest::TearDown();
+                    return;
+                }
+
+                defaultTexture = nullptr;
+                mBackend = nullptr;
+                DawnTest::TearDown();
+            }
+
+            wgpu::Texture WrapVulkanImage(
+                wgpu::Device dawnDevice,
+                const wgpu::TextureDescriptor* textureDescriptor,
+                const ExternalTexture* externalTexture,
+                std::vector<std::unique_ptr<ExternalSemaphore>> semaphores,
+                bool isInitialized = true,
+                bool expectValid = true) {
+                ExternalImageDescriptorVkForTesting descriptor;
+                return WrapVulkanImage(dawnDevice, textureDescriptor, externalTexture,
+                                       std::move(semaphores), descriptor.releasedOldLayout,
+                                       descriptor.releasedNewLayout, isInitialized, expectValid);
+            }
+
+            wgpu::Texture WrapVulkanImage(
+                wgpu::Device dawnDevice,
+                const wgpu::TextureDescriptor* textureDescriptor,
+                const ExternalTexture* externalTexture,
+                std::vector<std::unique_ptr<ExternalSemaphore>> semaphores,
+                VkImageLayout releasedOldLayout,
+                VkImageLayout releasedNewLayout,
+                bool isInitialized = true,
+                bool expectValid = true) {
+                ExternalImageDescriptorVkForTesting descriptor;
+                descriptor.cTextureDescriptor =
+                    reinterpret_cast<const WGPUTextureDescriptor*>(textureDescriptor);
+                descriptor.isInitialized = isInitialized;
+                descriptor.releasedOldLayout = releasedOldLayout;
+                descriptor.releasedNewLayout = releasedNewLayout;
+
+                wgpu::Texture texture = mBackend->WrapImage(dawnDevice, externalTexture, descriptor,
+                                                            std::move(semaphores));
+
+                if (expectValid) {
+                    EXPECT_NE(texture, nullptr) << "Failed to wrap image, are external memory / "
+                                                   "semaphore extensions supported?";
+                } else {
+                    EXPECT_EQ(texture, nullptr);
+                }
+
+                return texture;
+            }
+
+            // Exports the signal from a wrapped texture and ignores it
+            // We have to export the signal before destroying the wrapped texture else it's an
+            // assertion failure
+            void IgnoreSignalSemaphore(wgpu::Texture wrappedTexture) {
+                ExternalImageExportInfoVkForTesting exportInfo;
+                bool result =
+                    mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_GENERAL, &exportInfo);
+                ASSERT(result);
+            }
+
+          protected:
+            std::unique_ptr<VulkanImageWrappingTestBackend> mBackend;
+
+            wgpu::TextureDescriptor defaultDescriptor;
+            std::unique_ptr<ExternalTexture> defaultTexture;
+        };
+
+    }  // anonymous namespace
+
+    using VulkanImageWrappingValidationTests = VulkanImageWrappingTestBase;
+
+    // Test no error occurs if the import is valid
+    TEST_P(VulkanImageWrappingValidationTests, SuccessfulImport) {
+        wgpu::Texture texture =
+            WrapVulkanImage(device, &defaultDescriptor, defaultTexture.get(), {}, true, true);
+        EXPECT_NE(texture.Get(), nullptr);
+        IgnoreSignalSemaphore(texture);
+    }
+
+    // Test no error occurs if the import is valid with DawnTextureInternalUsageDescriptor
+    TEST_P(VulkanImageWrappingValidationTests, SuccessfulImportWithInternalUsageDescriptor) {
+        wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
+        defaultDescriptor.nextInChain = &internalDesc;
+        internalDesc.internalUsage = wgpu::TextureUsage::CopySrc;
+        internalDesc.sType = wgpu::SType::DawnTextureInternalUsageDescriptor;
+
+        wgpu::Texture texture =
+            WrapVulkanImage(device, &defaultDescriptor, defaultTexture.get(), {}, true, true);
+        EXPECT_NE(texture.Get(), nullptr);
+        IgnoreSignalSemaphore(texture);
+    }
+
+    // Test an error occurs if an invalid sType is the nextInChain
+    TEST_P(VulkanImageWrappingValidationTests, InvalidTextureDescriptor) {
+        wgpu::ChainedStruct chainedDescriptor;
+        chainedDescriptor.sType = wgpu::SType::SurfaceDescriptorFromWindowsSwapChainPanel;
+        defaultDescriptor.nextInChain = &chainedDescriptor;
+
+        ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapVulkanImage(
+                                device, &defaultDescriptor, defaultTexture.get(), {}, true, false));
+        EXPECT_EQ(texture.Get(), nullptr);
+    }
+
+    // Test an error occurs if the descriptor dimension isn't 2D
+    TEST_P(VulkanImageWrappingValidationTests, InvalidTextureDimension) {
+        defaultDescriptor.dimension = wgpu::TextureDimension::e1D;
+
+        ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapVulkanImage(
+                                device, &defaultDescriptor, defaultTexture.get(), {}, true, false));
+        EXPECT_EQ(texture.Get(), nullptr);
+    }
+
+    // Test an error occurs if the descriptor mip level count isn't 1
+    TEST_P(VulkanImageWrappingValidationTests, InvalidMipLevelCount) {
+        defaultDescriptor.mipLevelCount = 2;
+
+        ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapVulkanImage(
+                                device, &defaultDescriptor, defaultTexture.get(), {}, true, false));
+        EXPECT_EQ(texture.Get(), nullptr);
+    }
+
+    // Test an error occurs if the descriptor depth isn't 1
+    TEST_P(VulkanImageWrappingValidationTests, InvalidDepth) {
+        defaultDescriptor.size.depthOrArrayLayers = 2;
+
+        ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapVulkanImage(
+                                device, &defaultDescriptor, defaultTexture.get(), {}, true, false));
+        EXPECT_EQ(texture.Get(), nullptr);
+    }
+
+    // Test an error occurs if the descriptor sample count isn't 1
+    TEST_P(VulkanImageWrappingValidationTests, InvalidSampleCount) {
+        defaultDescriptor.sampleCount = 4;
+
+        ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapVulkanImage(
+                                device, &defaultDescriptor, defaultTexture.get(), {}, true, false));
+        EXPECT_EQ(texture.Get(), nullptr);
+    }
+
+    // Test an error occurs if we try to export the signal semaphore twice
+    TEST_P(VulkanImageWrappingValidationTests, DoubleSignalSemaphoreExport) {
+        wgpu::Texture texture =
+            WrapVulkanImage(device, &defaultDescriptor, defaultTexture.get(), {}, true, true);
+        ASSERT_NE(texture.Get(), nullptr);
+        IgnoreSignalSemaphore(texture);
+
+        ExternalImageExportInfoVkForTesting exportInfo;
+        ASSERT_DEVICE_ERROR(
+            bool success = mBackend->ExportImage(texture, VK_IMAGE_LAYOUT_GENERAL, &exportInfo));
+        ASSERT_FALSE(success);
+        ASSERT_EQ(exportInfo.semaphores.size(), 0u);
+    }
+
+    // Test an error occurs if we try to export the signal semaphore from a normal texture
+    TEST_P(VulkanImageWrappingValidationTests, NormalTextureSignalSemaphoreExport) {
+        wgpu::Texture texture = device.CreateTexture(&defaultDescriptor);
+        ASSERT_NE(texture.Get(), nullptr);
+
+        ExternalImageExportInfoVkForTesting exportInfo;
+        ASSERT_DEVICE_ERROR(
+            bool success = mBackend->ExportImage(texture, VK_IMAGE_LAYOUT_GENERAL, &exportInfo));
+        ASSERT_FALSE(success);
+        ASSERT_EQ(exportInfo.semaphores.size(), 0u);
+    }
+
+    // Test an error occurs if we try to export the signal semaphore from a destroyed texture
+    TEST_P(VulkanImageWrappingValidationTests, DestroyedTextureSignalSemaphoreExport) {
+        wgpu::Texture texture = device.CreateTexture(&defaultDescriptor);
+        ASSERT_NE(texture.Get(), nullptr);
+        texture.Destroy();
+
+        ExternalImageExportInfoVkForTesting exportInfo;
+        ASSERT_DEVICE_ERROR(
+            bool success = mBackend->ExportImage(texture, VK_IMAGE_LAYOUT_GENERAL, &exportInfo));
+        ASSERT_FALSE(success);
+        ASSERT_EQ(exportInfo.semaphores.size(), 0u);
+    }
+
+    // Fixture to test using external memory textures through different usages.
+    // These tests are skipped if the harness is using the wire.
+    class VulkanImageWrappingUsageTests : public VulkanImageWrappingTestBase {
+      public:
+        void SetUp() override {
+            VulkanImageWrappingTestBase::SetUp();
+            if (UsesWire()) {
+                return;
+            }
+
+            // Create another device based on the original
+            backendAdapter =
+                dawn::native::vulkan::ToBackend(dawn::native::FromAPI(device.Get())->GetAdapter());
+            deviceDescriptor.nextInChain = &togglesDesc;
+            togglesDesc.forceEnabledToggles = GetParam().forceEnabledWorkarounds.data();
+            togglesDesc.forceEnabledTogglesCount = GetParam().forceEnabledWorkarounds.size();
+            togglesDesc.forceDisabledToggles = GetParam().forceDisabledWorkarounds.data();
+            togglesDesc.forceDisabledTogglesCount = GetParam().forceDisabledWorkarounds.size();
+
+            secondDeviceVk =
+                dawn::native::vulkan::ToBackend(backendAdapter->APICreateDevice(&deviceDescriptor));
+            secondDevice = wgpu::Device::Acquire(dawn::native::ToAPI(secondDeviceVk));
+        }
+
+      protected:
+        dawn::native::vulkan::Adapter* backendAdapter;
+        dawn::native::DeviceDescriptor deviceDescriptor;
+        dawn::native::DawnTogglesDeviceDescriptor togglesDesc;
+
+        wgpu::Device secondDevice;
+        dawn::native::vulkan::Device* secondDeviceVk;
+
+        // Clear a texture on a given device
+        void ClearImage(wgpu::Device dawnDevice,
+                        wgpu::Texture wrappedTexture,
+                        wgpu::Color clearColor) {
+            wgpu::TextureView wrappedView = wrappedTexture.CreateView();
+
+            // Submit a clear operation
+            utils::ComboRenderPassDescriptor renderPassDescriptor({wrappedView}, {});
+            renderPassDescriptor.cColorAttachments[0].clearColor = clearColor;
+            renderPassDescriptor.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;
+
+            wgpu::CommandEncoder encoder = dawnDevice.CreateCommandEncoder();
+            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassDescriptor);
+            pass.EndPass();
+
+            wgpu::CommandBuffer commands = encoder.Finish();
+
+            wgpu::Queue queue = dawnDevice.GetQueue();
+            queue.Submit(1, &commands);
+        }
+
+        // Submits a 1x1x1 copy from source to destination
+        void SimpleCopyTextureToTexture(wgpu::Device dawnDevice,
+                                        wgpu::Queue dawnQueue,
+                                        wgpu::Texture source,
+                                        wgpu::Texture destination) {
+            wgpu::ImageCopyTexture copySrc = utils::CreateImageCopyTexture(source, 0, {0, 0, 0});
+            wgpu::ImageCopyTexture copyDst =
+                utils::CreateImageCopyTexture(destination, 0, {0, 0, 0});
+
+            wgpu::Extent3D copySize = {1, 1, 1};
+
+            wgpu::CommandEncoder encoder = dawnDevice.CreateCommandEncoder();
+            encoder.CopyTextureToTexture(&copySrc, &copyDst, &copySize);
+            wgpu::CommandBuffer commands = encoder.Finish();
+
+            dawnQueue.Submit(1, &commands);
+        }
+    };
+
+    // Clear an image in |secondDevice|
+    // Verify clear color is visible in |device|
+    TEST_P(VulkanImageWrappingUsageTests, ClearImageAcrossDevices) {
+        // Import the image on |secondDevice|
+        wgpu::Texture wrappedTexture =
+            WrapVulkanImage(secondDevice, &defaultDescriptor, defaultTexture.get(), {},
+                            VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+
+        // Clear |wrappedTexture| on |secondDevice|
+        ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
+
+        ExternalImageExportInfoVkForTesting exportInfo;
+        ASSERT_TRUE(mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                                          &exportInfo));
+
+        // Import the image to |device|, making sure we wait on signalFd
+        wgpu::Texture nextWrappedTexture = WrapVulkanImage(
+            device, &defaultDescriptor, defaultTexture.get(), std::move(exportInfo.semaphores),
+            exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
+
+        // Verify |device| sees the changes from |secondDevice|
+        EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), nextWrappedTexture, 0, 0);
+
+        IgnoreSignalSemaphore(nextWrappedTexture);
+    }
+
+    // Clear an image in |secondDevice|
+    // Verify clear color is not visible in |device| if we import the texture as not cleared
+    TEST_P(VulkanImageWrappingUsageTests, UninitializedTextureIsCleared) {
+        // Import the image on |secondDevice|
+        wgpu::Texture wrappedTexture =
+            WrapVulkanImage(secondDevice, &defaultDescriptor, defaultTexture.get(), {},
+                            VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+
+        // Clear |wrappedTexture| on |secondDevice|
+        ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
+
+        ExternalImageExportInfoVkForTesting exportInfo;
+        ASSERT_TRUE(mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                                          &exportInfo));
+
+        // Import the image to |device|, making sure we wait on signalFd
+        wgpu::Texture nextWrappedTexture = WrapVulkanImage(
+            device, &defaultDescriptor, defaultTexture.get(), std::move(exportInfo.semaphores),
+            exportInfo.releasedOldLayout, exportInfo.releasedNewLayout, false);
+
+        // Verify |device| doesn't see the changes from |secondDevice|
+        EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 0, 0, 0), nextWrappedTexture, 0, 0);
+
+        IgnoreSignalSemaphore(nextWrappedTexture);
+    }
+
+    // Import a texture into |secondDevice|
+    // Clear the texture on |secondDevice|
+    // Issue a copy of the imported texture inside |device| to |copyDstTexture|
+    // Verify the clear color from |secondDevice| is visible in |copyDstTexture|
+    TEST_P(VulkanImageWrappingUsageTests, CopyTextureToTextureSrcSync) {
+        // Import the image on |secondDevice|
+        wgpu::Texture wrappedTexture =
+            WrapVulkanImage(secondDevice, &defaultDescriptor, defaultTexture.get(), {},
+                            VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+
+        // Clear |wrappedTexture| on |secondDevice|
+        ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
+
+        ExternalImageExportInfoVkForTesting exportInfo;
+        ASSERT_TRUE(mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                                          &exportInfo));
+
+        // Import the image to |device|, making sure we wait on |signalFd|
+        wgpu::Texture deviceWrappedTexture = WrapVulkanImage(
+            device, &defaultDescriptor, defaultTexture.get(), std::move(exportInfo.semaphores),
+            exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
+
+        // Create a second texture on |device|
+        wgpu::Texture copyDstTexture = device.CreateTexture(&defaultDescriptor);
+
+        // Copy |deviceWrappedTexture| into |copyDstTexture|
+        SimpleCopyTextureToTexture(device, queue, deviceWrappedTexture, copyDstTexture);
+
+        // Verify |copyDstTexture| sees changes from |secondDevice|
+        EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), copyDstTexture, 0, 0);
+
+        IgnoreSignalSemaphore(deviceWrappedTexture);
+    }
+
+    // Import a texture into |device|
+    // Clear texture with color A on |device|
+    // Import same texture into |secondDevice|, waiting on the copy signal
+    // Clear the new texture with color B on |secondDevice|
+    // Copy color B using Texture to Texture copy on |secondDevice|
+    // Import texture back into |device|, waiting on color B signal
+    // Verify texture contains color B
+    // If texture destination isn't synchronized, |secondDevice| could copy color B
+    // into the texture first, then |device| writes color A
+    TEST_P(VulkanImageWrappingUsageTests, CopyTextureToTextureDstSync) {
+        // Import the image on |device|
+        wgpu::Texture wrappedTexture =
+            WrapVulkanImage(device, &defaultDescriptor, defaultTexture.get(), {},
+                            VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+
+        // Clear |wrappedTexture| on |device|
+        ClearImage(device, wrappedTexture, {5 / 255.0f, 6 / 255.0f, 7 / 255.0f, 8 / 255.0f});
+
+        ExternalImageExportInfoVkForTesting exportInfo;
+        ASSERT_TRUE(mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                                          &exportInfo));
+
+        // Import the image to |secondDevice|, making sure we wait on |signalFd|
+        wgpu::Texture secondDeviceWrappedTexture =
+            WrapVulkanImage(secondDevice, &defaultDescriptor, defaultTexture.get(),
+                            std::move(exportInfo.semaphores), exportInfo.releasedOldLayout,
+                            exportInfo.releasedNewLayout);
+
+        // Create a texture with color B on |secondDevice|
+        wgpu::Texture copySrcTexture = secondDevice.CreateTexture(&defaultDescriptor);
+        ClearImage(secondDevice, copySrcTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
+
+        // Copy color B on |secondDevice|
+        wgpu::Queue secondDeviceQueue = secondDevice.GetQueue();
+        SimpleCopyTextureToTexture(secondDevice, secondDeviceQueue, copySrcTexture,
+                                   secondDeviceWrappedTexture);
+
+        // Re-import back into |device|, waiting on |secondDevice|'s signal
+        ExternalImageExportInfoVkForTesting secondExportInfo;
+        ASSERT_TRUE(mBackend->ExportImage(secondDeviceWrappedTexture,
+                                          VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &secondExportInfo));
+
+        wgpu::Texture nextWrappedTexture =
+            WrapVulkanImage(device, &defaultDescriptor, defaultTexture.get(),
+                            std::move(secondExportInfo.semaphores),
+                            secondExportInfo.releasedOldLayout, secondExportInfo.releasedNewLayout);
+
+        // Verify |nextWrappedTexture| contains the color from our copy
+        EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), nextWrappedTexture, 0, 0);
+
+        IgnoreSignalSemaphore(nextWrappedTexture);
+    }
+
+    // Import a texture from |secondDevice|
+    // Clear the texture on |secondDevice|
+    // Issue a copy of the imported texture inside |device| to |copyDstBuffer|
+    // Verify the clear color from |secondDevice| is visible in |copyDstBuffer|
+    TEST_P(VulkanImageWrappingUsageTests, CopyTextureToBufferSrcSync) {
+        // Import the image on |secondDevice|
+        wgpu::Texture wrappedTexture =
+            WrapVulkanImage(secondDevice, &defaultDescriptor, defaultTexture.get(), {},
+                            VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+
+        // Clear |wrappedTexture| on |secondDevice|
+        ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
+
+        ExternalImageExportInfoVkForTesting exportInfo;
+        ASSERT_TRUE(mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                                          &exportInfo));
+
+        // Import the image to |device|, making sure we wait on |signalFd|
+        wgpu::Texture deviceWrappedTexture = WrapVulkanImage(
+            device, &defaultDescriptor, defaultTexture.get(), std::move(exportInfo.semaphores),
+            exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
+
+        // Create a destination buffer on |device|
+        wgpu::BufferDescriptor bufferDesc;
+        bufferDesc.size = 4;
+        bufferDesc.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::CopySrc;
+        wgpu::Buffer copyDstBuffer = device.CreateBuffer(&bufferDesc);
+
+        // Copy |deviceWrappedTexture| into |copyDstBuffer|
+        wgpu::ImageCopyTexture copySrc =
+            utils::CreateImageCopyTexture(deviceWrappedTexture, 0, {0, 0, 0});
+        wgpu::ImageCopyBuffer copyDst = utils::CreateImageCopyBuffer(copyDstBuffer, 0, 256);
+
+        wgpu::Extent3D copySize = {1, 1, 1};
+
+        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+        encoder.CopyTextureToBuffer(&copySrc, &copyDst, &copySize);
+        wgpu::CommandBuffer commands = encoder.Finish();
+        queue.Submit(1, &commands);
+
+        // Verify |copyDstBuffer| sees changes from |secondDevice|
+        uint32_t expected = 0x04030201;
+        EXPECT_BUFFER_U32_EQ(expected, copyDstBuffer, 0);
+
+        IgnoreSignalSemaphore(deviceWrappedTexture);
+    }
+
+    // Import a texture into |device|
+    // Clear texture with color A on |device|
+    // Import same texture into |secondDevice|, waiting on the copy signal
+    // Copy color B using Buffer to Texture copy on |secondDevice|
+    // Import texture back into |device|, waiting on color B signal
+    // Verify texture contains color B
+    // If texture destination isn't synchronized, |secondDevice| could copy color B
+    // into the texture first, then |device| writes color A
+    TEST_P(VulkanImageWrappingUsageTests, CopyBufferToTextureDstSync) {
+        // Import the image on |device|
+        wgpu::Texture wrappedTexture =
+            WrapVulkanImage(device, &defaultDescriptor, defaultTexture.get(), {},
+                            VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+
+        // Clear |wrappedTexture| on |device|
+        ClearImage(device, wrappedTexture, {5 / 255.0f, 6 / 255.0f, 7 / 255.0f, 8 / 255.0f});
+
+        ExternalImageExportInfoVkForTesting exportInfo;
+        ASSERT_TRUE(mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                                          &exportInfo));
+
+        // Import the image to |secondDevice|, making sure we wait on |signalFd|
+        wgpu::Texture secondDeviceWrappedTexture =
+            WrapVulkanImage(secondDevice, &defaultDescriptor, defaultTexture.get(),
+                            std::move(exportInfo.semaphores), exportInfo.releasedOldLayout,
+                            exportInfo.releasedNewLayout);
+
+        // Copy color B on |secondDevice|
+        wgpu::Queue secondDeviceQueue = secondDevice.GetQueue();
+
+        // Create a buffer on |secondDevice|
+        wgpu::Buffer copySrcBuffer =
+            utils::CreateBufferFromData(secondDevice, wgpu::BufferUsage::CopySrc, {0x04030201});
+
+        // Copy |copySrcBuffer| into |secondDeviceWrappedTexture|
+        wgpu::ImageCopyBuffer copySrc = utils::CreateImageCopyBuffer(copySrcBuffer, 0, 256);
+        wgpu::ImageCopyTexture copyDst =
+            utils::CreateImageCopyTexture(secondDeviceWrappedTexture, 0, {0, 0, 0});
+
+        wgpu::Extent3D copySize = {1, 1, 1};
+
+        wgpu::CommandEncoder encoder = secondDevice.CreateCommandEncoder();
+        encoder.CopyBufferToTexture(&copySrc, &copyDst, &copySize);
+        wgpu::CommandBuffer commands = encoder.Finish();
+        secondDeviceQueue.Submit(1, &commands);
+
+        // Re-import back into |device|, waiting on |secondDevice|'s signal
+        ExternalImageExportInfoVkForTesting secondExportInfo;
+        ASSERT_TRUE(mBackend->ExportImage(secondDeviceWrappedTexture,
+                                          VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &secondExportInfo));
+
+        wgpu::Texture nextWrappedTexture =
+            WrapVulkanImage(device, &defaultDescriptor, defaultTexture.get(),
+                            std::move(secondExportInfo.semaphores),
+                            secondExportInfo.releasedOldLayout, secondExportInfo.releasedNewLayout);
+
+        // Verify |nextWrappedTexture| contains the color from our copy
+        EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), nextWrappedTexture, 0, 0);
+
+        IgnoreSignalSemaphore(nextWrappedTexture);
+    }
+
+    // Import a texture from |secondDevice|
+    // Clear the texture on |secondDevice|
+    // Issue a copy of the imported texture inside |device| to |copyDstTexture|
+    // Issue second copy to |secondCopyDstTexture|
+    // Verify the clear color from |secondDevice| is visible in both copies
+    TEST_P(VulkanImageWrappingUsageTests, DoubleTextureUsage) {
+        // Import the image on |secondDevice|
+        wgpu::Texture wrappedTexture =
+            WrapVulkanImage(secondDevice, &defaultDescriptor, defaultTexture.get(), {},
+                            VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+
+        // Clear |wrappedTexture| on |secondDevice|
+        ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
+
+        ExternalImageExportInfoVkForTesting exportInfo;
+        ASSERT_TRUE(mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                                          &exportInfo));
+
+        // Import the image to |device|, making sure we wait on |signalFd|
+        wgpu::Texture deviceWrappedTexture = WrapVulkanImage(
+            device, &defaultDescriptor, defaultTexture.get(), std::move(exportInfo.semaphores),
+            exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
+
+        // Create a second texture on |device|
+        wgpu::Texture copyDstTexture = device.CreateTexture(&defaultDescriptor);
+
+        // Create a third texture on |device|
+        wgpu::Texture secondCopyDstTexture = device.CreateTexture(&defaultDescriptor);
+
+        // Copy |deviceWrappedTexture| into |copyDstTexture|
+        SimpleCopyTextureToTexture(device, queue, deviceWrappedTexture, copyDstTexture);
+
+        // Copy |deviceWrappedTexture| into |secondCopyDstTexture|
+        SimpleCopyTextureToTexture(device, queue, deviceWrappedTexture, secondCopyDstTexture);
+
+        // Verify |copyDstTexture| sees changes from |secondDevice|
+        EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), copyDstTexture, 0, 0);
+
+        // Verify |secondCopyDstTexture| sees changes from |secondDevice|
+        EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), secondCopyDstTexture, 0, 0);
+
+        IgnoreSignalSemaphore(deviceWrappedTexture);
+    }
+
+    // Tex A on device 3 (external export)
+    // Tex B on device 2 (external export)
+    // Tex C on device 1 (external export)
+    // Clear color for A on device 3
+    // Copy A->B on device 3
+    // Copy B->C on device 2 (wait on B from previous op)
+    // Copy C->D on device 1 (wait on C from previous op)
+    // Verify D has same color as A
+    TEST_P(VulkanImageWrappingUsageTests, ChainTextureCopy) {
+        // device 1 = |device|
+        // device 2 = |secondDevice|
+        // Create device 3
+        dawn::native::vulkan::Device* thirdDeviceVk =
+            dawn::native::vulkan::ToBackend(backendAdapter->APICreateDevice(&deviceDescriptor));
+        wgpu::Device thirdDevice = wgpu::Device::Acquire(dawn::native::ToAPI(thirdDeviceVk));
+
+        // Make queue for device 2 and 3
+        wgpu::Queue secondDeviceQueue = secondDevice.GetQueue();
+        wgpu::Queue thirdDeviceQueue = thirdDevice.GetQueue();
+
+        // Create textures A, B, C
+        std::unique_ptr<ExternalTexture> textureA =
+            mBackend->CreateTexture(1, 1, wgpu::TextureFormat::RGBA8Unorm, defaultDescriptor.usage);
+        std::unique_ptr<ExternalTexture> textureB =
+            mBackend->CreateTexture(1, 1, wgpu::TextureFormat::RGBA8Unorm, defaultDescriptor.usage);
+        std::unique_ptr<ExternalTexture> textureC =
+            mBackend->CreateTexture(1, 1, wgpu::TextureFormat::RGBA8Unorm, defaultDescriptor.usage);
+
+        // Import TexA, TexB on device 3
+        wgpu::Texture wrappedTexADevice3 =
+            WrapVulkanImage(thirdDevice, &defaultDescriptor, textureA.get(), {},
+                            VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+
+        wgpu::Texture wrappedTexBDevice3 =
+            WrapVulkanImage(thirdDevice, &defaultDescriptor, textureB.get(), {},
+                            VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
+
+        // Clear TexA
+        ClearImage(thirdDevice, wrappedTexADevice3,
+                   {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
+
+        // Copy A->B
+        SimpleCopyTextureToTexture(thirdDevice, thirdDeviceQueue, wrappedTexADevice3,
+                                   wrappedTexBDevice3);
+
+        ExternalImageExportInfoVkForTesting exportInfoTexBDevice3;
+        ASSERT_TRUE(mBackend->ExportImage(wrappedTexBDevice3, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                                          &exportInfoTexBDevice3));
+        IgnoreSignalSemaphore(wrappedTexADevice3);
+
+        // Import TexB, TexC on device 2
+        wgpu::Texture wrappedTexBDevice2 = WrapVulkanImage(
+            secondDevice, &defaultDescriptor, textureB.get(),
+            std::move(exportInfoTexBDevice3.semaphores), exportInfoTexBDevice3.releasedOldLayout,
+            exportInfoTexBDevice3.releasedNewLayout);
+
+        wgpu::Texture wrappedTexCDevice2 =
+            WrapVulkanImage(secondDevice, &defaultDescriptor, textureC.get(), {},
+                            VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
+
+        // Copy B->C on device 2
+        SimpleCopyTextureToTexture(secondDevice, secondDeviceQueue, wrappedTexBDevice2,
+                                   wrappedTexCDevice2);
+
+        ExternalImageExportInfoVkForTesting exportInfoTexCDevice2;
+        ASSERT_TRUE(mBackend->ExportImage(wrappedTexCDevice2, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                                          &exportInfoTexCDevice2));
+        IgnoreSignalSemaphore(wrappedTexBDevice2);
+
+        // Import TexC on device 1
+        wgpu::Texture wrappedTexCDevice1 = WrapVulkanImage(
+            device, &defaultDescriptor, textureC.get(), std::move(exportInfoTexCDevice2.semaphores),
+            exportInfoTexCDevice2.releasedOldLayout, exportInfoTexCDevice2.releasedNewLayout);
+
+        // Create TexD on device 1
+        wgpu::Texture texD = device.CreateTexture(&defaultDescriptor);
+
+        // Copy C->D on device 1
+        SimpleCopyTextureToTexture(device, queue, wrappedTexCDevice1, texD);
+
+        // Verify D matches clear color
+        EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), texD, 0, 0);
+
+        IgnoreSignalSemaphore(wrappedTexCDevice1);
+    }
+
+    // Tests a larger image is preserved when importing
+    TEST_P(VulkanImageWrappingUsageTests, LargerImage) {
+        wgpu::TextureDescriptor descriptor;
+        descriptor.dimension = wgpu::TextureDimension::e2D;
+        descriptor.size.width = 640;
+        descriptor.size.height = 480;
+        descriptor.size.depthOrArrayLayers = 1;
+        descriptor.sampleCount = 1;
+        descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
+        descriptor.mipLevelCount = 1;
+        descriptor.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::CopySrc;
+
+        // Fill memory with textures
+        std::vector<wgpu::Texture> textures;
+        for (int i = 0; i < 20; i++) {
+            textures.push_back(device.CreateTexture(&descriptor));
+        }
+
+        wgpu::Queue secondDeviceQueue = secondDevice.GetQueue();
+
+        // Make an image on |secondDevice|
+        std::unique_ptr<ExternalTexture> texture = mBackend->CreateTexture(
+            descriptor.size.width, descriptor.size.height, descriptor.format, descriptor.usage);
+
+        // Import the image on |secondDevice|
+        wgpu::Texture wrappedTexture =
+            WrapVulkanImage(secondDevice, &descriptor, texture.get(), {}, VK_IMAGE_LAYOUT_UNDEFINED,
+                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
+
+        // Draw a non-trivial picture
+        uint32_t width = 640, height = 480, pixelSize = 4;
+        uint32_t bytesPerRow = Align(width * pixelSize, kTextureBytesPerRowAlignment);
+        std::vector<unsigned char> data(bytesPerRow * (height - 1) + width * pixelSize);
+
+        for (uint32_t row = 0; row < height; row++) {
+            for (uint32_t col = 0; col < width; col++) {
+                float normRow = static_cast<float>(row) / height;
+                float normCol = static_cast<float>(col) / width;
+                float dist = sqrt(normRow * normRow + normCol * normCol) * 3;
+                dist = dist - static_cast<int>(dist);
+                data[4 * (row * width + col)] = static_cast<unsigned char>(dist * 255);
+                data[4 * (row * width + col) + 1] = static_cast<unsigned char>(dist * 255);
+                data[4 * (row * width + col) + 2] = static_cast<unsigned char>(dist * 255);
+                data[4 * (row * width + col) + 3] = 255;
+            }
+        }
+
+        // Write the picture
+        {
+            wgpu::Buffer copySrcBuffer = utils::CreateBufferFromData(
+                secondDevice, data.data(), data.size(), wgpu::BufferUsage::CopySrc);
+            wgpu::ImageCopyBuffer copySrc =
+                utils::CreateImageCopyBuffer(copySrcBuffer, 0, bytesPerRow);
+            wgpu::ImageCopyTexture copyDst =
+                utils::CreateImageCopyTexture(wrappedTexture, 0, {0, 0, 0});
+            wgpu::Extent3D copySize = {width, height, 1};
+
+            wgpu::CommandEncoder encoder = secondDevice.CreateCommandEncoder();
+            encoder.CopyBufferToTexture(&copySrc, &copyDst, &copySize);
+            wgpu::CommandBuffer commands = encoder.Finish();
+            secondDeviceQueue.Submit(1, &commands);
+        }
+        ExternalImageExportInfoVkForTesting exportInfo;
+        ASSERT_TRUE(mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                                          &exportInfo));
+
+        // Import the image on |device|
+        wgpu::Texture nextWrappedTexture =
+            WrapVulkanImage(device, &descriptor, texture.get(), std::move(exportInfo.semaphores),
+                            exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
+
+        // Copy the image into a buffer for comparison
+        wgpu::BufferDescriptor copyDesc;
+        copyDesc.size = data.size();
+        copyDesc.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
+        wgpu::Buffer copyDstBuffer = device.CreateBuffer(&copyDesc);
+        {
+            wgpu::ImageCopyTexture copySrc =
+                utils::CreateImageCopyTexture(nextWrappedTexture, 0, {0, 0, 0});
+            wgpu::ImageCopyBuffer copyDst =
+                utils::CreateImageCopyBuffer(copyDstBuffer, 0, bytesPerRow);
+
+            wgpu::Extent3D copySize = {width, height, 1};
+
+            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+            encoder.CopyTextureToBuffer(&copySrc, &copyDst, &copySize);
+            wgpu::CommandBuffer commands = encoder.Finish();
+            queue.Submit(1, &commands);
+        }
+
+        // Check the image is not corrupted on |device|
+        EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast<uint32_t*>(data.data()), copyDstBuffer, 0,
+                                   data.size() / 4);
+
+        IgnoreSignalSemaphore(nextWrappedTexture);
+    }
+
+    DAWN_INSTANTIATE_TEST(VulkanImageWrappingValidationTests, VulkanBackend());
+    DAWN_INSTANTIATE_TEST(VulkanImageWrappingUsageTests, VulkanBackend());
+
+}}  // namespace dawn::native::vulkan
diff --git a/src/tests/white_box/VulkanImageWrappingTests.h b/src/tests/white_box/VulkanImageWrappingTests.h
new file mode 100644
index 0000000..6c2deb7
--- /dev/null
+++ b/src/tests/white_box/VulkanImageWrappingTests.h
@@ -0,0 +1,76 @@
+// Copyright 2021 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef TESTS_VULKANIMAGEWRAPPINGTESTS_H_
+#define TESTS_VULKANIMAGEWRAPPINGTESTS_H_
+
+// This must be above all other includes otherwise VulkanBackend.h includes vulkan.h before we had
+// time to wrap it with vulkan_platform.h
+#include "common/vulkan_platform.h"
+
+#include "common/NonCopyable.h"
+#include "dawn/webgpu_cpp.h"
+#include "dawn_native/VulkanBackend.h"
+
+#include <memory>
+#include <vector>
+
+namespace dawn::native::vulkan {
+
+    struct ExternalImageDescriptorVkForTesting;
+    struct ExternalImageExportInfoVkForTesting;
+
+    class VulkanImageWrappingTestBackend {
+      public:
+        static std::unique_ptr<VulkanImageWrappingTestBackend> Create(const wgpu::Device& device);
+        virtual ~VulkanImageWrappingTestBackend() = default;
+
+        class ExternalTexture : NonCopyable {
+          public:
+            virtual ~ExternalTexture() = default;
+        };
+        class ExternalSemaphore : NonCopyable {
+          public:
+            virtual ~ExternalSemaphore() = default;
+        };
+
+        virtual std::unique_ptr<ExternalTexture> CreateTexture(uint32_t width,
+                                                               uint32_t height,
+                                                               wgpu::TextureFormat format,
+                                                               wgpu::TextureUsage usage) = 0;
+        virtual wgpu::Texture WrapImage(
+            const wgpu::Device& device,
+            const ExternalTexture* texture,
+            const ExternalImageDescriptorVkForTesting& descriptor,
+            std::vector<std::unique_ptr<ExternalSemaphore>> semaphores) = 0;
+
+        virtual bool ExportImage(const wgpu::Texture& texture,
+                                 VkImageLayout layout,
+                                 ExternalImageExportInfoVkForTesting* exportInfo) = 0;
+    };
+
+    struct ExternalImageDescriptorVkForTesting : public ExternalImageDescriptorVk {
+      public:
+        ExternalImageDescriptorVkForTesting();
+    };
+
+    struct ExternalImageExportInfoVkForTesting : public ExternalImageExportInfoVk {
+      public:
+        ExternalImageExportInfoVkForTesting();
+        std::vector<std::unique_ptr<VulkanImageWrappingTestBackend::ExternalSemaphore>> semaphores;
+    };
+
+}  // namespace dawn::native::vulkan
+
+#endif  // TESTS_VULKANIMAGEWRAPPINGTESTS_H_
diff --git a/src/tests/white_box/VulkanImageWrappingTestsOpaqueFD.cpp b/src/tests/white_box/VulkanImageWrappingTestsOpaqueFD.cpp
deleted file mode 100644
index cb045d5..0000000
--- a/src/tests/white_box/VulkanImageWrappingTestsOpaqueFD.cpp
+++ /dev/null
@@ -1,1019 +0,0 @@
-// Copyright 2019 The Dawn Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "common/Math.h"
-#include "tests/DawnTest.h"
-
-#include "common/vulkan_platform.h"
-#include "dawn_native/VulkanBackend.h"
-#include "dawn_native/vulkan/AdapterVk.h"
-#include "dawn_native/vulkan/DeviceVk.h"
-#include "dawn_native/vulkan/FencedDeleter.h"
-#include "dawn_native/vulkan/ResourceMemoryAllocatorVk.h"
-#include "dawn_native/vulkan/TextureVk.h"
-#include "utils/SystemUtils.h"
-#include "utils/WGPUHelpers.h"
-
-namespace dawn::native::vulkan {
-
-    namespace {
-
-        class VulkanImageWrappingTestBase : public DawnTest {
-          protected:
-            std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
-                return {wgpu::FeatureName::DawnInternalUsages};
-            }
-
-          public:
-            void SetUp() override {
-                DawnTest::SetUp();
-                DAWN_TEST_UNSUPPORTED_IF(UsesWire());
-
-                deviceVk = dawn::native::vulkan::ToBackend(dawn::native::FromAPI(device.Get()));
-            }
-
-            // Creates a VkImage with external memory
-            ::VkResult CreateImage(dawn::native::vulkan::Device* deviceVk,
-                                   uint32_t width,
-                                   uint32_t height,
-                                   VkFormat format,
-                                   VkImage* image) {
-                VkExternalMemoryImageCreateInfoKHR externalInfo;
-                externalInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR;
-                externalInfo.pNext = nullptr;
-                externalInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
-
-                auto usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
-                             VK_IMAGE_USAGE_TRANSFER_DST_BIT;
-
-                VkImageCreateInfo createInfo;
-                createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
-                createInfo.pNext = &externalInfo;
-                createInfo.flags = VK_IMAGE_CREATE_ALIAS_BIT_KHR;
-                createInfo.imageType = VK_IMAGE_TYPE_2D;
-                createInfo.format = format;
-                createInfo.extent = {width, height, 1};
-                createInfo.mipLevels = 1;
-                createInfo.arrayLayers = 1;
-                createInfo.samples = VK_SAMPLE_COUNT_1_BIT;
-                createInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
-                createInfo.usage = usage;
-                createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
-                createInfo.queueFamilyIndexCount = 0;
-                createInfo.pQueueFamilyIndices = nullptr;
-                createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
-
-                return deviceVk->fn.CreateImage(deviceVk->GetVkDevice(), &createInfo, nullptr,
-                                                &**image);
-            }
-
-            // Allocates memory for an image
-            ::VkResult AllocateMemory(dawn::native::vulkan::Device* deviceVk,
-                                      VkImage handle,
-                                      VkDeviceMemory* allocation,
-                                      VkDeviceSize* allocationSize,
-                                      uint32_t* memoryTypeIndex) {
-                // Create the image memory and associate it with the container
-                VkMemoryRequirements requirements;
-                deviceVk->fn.GetImageMemoryRequirements(deviceVk->GetVkDevice(), handle,
-                                                        &requirements);
-
-                // Import memory from file descriptor
-                VkExportMemoryAllocateInfoKHR externalInfo;
-                externalInfo.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR;
-                externalInfo.pNext = nullptr;
-                externalInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
-
-                int bestType = deviceVk->GetResourceMemoryAllocator()->FindBestTypeIndex(
-                    requirements, MemoryKind::Opaque);
-                VkMemoryAllocateInfo allocateInfo;
-                allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
-                allocateInfo.pNext = &externalInfo;
-                allocateInfo.allocationSize = requirements.size;
-                allocateInfo.memoryTypeIndex = static_cast<uint32_t>(bestType);
-
-                *allocationSize = allocateInfo.allocationSize;
-                *memoryTypeIndex = allocateInfo.memoryTypeIndex;
-
-                return deviceVk->fn.AllocateMemory(deviceVk->GetVkDevice(), &allocateInfo, nullptr,
-                                                   &**allocation);
-            }
-
-            // Binds memory to an image
-            ::VkResult BindMemory(dawn::native::vulkan::Device* deviceVk,
-                                  VkImage handle,
-                                  VkDeviceMemory* memory) {
-                return deviceVk->fn.BindImageMemory(deviceVk->GetVkDevice(), handle, *memory, 0);
-            }
-
-            // Extracts a file descriptor representing memory on a device
-            int GetMemoryFd(dawn::native::vulkan::Device* deviceVk, VkDeviceMemory memory) {
-                VkMemoryGetFdInfoKHR getFdInfo;
-                getFdInfo.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR;
-                getFdInfo.pNext = nullptr;
-                getFdInfo.memory = memory;
-                getFdInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
-
-                int memoryFd = -1;
-                deviceVk->fn.GetMemoryFdKHR(deviceVk->GetVkDevice(), &getFdInfo, &memoryFd);
-
-                EXPECT_GE(memoryFd, 0) << "Failed to get file descriptor for external memory";
-                return memoryFd;
-            }
-
-            // Prepares and exports memory for an image on a given device
-            void CreateBindExportImage(dawn::native::vulkan::Device* deviceVk,
-                                       uint32_t width,
-                                       uint32_t height,
-                                       VkFormat format,
-                                       VkImage* handle,
-                                       VkDeviceMemory* allocation,
-                                       VkDeviceSize* allocationSize,
-                                       uint32_t* memoryTypeIndex,
-                                       int* memoryFd) {
-                ::VkResult result = CreateImage(deviceVk, width, height, format, handle);
-                EXPECT_EQ(result, VK_SUCCESS) << "Failed to create external image";
-
-                ::VkResult resultBool =
-                    AllocateMemory(deviceVk, *handle, allocation, allocationSize, memoryTypeIndex);
-                EXPECT_EQ(resultBool, VK_SUCCESS) << "Failed to allocate external memory";
-
-                result = BindMemory(deviceVk, *handle, allocation);
-                EXPECT_EQ(result, VK_SUCCESS) << "Failed to bind image memory";
-
-                *memoryFd = GetMemoryFd(deviceVk, *allocation);
-            }
-
-            // Wraps a vulkan image from external memory
-            wgpu::Texture WrapVulkanImage(wgpu::Device dawnDevice,
-                                          const wgpu::TextureDescriptor* textureDescriptor,
-                                          int memoryFd,
-                                          VkDeviceSize allocationSize,
-                                          uint32_t memoryTypeIndex,
-                                          std::vector<int> waitFDs,
-                                          bool isInitialized = true,
-                                          bool expectValid = true) {
-                dawn::native::vulkan::ExternalImageDescriptorOpaqueFD descriptor;
-                return WrapVulkanImage(dawnDevice, textureDescriptor, memoryFd, allocationSize,
-                                       memoryTypeIndex, waitFDs, descriptor.releasedOldLayout,
-                                       descriptor.releasedNewLayout, isInitialized, expectValid);
-            }
-
-            wgpu::Texture WrapVulkanImage(wgpu::Device dawnDevice,
-                                          const wgpu::TextureDescriptor* textureDescriptor,
-                                          int memoryFd,
-                                          VkDeviceSize allocationSize,
-                                          uint32_t memoryTypeIndex,
-                                          std::vector<int> waitFDs,
-                                          VkImageLayout releasedOldLayout,
-                                          VkImageLayout releasedNewLayout,
-                                          bool isInitialized = true,
-                                          bool expectValid = true) {
-                dawn::native::vulkan::ExternalImageDescriptorOpaqueFD descriptor;
-                descriptor.cTextureDescriptor =
-                    reinterpret_cast<const WGPUTextureDescriptor*>(textureDescriptor);
-                descriptor.isInitialized = isInitialized;
-                descriptor.allocationSize = allocationSize;
-                descriptor.memoryTypeIndex = memoryTypeIndex;
-                descriptor.memoryFD = memoryFd;
-                descriptor.waitFDs = waitFDs;
-                descriptor.releasedOldLayout = releasedOldLayout;
-                descriptor.releasedNewLayout = releasedNewLayout;
-
-                WGPUTexture texture =
-                    dawn::native::vulkan::WrapVulkanImage(dawnDevice.Get(), &descriptor);
-
-                if (expectValid) {
-                    EXPECT_NE(texture, nullptr) << "Failed to wrap image, are external memory / "
-                                                   "semaphore extensions supported?";
-                } else {
-                    EXPECT_EQ(texture, nullptr);
-                }
-
-                return wgpu::Texture::Acquire(texture);
-            }
-
-            // Exports the signal from a wrapped texture and ignores it
-            // We have to export the signal before destroying the wrapped texture else it's an
-            // assertion failure
-            void IgnoreSignalSemaphore(wgpu::Texture wrappedTexture) {
-                dawn::native::vulkan::ExternalImageExportInfoOpaqueFD info;
-                dawn::native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
-                                                        VK_IMAGE_LAYOUT_GENERAL, &info);
-                for (int handle : info.semaphoreHandles) {
-                    ASSERT_NE(handle, -1);
-                    close(handle);
-                }
-            }
-
-          protected:
-            dawn::native::vulkan::Device* deviceVk;
-        };
-
-    }  // anonymous namespace
-
-    class VulkanImageWrappingValidationTests : public VulkanImageWrappingTestBase {
-      public:
-        void SetUp() override {
-            VulkanImageWrappingTestBase::SetUp();
-            DAWN_TEST_UNSUPPORTED_IF(UsesWire());
-
-            CreateBindExportImage(deviceVk, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, &defaultImage,
-                                  &defaultAllocation, &defaultAllocationSize,
-                                  &defaultMemoryTypeIndex, &defaultFd);
-            defaultDescriptor.dimension = wgpu::TextureDimension::e2D;
-            defaultDescriptor.format = wgpu::TextureFormat::RGBA8Unorm;
-            defaultDescriptor.size = {1, 1, 1};
-            defaultDescriptor.sampleCount = 1;
-            defaultDescriptor.mipLevelCount = 1;
-            defaultDescriptor.usage = wgpu::TextureUsage::RenderAttachment |
-                                      wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
-        }
-
-        void TearDown() override {
-            if (UsesWire()) {
-                VulkanImageWrappingTestBase::TearDown();
-                return;
-            }
-
-            deviceVk->GetFencedDeleter()->DeleteWhenUnused(defaultImage);
-            deviceVk->GetFencedDeleter()->DeleteWhenUnused(defaultAllocation);
-            VulkanImageWrappingTestBase::TearDown();
-        }
-
-      protected:
-        wgpu::TextureDescriptor defaultDescriptor;
-        VkImage defaultImage;
-        VkDeviceMemory defaultAllocation;
-        VkDeviceSize defaultAllocationSize;
-        uint32_t defaultMemoryTypeIndex;
-        int defaultFd;
-    };
-
-    // Test no error occurs if the import is valid
-    TEST_P(VulkanImageWrappingValidationTests, SuccessfulImport) {
-        wgpu::Texture texture =
-            WrapVulkanImage(device, &defaultDescriptor, defaultFd, defaultAllocationSize,
-                            defaultMemoryTypeIndex, {}, true, true);
-        EXPECT_NE(texture.Get(), nullptr);
-        IgnoreSignalSemaphore(texture);
-    }
-
-    // Test no error occurs if the import is valid with DawnTextureInternalUsageDescriptor
-    TEST_P(VulkanImageWrappingValidationTests, SuccessfulImportWithInternalUsageDescriptor) {
-        wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
-        defaultDescriptor.nextInChain = &internalDesc;
-        internalDesc.internalUsage = wgpu::TextureUsage::CopySrc;
-        internalDesc.sType = wgpu::SType::DawnTextureInternalUsageDescriptor;
-
-        wgpu::Texture texture =
-            WrapVulkanImage(device, &defaultDescriptor, defaultFd, defaultAllocationSize,
-                            defaultMemoryTypeIndex, {}, true, true);
-        EXPECT_NE(texture.Get(), nullptr);
-        IgnoreSignalSemaphore(texture);
-    }
-
-    // Test an error occurs if an invalid sType is the nextInChain
-    TEST_P(VulkanImageWrappingValidationTests, InvalidTextureDescriptor) {
-        wgpu::ChainedStruct chainedDescriptor;
-        chainedDescriptor.sType = wgpu::SType::SurfaceDescriptorFromWindowsSwapChainPanel;
-        defaultDescriptor.nextInChain = &chainedDescriptor;
-
-        ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapVulkanImage(
-                                device, &defaultDescriptor, defaultFd, defaultAllocationSize,
-                                defaultMemoryTypeIndex, {}, true, false));
-        EXPECT_EQ(texture.Get(), nullptr);
-    }
-
-    // Test an error occurs if the descriptor dimension isn't 2D
-    TEST_P(VulkanImageWrappingValidationTests, InvalidTextureDimension) {
-        defaultDescriptor.dimension = wgpu::TextureDimension::e1D;
-
-        ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapVulkanImage(
-                                device, &defaultDescriptor, defaultFd, defaultAllocationSize,
-                                defaultMemoryTypeIndex, {}, true, false));
-        EXPECT_EQ(texture.Get(), nullptr);
-    }
-
-    // Test an error occurs if the descriptor mip level count isn't 1
-    TEST_P(VulkanImageWrappingValidationTests, InvalidMipLevelCount) {
-        defaultDescriptor.mipLevelCount = 2;
-
-        ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapVulkanImage(
-                                device, &defaultDescriptor, defaultFd, defaultAllocationSize,
-                                defaultMemoryTypeIndex, {}, true, false));
-        EXPECT_EQ(texture.Get(), nullptr);
-    }
-
-    // Test an error occurs if the descriptor depth isn't 1
-    TEST_P(VulkanImageWrappingValidationTests, InvalidDepth) {
-        defaultDescriptor.size.depthOrArrayLayers = 2;
-
-        ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapVulkanImage(
-                                device, &defaultDescriptor, defaultFd, defaultAllocationSize,
-                                defaultMemoryTypeIndex, {}, true, false));
-        EXPECT_EQ(texture.Get(), nullptr);
-    }
-
-    // Test an error occurs if the descriptor sample count isn't 1
-    TEST_P(VulkanImageWrappingValidationTests, InvalidSampleCount) {
-        defaultDescriptor.sampleCount = 4;
-
-        ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapVulkanImage(
-                                device, &defaultDescriptor, defaultFd, defaultAllocationSize,
-                                defaultMemoryTypeIndex, {}, true, false));
-        EXPECT_EQ(texture.Get(), nullptr);
-    }
-
-    // Test an error occurs if we try to export the signal semaphore twice
-    TEST_P(VulkanImageWrappingValidationTests, DoubleSignalSemaphoreExport) {
-        wgpu::Texture texture =
-            WrapVulkanImage(device, &defaultDescriptor, defaultFd, defaultAllocationSize,
-                            defaultMemoryTypeIndex, {}, true, true);
-        ASSERT_NE(texture.Get(), nullptr);
-        IgnoreSignalSemaphore(texture);
-
-        dawn::native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
-        ASSERT_DEVICE_ERROR(bool success = dawn::native::vulkan::ExportVulkanImage(
-                                texture.Get(), VK_IMAGE_LAYOUT_GENERAL, &exportInfo));
-        ASSERT_FALSE(success);
-    }
-
-    // Test an error occurs if we try to export the signal semaphore from a normal texture
-    TEST_P(VulkanImageWrappingValidationTests, NormalTextureSignalSemaphoreExport) {
-        wgpu::Texture texture = device.CreateTexture(&defaultDescriptor);
-        ASSERT_NE(texture.Get(), nullptr);
-
-        dawn::native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
-        ASSERT_DEVICE_ERROR(bool success = dawn::native::vulkan::ExportVulkanImage(
-                                texture.Get(), VK_IMAGE_LAYOUT_GENERAL, &exportInfo));
-        ASSERT_FALSE(success);
-    }
-
-    // Test an error occurs if we try to export the signal semaphore from a destroyed texture
-    TEST_P(VulkanImageWrappingValidationTests, DestroyedTextureSignalSemaphoreExport) {
-        wgpu::Texture texture = device.CreateTexture(&defaultDescriptor);
-        ASSERT_NE(texture.Get(), nullptr);
-        texture.Destroy();
-
-        dawn::native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
-        ASSERT_DEVICE_ERROR(bool success = dawn::native::vulkan::ExportVulkanImage(
-                                texture.Get(), VK_IMAGE_LAYOUT_GENERAL, &exportInfo));
-        ASSERT_FALSE(success);
-    }
-
-    // Fixture to test using external memory textures through different usages.
-    // These tests are skipped if the harness is using the wire.
-    class VulkanImageWrappingUsageTests : public VulkanImageWrappingTestBase {
-      public:
-        void SetUp() override {
-            VulkanImageWrappingTestBase::SetUp();
-            DAWN_TEST_UNSUPPORTED_IF(UsesWire());
-
-            // Create another device based on the original
-            backendAdapter = dawn::native::vulkan::ToBackend(deviceVk->GetAdapter());
-            deviceDescriptor.nextInChain = &togglesDesc;
-            togglesDesc.forceEnabledToggles = GetParam().forceEnabledWorkarounds.data();
-            togglesDesc.forceEnabledTogglesCount = GetParam().forceEnabledWorkarounds.size();
-            togglesDesc.forceDisabledToggles = GetParam().forceDisabledWorkarounds.data();
-            togglesDesc.forceDisabledTogglesCount = GetParam().forceDisabledWorkarounds.size();
-
-            secondDeviceVk =
-                dawn::native::vulkan::ToBackend(backendAdapter->APICreateDevice(&deviceDescriptor));
-            secondDevice = wgpu::Device::Acquire(dawn::native::ToAPI(secondDeviceVk));
-
-            CreateBindExportImage(deviceVk, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, &defaultImage,
-                                  &defaultAllocation, &defaultAllocationSize,
-                                  &defaultMemoryTypeIndex, &defaultFd);
-            defaultDescriptor.dimension = wgpu::TextureDimension::e2D;
-            defaultDescriptor.format = wgpu::TextureFormat::RGBA8Unorm;
-            defaultDescriptor.size = {1, 1, 1};
-            defaultDescriptor.sampleCount = 1;
-            defaultDescriptor.mipLevelCount = 1;
-            defaultDescriptor.usage = wgpu::TextureUsage::RenderAttachment |
-                                      wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
-        }
-
-        void TearDown() override {
-            if (UsesWire()) {
-                VulkanImageWrappingTestBase::TearDown();
-                return;
-            }
-
-            deviceVk->GetFencedDeleter()->DeleteWhenUnused(defaultImage);
-            deviceVk->GetFencedDeleter()->DeleteWhenUnused(defaultAllocation);
-            VulkanImageWrappingTestBase::TearDown();
-        }
-
-      protected:
-        wgpu::Device secondDevice;
-        dawn::native::vulkan::Device* secondDeviceVk;
-
-        dawn::native::vulkan::Adapter* backendAdapter;
-        dawn::native::DeviceDescriptor deviceDescriptor;
-        dawn::native::DawnTogglesDeviceDescriptor togglesDesc;
-
-        wgpu::TextureDescriptor defaultDescriptor;
-        VkImage defaultImage;
-        VkDeviceMemory defaultAllocation;
-        VkDeviceSize defaultAllocationSize;
-        uint32_t defaultMemoryTypeIndex;
-        int defaultFd;
-
-        // Clear a texture on a given device
-        void ClearImage(wgpu::Device dawnDevice,
-                        wgpu::Texture wrappedTexture,
-                        wgpu::Color clearColor) {
-            wgpu::TextureView wrappedView = wrappedTexture.CreateView();
-
-            // Submit a clear operation
-            utils::ComboRenderPassDescriptor renderPassDescriptor({wrappedView}, {});
-            renderPassDescriptor.cColorAttachments[0].clearColor = clearColor;
-
-            wgpu::CommandEncoder encoder = dawnDevice.CreateCommandEncoder();
-            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassDescriptor);
-            pass.EndPass();
-
-            wgpu::CommandBuffer commands = encoder.Finish();
-
-            wgpu::Queue queue = dawnDevice.GetQueue();
-            queue.Submit(1, &commands);
-        }
-
-        // Submits a 1x1x1 copy from source to destination
-        void SimpleCopyTextureToTexture(wgpu::Device dawnDevice,
-                                        wgpu::Queue dawnQueue,
-                                        wgpu::Texture source,
-                                        wgpu::Texture destination) {
-            wgpu::ImageCopyTexture copySrc;
-            copySrc.texture = source;
-            copySrc.mipLevel = 0;
-            copySrc.origin = {0, 0, 0};
-
-            wgpu::ImageCopyTexture copyDst;
-            copyDst.texture = destination;
-            copyDst.mipLevel = 0;
-            copyDst.origin = {0, 0, 0};
-
-            wgpu::Extent3D copySize = {1, 1, 1};
-
-            wgpu::CommandEncoder encoder = dawnDevice.CreateCommandEncoder();
-            encoder.CopyTextureToTexture(&copySrc, &copyDst, &copySize);
-            wgpu::CommandBuffer commands = encoder.Finish();
-
-            dawnQueue.Submit(1, &commands);
-        }
-    };
-
-    // Clear an image in |secondDevice|
-    // Verify clear color is visible in |device|
-    TEST_P(VulkanImageWrappingUsageTests, ClearImageAcrossDevices) {
-        // Import the image on |secondDevice|
-        wgpu::Texture wrappedTexture =
-            WrapVulkanImage(secondDevice, &defaultDescriptor, defaultFd, defaultAllocationSize,
-                            defaultMemoryTypeIndex, {}, VK_IMAGE_LAYOUT_UNDEFINED,
-                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
-
-        // Clear |wrappedTexture| on |secondDevice|
-        ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
-
-        dawn::native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
-        dawn::native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
-                                                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
-
-        // Import the image to |device|, making sure we wait on signalFd
-        int memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
-        wgpu::Texture nextWrappedTexture =
-            WrapVulkanImage(device, &defaultDescriptor, memoryFd, defaultAllocationSize,
-                            defaultMemoryTypeIndex, exportInfo.semaphoreHandles,
-                            exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
-
-        // Verify |device| sees the changes from |secondDevice|
-        EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), nextWrappedTexture, 0, 0);
-
-        IgnoreSignalSemaphore(nextWrappedTexture);
-    }
-
-    // Clear an image in |secondDevice|
-    // Verify clear color is not visible in |device| if we import the texture as not cleared
-    TEST_P(VulkanImageWrappingUsageTests, UninitializedTextureIsCleared) {
-        // Import the image on |secondDevice|
-        wgpu::Texture wrappedTexture =
-            WrapVulkanImage(secondDevice, &defaultDescriptor, defaultFd, defaultAllocationSize,
-                            defaultMemoryTypeIndex, {}, VK_IMAGE_LAYOUT_UNDEFINED,
-                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
-
-        // Clear |wrappedTexture| on |secondDevice|
-        ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
-
-        dawn::native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
-        dawn::native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
-                                                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
-
-        // Import the image to |device|, making sure we wait on the semaphore
-        int memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
-        wgpu::Texture nextWrappedTexture =
-            WrapVulkanImage(device, &defaultDescriptor, memoryFd, defaultAllocationSize,
-                            defaultMemoryTypeIndex, exportInfo.semaphoreHandles,
-                            exportInfo.releasedOldLayout, exportInfo.releasedNewLayout, false);
-
-        // Verify |device| doesn't see the changes from |secondDevice|
-        EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 0, 0, 0), nextWrappedTexture, 0, 0);
-
-        IgnoreSignalSemaphore(nextWrappedTexture);
-    }
-
-    // Import a texture into |secondDevice|
-    // Issue a copy of the imported texture inside |device| to |copyDstTexture|
-    // Verify the clear color from |secondDevice| is visible in |copyDstTexture|
-    TEST_P(VulkanImageWrappingUsageTests, CopyTextureToTextureSrcSync) {
-        // Import the image on |secondDevice|
-        wgpu::Texture wrappedTexture =
-            WrapVulkanImage(secondDevice, &defaultDescriptor, defaultFd, defaultAllocationSize,
-                            defaultMemoryTypeIndex, {}, VK_IMAGE_LAYOUT_UNDEFINED,
-                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
-
-        // Clear |wrappedTexture| on |secondDevice|
-        ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
-
-        dawn::native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
-        dawn::native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
-                                                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
-
-        // Import the image to |device|, making sure we wait on the semaphore
-        int memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
-        wgpu::Texture deviceWrappedTexture =
-            WrapVulkanImage(device, &defaultDescriptor, memoryFd, defaultAllocationSize,
-                            defaultMemoryTypeIndex, exportInfo.semaphoreHandles,
-                            exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
-
-        // Create a second texture on |device|
-        wgpu::Texture copyDstTexture = device.CreateTexture(&defaultDescriptor);
-
-        // Copy |deviceWrappedTexture| into |copyDstTexture|
-        SimpleCopyTextureToTexture(device, queue, deviceWrappedTexture, copyDstTexture);
-
-        // Verify |copyDstTexture| sees changes from |secondDevice|
-        EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), copyDstTexture, 0, 0);
-
-        IgnoreSignalSemaphore(deviceWrappedTexture);
-    }
-
-    // Import a texture into |device|
-    // Copy color A into texture on |device|
-    // Import same texture into |secondDevice|, waiting on the copy signal
-    // Copy color B using Texture to Texture copy on |secondDevice|
-    // Import texture back into |device|, waiting on color B signal
-    // Verify texture contains color B
-    // If texture destination isn't synchronized, |secondDevice| could copy color B
-    // into the texture first, then |device| writes color A
-    TEST_P(VulkanImageWrappingUsageTests, CopyTextureToTextureDstSync) {
-        // Import the image on |device|
-        wgpu::Texture wrappedTexture = WrapVulkanImage(
-            device, &defaultDescriptor, defaultFd, defaultAllocationSize, defaultMemoryTypeIndex,
-            {}, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
-
-        // Clear |wrappedTexture| on |device|
-        ClearImage(device, wrappedTexture, {5 / 255.0f, 6 / 255.0f, 7 / 255.0f, 8 / 255.0f});
-
-        dawn::native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
-        dawn::native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
-                                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &exportInfo);
-
-        // Import the image to |secondDevice|, making sure we wait on the semaphore
-        int memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
-        wgpu::Texture secondDeviceWrappedTexture =
-            WrapVulkanImage(secondDevice, &defaultDescriptor, memoryFd, defaultAllocationSize,
-                            defaultMemoryTypeIndex, exportInfo.semaphoreHandles,
-                            exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
-
-        // Create a texture with color B on |secondDevice|
-        wgpu::Texture copySrcTexture = secondDevice.CreateTexture(&defaultDescriptor);
-        ClearImage(secondDevice, copySrcTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
-
-        // Copy color B on |secondDevice|
-        wgpu::Queue secondDeviceQueue = secondDevice.GetQueue();
-        SimpleCopyTextureToTexture(secondDevice, secondDeviceQueue, copySrcTexture,
-                                   secondDeviceWrappedTexture);
-
-        // Re-import back into |device|, waiting on |secondDevice|'s signal
-        dawn::native::vulkan::ExternalImageExportInfoOpaqueFD secondExportInfo;
-        dawn::native::vulkan::ExportVulkanImage(secondDeviceWrappedTexture.Get(),
-                                                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                                &secondExportInfo);
-        memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
-
-        wgpu::Texture nextWrappedTexture =
-            WrapVulkanImage(device, &defaultDescriptor, memoryFd, defaultAllocationSize,
-                            defaultMemoryTypeIndex, secondExportInfo.semaphoreHandles,
-                            secondExportInfo.releasedOldLayout, secondExportInfo.releasedNewLayout);
-
-        // Verify |nextWrappedTexture| contains the color from our copy
-        EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), nextWrappedTexture, 0, 0);
-
-        IgnoreSignalSemaphore(nextWrappedTexture);
-    }
-
-    // Import a texture from |secondDevice|
-    // Issue a copy of the imported texture inside |device| to |copyDstBuffer|
-    // Verify the clear color from |secondDevice| is visible in |copyDstBuffer|
-    TEST_P(VulkanImageWrappingUsageTests, CopyTextureToBufferSrcSync) {
-        // Import the image on |secondDevice|
-        wgpu::Texture wrappedTexture =
-            WrapVulkanImage(secondDevice, &defaultDescriptor, defaultFd, defaultAllocationSize,
-                            defaultMemoryTypeIndex, {}, VK_IMAGE_LAYOUT_UNDEFINED,
-                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
-
-        // Clear |wrappedTexture| on |secondDevice|
-        ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
-
-        dawn::native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
-        dawn::native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
-                                                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
-
-        // Import the image to |device|, making sure we wait on the semaphore
-        int memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
-        wgpu::Texture deviceWrappedTexture =
-            WrapVulkanImage(device, &defaultDescriptor, memoryFd, defaultAllocationSize,
-                            defaultMemoryTypeIndex, exportInfo.semaphoreHandles,
-                            exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
-
-        // Create a destination buffer on |device|
-        wgpu::BufferDescriptor bufferDesc;
-        bufferDesc.size = 4;
-        bufferDesc.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::CopySrc;
-        wgpu::Buffer copyDstBuffer = device.CreateBuffer(&bufferDesc);
-
-        // Copy |deviceWrappedTexture| into |copyDstBuffer|
-        wgpu::ImageCopyTexture copySrc =
-            utils::CreateImageCopyTexture(deviceWrappedTexture, 0, {0, 0, 0});
-        wgpu::ImageCopyBuffer copyDst = utils::CreateImageCopyBuffer(copyDstBuffer, 0, 256);
-
-        wgpu::Extent3D copySize = {1, 1, 1};
-
-        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
-        encoder.CopyTextureToBuffer(&copySrc, &copyDst, &copySize);
-        wgpu::CommandBuffer commands = encoder.Finish();
-        queue.Submit(1, &commands);
-
-        // Verify |copyDstBuffer| sees changes from |secondDevice|
-        uint32_t expected = 0x04030201;
-        EXPECT_BUFFER_U32_EQ(expected, copyDstBuffer, 0);
-
-        IgnoreSignalSemaphore(deviceWrappedTexture);
-    }
-
-    // Import a texture into |device|
-    // Copy color A into texture on |device|
-    // Import same texture into |secondDevice|, waiting on the copy signal
-    // Copy color B using Buffer to Texture copy on |secondDevice|
-    // Import texture back into |device|, waiting on color B signal
-    // Verify texture contains color B
-    // If texture destination isn't synchronized, |secondDevice| could copy color B
-    // into the texture first, then |device| writes color A
-    TEST_P(VulkanImageWrappingUsageTests, CopyBufferToTextureDstSync) {
-        // Import the image on |device|
-        wgpu::Texture wrappedTexture = WrapVulkanImage(
-            device, &defaultDescriptor, defaultFd, defaultAllocationSize, defaultMemoryTypeIndex,
-            {}, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
-
-        // Clear |wrappedTexture| on |device|
-        ClearImage(device, wrappedTexture, {5 / 255.0f, 6 / 255.0f, 7 / 255.0f, 8 / 255.0f});
-
-        dawn::native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
-        dawn::native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
-                                                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
-
-        // Import the image to |secondDevice|, making sure we wait on |signalFd|
-        int memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
-        wgpu::Texture secondDeviceWrappedTexture =
-            WrapVulkanImage(secondDevice, &defaultDescriptor, memoryFd, defaultAllocationSize,
-                            defaultMemoryTypeIndex, exportInfo.semaphoreHandles,
-                            exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
-
-        // Copy color B on |secondDevice|
-        wgpu::Queue secondDeviceQueue = secondDevice.GetQueue();
-
-        // Create a buffer on |secondDevice|
-        wgpu::Buffer copySrcBuffer =
-            utils::CreateBufferFromData(secondDevice, wgpu::BufferUsage::CopySrc, {0x04030201});
-
-        // Copy |copySrcBuffer| into |secondDeviceWrappedTexture|
-        wgpu::ImageCopyBuffer copySrc = utils::CreateImageCopyBuffer(copySrcBuffer, 0, 256);
-        wgpu::ImageCopyTexture copyDst =
-            utils::CreateImageCopyTexture(secondDeviceWrappedTexture, 0, {0, 0, 0});
-
-        wgpu::Extent3D copySize = {1, 1, 1};
-
-        wgpu::CommandEncoder encoder = secondDevice.CreateCommandEncoder();
-        encoder.CopyBufferToTexture(&copySrc, &copyDst, &copySize);
-        wgpu::CommandBuffer commands = encoder.Finish();
-        secondDeviceQueue.Submit(1, &commands);
-
-        // Re-import back into |device|, waiting on |secondDevice|'s signal
-        dawn::native::vulkan::ExternalImageExportInfoOpaqueFD secondExportInfo;
-        dawn::native::vulkan::ExportVulkanImage(secondDeviceWrappedTexture.Get(),
-                                                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                                &secondExportInfo);
-        memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
-
-        wgpu::Texture nextWrappedTexture =
-            WrapVulkanImage(device, &defaultDescriptor, memoryFd, defaultAllocationSize,
-                            defaultMemoryTypeIndex, secondExportInfo.semaphoreHandles,
-                            secondExportInfo.releasedOldLayout, secondExportInfo.releasedNewLayout);
-
-        // Verify |nextWrappedTexture| contains the color from our copy
-        EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), nextWrappedTexture, 0, 0);
-
-        IgnoreSignalSemaphore(nextWrappedTexture);
-    }
-
-    // Import a texture from |secondDevice|
-    // Issue a copy of the imported texture inside |device| to |copyDstTexture|
-    // Issue second copy to |secondCopyDstTexture|
-    // Verify the clear color from |secondDevice| is visible in both copies
-    TEST_P(VulkanImageWrappingUsageTests, DoubleTextureUsage) {
-        // Import the image on |secondDevice|
-        wgpu::Texture wrappedTexture =
-            WrapVulkanImage(secondDevice, &defaultDescriptor, defaultFd, defaultAllocationSize,
-                            defaultMemoryTypeIndex, {}, VK_IMAGE_LAYOUT_UNDEFINED,
-                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
-
-        // Clear |wrappedTexture| on |secondDevice|
-        ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
-
-        dawn::native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
-        dawn::native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
-                                                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
-
-        // Import the image to |device|, making sure we wait on the semaphore
-        int memoryFd = GetMemoryFd(deviceVk, defaultAllocation);
-        wgpu::Texture deviceWrappedTexture =
-            WrapVulkanImage(device, &defaultDescriptor, memoryFd, defaultAllocationSize,
-                            defaultMemoryTypeIndex, exportInfo.semaphoreHandles,
-                            exportInfo.releasedOldLayout, exportInfo.releasedNewLayout);
-
-        // Create a second texture on |device|
-        wgpu::Texture copyDstTexture = device.CreateTexture(&defaultDescriptor);
-
-        // Create a third texture on |device|
-        wgpu::Texture secondCopyDstTexture = device.CreateTexture(&defaultDescriptor);
-
-        // Copy |deviceWrappedTexture| into |copyDstTexture|
-        SimpleCopyTextureToTexture(device, queue, deviceWrappedTexture, copyDstTexture);
-
-        // Copy |deviceWrappedTexture| into |secondCopyDstTexture|
-        SimpleCopyTextureToTexture(device, queue, deviceWrappedTexture, secondCopyDstTexture);
-
-        // Verify |copyDstTexture| sees changes from |secondDevice|
-        EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), copyDstTexture, 0, 0);
-
-        // Verify |secondCopyDstTexture| sees changes from |secondDevice|
-        EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), secondCopyDstTexture, 0, 0);
-
-        IgnoreSignalSemaphore(deviceWrappedTexture);
-    }
-
-    // Tex A on device 3 (external export)
-    // Tex B on device 2 (external export)
-    // Tex C on device 1 (external export)
-    // Clear color for A on device 3
-    // Copy A->B on device 3
-    // Copy B->C on device 2 (wait on B from previous op)
-    // Copy C->D on device 1 (wait on C from previous op)
-    // Verify D has same color as A
-    TEST_P(VulkanImageWrappingUsageTests, ChainTextureCopy) {
-        // Close |defaultFd| since this test doesn't import it anywhere
-        close(defaultFd);
-
-        // device 1 = |device|
-        // device 2 = |secondDevice|
-        // Create device 3
-        dawn::native::vulkan::Device* thirdDeviceVk =
-            dawn::native::vulkan::ToBackend(backendAdapter->APICreateDevice(&deviceDescriptor));
-        wgpu::Device thirdDevice = wgpu::Device::Acquire(dawn::native::ToAPI(thirdDeviceVk));
-
-        // Make queue for device 2 and 3
-        wgpu::Queue secondDeviceQueue = secondDevice.GetQueue();
-        wgpu::Queue thirdDeviceQueue = thirdDevice.GetQueue();
-
-        // Allocate memory for A, B, C
-        VkImage imageA;
-        VkDeviceMemory allocationA;
-        int memoryFdA;
-        VkDeviceSize allocationSizeA;
-        uint32_t memoryTypeIndexA;
-        CreateBindExportImage(thirdDeviceVk, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, &imageA, &allocationA,
-                              &allocationSizeA, &memoryTypeIndexA, &memoryFdA);
-
-        VkImage imageB;
-        VkDeviceMemory allocationB;
-        int memoryFdB;
-        VkDeviceSize allocationSizeB;
-        uint32_t memoryTypeIndexB;
-        CreateBindExportImage(secondDeviceVk, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, &imageB, &allocationB,
-                              &allocationSizeB, &memoryTypeIndexB, &memoryFdB);
-
-        VkImage imageC;
-        VkDeviceMemory allocationC;
-        int memoryFdC;
-        VkDeviceSize allocationSizeC;
-        uint32_t memoryTypeIndexC;
-        CreateBindExportImage(deviceVk, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, &imageC, &allocationC,
-                              &allocationSizeC, &memoryTypeIndexC, &memoryFdC);
-
-        // Import TexA, TexB on device 3
-        wgpu::Texture wrappedTexADevice3 = WrapVulkanImage(
-            thirdDevice, &defaultDescriptor, memoryFdA, allocationSizeA, memoryTypeIndexA, {},
-            VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
-
-        wgpu::Texture wrappedTexBDevice3 = WrapVulkanImage(
-            thirdDevice, &defaultDescriptor, memoryFdB, allocationSizeB, memoryTypeIndexB, {},
-            VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
-
-        // Clear TexA
-        ClearImage(thirdDevice, wrappedTexADevice3,
-                   {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
-
-        // Copy A->B
-        SimpleCopyTextureToTexture(thirdDevice, thirdDeviceQueue, wrappedTexADevice3,
-                                   wrappedTexBDevice3);
-
-        dawn::native::vulkan::ExternalImageExportInfoOpaqueFD exportInfoTexBDevice3;
-        dawn::native::vulkan::ExportVulkanImage(
-            wrappedTexBDevice3.Get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfoTexBDevice3);
-
-        IgnoreSignalSemaphore(wrappedTexADevice3);
-
-        // Import TexB, TexC on device 2
-        memoryFdB = GetMemoryFd(secondDeviceVk, allocationB);
-        wgpu::Texture wrappedTexBDevice2 = WrapVulkanImage(
-            secondDevice, &defaultDescriptor, memoryFdB, allocationSizeB, memoryTypeIndexB,
-            exportInfoTexBDevice3.semaphoreHandles, exportInfoTexBDevice3.releasedOldLayout,
-            exportInfoTexBDevice3.releasedNewLayout);
-
-        wgpu::Texture wrappedTexCDevice2 = WrapVulkanImage(
-            secondDevice, &defaultDescriptor, memoryFdC, allocationSizeC, memoryTypeIndexC, {},
-            VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
-
-        // Copy B->C on device 2
-        SimpleCopyTextureToTexture(secondDevice, secondDeviceQueue, wrappedTexBDevice2,
-                                   wrappedTexCDevice2);
-
-        dawn::native::vulkan::ExternalImageExportInfoOpaqueFD exportInfoTexCDevice2;
-        dawn::native::vulkan::ExportVulkanImage(
-            wrappedTexCDevice2.Get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfoTexCDevice2);
-
-        IgnoreSignalSemaphore(wrappedTexBDevice2);
-
-        // Import TexC on device 1
-        memoryFdC = GetMemoryFd(deviceVk, allocationC);
-        wgpu::Texture wrappedTexCDevice1 = WrapVulkanImage(
-            device, &defaultDescriptor, memoryFdC, allocationSizeC, memoryTypeIndexC,
-            exportInfoTexCDevice2.semaphoreHandles, exportInfoTexCDevice2.releasedOldLayout,
-            exportInfoTexCDevice2.releasedNewLayout);
-
-        // Create TexD on device 1
-        wgpu::Texture texD = device.CreateTexture(&defaultDescriptor);
-
-        // Copy C->D on device 1
-        SimpleCopyTextureToTexture(device, queue, wrappedTexCDevice1, texD);
-
-        // Verify D matches clear color
-        EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 2, 3, 4), texD, 0, 0);
-
-        thirdDeviceVk->GetFencedDeleter()->DeleteWhenUnused(imageA);
-        thirdDeviceVk->GetFencedDeleter()->DeleteWhenUnused(allocationA);
-        secondDeviceVk->GetFencedDeleter()->DeleteWhenUnused(imageB);
-        secondDeviceVk->GetFencedDeleter()->DeleteWhenUnused(allocationB);
-        deviceVk->GetFencedDeleter()->DeleteWhenUnused(imageC);
-        deviceVk->GetFencedDeleter()->DeleteWhenUnused(allocationC);
-
-        IgnoreSignalSemaphore(wrappedTexCDevice1);
-    }
-
-    // Tests a larger image is preserved when importing
-    TEST_P(VulkanImageWrappingUsageTests, LargerImage) {
-        close(defaultFd);
-
-        wgpu::TextureDescriptor descriptor;
-        descriptor.dimension = wgpu::TextureDimension::e2D;
-        descriptor.size.width = 640;
-        descriptor.size.height = 480;
-        descriptor.size.depthOrArrayLayers = 1;
-        descriptor.sampleCount = 1;
-        descriptor.format = wgpu::TextureFormat::BGRA8Unorm;
-        descriptor.mipLevelCount = 1;
-        descriptor.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::CopySrc;
-
-        // Fill memory with textures to trigger layout issues on AMD
-        std::vector<wgpu::Texture> textures;
-        for (int i = 0; i < 20; i++) {
-            textures.push_back(device.CreateTexture(&descriptor));
-        }
-
-        wgpu::Queue secondDeviceQueue = secondDevice.GetQueue();
-
-        // Make an image on |secondDevice|
-        VkImage imageA;
-        VkDeviceMemory allocationA;
-        int memoryFdA;
-        VkDeviceSize allocationSizeA;
-        uint32_t memoryTypeIndexA;
-        CreateBindExportImage(secondDeviceVk, 640, 480, VK_FORMAT_R8G8B8A8_UNORM, &imageA,
-                              &allocationA, &allocationSizeA, &memoryTypeIndexA, &memoryFdA);
-
-        // Import the image on |secondDevice|
-        wgpu::Texture wrappedTexture =
-            WrapVulkanImage(secondDevice, &descriptor, memoryFdA, allocationSizeA, memoryTypeIndexA,
-                            {}, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
-
-        // Draw a non-trivial picture
-        uint32_t width = 640, height = 480, pixelSize = 4;
-        uint32_t bytesPerRow = Align(width * pixelSize, kTextureBytesPerRowAlignment);
-        std::vector<unsigned char> data(bytesPerRow * (height - 1) + width * pixelSize);
-
-        for (uint32_t row = 0; row < height; row++) {
-            for (uint32_t col = 0; col < width; col++) {
-                float normRow = static_cast<float>(row) / height;
-                float normCol = static_cast<float>(col) / width;
-                float dist = sqrt(normRow * normRow + normCol * normCol) * 3;
-                dist = dist - static_cast<int>(dist);
-                data[4 * (row * width + col)] = static_cast<unsigned char>(dist * 255);
-                data[4 * (row * width + col) + 1] = static_cast<unsigned char>(dist * 255);
-                data[4 * (row * width + col) + 2] = static_cast<unsigned char>(dist * 255);
-                data[4 * (row * width + col) + 3] = 255;
-            }
-        }
-
-        // Write the picture
-        {
-            wgpu::Buffer copySrcBuffer = utils::CreateBufferFromData(
-                secondDevice, data.data(), data.size(), wgpu::BufferUsage::CopySrc);
-            wgpu::ImageCopyBuffer copySrc =
-                utils::CreateImageCopyBuffer(copySrcBuffer, 0, bytesPerRow);
-            wgpu::ImageCopyTexture copyDst =
-                utils::CreateImageCopyTexture(wrappedTexture, 0, {0, 0, 0});
-            wgpu::Extent3D copySize = {width, height, 1};
-
-            wgpu::CommandEncoder encoder = secondDevice.CreateCommandEncoder();
-            encoder.CopyBufferToTexture(&copySrc, &copyDst, &copySize);
-            wgpu::CommandBuffer commands = encoder.Finish();
-            secondDeviceQueue.Submit(1, &commands);
-        }
-
-        dawn::native::vulkan::ExternalImageExportInfoOpaqueFD exportInfo;
-        dawn::native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
-                                                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
-
-        int memoryFd = GetMemoryFd(secondDeviceVk, allocationA);
-
-        // Import the image on |device|
-        wgpu::Texture nextWrappedTexture =
-            WrapVulkanImage(device, &descriptor, memoryFd, allocationSizeA, memoryTypeIndexA,
-                            exportInfo.semaphoreHandles, exportInfo.releasedOldLayout,
-                            exportInfo.releasedNewLayout);
-
-        // Copy the image into a buffer for comparison
-        wgpu::BufferDescriptor copyDesc;
-        copyDesc.size = data.size();
-        copyDesc.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
-        wgpu::Buffer copyDstBuffer = device.CreateBuffer(&copyDesc);
-        {
-            wgpu::ImageCopyTexture copySrc =
-                utils::CreateImageCopyTexture(nextWrappedTexture, 0, {0, 0, 0});
-            wgpu::ImageCopyBuffer copyDst =
-                utils::CreateImageCopyBuffer(copyDstBuffer, 0, bytesPerRow);
-
-            wgpu::Extent3D copySize = {width, height, 1};
-
-            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
-            encoder.CopyTextureToBuffer(&copySrc, &copyDst, &copySize);
-            wgpu::CommandBuffer commands = encoder.Finish();
-            queue.Submit(1, &commands);
-        }
-
-        // Check the image is not corrupted on |device|
-        EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast<uint32_t*>(data.data()), copyDstBuffer, 0,
-                                   data.size() / 4);
-
-        IgnoreSignalSemaphore(nextWrappedTexture);
-        secondDeviceVk->GetFencedDeleter()->DeleteWhenUnused(imageA);
-        secondDeviceVk->GetFencedDeleter()->DeleteWhenUnused(allocationA);
-    }
-
-    DAWN_INSTANTIATE_TEST(VulkanImageWrappingValidationTests, VulkanBackend());
-    DAWN_INSTANTIATE_TEST(VulkanImageWrappingUsageTests, VulkanBackend());
-
-}  // namespace dawn::native::vulkan
diff --git a/src/tests/white_box/VulkanImageWrappingTests_OpaqueFD.cpp b/src/tests/white_box/VulkanImageWrappingTests_OpaqueFD.cpp
new file mode 100644
index 0000000..23275dc
--- /dev/null
+++ b/src/tests/white_box/VulkanImageWrappingTests_OpaqueFD.cpp
@@ -0,0 +1,270 @@
+// Copyright 2021 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "tests/white_box/VulkanImageWrappingTests.h"
+
+#include "dawn_native/vulkan/DeviceVk.h"
+#include "dawn_native/vulkan/FencedDeleter.h"
+#include "dawn_native/vulkan/ResourceMemoryAllocatorVk.h"
+
+#include <gtest/gtest.h>
+#include <unistd.h>
+
+namespace dawn::native::vulkan {
+
+    class ExternalSemaphoreOpaqueFD : public VulkanImageWrappingTestBackend::ExternalSemaphore {
+      public:
+        ExternalSemaphoreOpaqueFD(int handle) : mHandle(handle) {
+        }
+        ~ExternalSemaphoreOpaqueFD() override {
+            if (mHandle != -1) {
+                close(mHandle);
+            }
+        }
+        int AcquireHandle() {
+            int handle = mHandle;
+            mHandle = -1;
+            return handle;
+        }
+
+      private:
+        int mHandle = -1;
+    };
+
+    class ExternalTextureOpaqueFD : public VulkanImageWrappingTestBackend::ExternalTexture {
+      public:
+        ExternalTextureOpaqueFD(dawn::native::vulkan::Device* device,
+                                int fd,
+                                VkDeviceMemory allocation,
+                                VkImage handle,
+                                VkDeviceSize allocationSize,
+                                uint32_t memoryTypeIndex)
+            : mDevice(device),
+              mFd(fd),
+              mAllocation(allocation),
+              mHandle(handle),
+              allocationSize(allocationSize),
+              memoryTypeIndex(memoryTypeIndex) {
+        }
+
+        ~ExternalTextureOpaqueFD() override {
+            if (mFd != -1) {
+                close(mFd);
+            }
+            if (mAllocation != VK_NULL_HANDLE) {
+                mDevice->GetFencedDeleter()->DeleteWhenUnused(mAllocation);
+            }
+            if (mHandle != VK_NULL_HANDLE) {
+                mDevice->GetFencedDeleter()->DeleteWhenUnused(mHandle);
+            }
+        }
+
+        int Dup() const {
+            return dup(mFd);
+        }
+
+      private:
+        dawn::native::vulkan::Device* mDevice;
+        int mFd = -1;
+        VkDeviceMemory mAllocation = VK_NULL_HANDLE;
+        VkImage mHandle = VK_NULL_HANDLE;
+
+      public:
+        const VkDeviceSize allocationSize;
+        const uint32_t memoryTypeIndex;
+    };
+
+    class VulkanImageWrappingTestBackendOpaqueFD : public VulkanImageWrappingTestBackend {
+      public:
+        VulkanImageWrappingTestBackendOpaqueFD(const wgpu::Device& device) : mDevice(device) {
+            mDeviceVk = dawn::native::vulkan::ToBackend(dawn::native::FromAPI(device.Get()));
+        }
+
+        std::unique_ptr<ExternalTexture> CreateTexture(uint32_t width,
+                                                       uint32_t height,
+                                                       wgpu::TextureFormat format,
+                                                       wgpu::TextureUsage usage) override {
+            EXPECT_EQ(format, wgpu::TextureFormat::RGBA8Unorm);
+            VkFormat vulkanFormat = VK_FORMAT_R8G8B8A8_UNORM;
+
+            VkImage handle;
+            ::VkResult result = CreateImage(mDeviceVk, width, height, vulkanFormat, &handle);
+            EXPECT_EQ(result, VK_SUCCESS) << "Failed to create external image";
+
+            VkDeviceMemory allocation;
+            VkDeviceSize allocationSize;
+            uint32_t memoryTypeIndex;
+            ::VkResult resultBool =
+                AllocateMemory(mDeviceVk, handle, &allocation, &allocationSize, &memoryTypeIndex);
+            EXPECT_EQ(resultBool, VK_SUCCESS) << "Failed to allocate external memory";
+
+            result = BindMemory(mDeviceVk, handle, allocation);
+            EXPECT_EQ(result, VK_SUCCESS) << "Failed to bind image memory";
+
+            int fd = GetMemoryFd(mDeviceVk, allocation);
+
+            return std::make_unique<ExternalTextureOpaqueFD>(mDeviceVk, fd, allocation, handle,
+                                                             allocationSize, memoryTypeIndex);
+        }
+
+        wgpu::Texture WrapImage(
+            const wgpu::Device& device,
+            const ExternalTexture* texture,
+            const ExternalImageDescriptorVkForTesting& descriptor,
+            std::vector<std::unique_ptr<ExternalSemaphore>> semaphores) override {
+            const ExternalTextureOpaqueFD* textureOpaqueFD =
+                static_cast<const ExternalTextureOpaqueFD*>(texture);
+            std::vector<int> waitFDs;
+            for (auto& semaphore : semaphores) {
+                waitFDs.push_back(
+                    static_cast<ExternalSemaphoreOpaqueFD*>(semaphore.get())->AcquireHandle());
+            }
+
+            ExternalImageDescriptorOpaqueFD descriptorOpaqueFD;
+            *static_cast<ExternalImageDescriptorVk*>(&descriptorOpaqueFD) = descriptor;
+            descriptorOpaqueFD.memoryFD = textureOpaqueFD->Dup();
+            descriptorOpaqueFD.allocationSize = textureOpaqueFD->allocationSize;
+            descriptorOpaqueFD.memoryTypeIndex = textureOpaqueFD->memoryTypeIndex;
+            descriptorOpaqueFD.waitFDs = std::move(waitFDs);
+
+            return dawn::native::vulkan::WrapVulkanImage(device.Get(), &descriptorOpaqueFD);
+        }
+
+        bool ExportImage(const wgpu::Texture& texture,
+                         VkImageLayout layout,
+                         ExternalImageExportInfoVkForTesting* exportInfo) override {
+            ExternalImageExportInfoOpaqueFD infoOpaqueFD;
+            bool success = ExportVulkanImage(texture.Get(), layout, &infoOpaqueFD);
+
+            *static_cast<ExternalImageExportInfoVk*>(exportInfo) = infoOpaqueFD;
+            for (int fd : infoOpaqueFD.semaphoreHandles) {
+                EXPECT_NE(fd, -1);
+                exportInfo->semaphores.push_back(std::make_unique<ExternalSemaphoreOpaqueFD>(fd));
+            }
+
+            return success;
+        }
+
+      private:
+        // Creates a VkImage with external memory
+        ::VkResult CreateImage(dawn::native::vulkan::Device* deviceVk,
+                               uint32_t width,
+                               uint32_t height,
+                               VkFormat format,
+                               VkImage* image) {
+            VkExternalMemoryImageCreateInfoKHR externalInfo;
+            externalInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR;
+            externalInfo.pNext = nullptr;
+            externalInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+
+            auto usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+                         VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+
+            VkImageCreateInfo createInfo;
+            createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+            createInfo.pNext = &externalInfo;
+            createInfo.flags = VK_IMAGE_CREATE_ALIAS_BIT_KHR;
+            createInfo.imageType = VK_IMAGE_TYPE_2D;
+            createInfo.format = format;
+            createInfo.extent = {width, height, 1};
+            createInfo.mipLevels = 1;
+            createInfo.arrayLayers = 1;
+            createInfo.samples = VK_SAMPLE_COUNT_1_BIT;
+            createInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
+            createInfo.usage = usage;
+            createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+            createInfo.queueFamilyIndexCount = 0;
+            createInfo.pQueueFamilyIndices = nullptr;
+            createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+
+            return deviceVk->fn.CreateImage(deviceVk->GetVkDevice(), &createInfo, nullptr,
+                                            &**image);
+        }
+
+        // Allocates memory for an image
+        ::VkResult AllocateMemory(dawn::native::vulkan::Device* deviceVk,
+                                  VkImage handle,
+                                  VkDeviceMemory* allocation,
+                                  VkDeviceSize* allocationSize,
+                                  uint32_t* memoryTypeIndex) {
+            // Create the image memory and associate it with the container
+            VkMemoryRequirements requirements;
+            deviceVk->fn.GetImageMemoryRequirements(deviceVk->GetVkDevice(), handle, &requirements);
+
+            // Import memory from file descriptor
+            VkExportMemoryAllocateInfoKHR externalInfo;
+            externalInfo.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR;
+            externalInfo.pNext = nullptr;
+            externalInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+
+            int bestType = deviceVk->GetResourceMemoryAllocator()->FindBestTypeIndex(
+                requirements, MemoryKind::Opaque);
+            VkMemoryAllocateInfo allocateInfo;
+            allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+            allocateInfo.pNext = &externalInfo;
+            allocateInfo.allocationSize = requirements.size;
+            allocateInfo.memoryTypeIndex = static_cast<uint32_t>(bestType);
+
+            *allocationSize = allocateInfo.allocationSize;
+            *memoryTypeIndex = allocateInfo.memoryTypeIndex;
+
+            return deviceVk->fn.AllocateMemory(deviceVk->GetVkDevice(), &allocateInfo, nullptr,
+                                               &**allocation);
+        }
+
+        // Binds memory to an image
+        ::VkResult BindMemory(dawn::native::vulkan::Device* deviceVk,
+                              VkImage handle,
+                              VkDeviceMemory memory) {
+            return deviceVk->fn.BindImageMemory(deviceVk->GetVkDevice(), handle, memory, 0);
+        }
+
+        // Extracts a file descriptor representing memory on a device
+        int GetMemoryFd(dawn::native::vulkan::Device* deviceVk, VkDeviceMemory memory) {
+            VkMemoryGetFdInfoKHR getFdInfo;
+            getFdInfo.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR;
+            getFdInfo.pNext = nullptr;
+            getFdInfo.memory = memory;
+            getFdInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+
+            int memoryFd = -1;
+            deviceVk->fn.GetMemoryFdKHR(deviceVk->GetVkDevice(), &getFdInfo, &memoryFd);
+
+            EXPECT_GE(memoryFd, 0) << "Failed to get file descriptor for external memory";
+            return memoryFd;
+        }
+
+        // Prepares and exports memory for an image on a given device
+        void CreateBindExportImage(dawn::native::vulkan::Device* deviceVk,
+                                   uint32_t width,
+                                   uint32_t height,
+                                   VkFormat format,
+                                   VkImage* handle,
+                                   VkDeviceMemory* allocation,
+                                   VkDeviceSize* allocationSize,
+                                   uint32_t* memoryTypeIndex,
+                                   int* memoryFd) {
+        }
+
+        wgpu::Device mDevice;
+        dawn::native::vulkan::Device* mDeviceVk;
+    };
+
+    // static
+    std::unique_ptr<VulkanImageWrappingTestBackend> VulkanImageWrappingTestBackend::Create(
+        const wgpu::Device& device) {
+        return std::make_unique<VulkanImageWrappingTestBackendOpaqueFD>(device);
+    }
+
+}  // namespace dawn::native::vulkan
