// Copyright 2020 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "tests/DawnTest.h"

#include "common/Math.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"

#include <fcntl.h>
#include <gbm.h>

namespace dawn_native { namespace vulkan {

    namespace {

        class VulkanImageWrappingTestBase : public DawnTest {
          protected:
            std::vector<const char*> GetRequiredExtensions() override {
                return {"dawn-internal-usages"};
            }

          public:
            void SetUp() override {
                DAWN_TEST_UNSUPPORTED_IF(UsesWire());

                gbmDevice = CreateGbmDevice();
                deviceVk = reinterpret_cast<dawn_native::vulkan::Device*>(device.Get());

                defaultGbmBo = CreateGbmBo(1, 1, true /* linear */);
                defaultStride = gbm_bo_get_stride_for_plane(defaultGbmBo, 0);
                defaultModifier = gbm_bo_get_modifier(defaultGbmBo);
                defaultFd = gbm_bo_get_fd(defaultGbmBo);

                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())
                    return;

                gbm_bo_destroy(defaultGbmBo);
                gbm_device_destroy(gbmDevice);
            }

            gbm_device* CreateGbmDevice() {
                // Render nodes [1] are the primary interface for communicating with the GPU on
                // devices that support DRM. The actual filename of the render node is
                // implementation-specific, so we must scan through all possible filenames to find
                // one that we can use [2].
                //
                // [1] https://dri.freedesktop.org/docs/drm/gpu/drm-uapi.html#render-nodes
                // [2]
                // https://cs.chromium.org/chromium/src/ui/ozone/platform/wayland/gpu/drm_render_node_path_finder.cc
                const uint32_t kRenderNodeStart = 128;
                const uint32_t kRenderNodeEnd = kRenderNodeStart + 16;
                const std::string kRenderNodeTemplate = "/dev/dri/renderD";

                int renderNodeFd = -1;
                for (uint32_t i = kRenderNodeStart; i < kRenderNodeEnd; i++) {
                    std::string renderNode = kRenderNodeTemplate + std::to_string(i);
                    renderNodeFd = open(renderNode.c_str(), O_RDWR);
                    if (renderNodeFd >= 0)
                        break;
                }
                EXPECT_GE(renderNodeFd, 0) << "Failed to get file descriptor for render node";

                gbm_device* gbmDevice = gbm_create_device(renderNodeFd);
                EXPECT_NE(gbmDevice, nullptr) << "Failed to create GBM device";
                return gbmDevice;
            }

            gbm_bo* CreateGbmBo(uint32_t width, uint32_t height, bool linear) {
                uint32_t flags = GBM_BO_USE_RENDERING;
                if (linear)
                    flags |= GBM_BO_USE_LINEAR;
                gbm_bo* gbmBo = gbm_bo_create(gbmDevice, width, height, GBM_FORMAT_XBGR8888, flags);
                EXPECT_NE(gbmBo, nullptr) << "Failed to create GBM buffer object";
                return gbmBo;
            }

            wgpu::Texture WrapVulkanImage(wgpu::Device dawnDevice,
                                          const wgpu::TextureDescriptor* textureDescriptor,
                                          int memoryFd,
                                          uint32_t stride,
                                          uint64_t drmModifier,
                                          std::vector<int> waitFDs,
                                          bool isInitialized = true,
                                          bool expectValid = true) {
                dawn_native::vulkan::ExternalImageDescriptorDmaBuf descriptor;
                return WrapVulkanImage(dawnDevice, textureDescriptor, memoryFd, stride, drmModifier,
                                       waitFDs, descriptor.releasedOldLayout,
                                       descriptor.releasedNewLayout, isInitialized, expectValid);
            }

            wgpu::Texture WrapVulkanImage(wgpu::Device dawnDevice,
                                          const wgpu::TextureDescriptor* textureDescriptor,
                                          int memoryFd,
                                          uint32_t stride,
                                          uint64_t drmModifier,
                                          std::vector<int> waitFDs,
                                          VkImageLayout releasedOldLayout,
                                          VkImageLayout releasedNewLayout,
                                          bool isInitialized = true,
                                          bool expectValid = true) {
                dawn_native::vulkan::ExternalImageDescriptorDmaBuf descriptor;
                descriptor.cTextureDescriptor =
                    reinterpret_cast<const WGPUTextureDescriptor*>(textureDescriptor);
                descriptor.isInitialized = isInitialized;
                descriptor.stride = stride;
                descriptor.drmModifier = drmModifier;
                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::ExternalImageExportInfoDmaBuf exportInfo;
                dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(), VK_IMAGE_LAYOUT_GENERAL, &exportInfo);
                for (int handle : exportInfo.semaphoreHandles) {
                    ASSERT_NE(handle, -1);
                    close(handle);
                }
            }

          protected:
            dawn_native::vulkan::Device* deviceVk;
            gbm_device* gbmDevice;
            wgpu::TextureDescriptor defaultDescriptor;
            gbm_bo* defaultGbmBo;
            int defaultFd;
            uint32_t defaultStride;
            uint64_t defaultModifier;
        };

    }  // anonymous namespace

    using VulkanImageWrappingValidationTests = VulkanImageWrappingTestBase;

    // Test no error occurs if the import is valid
    TEST_P(VulkanImageWrappingValidationTests, SuccessfulImport) {
        wgpu::Texture texture = WrapVulkanImage(device, &defaultDescriptor, defaultFd,
                                                defaultStride, defaultModifier, {}, 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,
                                                defaultStride, defaultModifier, {}, 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,
                                                defaultStride, defaultModifier, {}, true, false));
        EXPECT_EQ(texture.Get(), nullptr);
        close(defaultFd);
    }

    // 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,
                                                defaultStride, defaultModifier, {}, true, false));
        EXPECT_EQ(texture.Get(), nullptr);
        close(defaultFd);
    }

    // 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,
                                                defaultStride, defaultModifier, {}, true, false));
        EXPECT_EQ(texture.Get(), nullptr);
        close(defaultFd);
    }

    // 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,
                                                defaultStride, defaultModifier, {}, true, false));
        EXPECT_EQ(texture.Get(), nullptr);
        close(defaultFd);
    }

    // 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,
                                                defaultStride, defaultModifier, {}, true, false));
        EXPECT_EQ(texture.Get(), nullptr);
        close(defaultFd);
    }

    // Test an error occurs if we try to export the signal semaphore twice
    TEST_P(VulkanImageWrappingValidationTests, DoubleSignalSemaphoreExport) {
        wgpu::Texture texture = WrapVulkanImage(device, &defaultDescriptor, defaultFd,
                                                defaultStride, defaultModifier, {}, true, true);
        ASSERT_NE(texture.Get(), nullptr);
        IgnoreSignalSemaphore(texture);

        dawn_native::vulkan::ExternalImageExportInfoDmaBuf 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) {
        close(defaultFd);

        wgpu::Texture texture = device.CreateTexture(&defaultDescriptor);
        ASSERT_NE(texture.Get(), nullptr);

        dawn_native::vulkan::ExternalImageExportInfoDmaBuf 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) {
        close(defaultFd);

        wgpu::Texture texture = device.CreateTexture(&defaultDescriptor);
        ASSERT_NE(texture.Get(), nullptr);
        texture.Destroy();

        dawn_native::vulkan::ExternalImageExportInfoDmaBuf 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();
            if (UsesWire()) {
                return;
            }

            // Create another device based on the original
            backendAdapter =
                reinterpret_cast<dawn_native::vulkan::Adapter*>(deviceVk->GetAdapter());
            deviceDescriptor.forceEnabledToggles = GetParam().forceEnabledWorkarounds;
            deviceDescriptor.forceDisabledToggles = GetParam().forceDisabledWorkarounds;

            secondDeviceVk = reinterpret_cast<dawn_native::vulkan::Device*>(
                backendAdapter->CreateDevice(&deviceDescriptor));
            secondDevice = wgpu::Device::Acquire(reinterpret_cast<WGPUDevice>(secondDeviceVk));
        }

      protected:
        dawn_native::vulkan::Adapter* backendAdapter;
        dawn_native::DeviceDescriptor deviceDescriptor;

        wgpu::Device secondDevice;
        dawn_native::vulkan::Device* secondDeviceVk;

        // Clear a texture on a given device
        void ClearImage(wgpu::Device dawnDevice,
                        wgpu::Texture wrappedTexture,
                        wgpu::Color clearColor) {
            wgpu::TextureView wrappedView = wrappedTexture.CreateView();

            // Submit a clear operation
            utils::ComboRenderPassDescriptor renderPassDescriptor({wrappedView}, {});
            renderPassDescriptor.cColorAttachments[0].clearColor = clearColor;
            renderPassDescriptor.cColorAttachments[0].loadOp = wgpu::LoadOp::Clear;

            wgpu::CommandEncoder encoder = dawnDevice.CreateCommandEncoder();
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassDescriptor);
            pass.EndPass();

            wgpu::CommandBuffer commands = encoder.Finish();

            wgpu::Queue queue = dawnDevice.GetQueue();
            queue.Submit(1, &commands);
        }

        // Submits a 1x1x1 copy from source to destination
        void SimpleCopyTextureToTexture(wgpu::Device dawnDevice,
                                        wgpu::Queue dawnQueue,
                                        wgpu::Texture source,
                                        wgpu::Texture destination) {
            wgpu::ImageCopyTexture copySrc = utils::CreateImageCopyTexture(source, 0, {0, 0, 0});
            wgpu::ImageCopyTexture copyDst =
                utils::CreateImageCopyTexture(destination, 0, {0, 0, 0});

            wgpu::Extent3D copySize = {1, 1, 1};

            wgpu::CommandEncoder encoder = dawnDevice.CreateCommandEncoder();
            encoder.CopyTextureToTexture(&copySrc, &copyDst, &copySize);
            wgpu::CommandBuffer commands = encoder.Finish();

            dawnQueue.Submit(1, &commands);
        }
    };

    // Clear an image in |secondDevice|
    // Verify clear color is visible in |device|
    TEST_P(VulkanImageWrappingUsageTests, ClearImageAcrossDevices) {
        // Import the image on |secondDevice|
        wgpu::Texture wrappedTexture = WrapVulkanImage(
            secondDevice, &defaultDescriptor, defaultFd, defaultStride, defaultModifier, {},
            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::ExternalImageExportInfoDmaBuf 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 nextFd = gbm_bo_get_fd(defaultGbmBo);
        wgpu::Texture nextWrappedTexture =
            WrapVulkanImage(device, &defaultDescriptor, nextFd, defaultStride, defaultModifier,
                            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, defaultStride, defaultModifier, {},
            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::ExternalImageExportInfoDmaBuf 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 nextFd = gbm_bo_get_fd(defaultGbmBo);
        wgpu::Texture nextWrappedTexture =
            WrapVulkanImage(device, &defaultDescriptor, nextFd, defaultStride, defaultModifier,
                            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|
    // Clear the texture on |secondDevice|
    // Issue a copy of the imported texture inside |device| to |copyDstTexture|
    // Verify the clear color from |secondDevice| is visible in |copyDstTexture|
    TEST_P(VulkanImageWrappingUsageTests, CopyTextureToTextureSrcSync) {
        // Import the image on |secondDevice|
        wgpu::Texture wrappedTexture = WrapVulkanImage(
            secondDevice, &defaultDescriptor, defaultFd, defaultStride, defaultModifier, {},
            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::ExternalImageExportInfoDmaBuf 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 nextFd = gbm_bo_get_fd(defaultGbmBo);
        wgpu::Texture deviceWrappedTexture =
            WrapVulkanImage(device, &defaultDescriptor, nextFd, defaultStride, defaultModifier,
                            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|
    // Clear texture with color A on |device|
    // Import same texture into |secondDevice|, waiting on the copy signal
    // Clear the new texture with color B on |secondDevice|
    // Copy color B using Texture to Texture copy on |secondDevice|
    // Import texture back into |device|, waiting on color B signal
    // Verify texture contains color B
    // If texture destination isn't synchronized, |secondDevice| could copy color B
    // into the texture first, then |device| writes color A
    TEST_P(VulkanImageWrappingUsageTests, CopyTextureToTextureDstSync) {
        // Import the image on |device|
        wgpu::Texture wrappedTexture = WrapVulkanImage(
            device, &defaultDescriptor, defaultFd, defaultStride, defaultModifier, {},
            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::ExternalImageExportInfoDmaBuf exportInfo;
        dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
                                               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &exportInfo);

        // Import the image to |secondDevice|, making sure we wait on |signalFd|
        int nextFd = gbm_bo_get_fd(defaultGbmBo);
        wgpu::Texture secondDeviceWrappedTexture =
            WrapVulkanImage(secondDevice, &defaultDescriptor, nextFd, defaultStride,
                            defaultModifier, 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::ExternalImageExportInfoDmaBuf secondExportInfo;
        dawn_native::vulkan::ExportVulkanImage(secondDeviceWrappedTexture.Get(),
                                               VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
                                               &secondExportInfo);
        nextFd = gbm_bo_get_fd(defaultGbmBo);

        wgpu::Texture nextWrappedTexture =
            WrapVulkanImage(device, &defaultDescriptor, nextFd, defaultStride, defaultModifier,
                            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|
    // Clear the texture on |secondDevice|
    // Issue a copy of the imported texture inside |device| to |copyDstBuffer|
    // Verify the clear color from |secondDevice| is visible in |copyDstBuffer|
    TEST_P(VulkanImageWrappingUsageTests, CopyTextureToBufferSrcSync) {
        // Import the image on |secondDevice|
        wgpu::Texture wrappedTexture = WrapVulkanImage(
            secondDevice, &defaultDescriptor, defaultFd, defaultStride, defaultModifier, {},
            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::ExternalImageExportInfoDmaBuf 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 nextFd = gbm_bo_get_fd(defaultGbmBo);
        wgpu::Texture deviceWrappedTexture =
            WrapVulkanImage(device, &defaultDescriptor, nextFd, defaultStride, defaultModifier,
                            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 = 1;
        EXPECT_BUFFER_U32_EQ(expected, copyDstBuffer, 0);

        IgnoreSignalSemaphore(deviceWrappedTexture);
    }

    // Import a texture into |device|
    // Clear texture with color A on |device|
    // Import same texture into |secondDevice|, waiting on the copy signal
    // Copy color B using Buffer to Texture copy on |secondDevice|
    // Import texture back into |device|, waiting on color B signal
    // Verify texture contains color B
    // If texture destination isn't synchronized, |secondDevice| could copy color B
    // into the texture first, then |device| writes color A
    TEST_P(VulkanImageWrappingUsageTests, CopyBufferToTextureDstSync) {
        // Import the image on |device|
        wgpu::Texture wrappedTexture = WrapVulkanImage(
            device, &defaultDescriptor, defaultFd, defaultStride, defaultModifier, {},
            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::ExternalImageExportInfoDmaBuf 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 nextFd = gbm_bo_get_fd(defaultGbmBo);
        wgpu::Texture secondDeviceWrappedTexture =
            WrapVulkanImage(secondDevice, &defaultDescriptor, nextFd, defaultStride,
                            defaultModifier, 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::ExternalImageExportInfoDmaBuf secondExportInfo;
        dawn_native::vulkan::ExportVulkanImage(secondDeviceWrappedTexture.Get(),
                                               VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
                                               &secondExportInfo);
        nextFd = gbm_bo_get_fd(defaultGbmBo);

        wgpu::Texture nextWrappedTexture =
            WrapVulkanImage(device, &defaultDescriptor, nextFd, defaultStride, defaultModifier,
                            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|
    // Clear the texture on |secondDevice|
    // Issue a copy of the imported texture inside |device| to |copyDstTexture|
    // Issue second copy to |secondCopyDstTexture|
    // Verify the clear color from |secondDevice| is visible in both copies
    TEST_P(VulkanImageWrappingUsageTests, DoubleTextureUsage) {
        // Import the image on |secondDevice|
        wgpu::Texture wrappedTexture = WrapVulkanImage(
            secondDevice, &defaultDescriptor, defaultFd, defaultStride, defaultModifier, {},
            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::ExternalImageExportInfoDmaBuf 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 nextFd = gbm_bo_get_fd(defaultGbmBo);
        wgpu::Texture deviceWrappedTexture =
            WrapVulkanImage(device, &defaultDescriptor, nextFd, defaultStride, defaultModifier,
                            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 = reinterpret_cast<dawn_native::vulkan::Device*>(
            backendAdapter->CreateDevice(&deviceDescriptor));
        wgpu::Device thirdDevice =
            wgpu::Device::Acquire(reinterpret_cast<WGPUDevice>(thirdDeviceVk));

        // Make queue for device 2 and 3
        wgpu::Queue secondDeviceQueue = secondDevice.GetQueue();
        wgpu::Queue thirdDeviceQueue = thirdDevice.GetQueue();

        // Create BOs for A, B, C
        gbm_bo* gbmBoA = CreateGbmBo(1, 1, true /* linear */);
        uint32_t fdA = gbm_bo_get_fd(gbmBoA);
        uint32_t strideA = gbm_bo_get_stride_for_plane(gbmBoA, 0);
        uint64_t modifierA = gbm_bo_get_modifier(gbmBoA);

        gbm_bo* gbmBoB = CreateGbmBo(1, 1, true /* linear */);
        uint32_t fdB = gbm_bo_get_fd(gbmBoB);
        uint32_t strideB = gbm_bo_get_stride_for_plane(gbmBoB, 0);
        uint64_t modifierB = gbm_bo_get_modifier(gbmBoB);

        gbm_bo* gbmBoC = CreateGbmBo(1, 1, true /* linear */);
        uint32_t fdC = gbm_bo_get_fd(gbmBoC);
        uint32_t strideC = gbm_bo_get_stride_for_plane(gbmBoC, 0);
        uint64_t modifierC = gbm_bo_get_modifier(gbmBoC);

        // Import TexA, TexB on device 3
        wgpu::Texture wrappedTexADevice3 =
            WrapVulkanImage(thirdDevice, &defaultDescriptor, fdA, strideA, modifierA, {},
                            VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);

        wgpu::Texture wrappedTexBDevice3 =
            WrapVulkanImage(thirdDevice, &defaultDescriptor, fdB, strideB, modifierB, {},
                            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::ExternalImageExportInfoDmaBuf exportInfoTexBDevice3;
        dawn_native::vulkan::ExportVulkanImage(
            wrappedTexBDevice3.Get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfoTexBDevice3);
        IgnoreSignalSemaphore(wrappedTexADevice3);

        // Import TexB, TexC on device 2
        fdB = gbm_bo_get_fd(gbmBoB);
        wgpu::Texture wrappedTexBDevice2 = WrapVulkanImage(
            secondDevice, &defaultDescriptor, fdB, strideB, modifierB,
            exportInfoTexBDevice3.semaphoreHandles, exportInfoTexBDevice3.releasedOldLayout,
            exportInfoTexBDevice3.releasedNewLayout);

        wgpu::Texture wrappedTexCDevice2 =
            WrapVulkanImage(secondDevice, &defaultDescriptor, fdC, strideC, modifierC, {},
                            VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);

        // Copy B->C on device 2
        SimpleCopyTextureToTexture(secondDevice, secondDeviceQueue, wrappedTexBDevice2,
                                   wrappedTexCDevice2);

        dawn_native::vulkan::ExternalImageExportInfoDmaBuf exportInfoTexCDevice2;
        dawn_native::vulkan::ExportVulkanImage(
            wrappedTexCDevice2.Get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfoTexCDevice2);
        IgnoreSignalSemaphore(wrappedTexBDevice2);

        // Import TexC on device 1
        fdC = gbm_bo_get_fd(gbmBoC);
        wgpu::Texture wrappedTexCDevice1 = WrapVulkanImage(
            device, &defaultDescriptor, fdC, strideC, modifierC,
            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);

        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
        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|
        gbm_bo* gbmBo = CreateGbmBo(640, 480, false /* linear */);
        uint32_t fd = gbm_bo_get_fd(gbmBo);
        uint32_t stride = gbm_bo_get_stride_for_plane(gbmBo, 0);
        uint64_t modifier = gbm_bo_get_modifier(gbmBo);

        // Import the image on |secondDevice|
        wgpu::Texture wrappedTexture =
            WrapVulkanImage(secondDevice, &descriptor, fd, stride, modifier, {},
                            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::ExternalImageExportInfoDmaBuf exportInfo;
        dawn_native::vulkan::ExportVulkanImage(wrappedTexture.Get(),
                                               VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo);
        int nextFd = gbm_bo_get_fd(gbmBo);

        // Import the image on |device|
        wgpu::Texture nextWrappedTexture = WrapVulkanImage(
            device, &descriptor, nextFd, stride, modifier, 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);
    }

    DAWN_INSTANTIATE_TEST(VulkanImageWrappingValidationTests, VulkanBackend());
    DAWN_INSTANTIATE_TEST(VulkanImageWrappingUsageTests, VulkanBackend());

}}  // namespace dawn_native::vulkan
