// 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
