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