// Copyright 2023 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "dawn/native/vulkan/SharedTextureMemoryVk.h"

#include <algorithm>
#include <utility>
#include <vector>

#include "dawn/native/ChainUtils.h"
#include "dawn/native/Instance.h"
#include "dawn/native/SystemHandle.h"
#include "dawn/native/vulkan/DeviceVk.h"
#include "dawn/native/vulkan/FencedDeleter.h"
#include "dawn/native/vulkan/PhysicalDeviceVk.h"
#include "dawn/native/vulkan/ResourceMemoryAllocatorVk.h"
#include "dawn/native/vulkan/SharedFenceVk.h"
#include "dawn/native/vulkan/TextureVk.h"
#include "dawn/native/vulkan/UtilsVulkan.h"
#include "dawn/native/vulkan/VulkanError.h"

#if DAWN_PLATFORM_IS(ANDROID)
#include <android/hardware_buffer.h>

#include "dawn/native/AHBFunctions.h"
#endif  // DAWN_PLATFORM_IS(ANDROID)

namespace dawn::native::vulkan {

namespace {

#if DAWN_PLATFORM_IS(LINUX)

// Encoding from <drm/drm_fourcc.h>
constexpr uint32_t DrmFourccCode(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
    return a | (b << 8) | (c << 16) | (d << 24);
}

constexpr uint32_t DrmFourccCode(char a, char b, char c, char d) {
    return DrmFourccCode(static_cast<uint32_t>(a), static_cast<uint32_t>(b),
                         static_cast<uint32_t>(c), static_cast<uint32_t>(d));
}

constexpr auto kDrmFormatR8 = DrmFourccCode('R', '8', ' ', ' '); /* [7:0] R */
constexpr auto kDrmFormatGR88 =
    DrmFourccCode('G', 'R', '8', '8'); /* [15:0] G:R 8:8 little endian */
constexpr auto kDrmFormatXRGB8888 =
    DrmFourccCode('X', 'R', '2', '4'); /* [15:0] x:R:G:B 8:8:8:8 little endian */
constexpr auto kDrmFormatXBGR8888 =
    DrmFourccCode('X', 'B', '2', '4'); /* [15:0] x:B:G:R 8:8:8:8 little endian */
constexpr auto kDrmFormatARGB8888 =
    DrmFourccCode('A', 'R', '2', '4'); /* [31:0] A:R:G:B 8:8:8:8 little endian */
constexpr auto kDrmFormatABGR8888 =
    DrmFourccCode('A', 'B', '2', '4'); /* [31:0] A:B:G:R 8:8:8:8 little endian */
constexpr auto kDrmFormatABGR2101010 =
    DrmFourccCode('A', 'B', '3', '0'); /* [31:0] A:B:G:R 2:10:10:10 little endian */
constexpr auto kDrmFormatABGR16161616F =
    DrmFourccCode('A', 'B', '4', 'H'); /* [63:0] A:B:G:R 16:16:16:16 little endian */
constexpr auto kDrmFormatNV12 = DrmFourccCode('N', 'V', '1', '2'); /* 2x2 subsampled Cr:Cb plane */

ResultOrError<wgpu::TextureFormat> FormatFromDrmFormat(uint32_t drmFormat) {
    switch (drmFormat) {
        case kDrmFormatR8:
            return wgpu::TextureFormat::R8Unorm;
        case kDrmFormatGR88:
            return wgpu::TextureFormat::RG8Unorm;
        case kDrmFormatXRGB8888:
        case kDrmFormatARGB8888:
            return wgpu::TextureFormat::BGRA8Unorm;
        case kDrmFormatXBGR8888:
        case kDrmFormatABGR8888:
            return wgpu::TextureFormat::RGBA8Unorm;
        case kDrmFormatABGR2101010:
            return wgpu::TextureFormat::RGB10A2Unorm;
        case kDrmFormatABGR16161616F:
            return wgpu::TextureFormat::RGBA16Float;
        case kDrmFormatNV12:
            return wgpu::TextureFormat::R8BG8Biplanar420Unorm;
        default:
            return DAWN_VALIDATION_ERROR("Unsupported drm format %x.", drmFormat);
    }
}

#endif  // DAWN_PLATFORM_IS(LINUX)

// Creates a VkImage with VkExternalMemoryImageCreateInfo::handlesTypes set to
// `externalMemoryHandleTypeFlagBits`. The rest of the parameters are computed from `properties`
// and `imageFormatInfo`. Additional structs may be chained by passing them in the varardic
// parameter args.
template <typename... AdditionalChains>
ResultOrError<VkImage> CreateExternalVkImage(
    Device* device,
    const SharedTextureMemoryProperties& properties,
    const VkPhysicalDeviceImageFormatInfo2& imageFormatInfo,
    VkExternalMemoryHandleTypeFlagBits externalMemoryHandleTypeFlagBits,
    AdditionalChains*... additionalChains) {
    VkImageCreateInfo createInfo = {};
    createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
    createInfo.flags = imageFormatInfo.flags;
    createInfo.imageType = imageFormatInfo.type;
    createInfo.format = imageFormatInfo.format;
    createInfo.extent = {properties.size.width, properties.size.height, 1};
    createInfo.mipLevels = 1;
    createInfo.arrayLayers = properties.size.depthOrArrayLayers;
    createInfo.samples = VK_SAMPLE_COUNT_1_BIT;
    createInfo.tiling = imageFormatInfo.tiling;
    createInfo.usage = imageFormatInfo.usage;
    createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
    createInfo.queueFamilyIndexCount = 0;
    createInfo.pQueueFamilyIndices = nullptr;
    createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

    VkExternalMemoryImageCreateInfo externalMemoryImageCreateInfo = {};
    externalMemoryImageCreateInfo.handleTypes = externalMemoryHandleTypeFlagBits;

    PNextChainBuilder createInfoChain(&createInfo);
    createInfoChain.Add(&externalMemoryImageCreateInfo,
                        VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO);

    (createInfoChain.Add(additionalChains), ...);

    // Create the VkImage.
    VkImage vkImage;
    DAWN_TRY(CheckVkSuccess(
        device->fn.CreateImage(device->GetVkDevice(), &createInfo, nullptr, &*vkImage),
        "vkCreateImage"));
    return vkImage;
}

// Add `VkPhysicalDeviceExternalImageFormatInfo` and `additionalChains` to `imageFormatInfo` and
// check this memory type and format combination can be imported.
template <typename... AdditionalChains>
MaybeError CheckExternalImageFormatSupport(
    Device* device,
    const SharedTextureMemoryProperties& properties,
    VkPhysicalDeviceImageFormatInfo2* imageFormatInfo,
    VkExternalMemoryHandleTypeFlagBits externalMemoryHandleTypeFlagBits,
    AdditionalChains*... additionalChains) {
    VkPhysicalDeviceExternalImageFormatInfo externalImageFormatInfo = {};
    externalImageFormatInfo.handleType = externalMemoryHandleTypeFlagBits;

    PNextChainBuilder imageFormatInfoChain(imageFormatInfo);
    imageFormatInfoChain.Add(&externalImageFormatInfo,
                             VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO);
    (imageFormatInfoChain.Add(additionalChains), ...);

    VkImageFormatProperties2 imageFormatProps = {};
    imageFormatProps.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;

    VkExternalImageFormatProperties externalImageFormatProps = {};

    PNextChainBuilder imageFormatPropsChain(&imageFormatProps);
    imageFormatPropsChain.Add(&externalImageFormatProps,
                              VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES);

    DAWN_TRY_CONTEXT(
        CheckVkSuccess(device->fn.GetPhysicalDeviceImageFormatProperties2(
                           ToBackend(device->GetPhysicalDevice())->GetVkPhysicalDevice(),
                           imageFormatInfo, &imageFormatProps),
                       "vkGetPhysicalDeviceImageFormatProperties"),
        "checking import support for external memory type %x with %s %s\n",
        externalMemoryHandleTypeFlagBits, properties.format, properties.usage);

    VkExternalMemoryFeatureFlags featureFlags =
        externalImageFormatProps.externalMemoryProperties.externalMemoryFeatures;
    DAWN_INVALID_IF(!(featureFlags & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT),
                    "Vulkan memory is not importable.");

    return {};
}

// Add `additionalChains` to `memoryAllocateInfo` and call vkAllocateMemory.
template <typename... AdditionalChains>
ResultOrError<VkDeviceMemory> AllocateDeviceMemory(Device* device,
                                                   VkMemoryAllocateInfo* memoryAllocateInfo,
                                                   AdditionalChains*... additionalChains) {
    PNextChainBuilder memoryAllocateInfoChain(memoryAllocateInfo);

    (memoryAllocateInfoChain.Add(additionalChains), ...);

    VkDeviceMemory vkDeviceMemory;
    DAWN_TRY(CheckVkSuccess(device->fn.AllocateMemory(device->GetVkDevice(), memoryAllocateInfo,
                                                      nullptr, &*vkDeviceMemory),
                            "vkAllocateMemory"));
    return vkDeviceMemory;
}

}  // namespace

// static
ResultOrError<Ref<SharedTextureMemory>> SharedTextureMemory::Create(
    Device* device,
    const char* label,
    const SharedTextureMemoryDmaBufDescriptor* descriptor) {
#if DAWN_PLATFORM_IS(LINUX)
    VkDevice vkDevice = device->GetVkDevice();
    VkPhysicalDevice vkPhysicalDevice =
        ToBackend(device->GetPhysicalDevice())->GetVkPhysicalDevice();

    const VkExternalMemoryHandleTypeFlagBits handleType =
        VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;

    DAWN_INVALID_IF(descriptor->size.depthOrArrayLayers != 1, "depthOrArrayLayers was not 1.");

    SharedTextureMemoryProperties properties;
    properties.size = {descriptor->size.width, descriptor->size.height,
                       descriptor->size.depthOrArrayLayers};

    DAWN_TRY_ASSIGN(properties.format, FormatFromDrmFormat(descriptor->drmFormat));

    properties.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst |
                       wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::StorageBinding |
                       wgpu::TextureUsage::RenderAttachment;

    // Create the SharedTextureMemory object.
    Ref<SharedTextureMemory> sharedTextureMemory =
        SharedTextureMemory::Create(device, label, properties, VK_QUEUE_FAMILY_EXTERNAL_KHR);

    // Reflect properties to reify them.
    sharedTextureMemory->APIGetProperties(&properties);

    const Format* internalFormat = nullptr;
    DAWN_TRY_ASSIGN(internalFormat, device->GetInternalFormat(properties.format));

    const auto& compatibleViewFormats = device->GetCompatibleViewFormats(*internalFormat);

    VkFormat vkFormat = VulkanImageFormat(device, properties.format);

    // Usage flags to create the image with.
    VkImageUsageFlags vkUsageFlags = VulkanImageUsage(device, properties.usage, *internalFormat);

    // Number of memory planes in the image which will be queried from the DRM modifier.
    uint32_t memoryPlaneCount;

    // Info describing the image import. We will use this to check the import is valid, and then
    // perform the actual VkImage creation.
    VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = {};
    // List of view formats the image can be created.
    std::array<VkFormat, 3> viewFormats;
    VkImageFormatListCreateInfo imageFormatListInfo = {};
    imageFormatListInfo.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO;

    // The Vulkan spec seems to be too strict in that:
    // - use of DRM modifiers requires passing an image format list
    // - that image format list can't have sRGB formats if the usage has StorageBinding
    // In practice, it's "fine" to create a normal VkImage with StorageBinding and sRGB in the
    // format list, and the VVL here may be wrong. See also see
    // https://github.com/gpuweb/gpuweb/issues/4426. The support check may be unnecessarily strict.
    // TODO(crbug.com/dawn/2304): Follow up with the Vulkan spec and try to lift this.
    // Here, we set `addViewFormats` after checking for support to work around the strictness.
    bool addViewFormats = false;

    // Validate that the import is valid.
    {
        // Verify plane count for the modifier.
        // https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkDrmFormatModifierPropertiesEXT.html#_description
        VkDrmFormatModifierPropertiesEXT drmModifierProps;
        DAWN_TRY_ASSIGN(drmModifierProps,
                        GetFormatModifierProps(device->fn, vkPhysicalDevice, vkFormat,
                                               descriptor->drmModifier));
        memoryPlaneCount = drmModifierProps.drmFormatModifierPlaneCount;
        if (drmModifierProps.drmFormatModifier == 0 /* DRM_FORMAT_MOD_LINEAR */) {
            uint32_t formatPlaneCount = GetAspectCount(internalFormat->aspects);
            DAWN_INVALID_IF(memoryPlaneCount != formatPlaneCount,
                            "DRM format plane count (%u) must match the format plane count (%u) if "
                            "drmModifier is DRM_FORMAT_MOD_LINEAR.",
                            memoryPlaneCount, formatPlaneCount);
        }
        DAWN_INVALID_IF(
            memoryPlaneCount != descriptor->planeCount,
            "Memory plane count (%x) for drm format (%u) and modifier (%u) specify a plane "
            "count of %u which "
            "does not match the provided plane count (%u)",
            vkFormat, descriptor->drmFormat, descriptor->drmModifier, memoryPlaneCount,
            descriptor->planeCount);
        DAWN_INVALID_IF(memoryPlaneCount == 0, "Memory plane count must not be 0");
        DAWN_INVALID_IF(memoryPlaneCount > kMaxPlanesPerFormat,
                        "Memory plane count (%u) must not exceed %u.", memoryPlaneCount,
                        kMaxPlanesPerFormat);

        // Verify that the format modifier of the external memory and the requested Vulkan format
        // are actually supported together in a dma-buf import.
        imageFormatInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
        imageFormatInfo.format = vkFormat;
        imageFormatInfo.type = VK_IMAGE_TYPE_2D;
        imageFormatInfo.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
        imageFormatInfo.usage = vkUsageFlags;
        imageFormatInfo.flags = 0;

        VkPhysicalDeviceImageDrmFormatModifierInfoEXT drmModifierInfo = {};
        drmModifierInfo.sType =
            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT;
        drmModifierInfo.drmFormatModifier = descriptor->drmModifier;
        drmModifierInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

        constexpr wgpu::TextureUsage kUsageRequiringView = wgpu::TextureUsage::RenderAttachment |
                                                           wgpu::TextureUsage::TextureBinding |
                                                           wgpu::TextureUsage::StorageBinding;
        const bool mayNeedView = (properties.usage & kUsageRequiringView) != 0;

        if (mayNeedView) {
            // Add the mutable format bit for view reinterpretation.
            imageFormatInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;

            // Append the list of view formats the image must be compatible with.
            if (device->GetDeviceInfo().HasExt(DeviceExt::ImageFormatList)) {
                if (internalFormat->IsMultiPlanar()) {
                    viewFormats = {
                        VulkanImageFormat(device,
                                          internalFormat->GetAspectInfo(Aspect::Plane0).format),
                        VulkanImageFormat(device,
                                          internalFormat->GetAspectInfo(Aspect::Plane1).format)};
                    imageFormatListInfo.viewFormatCount = 2;
                } else {
                    // Pass the format as the one and only allowed view format.
                    // Use of VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT requires passing a non-zero
                    // list.
                    const bool needsBGRA8UnormStoragePolyfill =
                        properties.format == wgpu::TextureFormat::BGRA8Unorm &&
                        (properties.usage & wgpu::TextureUsage::StorageBinding);
                    if (compatibleViewFormats.empty()) {
                        DAWN_ASSERT(!needsBGRA8UnormStoragePolyfill);
                        viewFormats = {vkFormat};
                        imageFormatListInfo.viewFormatCount = 1;
                    } else {
                        viewFormats[imageFormatListInfo.viewFormatCount++] = vkFormat;
                        if (needsBGRA8UnormStoragePolyfill) {
                            viewFormats[imageFormatListInfo.viewFormatCount++] =
                                VK_FORMAT_R8G8B8A8_UNORM;
                        }
                        addViewFormats = true;
                    }
                }
                imageFormatListInfo.pViewFormats = viewFormats.data();
            }
        }

        if (imageFormatListInfo.viewFormatCount > 0) {
            DAWN_TRY_CONTEXT(
                CheckExternalImageFormatSupport(device, properties, &imageFormatInfo, handleType,
                                                &drmModifierInfo, &imageFormatListInfo),
                "checking import support for fd import of dma buf");
        } else {
            DAWN_TRY_CONTEXT(CheckExternalImageFormatSupport(device, properties, &imageFormatInfo,
                                                             handleType, &drmModifierInfo),
                             "checking import support for fd import of dma buf");
        }
    }

    // Validate that there is a single FD. If there is more than one FD, Dawn will need to validate
    // the format has VK_FORMAT_FEATURE_DISJOINT_BIT, create the VkImage with
    // VK_IMAGE_CREATE_DISJOINT_BIT, and separately bind the image planes to memory. Dawn doesn't
    // support use of VK_IMAGE_CREATE_DISJOINT_BIT currently. See crbug.com/42240514.
    int fd = descriptor->planes[0].fd;
    for (uint32_t i = 1; i < descriptor->planeCount; ++i) {
        DAWN_INVALID_IF(descriptor->planes[i].fd != fd,
                        "descriptor->planes[%u].fd (%i) does not match other plane fd (%i). All "
                        "fds must be the same.",
                        i, descriptor->planes[i].fd, fd);
    }

    // Don't add the view format if backend validation is enabled, otherwise most image creations
    // will fail with VVL. This view format is only needed for sRGB reinterpretation.
    // TODO(crbug.com/dawn/2304): Investigate if this is a bug in VVL.
    if (addViewFormats && !device->GetAdapter()->GetInstance()->IsBackendValidationEnabled()) {
        DAWN_ASSERT(compatibleViewFormats.size() == 1u);
        viewFormats[imageFormatListInfo.viewFormatCount++] =
            VulkanImageFormat(device, compatibleViewFormats[0]->format);
    }

    // Create the VkImage for the import.
    {
        std::array<VkSubresourceLayout, kMaxPlanesPerFormat> planeLayouts;
        for (uint32_t plane = 0u; plane < memoryPlaneCount; ++plane) {
            planeLayouts[plane].offset = descriptor->planes[plane].offset;
            planeLayouts[plane].size = 0;  // VK_EXT_image_drm_format_modifier mandates size = 0.
            planeLayouts[plane].rowPitch = descriptor->planes[plane].stride;
            planeLayouts[plane].arrayPitch = 0;  // Not an array texture
            planeLayouts[plane].depthPitch = 0;  // Not a depth texture
        }

        VkImageDrmFormatModifierExplicitCreateInfoEXT explicitCreateInfo = {};
        explicitCreateInfo.sType =
            VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT;
        explicitCreateInfo.drmFormatModifier = descriptor->drmModifier;
        explicitCreateInfo.drmFormatModifierPlaneCount = memoryPlaneCount;
        explicitCreateInfo.pPlaneLayouts = planeLayouts.data();

        VkImage vkImage;
        DAWN_TRY_ASSIGN(vkImage,
                        CreateExternalVkImage(device, properties, imageFormatInfo, handleType,
                                              &imageFormatListInfo, &explicitCreateInfo));

        sharedTextureMemory->mVkImage =
            AcquireRef(new RefCountedVkHandle<VkImage>(device, vkImage));
    }

    // Import the memory plane(s) as VkDeviceMemory and bind to the VkImage.
    VkMemoryFdPropertiesKHR fdProperties;
    fdProperties.sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR;
    fdProperties.pNext = nullptr;

    // Get the valid memory types that the external memory can be imported as.
    DAWN_TRY(CheckVkSuccess(device->fn.GetMemoryFdPropertiesKHR(
                                vkDevice, handleType, descriptor->planes[0].fd, &fdProperties),
                            "vkGetMemoryFdPropertiesKHR"));

    // Get the valid memory types for the VkImage.
    VkMemoryRequirements memoryRequirements;
    device->fn.GetImageMemoryRequirements(vkDevice, sharedTextureMemory->mVkImage->Get(),
                                          &memoryRequirements);

    // Choose the best memory type that satisfies both the image's constraint and the
    // import's constraint.
    memoryRequirements.memoryTypeBits &= fdProperties.memoryTypeBits;
    int memoryTypeIndex = device->GetResourceMemoryAllocator()->FindBestTypeIndex(
        memoryRequirements, MemoryKind::Opaque);
    DAWN_INVALID_IF(memoryTypeIndex == -1, "Unable to find an appropriate memory type for import.");

    SystemHandle memoryFD;
    DAWN_TRY_ASSIGN(memoryFD, SystemHandle::Duplicate(fd));

    VkMemoryAllocateInfo memoryAllocateInfo = {};
    memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
    memoryAllocateInfo.allocationSize = memoryRequirements.size;
    memoryAllocateInfo.memoryTypeIndex = memoryTypeIndex;

    VkImportMemoryFdInfoKHR importMemoryFdInfo;
    importMemoryFdInfo.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR;
    importMemoryFdInfo.handleType = handleType;
    importMemoryFdInfo.fd = memoryFD.Get();

    // Import the fd as VkDeviceMemory
    VkDeviceMemory vkDeviceMemory;
    DAWN_TRY_ASSIGN(vkDeviceMemory,
                    AllocateDeviceMemory(device, &memoryAllocateInfo, &importMemoryFdInfo));

    memoryFD.Detach();  // Ownership transfered to the VkDeviceMemory.
    sharedTextureMemory->mVkDeviceMemory =
        AcquireRef(new RefCountedVkHandle<VkDeviceMemory>(device, vkDeviceMemory));

    // Bind the VkImage to the memory.
    DAWN_TRY(
        CheckVkSuccess(device->fn.BindImageMemory(vkDevice, sharedTextureMemory->mVkImage->Get(),
                                                  sharedTextureMemory->mVkDeviceMemory->Get(), 0),
                       "vkBindImageMemory"));
    return sharedTextureMemory;
#else
    DAWN_UNREACHABLE();
#endif  // DAWN_PLATFORM_IS(LINUX)
}

// static
ResultOrError<Ref<SharedTextureMemory>> SharedTextureMemory::Create(
    Device* device,
    const char* label,
    const SharedTextureMemoryAHardwareBufferDescriptor* descriptor) {
#if DAWN_PLATFORM_IS(ANDROID)
    const auto* ahbFunctions =
        ToBackend(device->GetAdapter()->GetPhysicalDevice())->GetOrLoadAHBFunctions();
    VkDevice vkDevice = device->GetVkDevice();

    auto* aHardwareBuffer = static_cast<struct AHardwareBuffer*>(descriptor->handle);

    bool useExternalFormat = descriptor->useExternalFormat;

    const VkExternalMemoryHandleTypeFlagBits handleType =
        VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;

    // Reflect the properties of the AHardwareBuffer.
    AHardwareBuffer_Desc aHardwareBufferDesc{};
    ahbFunctions->Describe(aHardwareBuffer, &aHardwareBufferDesc);

    SharedTextureMemoryProperties properties;
    properties.size = {aHardwareBufferDesc.width, aHardwareBufferDesc.height,
                       aHardwareBufferDesc.layers};
    if (useExternalFormat) {
        if (aHardwareBufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE) {
            properties.usage = wgpu::TextureUsage::TextureBinding;
        }
    } else {
        properties.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
        if (aHardwareBufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER) {
            properties.usage |= wgpu::TextureUsage::RenderAttachment;
        }
        if (aHardwareBufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE) {
            properties.usage |= wgpu::TextureUsage::TextureBinding;
        }
        if (aHardwareBufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER) {
            properties.usage |= wgpu::TextureUsage::StorageBinding;
        }
    }

    VkFormat vkFormat;
    YCbCrVkDescriptor yCbCrAHBInfo;
    SampleTypeBit externalSampleType;
    VkAndroidHardwareBufferPropertiesANDROID bufferProperties = {
        .sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID,
    };
    VkExternalFormatANDROID externalFormatAndroid = {
        .sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID,
    };

    // Query the properties to find the appropriate VkFormat and memory type.
    {
        VkAndroidHardwareBufferFormatPropertiesANDROID bufferFormatProperties;
        PNextChainBuilder bufferPropertiesChain(&bufferProperties);
        bufferPropertiesChain.Add(
            &bufferFormatProperties,
            VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID);

        DAWN_TRY(CheckVkSuccess(device->fn.GetAndroidHardwareBufferPropertiesANDROID(
                                    vkDevice, aHardwareBuffer, &bufferProperties),
                                "vkGetAndroidHardwareBufferPropertiesANDROID"));

        // TODO(crbug.com/dawn/2476): Validate more as per
        // https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkImageCreateInfo.html
        if (useExternalFormat) {
            DAWN_INVALID_IF(
                bufferFormatProperties.externalFormat == 0,
                "AHardwareBuffer with external sampler must have non-zero external format.");
            vkFormat = VK_FORMAT_UNDEFINED;
            externalFormatAndroid.externalFormat = bufferFormatProperties.externalFormat;
            properties.format = wgpu::TextureFormat::External;
        } else {
            vkFormat = bufferFormatProperties.format;
            externalFormatAndroid.externalFormat = 0;
            DAWN_TRY_ASSIGN(properties.format, FormatFromVkFormat(device, vkFormat));
        }

        // Populate the YCbCr info.
        yCbCrAHBInfo.externalFormat = externalFormatAndroid.externalFormat;
        yCbCrAHBInfo.vkFormat = vkFormat;
        yCbCrAHBInfo.vkYCbCrModel = bufferFormatProperties.suggestedYcbcrModel;
        yCbCrAHBInfo.vkYCbCrRange = bufferFormatProperties.suggestedYcbcrRange;
        yCbCrAHBInfo.vkComponentSwizzleRed =
            bufferFormatProperties.samplerYcbcrConversionComponents.r;
        yCbCrAHBInfo.vkComponentSwizzleGreen =
            bufferFormatProperties.samplerYcbcrConversionComponents.g;
        yCbCrAHBInfo.vkComponentSwizzleBlue =
            bufferFormatProperties.samplerYcbcrConversionComponents.b;
        yCbCrAHBInfo.vkComponentSwizzleAlpha =
            bufferFormatProperties.samplerYcbcrConversionComponents.a;
        yCbCrAHBInfo.vkXChromaOffset = bufferFormatProperties.suggestedXChromaOffset;
        yCbCrAHBInfo.vkYChromaOffset = bufferFormatProperties.suggestedYChromaOffset;

        uint32_t formatFeatures = bufferFormatProperties.formatFeatures;
        if (formatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT) {
            yCbCrAHBInfo.vkChromaFilter = wgpu::FilterMode::Linear;
            externalSampleType = SampleTypeBit::UnfilterableFloat | SampleTypeBit::Float;
        } else {
            yCbCrAHBInfo.vkChromaFilter = wgpu::FilterMode::Nearest;
            externalSampleType = SampleTypeBit::UnfilterableFloat;
        }
        yCbCrAHBInfo.forceExplicitReconstruction =
            formatFeatures &
            VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT;
    }

    const Format* internalFormat = nullptr;
    DAWN_TRY_ASSIGN(internalFormat, device->GetInternalFormat(properties.format));

    DAWN_INVALID_IF(internalFormat->IsMultiPlanar(),
                    "Multi-planar AHardwareBuffer not supported yet.");

    // Create the SharedTextureMemory object.
    Ref<SharedTextureMemory> sharedTextureMemory =
        SharedTextureMemory::Create(device, label, properties, VK_QUEUE_FAMILY_FOREIGN_EXT);

    sharedTextureMemory->mYCbCrAHBInfo = yCbCrAHBInfo;
    sharedTextureMemory->GetContents()->SetExternalFormatSupportedSampleTypes(externalSampleType);

    // Reflect properties to reify them.
    sharedTextureMemory->APIGetProperties(&properties);

    // Compute the Vulkan usage flags to create the image with.
    VkImageUsageFlags vkUsageFlags = VulkanImageUsage(device, properties.usage, *internalFormat);

    const auto& compatibleViewFormats = device->GetCompatibleViewFormats(*internalFormat);

    // Info describing the image import. We will use this to check the import is valid, and then
    // perform the actual VkImage creation.
    VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = {};
    // List of view formats the image can be created.
    std::array<VkFormat, 2> viewFormats;
    VkImageFormatListCreateInfo imageFormatListInfo = {};
    imageFormatListInfo.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO;

    // Validate that the import is valid
    {
        // Verify that the format modifier of the external memory and the requested Vulkan format
        // are actually supported together in an AHB import.
        imageFormatInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
        imageFormatInfo.format = vkFormat;
        imageFormatInfo.type = VK_IMAGE_TYPE_2D;
        imageFormatInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
        imageFormatInfo.usage = vkUsageFlags;
        imageFormatInfo.flags = 0;

        if (!useExternalFormat) {
            constexpr wgpu::TextureUsage kUsageRequiringView =
                wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding |
                wgpu::TextureUsage::StorageBinding;
            const bool mayNeedViewReinterpretation =
                (properties.usage & kUsageRequiringView) != 0 && !compatibleViewFormats.empty();
            const bool needsBGRA8UnormStoragePolyfill =
                properties.format == wgpu::TextureFormat::BGRA8Unorm &&
                (properties.usage & wgpu::TextureUsage::StorageBinding);
            if (mayNeedViewReinterpretation || needsBGRA8UnormStoragePolyfill) {
                // Add the mutable format bit for view reinterpretation.
                imageFormatInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;

                if (properties.usage & wgpu::TextureUsage::StorageBinding) {
                    // Don't use an image format list because it becomes impossible to make an
                    // rgba8unorm storage texture which may be reinterpreted as rgba8unorm-srgb,
                    // because the srgb format doesn't support storage. Creation with an explicit
                    // format list that includes srgb will fail.
                    // This is the same issue seen with the DMA buf import path which has a
                    // workaround to bypass the support check.
                    // TODO(crbug.com/dawn/2304): If the dma buf import is resolved in a better way,
                    // apply the same fix here.
                } else if (device->GetDeviceInfo().HasExt(DeviceExt::ImageFormatList)) {
                    // Set the list of view formats the image can be compatible with.
                    DAWN_ASSERT(compatibleViewFormats.size() == 1u);
                    viewFormats[0] = vkFormat;
                    viewFormats[1] = VulkanImageFormat(device, compatibleViewFormats[0]->format);
                    imageFormatListInfo.viewFormatCount = 2;
                    imageFormatListInfo.pViewFormats = viewFormats.data();
                }
            }

            if (imageFormatListInfo.viewFormatCount > 0) {
                DAWN_TRY_CONTEXT(
                    CheckExternalImageFormatSupport(device, properties, &imageFormatInfo,
                                                    handleType, &imageFormatListInfo),
                    "checking import support of AHardwareBuffer");
            } else {
                DAWN_TRY_CONTEXT(CheckExternalImageFormatSupport(device, properties,
                                                                 &imageFormatInfo, handleType),
                                 "checking import support of AHardwareBuffer");
            }
        }
    }

    // Create the VkImage for the import.
    {
        VkImage vkImage;
        DAWN_TRY_ASSIGN(vkImage,
                        CreateExternalVkImage(device, properties, imageFormatInfo, handleType,
                                              &imageFormatListInfo, &externalFormatAndroid));

        sharedTextureMemory->mVkImage =
            AcquireRef(new RefCountedVkHandle<VkImage>(device, vkImage));
    }

    // Import the memory as VkDeviceMemory and bind to the VkImage.
    {
        // Choose the best memory type that satisfies the import's constraint.
        VkMemoryRequirements memoryRequirements;
        memoryRequirements.memoryTypeBits = bufferProperties.memoryTypeBits;
        int memoryTypeIndex = device->GetResourceMemoryAllocator()->FindBestTypeIndex(
            memoryRequirements, MemoryKind::Opaque);
        DAWN_INVALID_IF(memoryTypeIndex == -1,
                        "Unable to find an appropriate memory type for import.");

        VkMemoryAllocateInfo memoryAllocateInfo = {};
        memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
        memoryAllocateInfo.allocationSize = bufferProperties.allocationSize;
        memoryAllocateInfo.memoryTypeIndex = memoryTypeIndex;

        VkImportAndroidHardwareBufferInfoANDROID importMemoryAHBInfo = {};
        importMemoryAHBInfo.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
        importMemoryAHBInfo.buffer = aHardwareBuffer;

        // https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#memory-external-android-hardware-buffer-image-resources
        // AHardwareBuffer imports *must* use dedicated allocations.
        VkMemoryDedicatedAllocateInfo dedicatedAllocateInfo;
        dedicatedAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
        dedicatedAllocateInfo.image = sharedTextureMemory->mVkImage->Get();
        dedicatedAllocateInfo.buffer = VkBuffer{};

        // Import the AHardwareBuffer as VkDeviceMemory
        VkDeviceMemory vkDeviceMemory;
        DAWN_TRY_ASSIGN(vkDeviceMemory,
                        AllocateDeviceMemory(device, &memoryAllocateInfo, &dedicatedAllocateInfo,
                                             &importMemoryAHBInfo));

        sharedTextureMemory->mVkDeviceMemory =
            AcquireRef(new RefCountedVkHandle<VkDeviceMemory>(device, vkDeviceMemory));

        // Bind the VkImage to the memory.
        DAWN_TRY(CheckVkSuccess(
            device->fn.BindImageMemory(vkDevice, sharedTextureMemory->mVkImage->Get(),
                                       sharedTextureMemory->mVkDeviceMemory->Get(), 0),
            "vkBindImageMemory"));

        // Verify the texture memory requirements fit within the constraints of the AHardwareBuffer.
        device->fn.GetImageMemoryRequirements(vkDevice, sharedTextureMemory->mVkImage->Get(),
                                              &memoryRequirements);

        DAWN_INVALID_IF((memoryRequirements.memoryTypeBits & bufferProperties.memoryTypeBits) == 0,
                        "Required memory type bits (%u) do not overlap with AHardwareBuffer memory "
                        "type bits (%u).",
                        memoryRequirements.memoryTypeBits, bufferProperties.memoryTypeBits);

        if (!device->IsToggleEnabled(Toggle::IgnoreImportedAHardwareBufferVulkanImageSize)) {
            DAWN_INVALID_IF(memoryRequirements.size > bufferProperties.allocationSize,
                            "Required texture memory size (%u) is larger than the AHardwareBuffer "
                            "allocation size (%u).",
                            memoryRequirements.size, bufferProperties.allocationSize);
        }
    }
    return sharedTextureMemory;
#else
    DAWN_UNREACHABLE();
#endif  // DAWN_PLATFORM_IS(ANDROID)
}

// static
ResultOrError<Ref<SharedTextureMemory>> SharedTextureMemory::Create(
    Device* device,
    const char* label,
    const SharedTextureMemoryOpaqueFDDescriptor* descriptor) {
#if DAWN_PLATFORM_IS(POSIX)
    VkDevice vkDevice = device->GetVkDevice();

    const VkExternalMemoryHandleTypeFlagBits handleType =
        VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;

    const VkImageCreateInfo* createInfo =
        static_cast<const VkImageCreateInfo*>(descriptor->vkImageCreateInfo);
    DAWN_INVALID_IF(
        createInfo->sType != VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
        "descriptor->vkImageCreateInfo.sType was not VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO.");

    // Validate the createInfo chain.
    const VkExternalMemoryImageCreateInfo* externalMemoryImageCreateInfo = nullptr;
    const VkImageFormatListCreateInfo* imageFormatListInfo = nullptr;
    {
        const VkBaseInStructure* current = static_cast<const VkBaseInStructure*>(createInfo->pNext);
        while (current != nullptr) {
            switch (current->sType) {
                case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO:
                    // TODO(crbug.com/dawn/1745): Use this to inform supported types of WebGPU
                    // format reinterpretation (srgb).
                    imageFormatListInfo =
                        reinterpret_cast<const VkImageFormatListCreateInfo*>(current);
                    break;
                case VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO:
                    externalMemoryImageCreateInfo =
                        reinterpret_cast<const VkExternalMemoryImageCreateInfo*>(current);
                    DAWN_INVALID_IF((externalMemoryImageCreateInfo->handleTypes & handleType) == 0,
                                    "VkExternalMemoryImageCreateInfo::handleTypes (chained on "
                                    "descriptor->vkImageCreateInfo) did not have "
                                    "VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT.");
                    break;
                default:
                    return DAWN_VALIDATION_ERROR(
                        "Unsupported descriptor->vkImageCreateInfo chain with sType 0x%x",
                        current->sType);
            }
            current = current->pNext;
        }
    }

    DAWN_INVALID_IF(
        externalMemoryImageCreateInfo == nullptr,
        "descriptor->vkImageCreateInfo did not have chain with VkExternalMemoryImageCreateInfo");

    DAWN_INVALID_IF(
        (createInfo->usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) == 0,
        "descriptor->vkImageCreateInfo.usage did not have VK_IMAGE_USAGE_TRANSFER_DST_BIT");

    const bool isBGRA8UnormStorage = createInfo->format == VK_FORMAT_B8G8R8A8_UNORM &&
                                     (createInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT) != 0;
    DAWN_INVALID_IF(
        isBGRA8UnormStorage && (createInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) == 0,
        "descriptor->vkImageCreateInfo.flags did not have VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT when "
        "usage has VK_IMAGE_USAGE_STORAGE_BIT and format is VK_FORMAT_B8G8R8A8_UNORM");

    // Populate the properties from the VkImageCreateInfo
    SharedTextureMemoryProperties properties{};
    properties.size = {
        createInfo->extent.width,
        createInfo->extent.height,
        std::max(createInfo->arrayLayers, createInfo->extent.depth),
    };
    DAWN_TRY_ASSIGN(properties.format, FormatFromVkFormat(device, createInfo->format));
    if (createInfo->usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
        properties.usage |= wgpu::TextureUsage::CopySrc;
    }
    if (createInfo->usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
        properties.usage |= wgpu::TextureUsage::CopyDst;
    }
    if (createInfo->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
        properties.usage |= wgpu::TextureUsage::TextureBinding;
    }
    if (createInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
        properties.usage |= wgpu::TextureUsage::StorageBinding;
    }
    if (createInfo->usage &
        (VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) {
        properties.usage |= wgpu::TextureUsage::RenderAttachment;
    }

    const Format* internalFormat;
    DAWN_TRY_ASSIGN(internalFormat, device->GetInternalFormat(properties.format));

    const auto& compatibleViewFormats = device->GetCompatibleViewFormats(*internalFormat);

    // Create the SharedTextureMemory object.
    Ref<SharedTextureMemory> sharedTextureMemory =
        SharedTextureMemory::Create(device, label, properties, VK_QUEUE_FAMILY_EXTERNAL_KHR);

    // Reflect properties to reify them.
    sharedTextureMemory->APIGetProperties(&properties);

    constexpr wgpu::TextureUsage kUsageRequiringView = wgpu::TextureUsage::RenderAttachment |
                                                       wgpu::TextureUsage::TextureBinding |
                                                       wgpu::TextureUsage::StorageBinding;
    const bool mayNeedViewReinterpretation =
        (properties.usage & kUsageRequiringView) != 0 && !compatibleViewFormats.empty();

    DAWN_INVALID_IF(
        mayNeedViewReinterpretation && !(createInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT),
        "VkImageCreateInfo::flags did not have VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT "
        "which is required for view format reinterpretation.");

    if (imageFormatListInfo && mayNeedViewReinterpretation) {
        auto viewFormatsBegin = imageFormatListInfo->pViewFormats;
        auto viewFormatsEnd =
            imageFormatListInfo->pViewFormats + imageFormatListInfo->viewFormatCount;
        VkFormat baseVkFormat = VulkanImageFormat(device, properties.format);

        DAWN_INVALID_IF(
            std::find(viewFormatsBegin, viewFormatsEnd, baseVkFormat) == viewFormatsEnd,
            "VkImageFormatCreateInfo did not contain VkFormat 0x%x which may be required to "
            "create a texture view with %s.",
            baseVkFormat, properties.format);

        for (const auto* f : compatibleViewFormats) {
            VkFormat vkFormat = VulkanImageFormat(device, f->format);
            DAWN_INVALID_IF(std::find(viewFormatsBegin, viewFormatsEnd, vkFormat) == viewFormatsEnd,
                            "VkImageFormatCreateInfo did not contain VkFormat 0x%x which may be "
                            "required to create a texture view with %s.",
                            vkFormat, f->format);
        }
    }

    // Validate that an OpaqueFD import with this createInfo is valid.
    {
        VkPhysicalDeviceImageFormatInfo2 imageFormatInfo;
        imageFormatInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR;
        imageFormatInfo.pNext = nullptr;
        imageFormatInfo.format = createInfo->format;
        imageFormatInfo.type = createInfo->imageType;
        imageFormatInfo.tiling = createInfo->tiling;
        imageFormatInfo.usage = createInfo->usage;
        imageFormatInfo.flags = createInfo->flags;

        if (imageFormatListInfo) {
            VkImageFormatListCreateInfo imageFormatListInfoCopy;
            imageFormatListInfoCopy = *imageFormatListInfo;
            DAWN_TRY_CONTEXT(CheckExternalImageFormatSupport(device, properties, &imageFormatInfo,
                                                             handleType, &imageFormatListInfoCopy),
                             "checking import support for opaque fd import");
        } else {
            DAWN_TRY_CONTEXT(
                CheckExternalImageFormatSupport(device, properties, &imageFormatInfo, handleType),
                "checking import support for opaque fd import");
        }
    }

    // Create the VkImage
    {
        VkImage vkImage;
        DAWN_TRY(CheckVkSuccess(device->fn.CreateImage(vkDevice, createInfo, nullptr, &*vkImage),
                                "vkCreateImage"));
        sharedTextureMemory->mVkImage =
            AcquireRef(new RefCountedVkHandle<VkImage>(device, vkImage));
    }

    // Import the memoryFD as VkDeviceMemory and bind to the VkImage.
    {
        VkMemoryRequirements requirements;
        device->fn.GetImageMemoryRequirements(device->GetVkDevice(),
                                              sharedTextureMemory->mVkImage->Get(), &requirements);
        DAWN_INVALID_IF(requirements.size > descriptor->allocationSize,
                        "Required texture memory size (%u) is larger than the memory fd "
                        "allocation size (%u).",
                        requirements.size, descriptor->allocationSize);

        SystemHandle memoryFD;
        DAWN_TRY_ASSIGN(memoryFD, SystemHandle::Duplicate(descriptor->memoryFD));

        VkMemoryDedicatedAllocateInfo dedicatedAllocateInfo{};
        dedicatedAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
        dedicatedAllocateInfo.image = sharedTextureMemory->mVkImage->Get();

        VkImportMemoryFdInfoKHR importMemoryFdInfo{};
        importMemoryFdInfo.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR;
        importMemoryFdInfo.handleType = handleType;
        importMemoryFdInfo.fd = memoryFD.Get();

        VkMemoryAllocateInfo memoryAllocateInfo = {};
        memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
        memoryAllocateInfo.allocationSize = descriptor->allocationSize;
        memoryAllocateInfo.memoryTypeIndex = descriptor->memoryTypeIndex;

        // Import as VkDeviceMemory
        VkDeviceMemory vkDeviceMemory;
        if (descriptor->dedicatedAllocation) {
            DAWN_TRY_ASSIGN(vkDeviceMemory,
                            AllocateDeviceMemory(device, &memoryAllocateInfo, &importMemoryFdInfo,
                                                 &dedicatedAllocateInfo));
        } else {
            DAWN_TRY_ASSIGN(vkDeviceMemory,
                            AllocateDeviceMemory(device, &memoryAllocateInfo, &importMemoryFdInfo));
        }

        memoryFD.Detach();  // Ownership transfered to the VkDeviceMemory.
        sharedTextureMemory->mVkDeviceMemory =
            AcquireRef(new RefCountedVkHandle<VkDeviceMemory>(device, vkDeviceMemory));

        // Bind the VkImage to the memory.
        DAWN_TRY(CheckVkSuccess(
            device->fn.BindImageMemory(vkDevice, sharedTextureMemory->mVkImage->Get(),
                                       sharedTextureMemory->mVkDeviceMemory->Get(), 0),
            "vkBindImageMemory"));
    }
    return sharedTextureMemory;
#else
    DAWN_UNREACHABLE();
#endif  // DAWN_PLATFORM_IS(POSIX)
}

// static
Ref<SharedTextureMemory> SharedTextureMemory::Create(
    Device* device,
    const char* label,
    const SharedTextureMemoryProperties& properties,
    uint32_t queueFamilyIndex) {
    Ref<SharedTextureMemory> sharedTextureMemory =
        AcquireRef(new SharedTextureMemory(device, label, properties, queueFamilyIndex));
    sharedTextureMemory->Initialize();
    return sharedTextureMemory;
}

SharedTextureMemory::SharedTextureMemory(Device* device,
                                         const char* label,
                                         const SharedTextureMemoryProperties& properties,
                                         uint32_t queueFamilyIndex)
    : SharedTextureMemoryBase(device, label, properties), mQueueFamilyIndex(queueFamilyIndex) {}

RefCountedVkHandle<VkDeviceMemory>* SharedTextureMemory::GetVkDeviceMemory() const {
    return mVkDeviceMemory.Get();
}

RefCountedVkHandle<VkImage>* SharedTextureMemory::GetVkImage() const {
    return mVkImage.Get();
}

uint32_t SharedTextureMemory::GetQueueFamilyIndex() const {
    return mQueueFamilyIndex;
}

void SharedTextureMemory::DestroyImpl() {
    mVkImage = nullptr;
    mVkDeviceMemory = nullptr;
}

ResultOrError<Ref<TextureBase>> SharedTextureMemory::CreateTextureImpl(
    const UnpackedPtr<TextureDescriptor>& descriptor) {
    return Texture::CreateFromSharedTextureMemory(this, descriptor);
}

MaybeError SharedTextureMemory::BeginAccessImpl(
    TextureBase* texture,
    const UnpackedPtr<BeginAccessDescriptor>& descriptor) {
    // TODO(dawn/2276): support concurrent read access.
    DAWN_INVALID_IF(descriptor->concurrentRead, "Vulkan backend doesn't support concurrent read.");
    DAWN_INVALID_IF(
        texture->GetFormat().format == wgpu::TextureFormat::External && !descriptor->initialized,
        "BeginAccess with Texture format (%s) must be initialized", texture->GetFormat().format);

    wgpu::SType type;
    DAWN_TRY_ASSIGN(
        type, (descriptor.ValidateBranches<Branch<SharedTextureMemoryVkImageLayoutBeginState>>()));
    DAWN_ASSERT(type == wgpu::SType::SharedTextureMemoryVkImageLayoutBeginState);

    auto vkLayoutBeginState = descriptor.Get<SharedTextureMemoryVkImageLayoutBeginState>();
    DAWN_ASSERT(vkLayoutBeginState != nullptr);

    for (size_t i = 0; i < descriptor->fenceCount; ++i) {
        // All fences are backed by binary semaphores.
        DAWN_INVALID_IF(descriptor->signaledValues[i] != 1, "%s signaled value (%u) was not 1.",
                        descriptor->fences[i], descriptor->signaledValues[i]);
    }
    ToBackend(texture)->SetPendingAcquire(
        static_cast<VkImageLayout>(vkLayoutBeginState->oldLayout),
        static_cast<VkImageLayout>(vkLayoutBeginState->newLayout));
    return {};
}

#if DAWN_PLATFORM_IS(FUCHSIA) || DAWN_PLATFORM_IS(LINUX)
ResultOrError<FenceAndSignalValue> SharedTextureMemory::EndAccessImpl(
    TextureBase* texture,
    ExecutionSerial lastUsageSerial,
    UnpackedPtr<EndAccessState>& state) {
    wgpu::SType type;
    DAWN_TRY_ASSIGN(type,
                    (state.ValidateBranches<Branch<SharedTextureMemoryVkImageLayoutEndState>>()));
    DAWN_ASSERT(type == wgpu::SType::SharedTextureMemoryVkImageLayoutEndState);

    auto vkLayoutEndState = state.Get<SharedTextureMemoryVkImageLayoutEndState>();
    DAWN_ASSERT(vkLayoutEndState != nullptr);

#if DAWN_PLATFORM_IS(FUCHSIA)
    DAWN_INVALID_IF(!GetDevice()->HasFeature(Feature::SharedFenceVkSemaphoreZirconHandle),
                    "Required feature (%s) for %s is missing.",
                    wgpu::FeatureName::SharedFenceVkSemaphoreZirconHandle,
                    wgpu::SharedFenceType::VkSemaphoreZirconHandle);
#elif DAWN_PLATFORM_IS(LINUX)
    DAWN_INVALID_IF(!GetDevice()->HasFeature(Feature::SharedFenceVkSemaphoreSyncFD) &&
                        !GetDevice()->HasFeature(Feature::SharedFenceVkSemaphoreOpaqueFD),
                    "Required feature (%s or %s) for %s or %s is missing.",
                    wgpu::FeatureName::SharedFenceVkSemaphoreOpaqueFD,
                    wgpu::FeatureName::SharedFenceVkSemaphoreSyncFD,
                    wgpu::SharedFenceType::VkSemaphoreOpaqueFD,
                    wgpu::SharedFenceType::VkSemaphoreSyncFD);
#endif

    SystemHandle handle;
    {
        ExternalSemaphoreHandle semaphoreHandle;
        VkImageLayout releasedOldLayout;
        VkImageLayout releasedNewLayout;
        DAWN_TRY(ToBackend(texture)->EndAccess(&semaphoreHandle, &releasedOldLayout,
                                               &releasedNewLayout));
        // Handle is acquired from the texture so we need to make sure to close it.
        // TODO(dawn:1745): Consider using one event per submit that is tracked by the
        // CommandRecordingContext so that we don't need to create one handle per texture,
        // and so we don't need to acquire it here to close it.
        handle = SystemHandle::Acquire(semaphoreHandle);
        vkLayoutEndState->oldLayout = releasedOldLayout;
        vkLayoutEndState->newLayout = releasedNewLayout;
    }

    Ref<SharedFence> fence;

#if DAWN_PLATFORM_IS(FUCHSIA)
    SharedFenceVkSemaphoreZirconHandleDescriptor desc;
    desc.handle = handle.Get();

    DAWN_TRY_ASSIGN(fence,
                    SharedFence::Create(ToBackend(GetDevice()), "Internal VkSemaphore", &desc));
#elif DAWN_PLATFORM_IS(LINUX)
    if (GetDevice()->HasFeature(Feature::SharedFenceVkSemaphoreSyncFD)) {
        SharedFenceVkSemaphoreSyncFDDescriptor desc;
        desc.handle = handle.Get();

        DAWN_TRY_ASSIGN(fence,
                        SharedFence::Create(ToBackend(GetDevice()), "Internal VkSemaphore", &desc));
    } else {
        SharedFenceVkSemaphoreOpaqueFDDescriptor desc;
        desc.handle = handle.Get();

        DAWN_TRY_ASSIGN(fence,
                        SharedFence::Create(ToBackend(GetDevice()), "Internal VkSemaphore", &desc));
    }
#endif
    // All semaphores are binary semaphores.
    return FenceAndSignalValue{std::move(fence), 1};
}

#else  // DAWN_PLATFORM_IS(FUCHSIA) || DAWN_PLATFORM_IS(LINUX)

ResultOrError<FenceAndSignalValue> SharedTextureMemory::EndAccessImpl(
    TextureBase* texture,
    ExecutionSerial lastUsageSerial,
    UnpackedPtr<EndAccessState>& state) {
    return DAWN_VALIDATION_ERROR("No shared fence features supported.");
}

#endif  // DAWN_PLATFORM_IS(FUCHSIA) || DAWN_PLATFORM_IS(LINUX)

MaybeError SharedTextureMemory::GetChainedProperties(
    UnpackedPtr<SharedTextureMemoryProperties>& properties) const {
    auto ahbProperties = properties.Get<SharedTextureMemoryAHardwareBufferProperties>();

    if (!ahbProperties) {
        return {};
    }

    if (ahbProperties->yCbCrInfo.nextInChain) {
        return DAWN_VALIDATION_ERROR(
            "yCBCrInfo field of SharedTextureMemoryAHardwareBufferProperties has a chained "
            "struct.");
    }

    ahbProperties->yCbCrInfo = mYCbCrAHBInfo;

    return {};
}

}  // namespace dawn::native::vulkan
