// 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 {
          public:
            void SetUp() override {
                DAWN_SKIP_TEST_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 an error occurs if the texture descriptor is invalid
    TEST_P(VulkanImageWrappingValidationTests, InvalidTextureDescriptor) {
        wgpu::ChainedStruct chainedDescriptor;
        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
