// Copyright 2018 The Android Open Source Project
//
// 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 expresso or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "VkCommonOperations.h"

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES3/gl3.h>
#include <stdio.h>
#include <string.h>
#include <vulkan/vk_enum_string_helper.h>

#include <iomanip>
#include <ostream>
#include <sstream>
#include <unordered_set>

#include "BlobManager.h"
#include "VkDecoderGlobalState.h"
#include "VkEmulatedPhysicalDeviceMemory.h"
#include "VkFormatUtils.h"
#include "VulkanDispatch.h"
#include "aemu/base/Optional.h"
#include "aemu/base/Tracing.h"
#include "aemu/base/containers/Lookup.h"
#include "aemu/base/containers/StaticMap.h"
#include "aemu/base/synchronization/Lock.h"
#include "aemu/base/system/System.h"
#include "common/goldfish_vk_dispatch.h"
#include "host-common/GfxstreamFatalError.h"
#include "host-common/emugl_vm_operations.h"
#include "host-common/vm_operations.h"

#ifdef _WIN32
#include <windows.h>
#else
#include <fcntl.h>
#include <unistd.h>
#endif

#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
#include <vulkan/vulkan_beta.h>  // for MoltenVK portability extensions
#endif

namespace gfxstream {
namespace vk {
namespace {

using android::base::AutoLock;
using android::base::kNullopt;
using android::base::ManagedDescriptor;
using android::base::Optional;
using android::base::StaticLock;
using android::base::StaticMap;
using emugl::ABORT_REASON_OTHER;
using emugl::FatalError;

#ifndef VERBOSE
#define VERBOSE(fmt, ...)        \
    if (android::base::isVerboseLogging()) \
        fprintf(stderr, "%s:%d " fmt "\n", __func__, __LINE__, ##__VA_ARGS__);
#endif

constexpr size_t kPageBits = 12;
constexpr size_t kPageSize = 1u << kPageBits;

static int kMaxDebugMarkerAnnotations = 10;

static std::optional<std::string> sMemoryLogPath = std::nullopt;

const char* string_AstcEmulationMode(AstcEmulationMode mode) {
    switch (mode) {
        case AstcEmulationMode::Disabled:
            return "Disabled";
        case AstcEmulationMode::Cpu:
            return "Cpu";
        case AstcEmulationMode::Gpu:
            return "Gpu";
    }
    return "Unknown";
}

}  // namespace

static StaticMap<VkDevice, uint32_t> sKnownStagingTypeIndices;

static android::base::StaticLock sVkEmulationLock;

static bool updateColorBufferFromBytesLocked(uint32_t colorBufferHandle, uint32_t x, uint32_t y,
                                             uint32_t w, uint32_t h, const void* pixels,
                                             size_t inputPixelsSize);

#if !defined(__QNX__)
VK_EXT_MEMORY_HANDLE dupExternalMemory(VK_EXT_MEMORY_HANDLE h) {
#ifdef _WIN32
    auto myProcessHandle = GetCurrentProcess();
    VK_EXT_MEMORY_HANDLE res;
    DuplicateHandle(myProcessHandle, h,     // source process and handle
                    myProcessHandle, &res,  // target process and pointer to handle
                    0 /* desired access (ignored) */, true /* inherit */,
                    DUPLICATE_SAME_ACCESS /* same access option */);
    return res;
#else
    return dup(h);
#endif
}
#endif

bool getStagingMemoryTypeIndex(VulkanDispatch* vk, VkDevice device,
                               const VkPhysicalDeviceMemoryProperties* memProps,
                               uint32_t* typeIndex) {
    auto res = sKnownStagingTypeIndices.get(device);

    if (res) {
        *typeIndex = *res;
        return true;
    }

    VkBufferCreateInfo testCreateInfo = {
        VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
        0,
        0,
        4096,
        // To be a staging buffer, it must support being
        // both a transfer src and dst.
        VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
        // TODO: See if buffers over shared queues need to be
        // considered separately
        VK_SHARING_MODE_EXCLUSIVE,
        0,
        nullptr,
    };

    VkBuffer testBuffer;
    VkResult testBufferCreateRes =
        vk->vkCreateBuffer(device, &testCreateInfo, nullptr, &testBuffer);

    if (testBufferCreateRes != VK_SUCCESS) {
        ERR("Could not create test buffer "
            "for staging buffer query. VkResult: %s",
            string_VkResult(testBufferCreateRes));
        return false;
    }

    VkMemoryRequirements memReqs;
    vk->vkGetBufferMemoryRequirements(device, testBuffer, &memReqs);

    // To be a staging buffer, we need to allow CPU read/write access.
    // Thus, we need the memory type index both to be host visible
    // and to be supported in the memory requirements of the buffer.
    bool foundSuitableStagingMemoryType = false;
    uint32_t stagingMemoryTypeIndex = 0;

    for (uint32_t i = 0; i < memProps->memoryTypeCount; ++i) {
        const auto& typeInfo = memProps->memoryTypes[i];
        bool hostVisible = typeInfo.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
        bool hostCached = typeInfo.propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
        bool allowedInBuffer = (1 << i) & memReqs.memoryTypeBits;
        if (hostVisible && hostCached && allowedInBuffer) {
            foundSuitableStagingMemoryType = true;
            stagingMemoryTypeIndex = i;
            break;
        }
    }

    // If the previous loop failed, try to accept a type that is not HOST_CACHED.
    if (!foundSuitableStagingMemoryType) {
        for (uint32_t i = 0; i < memProps->memoryTypeCount; ++i) {
            const auto& typeInfo = memProps->memoryTypes[i];
            bool hostVisible = typeInfo.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
            bool allowedInBuffer = (1 << i) & memReqs.memoryTypeBits;
            if (hostVisible && allowedInBuffer) {
                ERR("Warning: using non-cached HOST_VISIBLE type for staging memory");
                foundSuitableStagingMemoryType = true;
                stagingMemoryTypeIndex = i;
                break;
            }
        }
    }

    vk->vkDestroyBuffer(device, testBuffer, nullptr);

    if (!foundSuitableStagingMemoryType) {
        std::stringstream ss;
        ss << "Could not find suitable memory type index "
           << "for staging buffer. Memory type bits: " << std::hex << memReqs.memoryTypeBits << "\n"
           << "Available host visible memory type indices:"
           << "\n";
        for (uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; ++i) {
            if (memProps->memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
                ss << "Host visible memory type index: %u" << i << "\n";
            }
            if (memProps->memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) {
                ss << "Host cached memory type index: %u" << i << "\n";
            }
        }

        ERR("Error: %s", ss.str().c_str());

        return false;
    }

    sKnownStagingTypeIndices.set(device, stagingMemoryTypeIndex);
    *typeIndex = stagingMemoryTypeIndex;

    return true;
}

static VkEmulation* sVkEmulation = nullptr;

static bool extensionsSupported(const std::vector<VkExtensionProperties>& currentProps,
                                const std::vector<const char*>& wantedExtNames) {
    std::vector<bool> foundExts(wantedExtNames.size(), false);

    for (uint32_t i = 0; i < currentProps.size(); ++i) {
        for (size_t j = 0; j < wantedExtNames.size(); ++j) {
            if (!strcmp(wantedExtNames[j], currentProps[i].extensionName)) {
                foundExts[j] = true;
            }
        }
    }

    for (size_t i = 0; i < wantedExtNames.size(); ++i) {
        bool found = foundExts[i];
        if (!found) {
            VERBOSE("%s not found, bailing.", wantedExtNames[i]);
            return false;
        }
    }

    return true;
}

// For a given ImageSupportInfo, populates usageWithExternalHandles and
// requiresDedicatedAllocation. memoryTypeBits are populated later once the
// device is created, because that needs a test image to be created.
// If we don't support external memory, it's assumed dedicated allocations are
// not needed.
// Precondition: sVkEmulation instance has been created and ext memory caps known.
// Returns false if the query failed.
static bool getImageFormatExternalMemorySupportInfo(VulkanDispatch* vk, VkPhysicalDevice physdev,
                                                    VkEmulation::ImageSupportInfo* info) {
    // Currently there is nothing special we need to do about
    // VkFormatProperties2, so just use the normal version
    // and put it in the format2 struct.
    VkFormatProperties outFormatProps;
    vk->vkGetPhysicalDeviceFormatProperties(physdev, info->format, &outFormatProps);

    info->formatProps2 = {
        VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
        0,
        outFormatProps,
    };

    if (!sVkEmulation->instanceSupportsExternalMemoryCapabilities) {
        info->supportsExternalMemory = false;
        info->requiresDedicatedAllocation = false;

        VkImageFormatProperties outImageFormatProps;
        VkResult res = vk->vkGetPhysicalDeviceImageFormatProperties(
            physdev, info->format, info->type, info->tiling, info->usageFlags, info->createFlags,
            &outImageFormatProps);

        if (res != VK_SUCCESS) {
            if (res == VK_ERROR_FORMAT_NOT_SUPPORTED) {
                info->supported = false;
                return true;
            } else {
                ERR("vkGetPhysicalDeviceImageFormatProperties query "
                    "failed with %s"
                    "for format 0x%x type 0x%x usage 0x%x flags 0x%x",
                    string_VkResult(res), info->format, info->type, info->usageFlags,
                    info->createFlags);
                return false;
            }
        }

        info->supported = true;

        info->imageFormatProps2 = {
            VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
            0,
            outImageFormatProps,
        };

        VERBOSE("Supported (not externally): %s %s %s %s", string_VkFormat(info->format),
                string_VkImageType(info->type), string_VkImageTiling(info->tiling),
                string_VkImageUsageFlagBits((VkImageUsageFlagBits)info->usageFlags));

        return true;
    }

    VkPhysicalDeviceExternalImageFormatInfo extInfo = {
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
        0,
        VK_EXT_MEMORY_HANDLE_TYPE_BIT,
    };
#if defined(__APPLE__)
    if (sVkEmulation->instanceSupportsMoltenVK) {
        // Using a different handle type when in MoltenVK mode
        extInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR;
    }
#endif

    VkPhysicalDeviceImageFormatInfo2 formatInfo2 = {
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
        &extInfo,
        info->format,
        info->type,
        info->tiling,
        info->usageFlags,
        info->createFlags,
    };

    VkExternalImageFormatProperties outExternalProps = {
        VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
        0,
        {
            (VkExternalMemoryFeatureFlags)0,
            (VkExternalMemoryHandleTypeFlags)0,
            (VkExternalMemoryHandleTypeFlags)0,
        },
    };

    VkImageFormatProperties2 outProps2 = {VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
                                          &outExternalProps,
                                          {
                                              {0, 0, 0},
                                              0,
                                              0,
                                              1,
                                              0,
                                          }};

    VkResult res = sVkEmulation->getImageFormatProperties2Func(physdev, &formatInfo2, &outProps2);

    if (res != VK_SUCCESS) {
        if (res == VK_ERROR_FORMAT_NOT_SUPPORTED) {
            VERBOSE("Not Supported: %s %s %s %s", string_VkFormat(info->format),
                    string_VkImageType(info->type), string_VkImageTiling(info->tiling),
                    string_VkImageUsageFlagBits((VkImageUsageFlagBits)info->usageFlags));

            info->supported = false;
            return true;
        } else {
            ERR("vkGetPhysicalDeviceImageFormatProperties2KHR query "
                "failed with %s "
                "for format 0x%x type 0x%x usage 0x%x flags 0x%x",
                string_VkResult(res), info->format, info->type, info->usageFlags,
                info->createFlags);
            return false;
        }
    }

    info->supported = true;

    VkExternalMemoryFeatureFlags featureFlags =
        outExternalProps.externalMemoryProperties.externalMemoryFeatures;

    VkExternalMemoryHandleTypeFlags exportImportedFlags =
        outExternalProps.externalMemoryProperties.exportFromImportedHandleTypes;

    // Don't really care about export form imported handle types yet
    (void)exportImportedFlags;

    VkExternalMemoryHandleTypeFlags compatibleHandleTypes =
        outExternalProps.externalMemoryProperties.compatibleHandleTypes;

    VkExternalMemoryHandleTypeFlagBits handleTypeNeeded = VK_EXT_MEMORY_HANDLE_TYPE_BIT;
#if defined(__APPLE__)
    if (sVkEmulation->instanceSupportsMoltenVK) {
        // Using a different handle type when in MoltenVK mode
        handleTypeNeeded = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR;
    }
#endif

    info->supportsExternalMemory = (handleTypeNeeded & compatibleHandleTypes) &&
                                   (VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT & featureFlags) &&
                                   (VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT & featureFlags);

    info->requiresDedicatedAllocation =
        (VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT & featureFlags);

    info->imageFormatProps2 = outProps2;
    info->extFormatProps = outExternalProps;
    info->imageFormatProps2.pNext = &info->extFormatProps;

    VERBOSE("Supported: %s %s %s %s, supportsExternalMemory? %d, requiresDedicated? %d",
            string_VkFormat(info->format), string_VkImageType(info->type),
            string_VkImageTiling(info->tiling),
            string_VkImageUsageFlagBits((VkImageUsageFlagBits)info->usageFlags),
            info->supportsExternalMemory, info->requiresDedicatedAllocation);

    return true;
}

// Vulkan driverVersions are bit-shift packs of their dotted versions
// For example, nvidia driverversion 1934229504 unpacks to 461.40
// note: while this is equivalent to VkPhysicalDeviceDriverProperties.driverInfo on NVIDIA,
// on intel that value is simply "Intel driver".
static std::string decodeDriverVersion(uint32_t vendorId, uint32_t driverVersion) {
    std::stringstream result;
    switch (vendorId) {
        case 0x10DE: {
            // Nvidia. E.g. driverVersion = 1934229504(0x734a0000) maps to 461.40
            uint32_t major = driverVersion >> 22;
            uint32_t minor = (driverVersion >> 14) & 0xff;
            uint32_t build = (driverVersion >> 6) & 0xff;
            uint32_t revision = driverVersion & 0x3f;
            result << major << '.' << minor << '.' << build << '.' << revision;
            break;
        }
        case 0x8086: {
            // Intel. E.g. driverVersion = 1647866(0x1924fa) maps to 100.9466 (27.20.100.9466)
            uint32_t high = driverVersion >> 14;
            uint32_t low = driverVersion & 0x3fff;
            result << high << '.' << low;
            break;
        }
        case 0x002:  // amd
        default: {
            uint32_t major = VK_VERSION_MAJOR(driverVersion);
            uint32_t minor = VK_VERSION_MINOR(driverVersion);
            uint32_t patch = VK_VERSION_PATCH(driverVersion);
            result << major << "." << minor << "." << patch;
            break;
        }
    }
    return result.str();
}

static std::vector<VkEmulation::ImageSupportInfo> getBasicImageSupportList() {
    struct ImageFeatureCombo {
        VkFormat format;
        VkImageCreateFlags createFlags = 0;
    };
    // Set the mutable flag for RGB UNORM formats so that the created image can also be sampled in
    // the sRGB Colorspace. See
    // https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/3827672/comments/77db9cb3_60663a6a
    // for details.
    std::vector<ImageFeatureCombo> combos = {
        // Cover all the gralloc formats
        {VK_FORMAT_R8G8B8A8_UNORM,
         VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT},
        {VK_FORMAT_R8G8B8_UNORM,
         VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT},

        {VK_FORMAT_R5G6B5_UNORM_PACK16},

        {VK_FORMAT_R16G16B16A16_SFLOAT},
        {VK_FORMAT_R16G16B16_SFLOAT},

        {VK_FORMAT_B8G8R8A8_UNORM,
         VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT},

        {VK_FORMAT_R8_UNORM,
         VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT},
        {VK_FORMAT_R16_UNORM,
         VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT},

        {VK_FORMAT_A2R10G10B10_UINT_PACK32},
        {VK_FORMAT_A2R10G10B10_UNORM_PACK32},
        {VK_FORMAT_A2B10G10R10_UNORM_PACK32},

        // Compressed texture formats
        {VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK},
        {VK_FORMAT_ASTC_4x4_UNORM_BLOCK},

        // TODO: YUV formats used in Android
        // Fails on Mac
        {VK_FORMAT_G8_B8R8_2PLANE_420_UNORM},
        {VK_FORMAT_G8_B8R8_2PLANE_422_UNORM},
        {VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM},
        {VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM},
        {VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16},

    };

    std::vector<VkImageType> types = {
        VK_IMAGE_TYPE_2D,
    };

    std::vector<VkImageTiling> tilings = {
        VK_IMAGE_TILING_LINEAR,
        VK_IMAGE_TILING_OPTIMAL,
    };

    std::vector<VkImageUsageFlags> usageFlags = {
        VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
        VK_IMAGE_USAGE_SAMPLED_BIT,          VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
        VK_IMAGE_USAGE_TRANSFER_DST_BIT,
    };

    std::vector<VkEmulation::ImageSupportInfo> res;

    // Currently: 17 format + create flags combo, 2 tilings, 5 usage flags -> 170 cases to check.
    for (auto combo : combos) {
        for (auto t : types) {
            for (auto ti : tilings) {
                for (auto u : usageFlags) {
                    VkEmulation::ImageSupportInfo info;
                    info.format = combo.format;
                    info.type = t;
                    info.tiling = ti;
                    info.usageFlags = u;
                    info.createFlags = combo.createFlags;
                    res.push_back(info);
                }
            }
        }
    }

    return res;
}

VkEmulation* createGlobalVkEmulation(VulkanDispatch* vk, gfxstream::host::FeatureSet features) {
// Downstream branches can provide abort logic or otherwise use result without a new macro
#define VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(res, ...) \
    do {                                               \
        (void)res; /* no-op of unused param*/          \
        ERR(__VA_ARGS__);                              \
        return nullptr;                                \
    } while (0)

    AutoLock lock(sVkEmulationLock);

    if (sVkEmulation) return sVkEmulation;

    if (!vkDispatchValid(vk)) {
        VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(ABORT_REASON_OTHER, "Dispatch is invalid.");
    }

    sVkEmulation = new VkEmulation;

    sVkEmulation->features = features;

    sVkEmulation->gvk = vk;
    auto gvk = vk;

    std::vector<const char*> externalMemoryInstanceExtNames = {
        VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
        VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
    };

    std::vector<const char*> externalMemoryDeviceExtNames = {
        VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME,
        VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
        VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
#ifdef _WIN32
        VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME,
#elif defined(__QNX__)
        VK_QNX_EXTERNAL_MEMORY_SCREEN_BUFFER_EXTENSION_NAME,
        VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME,
#elif defined(__APPLE__)
        // VK_EXT_metal_objects will be added if host MoltenVK is enabled,
        // otherwise VK_KHR_external_memory_fd will be used
#else
        VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
#endif
    };

    std::vector<const char*> externalSemaphoreInstanceExtNames = {
        VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME,
    };

    std::vector<const char*> surfaceInstanceExtNames = {
        VK_KHR_SURFACE_EXTENSION_NAME,
    };

#if defined(__APPLE__)
    std::vector<const char*> moltenVkInstanceExtNames = {
        VK_MVK_MACOS_SURFACE_EXTENSION_NAME,
        VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
    };
    std::vector<const char*> moltenVkDeviceExtNames = {
        VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME,
        VK_EXT_METAL_OBJECTS_EXTENSION_NAME,
    };
#endif

    uint32_t instanceExtCount = 0;
    gvk->vkEnumerateInstanceExtensionProperties(nullptr, &instanceExtCount, nullptr);
    std::vector<VkExtensionProperties>& instanceExts = sVkEmulation->instanceExtensions;
    instanceExts.resize(instanceExtCount);
    gvk->vkEnumerateInstanceExtensionProperties(nullptr, &instanceExtCount, instanceExts.data());

    bool externalMemoryCapabilitiesSupported =
        extensionsSupported(instanceExts, externalMemoryInstanceExtNames);
    bool externalSemaphoreCapabilitiesSupported =
        extensionsSupported(instanceExts, externalSemaphoreInstanceExtNames);
    bool surfaceSupported = extensionsSupported(instanceExts, surfaceInstanceExtNames);
#if defined(__APPLE__)
    const std::string vulkanIcd = android::base::getEnvironmentVariable("ANDROID_EMU_VK_ICD");
    const bool moltenVKEnabled = (vulkanIcd == "moltenvk");
    bool moltenVKSupported = moltenVKEnabled &&
                             extensionsSupported(instanceExts, moltenVkInstanceExtNames);
#endif

    VkInstanceCreateInfo instCi = {
        VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 0, 0, nullptr, 0, nullptr, 0, nullptr,
    };

    std::unordered_set<const char*> selectedInstanceExtensionNames;

    const bool debugUtilsSupported =
        extensionsSupported(instanceExts, {VK_EXT_DEBUG_UTILS_EXTENSION_NAME});
    const bool debugUtilsRequested = sVkEmulation->features.VulkanDebugUtils.enabled;
    const bool debugUtilsAvailableAndRequested = debugUtilsSupported && debugUtilsRequested;
    if (debugUtilsAvailableAndRequested) {
        selectedInstanceExtensionNames.emplace(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
    } else if (debugUtilsRequested) {
        WARN("VulkanDebugUtils requested, but '%' extension is not supported.",
             VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
    }

    if (externalMemoryCapabilitiesSupported) {
        for (auto extension : externalMemoryInstanceExtNames) {
            selectedInstanceExtensionNames.emplace(extension);
        }
    }

    if (surfaceSupported) {
        for (auto extension : surfaceInstanceExtNames) {
            selectedInstanceExtensionNames.emplace(extension);
        }
    }

    if (sVkEmulation->features.VulkanNativeSwapchain.enabled) {
        for (auto extension : SwapChainStateVk::getRequiredInstanceExtensions()) {
            selectedInstanceExtensionNames.emplace(extension);
        }
    }

#if defined(__APPLE__)
    if (moltenVKSupported) {
        INFO("MoltenVK is supported, enabling Vulkan portability.");
        instCi.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
        for (auto extension : moltenVkInstanceExtNames) {
            selectedInstanceExtensionNames.emplace(extension);
        }
    }
#endif

    std::vector<const char*> selectedInstanceExtensionNames_(selectedInstanceExtensionNames.begin(),
                                                             selectedInstanceExtensionNames.end());
    instCi.enabledExtensionCount = static_cast<uint32_t>(selectedInstanceExtensionNames_.size());
    instCi.ppEnabledExtensionNames = selectedInstanceExtensionNames_.data();

    VkApplicationInfo appInfo = {
        VK_STRUCTURE_TYPE_APPLICATION_INFO, 0, "AEMU", 1, "AEMU", 1, VK_MAKE_VERSION(1, 0, 0),
    };

    instCi.pApplicationInfo = &appInfo;

    // Can we know instance version early?
    if (gvk->vkEnumerateInstanceVersion) {
        VERBOSE("global loader has vkEnumerateInstanceVersion.");
        uint32_t instanceVersion;
        VkResult res = gvk->vkEnumerateInstanceVersion(&instanceVersion);
        if (VK_SUCCESS == res) {
            if (instanceVersion >= VK_MAKE_VERSION(1, 1, 0)) {
                VERBOSE("global loader has vkEnumerateInstanceVersion returning >= 1.1.");
                appInfo.apiVersion = VK_MAKE_VERSION(1, 1, 0);
            }
        }
    }

    VERBOSE("Creating instance, asking for version %d.%d.%d ...",
            VK_VERSION_MAJOR(appInfo.apiVersion), VK_VERSION_MINOR(appInfo.apiVersion),
            VK_VERSION_PATCH(appInfo.apiVersion));

    VkResult res = gvk->vkCreateInstance(&instCi, nullptr, &sVkEmulation->instance);

    if (res != VK_SUCCESS) {
        VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(res, "Failed to create Vulkan instance. Error %s.",
                                             string_VkResult(res));
    }

    // Create instance level dispatch.
    sVkEmulation->ivk = new VulkanDispatch;
    init_vulkan_dispatch_from_instance(vk, sVkEmulation->instance, sVkEmulation->ivk);

    auto ivk = sVkEmulation->ivk;

    if (!vulkan_dispatch_check_instance_VK_VERSION_1_0(ivk)) {
        ERR("Warning: Vulkan 1.0 APIs missing from instance");
    }

    if (ivk->vkEnumerateInstanceVersion) {
        uint32_t instanceVersion;
        VkResult enumInstanceRes = ivk->vkEnumerateInstanceVersion(&instanceVersion);
        if ((VK_SUCCESS == enumInstanceRes) && instanceVersion >= VK_MAKE_VERSION(1, 1, 0)) {
            if (!vulkan_dispatch_check_instance_VK_VERSION_1_1(ivk)) {
                ERR("Warning: Vulkan 1.1 APIs missing from instance (1st try)");
            }
        }

        if (appInfo.apiVersion < VK_MAKE_VERSION(1, 1, 0) &&
            instanceVersion >= VK_MAKE_VERSION(1, 1, 0)) {
            VERBOSE("Found out that we can create a higher version instance.");
            appInfo.apiVersion = VK_MAKE_VERSION(1, 1, 0);

            gvk->vkDestroyInstance(sVkEmulation->instance, nullptr);

            VkResult res = gvk->vkCreateInstance(&instCi, nullptr, &sVkEmulation->instance);

            if (res != VK_SUCCESS) {
                VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(
                    res, "Failed to create Vulkan 1.1 instance. Error %s.", string_VkResult(res));
            }

            init_vulkan_dispatch_from_instance(vk, sVkEmulation->instance, sVkEmulation->ivk);

            VERBOSE("Created Vulkan 1.1 instance on second try.");

            if (!vulkan_dispatch_check_instance_VK_VERSION_1_1(ivk)) {
                ERR("Warning: Vulkan 1.1 APIs missing from instance (2nd try)");
            }
        }
    }

    sVkEmulation->vulkanInstanceVersion = appInfo.apiVersion;

    sVkEmulation->instanceSupportsExternalMemoryCapabilities = externalMemoryCapabilitiesSupported;
    sVkEmulation->instanceSupportsExternalSemaphoreCapabilities =
        externalSemaphoreCapabilitiesSupported;
    sVkEmulation->instanceSupportsSurface = surfaceSupported;
#if defined(__APPLE__)
    sVkEmulation->instanceSupportsMoltenVK = moltenVKSupported;
#endif

    if (sVkEmulation->instanceSupportsExternalMemoryCapabilities) {
        sVkEmulation->getImageFormatProperties2Func = vk_util::getVkInstanceProcAddrWithFallback<
            vk_util::vk_fn_info::GetPhysicalDeviceImageFormatProperties2>(
            {ivk->vkGetInstanceProcAddr, vk->vkGetInstanceProcAddr}, sVkEmulation->instance);
        sVkEmulation->getPhysicalDeviceProperties2Func = vk_util::getVkInstanceProcAddrWithFallback<
            vk_util::vk_fn_info::GetPhysicalDeviceProperties2>(
            {ivk->vkGetInstanceProcAddr, vk->vkGetInstanceProcAddr}, sVkEmulation->instance);
    }
    sVkEmulation->getPhysicalDeviceFeatures2Func =
        vk_util::getVkInstanceProcAddrWithFallback<vk_util::vk_fn_info::GetPhysicalDeviceFeatures2>(
            {ivk->vkGetInstanceProcAddr, vk->vkGetInstanceProcAddr}, sVkEmulation->instance);

#if defined(__APPLE__)
    if (sVkEmulation->instanceSupportsMoltenVK) {
        // Using metal_objects extension on MacOS when moltenVK is used.
        externalMemoryDeviceExtNames.push_back(VK_EXT_METAL_OBJECTS_EXTENSION_NAME);
    } else {
        // When MoltenVK is not used(e.g. SwiftShader), use memory fd extension for external memory.
        externalMemoryDeviceExtNames.push_back(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
    }
#endif

    uint32_t physdevCount = 0;
    ivk->vkEnumeratePhysicalDevices(sVkEmulation->instance, &physdevCount, nullptr);
    std::vector<VkPhysicalDevice> physdevs(physdevCount);
    ivk->vkEnumeratePhysicalDevices(sVkEmulation->instance, &physdevCount, physdevs.data());

    VERBOSE("Found %d Vulkan physical devices.", physdevCount);

    if (physdevCount == 0) {
        VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(ABORT_REASON_OTHER, "No physical devices available.");
    }

    std::vector<VkEmulation::DeviceSupportInfo> deviceInfos(physdevCount);

    for (int i = 0; i < physdevCount; ++i) {
        ivk->vkGetPhysicalDeviceProperties(physdevs[i], &deviceInfos[i].physdevProps);

        VERBOSE("Considering Vulkan physical device %d : %s", i,
                deviceInfos[i].physdevProps.deviceName);

        // It's easier to figure out the staging buffer along with
        // external memories if we have the memory properties on hand.
        ivk->vkGetPhysicalDeviceMemoryProperties(physdevs[i], &deviceInfos[i].memProps);

        uint32_t deviceExtensionCount = 0;
        ivk->vkEnumerateDeviceExtensionProperties(physdevs[i], nullptr, &deviceExtensionCount,
                                                  nullptr);
        std::vector<VkExtensionProperties>& deviceExts = deviceInfos[i].extensions;
        deviceExts.resize(deviceExtensionCount);
        ivk->vkEnumerateDeviceExtensionProperties(physdevs[i], nullptr, &deviceExtensionCount,
                                                  deviceExts.data());

        deviceInfos[i].supportsExternalMemoryImport = false;
        deviceInfos[i].supportsExternalMemoryExport = false;
        deviceInfos[i].glInteropSupported = 0;  // set later

#if defined(__APPLE__)
        if (moltenVKSupported && !extensionsSupported(deviceExts, moltenVkDeviceExtNames)) {
            VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(
                ABORT_REASON_OTHER,
                "MoltenVK enabled but necessary device extensions are not supported.");
        }
#endif

        if (sVkEmulation->instanceSupportsExternalMemoryCapabilities) {
            deviceInfos[i].supportsExternalMemoryExport =
                deviceInfos[i].supportsExternalMemoryImport =
                    extensionsSupported(deviceExts, externalMemoryDeviceExtNames);
#if defined(__QNX__)
            // External memory export not supported on QNX
            deviceInfos[i].supportsExternalMemoryExport = false;
#endif

            deviceInfos[i].supportsDmaBuf =
                extensionsSupported(deviceExts, {VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME});
            deviceInfos[i].supportsIdProperties =
                sVkEmulation->getPhysicalDeviceProperties2Func != nullptr;
            deviceInfos[i].supportsDriverProperties =
                extensionsSupported(deviceExts, {VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME}) ||
                (deviceInfos[i].physdevProps.apiVersion >= VK_API_VERSION_1_2);

            if (!sVkEmulation->getPhysicalDeviceProperties2Func) {
                ERR("Warning: device claims to support ID properties "
                    "but vkGetPhysicalDeviceProperties2 could not be found");
            }
        }

        if (sVkEmulation->getPhysicalDeviceProperties2Func) {
            VkPhysicalDeviceProperties2 deviceProps = {
                VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,
            };
            VkPhysicalDeviceIDProperties idProps = {
                VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR,
            };
            VkPhysicalDeviceDriverPropertiesKHR driverProps = {
                VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR,
            };

            auto devicePropsChain = vk_make_chain_iterator(&deviceProps);

            if (deviceInfos[i].supportsIdProperties) {
                vk_append_struct(&devicePropsChain, &idProps);
            }

            if (deviceInfos[i].supportsDriverProperties) {
                vk_append_struct(&devicePropsChain, &driverProps);
            }

            sVkEmulation->getPhysicalDeviceProperties2Func(physdevs[i], &deviceProps);

            deviceInfos[i].idProps = vk_make_orphan_copy(idProps);

            std::stringstream driverVendorBuilder;
            driverVendorBuilder << "Vendor " << std::hex << std::setfill('0') << std::showbase
                                << deviceInfos[i].physdevProps.vendorID;

            std::string decodedDriverVersion = decodeDriverVersion(
                deviceInfos[i].physdevProps.vendorID, deviceInfos[i].physdevProps.driverVersion);

            std::stringstream driverVersionBuilder;
            driverVersionBuilder << "Driver Version " << std::hex << std::setfill('0')
                                 << std::showbase << deviceInfos[i].physdevProps.driverVersion
                                 << " Decoded As " << decodedDriverVersion;

            std::string driverVendor = driverVendorBuilder.str();
            std::string driverVersion = driverVersionBuilder.str();
            if (deviceInfos[i].supportsDriverProperties && driverProps.driverID) {
                driverVendor = std::string{driverProps.driverName} + " (" + driverVendor + ")";
                driverVersion = std::string{driverProps.driverInfo} + " (" +
                                string_VkDriverId(driverProps.driverID) + " " + driverVersion + ")";
            }

            deviceInfos[i].driverVendor = driverVendor;
            deviceInfos[i].driverVersion = driverVersion;
        }

        deviceInfos[i].hasSamplerYcbcrConversionExtension =
            extensionsSupported(deviceExts, {VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME});
        if (sVkEmulation->getPhysicalDeviceFeatures2Func) {
            VkPhysicalDeviceFeatures2 features2 = {
                .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
            };
            auto features2Chain = vk_make_chain_iterator(&features2);
            VkPhysicalDeviceSamplerYcbcrConversionFeatures samplerYcbcrConversionFeatures = {
                .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES,
            };
            vk_append_struct(&features2Chain, &samplerYcbcrConversionFeatures);
#if defined(__QNX__)
            VkPhysicalDeviceExternalMemoryScreenBufferFeaturesQNX extMemScreenBufferFeatures = {
                .sType =
                    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_SCREEN_BUFFER_FEATURES_QNX,
            };
            vk_append_struct(&features2Chain, &extMemScreenBufferFeatures);
#endif
            sVkEmulation->getPhysicalDeviceFeatures2Func(physdevs[i], &features2);

            deviceInfos[i].supportsSamplerYcbcrConversion =
                samplerYcbcrConversionFeatures.samplerYcbcrConversion == VK_TRUE;
#if defined(__QNX__)
            deviceInfos[i].supportsExternalMemoryImport =
                extMemScreenBufferFeatures.screenBufferImport == VK_TRUE;
        } else {
            deviceInfos[i].supportsExternalMemoryImport = false;
#endif
        }

        uint32_t queueFamilyCount = 0;
        ivk->vkGetPhysicalDeviceQueueFamilyProperties(physdevs[i], &queueFamilyCount, nullptr);
        std::vector<VkQueueFamilyProperties> queueFamilyProps(queueFamilyCount);
        ivk->vkGetPhysicalDeviceQueueFamilyProperties(physdevs[i], &queueFamilyCount,
                                                      queueFamilyProps.data());

        for (uint32_t j = 0; j < queueFamilyCount; ++j) {
            auto count = queueFamilyProps[j].queueCount;
            auto flags = queueFamilyProps[j].queueFlags;

            bool hasGraphicsQueueFamily = (count > 0 && (flags & VK_QUEUE_GRAPHICS_BIT));
            bool hasComputeQueueFamily = (count > 0 && (flags & VK_QUEUE_COMPUTE_BIT));

            deviceInfos[i].hasGraphicsQueueFamily =
                deviceInfos[i].hasGraphicsQueueFamily || hasGraphicsQueueFamily;

            deviceInfos[i].hasComputeQueueFamily =
                deviceInfos[i].hasComputeQueueFamily || hasComputeQueueFamily;

            if (hasGraphicsQueueFamily) {
                deviceInfos[i].graphicsQueueFamilyIndices.push_back(j);
                VERBOSE("Graphics queue family index: %d", j);
            }

            if (hasComputeQueueFamily) {
                deviceInfos[i].computeQueueFamilyIndices.push_back(j);
                VERBOSE("Compute queue family index: %d", j);
            }
        }
    }

    // Of all the devices enumerated, find the best one. Try to find a device
    // with graphics queue as the highest priority, then ext memory, then
    // compute.

    // Graphics queue is highest priority since without that, we really
    // shouldn't be using the driver. Although, one could make a case for doing
    // some sorts of things if only a compute queue is available (such as for
    // AI), that's not really the priority yet.

    // As for external memory, we really should not be running on any driver
    // without external memory support, but we might be able to pull it off, and
    // single Vulkan apps might work via CPU transfer of the rendered frames.

    // Compute support is treated as icing on the cake and not relied upon yet
    // for anything critical to emulation. However, we might potentially use it
    // to perform image format conversion on GPUs where that's not natively
    // supported.

    // Another implicit choice is to select only one Vulkan device. This makes
    // things simple for now, but we could consider utilizing multiple devices
    // in use cases that make sense, if/when they come up.

    std::vector<uint32_t> deviceScores(physdevCount, 0);

    for (uint32_t i = 0; i < physdevCount; ++i) {
        uint32_t deviceScore = 0;
        if (deviceInfos[i].hasGraphicsQueueFamily) deviceScore += 10000;
        if (deviceInfos[i].supportsExternalMemoryImport ||
            deviceInfos[i].supportsExternalMemoryExport)
            deviceScore += 1000;
        if (deviceInfos[i].physdevProps.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU ||
            deviceInfos[i].physdevProps.deviceType == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU) {
            deviceScore += 100;
        }
        if (deviceInfos[i].physdevProps.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) {
            deviceScore += 50;
        }
        deviceScores[i] = deviceScore;
    }

    uint32_t maxScoringIndex = 0;
    uint32_t maxScore = 0;

    // If we don't support physical device ID properties,
    // just pick the first physical device.
    if (!sVkEmulation->instanceSupportsExternalMemoryCapabilities) {
        ERR("Warning: instance doesn't support "
            "external memory capabilities, picking first physical device");
        maxScoringIndex = 0;
    } else {
        for (uint32_t i = 0; i < physdevCount; ++i) {
            if (deviceScores[i] > maxScore) {
                maxScoringIndex = i;
                maxScore = deviceScores[i];
            }
        }
    }

    sVkEmulation->physdev = physdevs[maxScoringIndex];
    sVkEmulation->physicalDeviceIndex = maxScoringIndex;
    sVkEmulation->deviceInfo = deviceInfos[maxScoringIndex];
    // Postcondition: sVkEmulation has valid device support info

    // Ask about image format support here.
    // TODO: May have to first ask when selecting physical devices
    // (e.g., choose between Intel or NVIDIA GPU for certain image format
    // support)
    sVkEmulation->imageSupportInfo = getBasicImageSupportList();
    for (size_t i = 0; i < sVkEmulation->imageSupportInfo.size(); ++i) {
        getImageFormatExternalMemorySupportInfo(ivk, sVkEmulation->physdev,
                                                &sVkEmulation->imageSupportInfo[i]);
    }

    if (!sVkEmulation->deviceInfo.hasGraphicsQueueFamily) {
        VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(ABORT_REASON_OTHER,
                                             "No Vulkan devices with graphics queues found.");
    }

    auto deviceVersion = sVkEmulation->deviceInfo.physdevProps.apiVersion;
    WARN("Selecting Vulkan device: %s, Version: %d.%d.%d",
         sVkEmulation->deviceInfo.physdevProps.deviceName, VK_VERSION_MAJOR(deviceVersion),
         VK_VERSION_MINOR(deviceVersion), VK_VERSION_PATCH(deviceVersion));

    VERBOSE(
        "deviceInfo: \n"
        "hasGraphicsQueueFamily = %d\n"
        "hasComputeQueueFamily = %d\n"
        "supportsExternalMemoryImport = %d\n"
        "supportsExternalMemoryExport = %d\n"
        "supportsIdProperties = %d\n"
        "supportsDriverProperties = %d\n"
        "hasSamplerYcbcrConversionExtension = %d\n"
        "supportsSamplerYcbcrConversion = %d\n"
        "glInteropSupported = %d",
        sVkEmulation->deviceInfo.hasGraphicsQueueFamily,
        sVkEmulation->deviceInfo.hasComputeQueueFamily,
        sVkEmulation->deviceInfo.supportsExternalMemoryImport,
        sVkEmulation->deviceInfo.supportsExternalMemoryExport,
        sVkEmulation->deviceInfo.supportsIdProperties,
        sVkEmulation->deviceInfo.supportsDriverProperties,
        sVkEmulation->deviceInfo.hasSamplerYcbcrConversionExtension,
        sVkEmulation->deviceInfo.supportsSamplerYcbcrConversion,
        sVkEmulation->deviceInfo.glInteropSupported);

    float priority = 1.0f;
    VkDeviceQueueCreateInfo dqCi = {
        VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
        0,
        0,
        sVkEmulation->deviceInfo.graphicsQueueFamilyIndices[0],
        1,
        &priority,
    };

    std::unordered_set<const char*> selectedDeviceExtensionNames_;

    if (sVkEmulation->deviceInfo.supportsExternalMemoryImport ||
        sVkEmulation->deviceInfo.supportsExternalMemoryExport) {
        for (auto extension : externalMemoryDeviceExtNames) {
            selectedDeviceExtensionNames_.emplace(extension);
        }
    }

#if defined(__linux__)
    if (sVkEmulation->deviceInfo.supportsDmaBuf) {
        selectedDeviceExtensionNames_.emplace(VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME);
    }
#endif

    // We need to always enable swapchain extensions to be able to use this device
    // to do VK_IMAGE_LAYOUT_PRESENT_SRC_KHR transition operations done
    // in releaseColorBufferForGuestUse for the apps using Vulkan swapchain
    selectedDeviceExtensionNames_.emplace(VK_KHR_SWAPCHAIN_EXTENSION_NAME);

    if (sVkEmulation->features.VulkanNativeSwapchain.enabled) {
        for (auto extension : SwapChainStateVk::getRequiredDeviceExtensions()) {
            selectedDeviceExtensionNames_.emplace(extension);
        }
    }

    if (sVkEmulation->deviceInfo.hasSamplerYcbcrConversionExtension) {
        selectedDeviceExtensionNames_.emplace(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
    }

#if defined(__APPLE__)
    if (moltenVKSupported) {
        for (auto extension : moltenVkDeviceExtNames) {
            selectedDeviceExtensionNames_.emplace(extension);
        }
    }
#endif

    std::vector<const char*> selectedDeviceExtensionNames(selectedDeviceExtensionNames_.begin(),
                                                          selectedDeviceExtensionNames_.end());

    VkDeviceCreateInfo dCi = {};
    dCi.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
    dCi.queueCreateInfoCount = 1;
    dCi.pQueueCreateInfos = &dqCi;
    dCi.enabledExtensionCount = static_cast<uint32_t>(selectedDeviceExtensionNames.size());
    dCi.ppEnabledExtensionNames = selectedDeviceExtensionNames.data();

    // Setting up VkDeviceCreateInfo::pNext
    auto deviceCiChain = vk_make_chain_iterator(&dCi);

    VkPhysicalDeviceFeatures2 physicalDeviceFeatures = {
        .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
    };
    vk_append_struct(&deviceCiChain, &physicalDeviceFeatures);

    std::unique_ptr<VkPhysicalDeviceSamplerYcbcrConversionFeatures> samplerYcbcrConversionFeatures =
        nullptr;
    if (sVkEmulation->deviceInfo.supportsSamplerYcbcrConversion) {
        samplerYcbcrConversionFeatures =
            std::make_unique<VkPhysicalDeviceSamplerYcbcrConversionFeatures>(
                VkPhysicalDeviceSamplerYcbcrConversionFeatures{
                    .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES,
                    .samplerYcbcrConversion = VK_TRUE,
                });
        vk_append_struct(&deviceCiChain, samplerYcbcrConversionFeatures.get());
    }
#if defined(__QNX__)
    std::unique_ptr<VkPhysicalDeviceExternalMemoryScreenBufferFeaturesQNX>
        extMemScreenBufferFeaturesQNX = nullptr;
    if (sVkEmulation->deviceInfo.supportsExternalMemoryImport) {
        extMemScreenBufferFeaturesQNX = std::make_unique<
            VkPhysicalDeviceExternalMemoryScreenBufferFeaturesQNX>(
            VkPhysicalDeviceExternalMemoryScreenBufferFeaturesQNX{
                .sType =
                    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_SCREEN_BUFFER_FEATURES_QNX,
                .screenBufferImport = VK_TRUE,
            });
        vk_append_struct(&deviceCiChain, extMemScreenBufferFeaturesQNX.get());
    }
#endif

    ivk->vkCreateDevice(sVkEmulation->physdev, &dCi, nullptr, &sVkEmulation->device);

    if (res != VK_SUCCESS) {
        VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(res, "Failed to create Vulkan device. Error %s.",
                                             string_VkResult(res));
    }

    // device created; populate dispatch table
    sVkEmulation->dvk = new VulkanDispatch;
    init_vulkan_dispatch_from_device(ivk, sVkEmulation->device, sVkEmulation->dvk);

    auto dvk = sVkEmulation->dvk;

    // Check if the dispatch table has everything 1.1 related
    if (!vulkan_dispatch_check_device_VK_VERSION_1_0(dvk)) {
        ERR("Warning: Vulkan 1.0 APIs missing from device.");
    }
    if (deviceVersion >= VK_MAKE_VERSION(1, 1, 0)) {
        if (!vulkan_dispatch_check_device_VK_VERSION_1_1(dvk)) {
            ERR("Warning: Vulkan 1.1 APIs missing from device");
        }
    }

    if (sVkEmulation->deviceInfo.supportsExternalMemoryImport) {
        sVkEmulation->deviceInfo.getImageMemoryRequirements2Func =
            reinterpret_cast<PFN_vkGetImageMemoryRequirements2KHR>(
                dvk->vkGetDeviceProcAddr(sVkEmulation->device, "vkGetImageMemoryRequirements2KHR"));
        if (!sVkEmulation->deviceInfo.getImageMemoryRequirements2Func) {
            VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(ABORT_REASON_OTHER,
                                                 "Cannot find vkGetImageMemoryRequirements2KHR.");
        }
        sVkEmulation->deviceInfo.getBufferMemoryRequirements2Func =
            reinterpret_cast<PFN_vkGetBufferMemoryRequirements2KHR>(dvk->vkGetDeviceProcAddr(
                sVkEmulation->device, "vkGetBufferMemoryRequirements2KHR"));
        if (!sVkEmulation->deviceInfo.getBufferMemoryRequirements2Func) {
            VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(ABORT_REASON_OTHER,
                                                 "Cannot find vkGetBufferMemoryRequirements2KHR");
        }
    }
    if (sVkEmulation->deviceInfo.supportsExternalMemoryExport) {
#ifdef _WIN32
        // Use vkGetMemoryWin32HandleKHR
        sVkEmulation->deviceInfo.getMemoryHandleFunc =
            reinterpret_cast<PFN_vkGetMemoryWin32HandleKHR>(
                dvk->vkGetDeviceProcAddr(sVkEmulation->device, "vkGetMemoryWin32HandleKHR"));
        if (!sVkEmulation->deviceInfo.getMemoryHandleFunc) {
            VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(ABORT_REASON_OTHER,
                                                 "Cannot find vkGetMemoryWin32HandleKHR");
        }
#else
        if (sVkEmulation->instanceSupportsMoltenVK) {
            // vkExportMetalObjectsEXT will be used directly
            sVkEmulation->deviceInfo.getMemoryHandleFunc = nullptr;
            if (!dvk->vkGetDeviceProcAddr(sVkEmulation->device, "vkExportMetalObjectsEXT")) {
                VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(ABORT_REASON_OTHER,
                                                     "Cannot find vkExportMetalObjectsEXT");
            }
        } else {
            // Use vkGetMemoryFdKHR
            sVkEmulation->deviceInfo.getMemoryHandleFunc = reinterpret_cast<PFN_vkGetMemoryFdKHR>(
                dvk->vkGetDeviceProcAddr(sVkEmulation->device, "vkGetMemoryFdKHR"));
            if (!sVkEmulation->deviceInfo.getMemoryHandleFunc) {
                VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(ABORT_REASON_OTHER,
                                                     "Cannot find vkGetMemoryFdKHR");
            }
        }
#endif
    }

    VERBOSE("Vulkan logical device created and extension functions obtained.");

    sVkEmulation->queueLock = std::make_shared<android::base::Lock>();
    {
        android::base::AutoLock lock(*sVkEmulation->queueLock);
        dvk->vkGetDeviceQueue(sVkEmulation->device,
                              sVkEmulation->deviceInfo.graphicsQueueFamilyIndices[0], 0,
                              &sVkEmulation->queue);
    }

    sVkEmulation->queueFamilyIndex = sVkEmulation->deviceInfo.graphicsQueueFamilyIndices[0];

    VERBOSE("Vulkan device queue obtained.");

    VkCommandPoolCreateInfo poolCi = {
        VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
        0,
        VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
        sVkEmulation->queueFamilyIndex,
    };

    VkResult poolCreateRes = dvk->vkCreateCommandPool(sVkEmulation->device, &poolCi, nullptr,
                                                      &sVkEmulation->commandPool);

    if (poolCreateRes != VK_SUCCESS) {
        VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(poolCreateRes,
                                             "Failed to create command pool. Error: %s.",
                                             string_VkResult(poolCreateRes));
    }

    VkCommandBufferAllocateInfo cbAi = {
        VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
        0,
        sVkEmulation->commandPool,
        VK_COMMAND_BUFFER_LEVEL_PRIMARY,
        1,
    };

    VkResult cbAllocRes =
        dvk->vkAllocateCommandBuffers(sVkEmulation->device, &cbAi, &sVkEmulation->commandBuffer);

    if (cbAllocRes != VK_SUCCESS) {
        VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(cbAllocRes,
                                             "Failed to allocate command buffer. Error: %s.",
                                             string_VkResult(cbAllocRes));
    }

    VkFenceCreateInfo fenceCi = {
        VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
        0,
        0,
    };

    VkResult fenceCreateRes = dvk->vkCreateFence(sVkEmulation->device, &fenceCi, nullptr,
                                                 &sVkEmulation->commandBufferFence);

    if (fenceCreateRes != VK_SUCCESS) {
        VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(
            fenceCreateRes, "Failed to create fence for command buffer. Error: %s.",
            string_VkResult(fenceCreateRes));
    }

    // At this point, the global emulation state's logical device can alloc
    // memory and send commands. However, it can't really do much yet to
    // communicate the results without the staging buffer. Set that up here.
    // Note that the staging buffer is meant to use external memory, with a
    // non-external-memory fallback.

    VkBufferCreateInfo bufCi = {
        VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
        0,
        0,
        sVkEmulation->staging.size,
        VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
        VK_SHARING_MODE_EXCLUSIVE,
        0,
        nullptr,
    };

    VkResult bufCreateRes =
        dvk->vkCreateBuffer(sVkEmulation->device, &bufCi, nullptr, &sVkEmulation->staging.buffer);

    if (bufCreateRes != VK_SUCCESS) {
        VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(bufCreateRes,
                                             "Failed to create staging buffer index. Error: %s.",
                                             string_VkResult(bufCreateRes));
    }

    VkMemoryRequirements memReqs;
    dvk->vkGetBufferMemoryRequirements(sVkEmulation->device, sVkEmulation->staging.buffer,
                                       &memReqs);

    sVkEmulation->staging.memory.size = memReqs.size;

    bool gotStagingTypeIndex =
        getStagingMemoryTypeIndex(dvk, sVkEmulation->device, &sVkEmulation->deviceInfo.memProps,
                                  &sVkEmulation->staging.memory.typeIndex);

    if (!gotStagingTypeIndex) {
        VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(ABORT_REASON_OTHER,
                                             "Failed to determine staging memory type index.");
    }

    if (!((1 << sVkEmulation->staging.memory.typeIndex) & memReqs.memoryTypeBits)) {
        VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(
            ABORT_REASON_OTHER,
            "Failed: Inconsistent determination of memory type index for staging buffer");
    }

    if (!allocExternalMemory(dvk, &sVkEmulation->staging.memory, false /* not external */,
                             kNullopt /* deviceAlignment */)) {
        VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(ABORT_REASON_OTHER,
                                             "Failed to allocate memory for staging buffer.");
    }

    VkResult stagingBufferBindRes = dvk->vkBindBufferMemory(
        sVkEmulation->device, sVkEmulation->staging.buffer, sVkEmulation->staging.memory.memory, 0);

    if (stagingBufferBindRes != VK_SUCCESS) {
        VK_EMU_INIT_RETURN_OR_ABORT_ON_ERROR(stagingBufferBindRes,
                                             "Failed to bind memory for staging buffer. Error %s.",
                                             string_VkResult(stagingBufferBindRes));
    }

    sVkEmulation->debugUtilsAvailableAndRequested = debugUtilsAvailableAndRequested;
    if (sVkEmulation->debugUtilsAvailableAndRequested) {
        sVkEmulation->debugUtilsHelper =
            DebugUtilsHelper::withUtilsEnabled(sVkEmulation->device, sVkEmulation->ivk);

        sVkEmulation->debugUtilsHelper.addDebugLabel(sVkEmulation->instance, "AEMU_Instance");
        sVkEmulation->debugUtilsHelper.addDebugLabel(sVkEmulation->device, "AEMU_Device");
        sVkEmulation->debugUtilsHelper.addDebugLabel(sVkEmulation->staging.buffer,
                                                     "AEMU_StagingBuffer");
        sVkEmulation->debugUtilsHelper.addDebugLabel(sVkEmulation->commandBuffer,
                                                     "AEMU_CommandBuffer");
    }

    VERBOSE("Vulkan global emulation state successfully initialized.");
    sVkEmulation->live = true;

    sVkEmulation->transferQueueCommandBufferPool.resize(0);

    return sVkEmulation;
}

std::optional<VkEmulation::RepresentativeColorBufferMemoryTypeInfo>
findRepresentativeColorBufferMemoryTypeIndexLocked();

void initVkEmulationFeatures(std::unique_ptr<VkEmulationFeatures> features) {
    if (!sVkEmulation || !sVkEmulation->live) {
        ERR("VkEmulation is either not initialized or destroyed.");
        return;
    }

    AutoLock lock(sVkEmulationLock);
    INFO("Initializing VkEmulation features:");
    INFO("    glInteropSupported: %s", features->glInteropSupported ? "true" : "false");
    INFO("    useDeferredCommands: %s", features->deferredCommands ? "true" : "false");
    INFO("    createResourceWithRequirements: %s",
         features->createResourceWithRequirements ? "true" : "false");
    INFO("    useVulkanComposition: %s", features->useVulkanComposition ? "true" : "false");
    INFO("    useVulkanNativeSwapchain: %s", features->useVulkanNativeSwapchain ? "true" : "false");
    INFO("    enable guestRenderDoc: %s", features->guestRenderDoc ? "true" : "false");
    INFO("    ASTC LDR emulation mode: %d", features->astcLdrEmulationMode);
    INFO("    enable ETC2 emulation: %s", features->enableEtc2Emulation ? "true" : "false");
    INFO("    enable Ycbcr emulation: %s", features->enableYcbcrEmulation ? "true" : "false");
    INFO("    guestVulkanOnly: %s", features->guestVulkanOnly ? "true" : "false");
    INFO("    useDedicatedAllocations: %s", features->useDedicatedAllocations ? "true" : "false");
    sVkEmulation->deviceInfo.glInteropSupported = features->glInteropSupported;
    sVkEmulation->useDeferredCommands = features->deferredCommands;
    sVkEmulation->useCreateResourcesWithRequirements = features->createResourceWithRequirements;
    sVkEmulation->guestRenderDoc = std::move(features->guestRenderDoc);
    sVkEmulation->astcLdrEmulationMode = features->astcLdrEmulationMode;
    sVkEmulation->enableEtc2Emulation = features->enableEtc2Emulation;
    sVkEmulation->enableYcbcrEmulation = features->enableYcbcrEmulation;
    sVkEmulation->guestVulkanOnly = features->guestVulkanOnly;
    sVkEmulation->useDedicatedAllocations = features->useDedicatedAllocations;

    if (features->useVulkanComposition) {
        if (sVkEmulation->compositorVk) {
            ERR("Reset VkEmulation::compositorVk.");
        }
        sVkEmulation->compositorVk =
            CompositorVk::create(*sVkEmulation->ivk, sVkEmulation->device, sVkEmulation->physdev,
                                 sVkEmulation->queue, sVkEmulation->queueLock,
                                 sVkEmulation->queueFamilyIndex, 3, sVkEmulation->debugUtilsHelper);
    }

    if (features->useVulkanNativeSwapchain) {
        if (sVkEmulation->displayVk) {
            ERR("Reset VkEmulation::displayVk.");
        }
        sVkEmulation->displayVk = std::make_unique<DisplayVk>(
            *sVkEmulation->ivk, sVkEmulation->physdev, sVkEmulation->queueFamilyIndex,
            sVkEmulation->queueFamilyIndex, sVkEmulation->device, sVkEmulation->queue,
            sVkEmulation->queueLock, sVkEmulation->queue, sVkEmulation->queueLock);
    }

    sVkEmulation->representativeColorBufferMemoryTypeInfo =
        findRepresentativeColorBufferMemoryTypeIndexLocked();
    if (sVkEmulation->representativeColorBufferMemoryTypeInfo) {
        VERBOSE(
            "Representative ColorBuffer memory type using host memory type index %d "
            "and guest memory type index :%d",
            sVkEmulation->representativeColorBufferMemoryTypeInfo->hostMemoryTypeIndex,
            sVkEmulation->representativeColorBufferMemoryTypeInfo->guestMemoryTypeIndex);
    } else {
        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
            << "Failed to find memory type for ColorBuffers.";
    }
}

VkEmulation* getGlobalVkEmulation() {
    if (sVkEmulation && !sVkEmulation->live) return nullptr;
    return sVkEmulation;
}

void teardownGlobalVkEmulation() {
    if (!sVkEmulation) return;

    // Don't try to tear down something that did not set up completely; too risky
    if (!sVkEmulation->live) return;

    sVkEmulation->compositorVk.reset();
    sVkEmulation->displayVk.reset();

    freeExternalMemoryLocked(sVkEmulation->dvk, &sVkEmulation->staging.memory);

    sVkEmulation->dvk->vkDestroyBuffer(sVkEmulation->device, sVkEmulation->staging.buffer, nullptr);

    sVkEmulation->dvk->vkDestroyFence(sVkEmulation->device, sVkEmulation->commandBufferFence,
                                      nullptr);

    sVkEmulation->dvk->vkFreeCommandBuffers(sVkEmulation->device, sVkEmulation->commandPool, 1,
                                            &sVkEmulation->commandBuffer);

    sVkEmulation->dvk->vkDestroyCommandPool(sVkEmulation->device, sVkEmulation->commandPool,
                                            nullptr);

    sVkEmulation->ivk->vkDestroyDevice(sVkEmulation->device, nullptr);
    sVkEmulation->gvk->vkDestroyInstance(sVkEmulation->instance, nullptr);

    VkDecoderGlobalState::reset();

    sVkEmulation->live = false;
    delete sVkEmulation;
    sVkEmulation = nullptr;
}

std::unique_ptr<gfxstream::DisplaySurface> createDisplaySurface(FBNativeWindowType window,
                                                                uint32_t width, uint32_t height) {
    if (!sVkEmulation || !sVkEmulation->live) {
        return nullptr;
    }

    auto surfaceVk = DisplaySurfaceVk::create(*sVkEmulation->ivk, sVkEmulation->instance, window);
    if (!surfaceVk) {
        ERR("Failed to create DisplaySurfaceVk.");
        return nullptr;
    }

    return std::make_unique<gfxstream::DisplaySurface>(width, height, std::move(surfaceVk));
}

#ifdef __APPLE__
static MTLBufferRef getMtlBufferFromVkDeviceMemory(VulkanDispatch* vk, VkDeviceMemory memory) {
    VkExportMetalBufferInfoEXT exportMetalBufferInfo = {
        VK_STRUCTURE_TYPE_EXPORT_METAL_BUFFER_INFO_EXT, nullptr, memory, VK_NULL_HANDLE};
    VkExportMetalObjectsInfoEXT metalObjectsInfo = {VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECTS_INFO_EXT,
                                                    &exportMetalBufferInfo};
    vk->vkExportMetalObjectsEXT(sVkEmulation->device, &metalObjectsInfo);

    return exportMetalBufferInfo.mtlBuffer;
}

static MTLTextureRef getMtlTextureFromVkImage(VulkanDispatch* vk, VkImage image) {
    VkExportMetalTextureInfoEXT exportMetalTextureInfo = {
        VK_STRUCTURE_TYPE_EXPORT_METAL_TEXTURE_INFO_EXT,
        nullptr,
        image,
        VK_NULL_HANDLE,
        VK_NULL_HANDLE,
        VK_IMAGE_ASPECT_PLANE_0_BIT,
        VK_NULL_HANDLE};
    VkExportMetalObjectsInfoEXT metalObjectsInfo = {VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECTS_INFO_EXT,
                                                    &exportMetalTextureInfo};
    vk->vkExportMetalObjectsEXT(sVkEmulation->device, &metalObjectsInfo);

    return exportMetalTextureInfo.mtlTexture;
}
#endif

// Precondition: sVkEmulation has valid device support info
bool allocExternalMemory(VulkanDispatch* vk, VkEmulation::ExternalMemoryInfo* info,
                         bool actuallyExternal, Optional<uint64_t> deviceAlignment,
                         Optional<VkBuffer> bufferForDedicatedAllocation,
                         Optional<VkImage> imageForDedicatedAllocation) {
    VkExportMemoryAllocateInfo exportAi = {
        .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
        .pNext = nullptr,
        .handleTypes = VK_EXT_MEMORY_HANDLE_TYPE_BIT,
    };

    VkMemoryDedicatedAllocateInfo dedicatedAllocInfo = {
        .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
        .pNext = nullptr,
        .image = VK_NULL_HANDLE,
        .buffer = VK_NULL_HANDLE,
    };

    VkMemoryAllocateInfo allocInfo = {
        .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
        .pNext = nullptr,
        .allocationSize = info->size,
        .memoryTypeIndex = info->typeIndex,
    };

    auto allocInfoChain = vk_make_chain_iterator(&allocInfo);

#ifdef __APPLE__
    // On MoltenVK, use metal objects to export metal handles
    VkExportMetalObjectCreateInfoEXT metalBufferExport = {
        VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECT_CREATE_INFO_EXT, nullptr,
        VK_EXPORT_METAL_OBJECT_TYPE_METAL_BUFFER_BIT_EXT};
#endif

    if (sVkEmulation->deviceInfo.supportsExternalMemoryExport && actuallyExternal) {
#ifdef __APPLE__
        if (sVkEmulation->instanceSupportsMoltenVK) {
            // Change handle type to metal buffers
            exportAi.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLBUFFER_BIT_KHR;

            // Append metal buffer export for getting metal handles for the allocation
            vk_append_struct(&allocInfoChain, &metalBufferExport);
        }
#endif
        if (sVkEmulation->deviceInfo.supportsDmaBuf && actuallyExternal) {
            exportAi.handleTypes |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
        }

        vk_append_struct(&allocInfoChain, &exportAi);
    }

    if (bufferForDedicatedAllocation.hasValue() || imageForDedicatedAllocation.hasValue()) {
        info->dedicatedAllocation = true;
        if (bufferForDedicatedAllocation.hasValue()) {
            dedicatedAllocInfo.buffer = *bufferForDedicatedAllocation;
        }
        if (imageForDedicatedAllocation.hasValue()) {
            dedicatedAllocInfo.image = *imageForDedicatedAllocation;
        }
        vk_append_struct(&allocInfoChain, &dedicatedAllocInfo);
    }

    bool memoryAllocated = false;
    std::vector<VkDeviceMemory> allocationAttempts;
    constexpr size_t kMaxAllocationAttempts = 20u;

    while (!memoryAllocated) {
        VkResult allocRes =
            vk->vkAllocateMemory(sVkEmulation->device, &allocInfo, nullptr, &info->memory);

        if (allocRes != VK_SUCCESS) {
            VERBOSE("allocExternalMemory: failed in vkAllocateMemory: %s",
                    string_VkResult(allocRes));
            break;
        }

        if (sVkEmulation->deviceInfo.memProps.memoryTypes[info->typeIndex].propertyFlags &
            VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
            VkResult mapRes = vk->vkMapMemory(sVkEmulation->device, info->memory, 0, info->size, 0,
                                              &info->mappedPtr);
            if (mapRes != VK_SUCCESS) {
                VERBOSE("allocExternalMemory: failed in vkMapMemory: %s", string_VkResult(mapRes));
                break;
            }
        }

        uint64_t mappedPtrPageOffset = reinterpret_cast<uint64_t>(info->mappedPtr) % kPageSize;

        if (  // don't care about alignment (e.g. device-local memory)
            !deviceAlignment.hasValue() ||
            // If device has an alignment requirement larger than current
            // host pointer alignment (i.e. the lowest 1 bit of mappedPtr),
            // the only possible way to make mappedPtr valid is to ensure
            // that it is already aligned to page.
            mappedPtrPageOffset == 0u ||
            // If device has an alignment requirement smaller or equals to
            // current host pointer alignment, clients can set a offset
            // |kPageSize - mappedPtrPageOffset| in vkBindImageMemory to
            // make it aligned to page and compatible with device
            // requirements.
            (kPageSize - mappedPtrPageOffset) % deviceAlignment.value() == 0) {
            // allocation success.
            memoryAllocated = true;
        } else {
            allocationAttempts.push_back(info->memory);

            VERBOSE("allocExternalMemory: attempt #%zu failed; deviceAlignment: %" PRIu64
                    ", mappedPtrPageOffset: %" PRIu64,
                    allocationAttempts.size(), deviceAlignment.valueOr(0), mappedPtrPageOffset);

            if (allocationAttempts.size() >= kMaxAllocationAttempts) {
                VERBOSE(
                    "allocExternalMemory: unable to allocate memory with CPU mapped ptr aligned to "
                    "page");
                break;
            }
        }
    }

    // clean up previous failed attempts
    for (const auto& mem : allocationAttempts) {
        vk->vkFreeMemory(sVkEmulation->device, mem, nullptr /* allocator */);
    }
    if (!memoryAllocated) {
        return false;
    }

    if (!sVkEmulation->deviceInfo.supportsExternalMemoryExport || !actuallyExternal) {
        return true;
    }

    VkExternalMemoryHandleTypeFlagBits vkHandleType = VK_EXT_MEMORY_HANDLE_TYPE_BIT;
    uint32_t streamHandleType = 0;
    VkResult exportRes = VK_SUCCESS;
    bool validHandle = false;
#ifdef _WIN32
    VkMemoryGetWin32HandleInfoKHR getWin32HandleInfo = {
        VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
        0,
        info->memory,
        vkHandleType,
    };

    exportRes = sVkEmulation->deviceInfo.getMemoryHandleFunc(
        sVkEmulation->device, &getWin32HandleInfo, &info->externalHandle);
    validHandle = (VK_EXT_MEMORY_HANDLE_INVALID != info->externalHandle);
    info->streamHandleType = STREAM_MEM_HANDLE_TYPE_OPAQUE_WIN32;
#elif !defined(__QNX__)
    bool opaque_fd = true;
    if (sVkEmulation->instanceSupportsMoltenVK) {
        opaque_fd = false;
#if defined(__APPLE__)
        info->externalMetalHandle = getMtlBufferFromVkDeviceMemory(vk, info->memory);
        validHandle = (nullptr != info->externalMetalHandle);
        if (validHandle) {
            CFRetain(info->externalMetalHandle);
            exportRes = VK_SUCCESS;
        } else {
            exportRes = VK_ERROR_INVALID_EXTERNAL_HANDLE;
        }
#endif
    }
    if (opaque_fd) {
        if (sVkEmulation->deviceInfo.supportsDmaBuf) {
            vkHandleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
            info->streamHandleType = STREAM_MEM_HANDLE_TYPE_DMABUF;
        } else {
            info->streamHandleType = STREAM_MEM_HANDLE_TYPE_OPAQUE_FD;
        }

        VkMemoryGetFdInfoKHR getFdInfo = {
            VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
            0,
            info->memory,
            vkHandleType,
        };
        exportRes = sVkEmulation->deviceInfo.getMemoryHandleFunc(sVkEmulation->device, &getFdInfo,
                                                                 &info->externalHandle);
        validHandle = (VK_EXT_MEMORY_HANDLE_INVALID != info->externalHandle);
    }
#endif

    if (exportRes != VK_SUCCESS || !validHandle) {
        WARN("allocExternalMemory: Failed to get external memory, result: %s",
             string_VkResult(exportRes));
        return false;
    }

    return true;
}

void freeExternalMemoryLocked(VulkanDispatch* vk, VkEmulation::ExternalMemoryInfo* info) {
    if (!info->memory) return;

    if (sVkEmulation->deviceInfo.memProps.memoryTypes[info->typeIndex].propertyFlags &
        VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
        if (sVkEmulation->occupiedGpas.find(info->gpa) != sVkEmulation->occupiedGpas.end()) {
            sVkEmulation->occupiedGpas.erase(info->gpa);
            get_emugl_vm_operations().unmapUserBackedRam(info->gpa, info->sizeToPage);
            info->gpa = 0u;
        }

        if (info->mappedPtr != nullptr) {
            vk->vkUnmapMemory(sVkEmulation->device, info->memory);
            info->mappedPtr = nullptr;
            info->pageAlignedHva = nullptr;
        }
    }

    vk->vkFreeMemory(sVkEmulation->device, info->memory, nullptr);

    info->memory = VK_NULL_HANDLE;

    if (info->externalHandle != VK_EXT_MEMORY_HANDLE_INVALID) {
#ifdef _WIN32
        CloseHandle(info->externalHandle);
#elif !defined(__QNX__)
        close(info->externalHandle);
#endif
        info->externalHandle = VK_EXT_MEMORY_HANDLE_INVALID;
    }

#if defined(__APPLE__)
    if (info->externalMetalHandle) {
        CFRelease(info->externalMetalHandle);
    }
#endif
}

bool importExternalMemory(VulkanDispatch* vk, VkDevice targetDevice,
                          const VkEmulation::ExternalMemoryInfo* info, VkDeviceMemory* out) {
    const void* importInfoPtr = nullptr;
#ifdef _WIN32
    VkImportMemoryWin32HandleInfoKHR importInfo = {
        VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
        0,
        VK_EXT_MEMORY_HANDLE_TYPE_BIT,
        info->externalHandle,
        0,
    };
    importInfoPtr = &importInfo;
#elif defined(__QNX__)
    VkImportScreenBufferInfoQNX importInfo = {
        VK_STRUCTURE_TYPE_IMPORT_SCREEN_BUFFER_INFO_QNX,
        NULL,
        info->externalHandle,
    };
    importInfoPtr = &importInfo;
#else
    VkImportMemoryFdInfoKHR importInfoFd = {
        VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
        0,
        VK_EXT_MEMORY_HANDLE_TYPE_BIT,
        VK_EXT_MEMORY_HANDLE_INVALID,
    };

#ifdef __APPLE__
    VkImportMetalBufferInfoEXT importInfoMetalBuffer = {
        VK_STRUCTURE_TYPE_IMPORT_METAL_BUFFER_INFO_EXT,
        0,
        nullptr,
    };
    if (sVkEmulation->instanceSupportsMoltenVK) {
        importInfoMetalBuffer.mtlBuffer = info->externalMetalHandle;
        importInfoPtr = &importInfoMetalBuffer;
    } else
#endif
    {
        importInfoFd.fd = dupExternalMemory(info->externalHandle);
        importInfoPtr = &importInfoFd;
    }
#endif
    VkMemoryAllocateInfo allocInfo = {
        VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
        importInfoPtr,
        info->size,
        info->typeIndex,
    };

    VkResult res = vk->vkAllocateMemory(targetDevice, &allocInfo, nullptr, out);

    if (res != VK_SUCCESS) {
        ERR("importExternalMemory: Failed with %s", string_VkResult(res));
        return false;
    }

    return true;
}

bool importExternalMemoryDedicatedImage(VulkanDispatch* vk, VkDevice targetDevice,
                                        const VkEmulation::ExternalMemoryInfo* info, VkImage image,
                                        VkDeviceMemory* out) {
    VkMemoryDedicatedAllocateInfo dedicatedInfo = {
        VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
        0,
        image,
        VK_NULL_HANDLE,
    };

    const void* importInfoPtr = nullptr;
#ifdef _WIN32
    VkImportMemoryWin32HandleInfoKHR importInfo = {
        VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
        &dedicatedInfo,
        VK_EXT_MEMORY_HANDLE_TYPE_BIT,
        info->externalHandle,
        0,
    };
    importInfoPtr = &importInfo;
#elif defined(__QNX__)
    VkImportScreenBufferInfoQNX importInfo = {
        VK_STRUCTURE_TYPE_IMPORT_SCREEN_BUFFER_INFO_QNX,
        &dedicatedInfo,
        info->externalHandle,
    };
    importInfoPtr = &importInfo;
#else
    VkImportMemoryFdInfoKHR importInfoFd = {
        VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
        &dedicatedInfo,
        VK_EXT_MEMORY_HANDLE_TYPE_BIT,
        -1,
    };

#ifdef __APPLE__
    VkImportMetalBufferInfoEXT importInfoMetalBuffer = {
        VK_STRUCTURE_TYPE_IMPORT_METAL_BUFFER_INFO_EXT,
        &dedicatedInfo,
        nullptr,
    };
    if (sVkEmulation->instanceSupportsMoltenVK) {
        importInfoMetalBuffer.mtlBuffer = info->externalMetalHandle;
        importInfoPtr = &importInfoMetalBuffer;
    } else
#endif
    {
        importInfoFd.fd = dupExternalMemory(info->externalHandle);
        importInfoPtr = &importInfoFd;
    }
#endif
    VkMemoryAllocateInfo allocInfo = {
        VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
        importInfoPtr,
        info->size,
        info->typeIndex,
    };

    VkResult res = vk->vkAllocateMemory(targetDevice, &allocInfo, nullptr, out);

    if (res != VK_SUCCESS) {
        ERR("importExternalMemoryDedicatedImage: Failed with %s", string_VkResult(res));
        return false;
    }

    return true;
}

// From ANGLE "src/common/angleutils.h"
#define GL_BGR10_A2_ANGLEX 0x6AF9

static VkFormat glFormat2VkFormat(GLint internalFormat) {
    switch (internalFormat) {
        case GL_R8:
        case GL_LUMINANCE:
            return VK_FORMAT_R8_UNORM;
        case GL_RGB:
        case GL_RGB8:
            // b/281550953
            // RGB8 is not supported on many vulkan drivers.
            // Try RGBA8 instead.
            // Note: copyImageData() performs channel conversion for this case.
            return VK_FORMAT_R8G8B8A8_UNORM;
        case GL_RGB565:
            return VK_FORMAT_R5G6B5_UNORM_PACK16;
        case GL_RGB16F:
            return VK_FORMAT_R16G16B16_SFLOAT;
        case GL_RGBA:
        case GL_RGBA8:
            return VK_FORMAT_R8G8B8A8_UNORM;
        case GL_RGB5_A1_OES:
            return VK_FORMAT_A1R5G5B5_UNORM_PACK16;
        case GL_RGBA4_OES:
            return VK_FORMAT_R4G4B4A4_UNORM_PACK16;
        case GL_RGB10_A2:
        case GL_UNSIGNED_INT_10_10_10_2_OES:
            return VK_FORMAT_A2R10G10B10_UNORM_PACK32;
        case GL_BGR10_A2_ANGLEX:
            return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
        case GL_RGBA16F:
            return VK_FORMAT_R16G16B16A16_SFLOAT;
        case GL_BGRA_EXT:
        case GL_BGRA8_EXT:
            return VK_FORMAT_B8G8R8A8_UNORM;
        case GL_R16_EXT:
            return VK_FORMAT_R16_UNORM;
        case GL_RG8_EXT:
            return VK_FORMAT_R8G8_UNORM;
        default:
            ERR("Unhandled format %d, falling back to VK_FORMAT_R8G8B8A8_UNORM", internalFormat);
            return VK_FORMAT_R8G8B8A8_UNORM;
    }
};

static bool isFormatVulkanCompatible(GLenum internalFormat) {
    VkFormat vkFormat = glFormat2VkFormat(internalFormat);

    for (const auto& supportInfo : sVkEmulation->imageSupportInfo) {
        if (supportInfo.format == vkFormat && supportInfo.supported) {
            return true;
        }
    }

    return false;
}

bool getColorBufferShareInfo(uint32_t colorBufferHandle, bool* glExported,
                             bool* externalMemoryCompatible) {
    if (!sVkEmulation || !sVkEmulation->live) {
        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Vulkan emulation not available.";
    }

    AutoLock lock(sVkEmulationLock);

    auto info = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
    if (!info) {
        return false;
    }

    *glExported = info->glExported;
    *externalMemoryCompatible = info->externalMemoryCompatible;
    return true;
}

bool getColorBufferAllocationInfoLocked(uint32_t colorBufferHandle, VkDeviceSize* outSize,
                                        uint32_t* outMemoryTypeIndex,
                                        bool* outMemoryIsDedicatedAlloc, void** outMappedPtr) {
    auto info = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
    if (!info) {
        return false;
    }

    if (outSize) {
        *outSize = info->memory.size;
    }

    if (outMemoryTypeIndex) {
        *outMemoryTypeIndex = info->memory.typeIndex;
    }

    if (outMemoryIsDedicatedAlloc) {
        *outMemoryIsDedicatedAlloc = info->memory.dedicatedAllocation;
    }

    if (outMappedPtr) {
        *outMappedPtr = info->memory.mappedPtr;
    }

    return true;
}

bool getColorBufferAllocationInfo(uint32_t colorBufferHandle, VkDeviceSize* outSize,
                                  uint32_t* outMemoryTypeIndex, bool* outMemoryIsDedicatedAlloc,
                                  void** outMappedPtr) {
    if (!sVkEmulation || !sVkEmulation->live) {
        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Vulkan emulation not available.";
    }

    AutoLock lock(sVkEmulationLock);
    return getColorBufferAllocationInfoLocked(colorBufferHandle, outSize, outMemoryTypeIndex,
                                              outMemoryIsDedicatedAlloc, outMappedPtr);
}

// This function will return the first memory type that exactly matches the
// requested properties, if there is any. Otherwise it'll return the last
// index that supports all the requested memory property flags.
// Eg. this avoids returning a host coherent memory type when only device local
// memory flag is requested, which may be slow or not support some other features,
// such as association with optimal-tiling images on some implementations.
static uint32_t getValidMemoryTypeIndex(uint32_t requiredMemoryTypeBits,
                                        VkMemoryPropertyFlags memoryProperty = 0) {
    uint32_t secondBest = ~0;
    bool found = false;
    for (int32_t i = 0; i <= 31; i++) {
        if ((requiredMemoryTypeBits & (1u << i)) == 0) {
            // Not a suitable memory index
            continue;
        }

        const VkMemoryPropertyFlags memPropertyFlags =
            sVkEmulation->deviceInfo.memProps.memoryTypes[i].propertyFlags;

        // Exact match, return immediately
        if (memPropertyFlags == memoryProperty) {
            return i;
        }

        // Valid memory index, but keep  looking for an exact match
        // TODO: this should compare against memoryProperty, but some existing tests
        // are depending on this behavior.
        const bool propertyValid = !memoryProperty || ((memPropertyFlags & memoryProperty) != 0);
        if (propertyValid) {
            secondBest = i;
            found = true;
        }
    }

    if (!found) {
        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
            << "Could not find a valid memory index with memoryProperty: "
            << string_VkMemoryPropertyFlags(memoryProperty)
            << ", and requiredMemoryTypeBits: " << requiredMemoryTypeBits;
    }
    return secondBest;
}

// pNext, sharingMode, queueFamilyIndexCount, pQueueFamilyIndices, and initialLayout won't be
// filled.
static std::unique_ptr<VkImageCreateInfo> generateColorBufferVkImageCreateInfo_locked(
    VkFormat format, uint32_t width, uint32_t height, VkImageTiling tiling) {
    const VkEmulation::ImageSupportInfo* maybeImageSupportInfo = nullptr;
    for (const auto& supportInfo : sVkEmulation->imageSupportInfo) {
        if (supportInfo.format == format && supportInfo.supported) {
            maybeImageSupportInfo = &supportInfo;
            break;
        }
    }
    if (!maybeImageSupportInfo) {
        ERR("Format %s is not supported.", string_VkFormat(format));
        return nullptr;
    }
    const VkEmulation::ImageSupportInfo& imageSupportInfo = *maybeImageSupportInfo;
    const VkFormatProperties& formatProperties = imageSupportInfo.formatProps2.formatProperties;

    constexpr std::pair<VkFormatFeatureFlags, VkImageUsageFlags> formatUsagePairs[] = {
        {VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT,
         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT},
        {VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, VK_IMAGE_USAGE_SAMPLED_BIT},
        {VK_FORMAT_FEATURE_TRANSFER_SRC_BIT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT},
        {VK_FORMAT_FEATURE_TRANSFER_DST_BIT, VK_IMAGE_USAGE_TRANSFER_DST_BIT},
        {VK_FORMAT_FEATURE_BLIT_SRC_BIT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT},
    };
    VkFormatFeatureFlags tilingFeatures = (tiling == VK_IMAGE_TILING_OPTIMAL)
                                              ? formatProperties.optimalTilingFeatures
                                              : formatProperties.linearTilingFeatures;

    VkImageUsageFlags usage = 0;
    for (const auto& formatUsage : formatUsagePairs) {
        usage |= (tilingFeatures & formatUsage.first) ? formatUsage.second : 0u;
    }

    return std::make_unique<VkImageCreateInfo>(VkImageCreateInfo{
        .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
        // The caller is responsible to fill pNext.
        .pNext = nullptr,
        .flags = imageSupportInfo.createFlags,
        .imageType = VK_IMAGE_TYPE_2D,
        .format = format,
        .extent =
            {
                .width = width,
                .height = height,
                .depth = 1,
            },
        .mipLevels = 1,
        .arrayLayers = 1,
        .samples = VK_SAMPLE_COUNT_1_BIT,
        .tiling = tiling,
        .usage = usage,
        // The caller is responsible to fill sharingMode.
        .sharingMode = VK_SHARING_MODE_MAX_ENUM,
        // The caller is responsible to fill queueFamilyIndexCount.
        .queueFamilyIndexCount = 0,
        // The caller is responsible to fill pQueueFamilyIndices.
        .pQueueFamilyIndices = nullptr,
        // The caller is responsible to fill initialLayout.
        .initialLayout = VK_IMAGE_LAYOUT_MAX_ENUM,
    });
}

std::unique_ptr<VkImageCreateInfo> generateColorBufferVkImageCreateInfo(VkFormat format,
                                                                        uint32_t width,
                                                                        uint32_t height,
                                                                        VkImageTiling tiling) {
    if (!sVkEmulation || !sVkEmulation->live) {
        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Host Vulkan device lost";
    }
    AutoLock lock(sVkEmulationLock);
    return generateColorBufferVkImageCreateInfo_locked(format, width, height, tiling);
}

static bool updateExternalMemoryInfo(VK_EXT_MEMORY_HANDLE extMemHandle,
                                     const VkMemoryRequirements* pMemReqs,
                                     VkEmulation::ExternalMemoryInfo* pInfo) {
    // Set externalHandle on the output info
    pInfo->externalHandle = extMemHandle;
    pInfo->dedicatedAllocation = true;

#if defined(__QNX__)
    VkScreenBufferPropertiesQNX screenBufferProps = {
        VK_STRUCTURE_TYPE_SCREEN_BUFFER_PROPERTIES_QNX,
        0,
    };
    auto vk = sVkEmulation->dvk;
    VkResult queryRes =
        vk->vkGetScreenBufferPropertiesQNX(sVkEmulation->device, extMemHandle, &screenBufferProps);
    if (VK_SUCCESS != queryRes) {
        ERR("Failed to get QNX Screen Buffer properties, VK error: %s", string_VkResult(queryRes));
        return false;
    }
    if (!((1 << pInfo->typeIndex) & screenBufferProps.memoryTypeBits)) {
        ERR("QNX Screen buffer can not be imported to memory (typeIndex=%d): %d", pInfo->typeIndex);
        return false;
    }
    if (screenBufferProps.allocationSize < pMemReqs->size) {
        ERR("QNX Screen buffer allocationSize (0x%lx) is not large enough for ColorBuffer image "
            "size requirements (0x%lx)",
            screenBufferProps.allocationSize, pMemReqs->size);
        return false;
    }
    // Use the actual allocationSize for VkDeviceMemory object creation
    pInfo->size = screenBufferProps.allocationSize;
#endif

    return true;
}

// TODO(liyl): Currently we can only specify required memoryProperty
// and initial layout for a color buffer.
//
// Ideally we would like to specify a memory type index directly from
// localAllocInfo.memoryTypeIndex when allocating color buffers in
// vkAllocateMemory(). But this type index mechanism breaks "Modify the
// allocation size and type index to suit the resulting image memory
// size." which seems to be needed to keep the Android/Fuchsia guest
// memory type index consistent across guest allocations, and without
// which those guests might end up import allocating from a color buffer
// with mismatched type indices.
//
// We should make it so the guest can only allocate external images/
// buffers of one type index for image and one type index for buffer
// to begin with, via filtering from the host.

bool initializeVkColorBufferLocked(
    uint32_t colorBufferHandle, VK_EXT_MEMORY_HANDLE extMemHandle = VK_EXT_MEMORY_HANDLE_INVALID) {
    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
    // Not initialized
    if (!infoPtr) {
        return false;
    }
    // Already initialized Vulkan memory and other related Vulkan objects
    if (infoPtr->initialized) {
        return true;
    }

    if (!isFormatVulkanCompatible(infoPtr->internalFormat)) {
        VERBOSE("Failed to create Vk ColorBuffer: format:%d not compatible.",
                infoPtr->internalFormat);
        return false;
    }

    const bool extMemImport = (VK_EXT_MEMORY_HANDLE_INVALID != extMemHandle);
    if (extMemImport && !sVkEmulation->deviceInfo.supportsExternalMemoryImport) {
        ERR("Failed to initialize Vk ColorBuffer -- extMemHandle provided, but device does "
            "not support externalMemoryImport");
        return false;
    }

    VkFormat vkFormat;
    bool glCompatible = (infoPtr->frameworkFormat == FRAMEWORK_FORMAT_GL_COMPATIBLE);
    switch (infoPtr->frameworkFormat) {
        case FrameworkFormat::FRAMEWORK_FORMAT_GL_COMPATIBLE:
            vkFormat = glFormat2VkFormat(infoPtr->internalFormat);
            break;
        case FrameworkFormat::FRAMEWORK_FORMAT_NV12:
            vkFormat = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
            break;
        case FrameworkFormat::FRAMEWORK_FORMAT_P010:
            vkFormat = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16;
            break;
        case FrameworkFormat::FRAMEWORK_FORMAT_YV12:
        case FrameworkFormat::FRAMEWORK_FORMAT_YUV_420_888:
            vkFormat = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
            break;
        default:
            ERR("WARNING: unhandled framework format %d\n", infoPtr->frameworkFormat);
            vkFormat = glFormat2VkFormat(infoPtr->internalFormat);
            break;
    }

    VkImageTiling tiling = (infoPtr->memoryProperty & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
                               ? VK_IMAGE_TILING_LINEAR
                               : VK_IMAGE_TILING_OPTIMAL;
    std::unique_ptr<VkImageCreateInfo> imageCi = generateColorBufferVkImageCreateInfo_locked(
        vkFormat, infoPtr->width, infoPtr->height, tiling);
    // pNext will be filled later.
    if (imageCi == nullptr) {
        // it can happen if the format is not supported
        return false;
    }
    imageCi->sharingMode = VK_SHARING_MODE_EXCLUSIVE;
    imageCi->queueFamilyIndexCount = 0;
    imageCi->pQueueFamilyIndices = nullptr;
    imageCi->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

    // Create the image. If external memory is supported, make it external.
    VkExternalMemoryImageCreateInfo extImageCi = {
        VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
        0,
        VK_EXT_MEMORY_HANDLE_TYPE_BIT,
    };
#if defined(__APPLE__)
    VkExportMetalObjectCreateInfoEXT metalImageExportCI = {
        VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECT_CREATE_INFO_EXT, nullptr,
        VK_EXPORT_METAL_OBJECT_TYPE_METAL_TEXTURE_BIT_EXT};

    if (sVkEmulation->instanceSupportsMoltenVK) {
        // Using a different handle type when in MoltenVK mode
        extImageCi.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR;

        extImageCi.pNext = &metalImageExportCI;
    }
#endif

    VkExternalMemoryImageCreateInfo* extImageCiPtr = nullptr;

    if (extMemImport || sVkEmulation->deviceInfo.supportsExternalMemoryExport) {
        extImageCiPtr = &extImageCi;
    }

    imageCi->pNext = extImageCiPtr;

    auto vk = sVkEmulation->dvk;

    VkResult createRes =
        vk->vkCreateImage(sVkEmulation->device, imageCi.get(), nullptr, &infoPtr->image);
    if (createRes != VK_SUCCESS) {
        VERBOSE("Failed to create Vulkan image for ColorBuffer %d, error: %s", colorBufferHandle,
                string_VkResult(createRes));
        return false;
    }

    bool useDedicated = sVkEmulation->useDedicatedAllocations;

    infoPtr->imageCreateInfoShallow = vk_make_orphan_copy(*imageCi);
    infoPtr->currentQueueFamilyIndex = sVkEmulation->queueFamilyIndex;

    if (!useDedicated && vk->vkGetImageMemoryRequirements2KHR) {
        VkMemoryDedicatedRequirements dedicated_reqs{
            VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, nullptr};
        VkMemoryRequirements2 reqs{VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, &dedicated_reqs};

        VkImageMemoryRequirementsInfo2 info{VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
                                            nullptr, infoPtr->image};
        vk->vkGetImageMemoryRequirements2KHR(sVkEmulation->device, &info, &reqs);
        useDedicated = dedicated_reqs.requiresDedicatedAllocation;
        infoPtr->memReqs = reqs.memoryRequirements;
    } else {
        vk->vkGetImageMemoryRequirements(sVkEmulation->device, infoPtr->image, &infoPtr->memReqs);
    }

    // Currently we only care about two memory properties: DEVICE_LOCAL
    // and HOST_VISIBLE; other memory properties specified in
    // rcSetColorBufferVulkanMode2() call will be ignored for now.
    infoPtr->memoryProperty = infoPtr->memoryProperty & (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
                                                         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);

    infoPtr->memory.size = infoPtr->memReqs.size;

    // Determine memory type.
    infoPtr->memory.typeIndex =
        getValidMemoryTypeIndex(infoPtr->memReqs.memoryTypeBits, infoPtr->memoryProperty);

    VERBOSE(
        "ColorBuffer %d, "
        "allocation size and type index: %lu, %d, "
        "allocated memory property: %d, "
        "requested memory property: %d",
        colorBufferHandle, infoPtr->memory.size, infoPtr->memory.typeIndex,
        sVkEmulation->deviceInfo.memProps.memoryTypes[infoPtr->memory.typeIndex].propertyFlags,
        infoPtr->memoryProperty);

    Optional<VkImage> dedicatedImage = useDedicated ? Optional<VkImage>(infoPtr->image) : kNullopt;
    if (VK_EXT_MEMORY_HANDLE_INVALID != extMemHandle) {
        if (!updateExternalMemoryInfo(extMemHandle, &infoPtr->memReqs, &infoPtr->memory)) {
            ERR("Failed to update external memory info for ColorBuffer: %d\n", colorBufferHandle);
            return false;
        }
        if (useDedicated) {
            if (!importExternalMemoryDedicatedImage(vk, sVkEmulation->device, &infoPtr->memory,
                                                    *dedicatedImage, &infoPtr->memory.memory)) {
                ERR("Failed to import external memory with dedicated Image for colorBuffer: %d\n",
                    colorBufferHandle);
                return false;
            }
        } else if (!importExternalMemory(vk, sVkEmulation->device, &infoPtr->memory,
                                         &infoPtr->memory.memory)) {
            ERR("Failed to import external memory for colorBuffer: %d\n", colorBufferHandle);
            return false;
        }

        infoPtr->externalMemoryCompatible = true;
    } else {
        bool isHostVisible = infoPtr->memoryProperty & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
        Optional<uint64_t> deviceAlignment =
            isHostVisible ? Optional<uint64_t>(infoPtr->memReqs.alignment) : kNullopt;
        bool allocRes = allocExternalMemory(vk, &infoPtr->memory, true /*actuallyExternal*/,
                                            deviceAlignment, kNullopt, dedicatedImage);
        if (!allocRes) {
            ERR("Failed to allocate ColorBuffer with Vulkan backing.");
            return false;
        }

        infoPtr->externalMemoryCompatible = sVkEmulation->deviceInfo.supportsExternalMemoryExport;
    }

    infoPtr->memory.pageOffset = reinterpret_cast<uint64_t>(infoPtr->memory.mappedPtr) % kPageSize;
    infoPtr->memory.bindOffset =
        infoPtr->memory.pageOffset ? kPageSize - infoPtr->memory.pageOffset : 0u;

    VkResult bindImageMemoryRes = vk->vkBindImageMemory(
        sVkEmulation->device, infoPtr->image, infoPtr->memory.memory, infoPtr->memory.bindOffset);

    if (bindImageMemoryRes != VK_SUCCESS) {
        ERR("Failed to bind image memory. Error: %s", string_VkResult(bindImageMemoryRes));
        return false;
    }

    const VkImageViewCreateInfo imageViewCi = {
        .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
        .pNext = nullptr,
        .flags = 0,
        .image = infoPtr->image,
        .viewType = VK_IMAGE_VIEW_TYPE_2D,
        .format = infoPtr->imageCreateInfoShallow.format,
        .components =
            {
                .r = VK_COMPONENT_SWIZZLE_IDENTITY,
                .g = VK_COMPONENT_SWIZZLE_IDENTITY,
                .b = VK_COMPONENT_SWIZZLE_IDENTITY,
                .a = VK_COMPONENT_SWIZZLE_IDENTITY,
            },
        .subresourceRange =
            {
                .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
                .baseMipLevel = 0,
                .levelCount = 1,
                .baseArrayLayer = 0,
                .layerCount = 1,
            },
    };
    createRes =
        vk->vkCreateImageView(sVkEmulation->device, &imageViewCi, nullptr, &infoPtr->imageView);
    if (createRes != VK_SUCCESS) {
        VERBOSE("Failed to create Vulkan image view for ColorBuffer %d, Error: %s",
                colorBufferHandle, string_VkResult(createRes));
        return false;
    }

#if defined(__APPLE__)
    if (sVkEmulation->instanceSupportsMoltenVK) {
        // Retrieve metal texture for this image
        infoPtr->mtlTexture = getMtlTextureFromVkImage(vk, infoPtr->image);
        CFRetain(infoPtr->mtlTexture);
    }
#endif

    sVkEmulation->debugUtilsHelper.addDebugLabel(infoPtr->image, "ColorBuffer:%d",
                                                 colorBufferHandle);
    sVkEmulation->debugUtilsHelper.addDebugLabel(infoPtr->imageView, "ColorBuffer:%d",
                                                 colorBufferHandle);
    sVkEmulation->debugUtilsHelper.addDebugLabel(infoPtr->memory.memory, "ColorBuffer:%d",
                                                 colorBufferHandle);

    infoPtr->initialized = true;

    return true;
}

static bool createVkColorBufferLocked(uint32_t width, uint32_t height, GLenum internalFormat,
                                      FrameworkFormat frameworkFormat, uint32_t colorBufferHandle,
                                      bool vulkanOnly, uint32_t memoryProperty) {
    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
    // Already initialized
    if (infoPtr) {
        return true;
    }

    VkEmulation::ColorBufferInfo res;

    res.handle = colorBufferHandle;
    res.width = width;
    res.height = height;
    res.memoryProperty = memoryProperty;
    res.internalFormat = internalFormat;
    res.frameworkFormat = frameworkFormat;
    res.frameworkStride = 0;

    if (vulkanOnly) {
        res.vulkanMode = VkEmulation::VulkanMode::VulkanOnly;
    }

    sVkEmulation->colorBuffers[colorBufferHandle] = res;
    return true;
}

bool createVkColorBuffer(uint32_t width, uint32_t height, GLenum internalFormat,
                         FrameworkFormat frameworkFormat, uint32_t colorBufferHandle,
                         bool vulkanOnly, uint32_t memoryProperty) {
    if (!sVkEmulation || !sVkEmulation->live) {
        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "VkEmulation not available.";
    }

    AutoLock lock(sVkEmulationLock);
    if (!createVkColorBufferLocked(width, height, internalFormat, frameworkFormat,
                                   colorBufferHandle, vulkanOnly, memoryProperty)) {
        return false;
    }

    const auto& deviceInfo = sVkEmulation->deviceInfo;
    if (!deviceInfo.supportsExternalMemoryExport && deviceInfo.supportsExternalMemoryImport) {
        /* Returns, deferring initialization of the Vulkan components themselves.
         * Platforms that support import but not export of external memory must
         * use importExtMemoryHandleToVkColorBuffer(). Otherwise, the colorBuffer
         * memory can not be externalized.
         */
        return true;
    }

    return initializeVkColorBufferLocked(colorBufferHandle);
}

std::optional<VkColorBufferMemoryExport> exportColorBufferMemory(uint32_t colorBufferHandle) {
    if (!sVkEmulation || !sVkEmulation->live) {
        return std::nullopt;
    }

    AutoLock lock(sVkEmulationLock);

    const auto& deviceInfo = sVkEmulation->deviceInfo;
    if ((!(deviceInfo.supportsExternalMemoryExport || !deviceInfo.supportsExternalMemoryImport)) ||
        (!deviceInfo.glInteropSupported)) {
        return std::nullopt;
    }

    auto info = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
    if (!info) {
        return std::nullopt;
    }

    if (info->frameworkFormat != FRAMEWORK_FORMAT_GL_COMPATIBLE) {
        return std::nullopt;
    }

#if !defined(__QNX__)
    ManagedDescriptor descriptor(dupExternalMemory(info->memory.externalHandle));

    info->glExported = true;

    return VkColorBufferMemoryExport{
        .descriptor = std::move(descriptor),
        .size = info->memory.size,
        .streamHandleType = info->memory.streamHandleType,
        .linearTiling = info->imageCreateInfoShallow.tiling == VK_IMAGE_TILING_LINEAR,
        .dedicatedAllocation = info->memory.dedicatedAllocation,
    };
#else
    return std::nullopt;
#endif
}

bool teardownVkColorBufferLocked(uint32_t colorBufferHandle) {
    if (!sVkEmulation || !sVkEmulation->live) return false;

    auto vk = sVkEmulation->dvk;

    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);

    if (!infoPtr) return false;

    if (infoPtr->initialized) {
        auto& info = *infoPtr;
        {
            android::base::AutoLock lock(*sVkEmulation->queueLock);
            VK_CHECK(vk->vkQueueWaitIdle(sVkEmulation->queue));
        }
        vk->vkDestroyImageView(sVkEmulation->device, info.imageView, nullptr);
        vk->vkDestroyImage(sVkEmulation->device, info.image, nullptr);
        freeExternalMemoryLocked(vk, &info.memory);

#ifdef __APPLE__
        if (info.mtlTexture) {
            CFRelease(info.mtlTexture);
        }
#endif
    }

    sVkEmulation->colorBuffers.erase(colorBufferHandle);

    return true;
}

bool teardownVkColorBuffer(uint32_t colorBufferHandle) {
    if (!sVkEmulation || !sVkEmulation->live) return false;

    AutoLock lock(sVkEmulationLock);
    return teardownVkColorBufferLocked(colorBufferHandle);
}

bool importExtMemoryHandleToVkColorBuffer(uint32_t colorBufferHandle, uint32_t type,
                                          VK_EXT_MEMORY_HANDLE extMemHandle) {
    if (!sVkEmulation || !sVkEmulation->live) {
        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "VkEmulation not available.";
    }
    if (VK_EXT_MEMORY_HANDLE_INVALID == extMemHandle) {
        return false;
    }

    AutoLock lock(sVkEmulationLock);
    // Initialize the colorBuffer with the external memory handle
    // Note that this will fail if the colorBuffer memory was previously initialized.
    return initializeVkColorBufferLocked(colorBufferHandle, extMemHandle);
}

VkEmulation::ColorBufferInfo getColorBufferInfo(uint32_t colorBufferHandle) {
    VkEmulation::ColorBufferInfo res;

    AutoLock lock(sVkEmulationLock);

    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);

    if (!infoPtr) return res;

    res = *infoPtr;
    return res;
}

bool colorBufferNeedsUpdateBetweenGlAndVk(const VkEmulation::ColorBufferInfo& colorBufferInfo) {
    // GL is not used.
    if (colorBufferInfo.vulkanMode == VkEmulation::VulkanMode::VulkanOnly) {
        return false;
    }

    // YUV formats require extra conversions.
    if (colorBufferInfo.frameworkFormat != FrameworkFormat::FRAMEWORK_FORMAT_GL_COMPATIBLE) {
        return true;
    }

    // GL and VK are sharing the same underlying memory.
    if (colorBufferInfo.glExported) {
        return false;
    }

    return true;
}

bool colorBufferNeedsUpdateBetweenGlAndVk(uint32_t colorBufferHandle) {
    if (!sVkEmulation || !sVkEmulation->live) {
        return false;
    }

    AutoLock lock(sVkEmulationLock);

    auto colorBufferInfo = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
    if (!colorBufferInfo) {
        return false;
    }

    return colorBufferNeedsUpdateBetweenGlAndVk(*colorBufferInfo);
}

bool readColorBufferToBytes(uint32_t colorBufferHandle, std::vector<uint8_t>* bytes) {
    if (!sVkEmulation || !sVkEmulation->live) {
        VERBOSE("VkEmulation not available.");
        return false;
    }

    AutoLock lock(sVkEmulationLock);

    auto colorBufferInfo = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
    if (!colorBufferInfo) {
        VERBOSE("Failed to read from ColorBuffer:%d, not found.", colorBufferHandle);
        bytes->clear();
        return false;
    }

    VkDeviceSize bytesNeeded = 0;
    bool result = getFormatTransferInfo(colorBufferInfo->imageCreateInfoShallow.format,
                                        colorBufferInfo->imageCreateInfoShallow.extent.width,
                                        colorBufferInfo->imageCreateInfoShallow.extent.height,
                                        &bytesNeeded, nullptr);
    if (!result) {
        ERR("Failed to read from ColorBuffer:%d, failed to get read size.", colorBufferHandle);
        return false;
    }

    bytes->resize(bytesNeeded);

    result = readColorBufferToBytesLocked(
        colorBufferHandle, 0, 0, colorBufferInfo->imageCreateInfoShallow.extent.width,
        colorBufferInfo->imageCreateInfoShallow.extent.height, bytes->data());
    if (!result) {
        ERR("Failed to read from ColorBuffer:%d, failed to get read size.", colorBufferHandle);
        return false;
    }

    return true;
}

bool readColorBufferToBytes(uint32_t colorBufferHandle, uint32_t x, uint32_t y, uint32_t w,
                            uint32_t h, void* outPixels) {
    if (!sVkEmulation || !sVkEmulation->live) {
        ERR("VkEmulation not available.");
        return false;
    }

    AutoLock lock(sVkEmulationLock);
    return readColorBufferToBytesLocked(colorBufferHandle, x, y, w, h, outPixels);
}

bool readColorBufferToBytesLocked(uint32_t colorBufferHandle, uint32_t x, uint32_t y, uint32_t w,
                                  uint32_t h, void* outPixels) {
    if (!sVkEmulation || !sVkEmulation->live) {
        ERR("VkEmulation not available.");
        return false;
    }

    auto vk = sVkEmulation->dvk;

    auto colorBufferInfo = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
    if (!colorBufferInfo) {
        ERR("Failed to read from ColorBuffer:%d, not found.", colorBufferHandle);
        return false;
    }

    if (!colorBufferInfo->image) {
        ERR("Failed to read from ColorBuffer:%d, no VkImage.", colorBufferHandle);
        return false;
    }

    if (x != 0 || y != 0 || w != colorBufferInfo->imageCreateInfoShallow.extent.width ||
        h != colorBufferInfo->imageCreateInfoShallow.extent.height) {
        ERR("Failed to read from ColorBuffer:%d, unhandled subrect.", colorBufferHandle);
        return false;
    }

    VkDeviceSize bufferCopySize = 0;
    std::vector<VkBufferImageCopy> bufferImageCopies;
    if (!getFormatTransferInfo(colorBufferInfo->imageCreateInfoShallow.format,
                               colorBufferInfo->imageCreateInfoShallow.extent.width,
                               colorBufferInfo->imageCreateInfoShallow.extent.height,
                               &bufferCopySize, &bufferImageCopies)) {
        ERR("Failed to read ColorBuffer:%d, unable to get transfer info.", colorBufferHandle);
        return false;
    }

    // Avoid transitioning from VK_IMAGE_LAYOUT_UNDEFINED. Unfortunetly, Android does not
    // yet have a mechanism for sharing the expected VkImageLayout. However, the Vulkan
    // spec's image layout transition sections says "If the old layout is
    // VK_IMAGE_LAYOUT_UNDEFINED, the contents of that range may be discarded." Some
    // Vulkan drivers have been observed to actually perform the discard which leads to
    // ColorBuffer-s being unintentionally cleared. See go/ahb-vkimagelayout for a more
    // thorough write up.
    if (colorBufferInfo->currentLayout == VK_IMAGE_LAYOUT_UNDEFINED) {
        colorBufferInfo->currentLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
    }

    // Record our synchronization commands.
    const VkCommandBufferBeginInfo beginInfo = {
        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
        .pNext = nullptr,
        .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
    };

    VkCommandBuffer commandBuffer = sVkEmulation->commandBuffer;

    VK_CHECK(vk->vkBeginCommandBuffer(commandBuffer, &beginInfo));

    sVkEmulation->debugUtilsHelper.cmdBeginDebugLabel(
        commandBuffer, "readColorBufferToBytes(ColorBuffer:%d)", colorBufferHandle);

    VkImageLayout currentLayout = colorBufferInfo->currentLayout;
    VkImageLayout transferSrcLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;

    const VkImageMemoryBarrier toTransferSrcImageBarrier = {
        .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
        .pNext = nullptr,
        .srcAccessMask = 0,
        .dstAccessMask = VK_ACCESS_HOST_READ_BIT,
        .oldLayout = currentLayout,
        .newLayout = transferSrcLayout,
        .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
        .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
        .image = colorBufferInfo->image,
        .subresourceRange =
            {
                .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
                .baseMipLevel = 0,
                .levelCount = 1,
                .baseArrayLayer = 0,
                .layerCount = 1,
            },
    };

    vk->vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
                             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
                             &toTransferSrcImageBarrier);

    vk->vkCmdCopyImageToBuffer(commandBuffer, colorBufferInfo->image,
                               VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, sVkEmulation->staging.buffer,
                               bufferImageCopies.size(), bufferImageCopies.data());

    // Change back to original layout
    if (currentLayout != VK_IMAGE_LAYOUT_UNDEFINED) {
        // Transfer back to original layout.
        const VkImageMemoryBarrier toCurrentLayoutImageBarrier = {
            .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
            .pNext = nullptr,
            .srcAccessMask = VK_ACCESS_HOST_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
            .dstAccessMask = VK_ACCESS_NONE_KHR,
            .oldLayout = transferSrcLayout,
            .newLayout = colorBufferInfo->currentLayout,
            .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
            .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
            .image = colorBufferInfo->image,
            .subresourceRange =
                {
                    .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
                    .baseMipLevel = 0,
                    .levelCount = 1,
                    .baseArrayLayer = 0,
                    .layerCount = 1,
                },
        };
        vk->vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
                                 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
                                 &toCurrentLayoutImageBarrier);
    } else {
        colorBufferInfo->currentLayout = transferSrcLayout;
    }

    sVkEmulation->debugUtilsHelper.cmdEndDebugLabel(commandBuffer);

    VK_CHECK(vk->vkEndCommandBuffer(commandBuffer));

    const VkSubmitInfo submitInfo = {
        .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
        .pNext = nullptr,
        .waitSemaphoreCount = 0,
        .pWaitSemaphores = nullptr,
        .pWaitDstStageMask = nullptr,
        .commandBufferCount = 1,
        .pCommandBuffers = &commandBuffer,
        .signalSemaphoreCount = 0,
        .pSignalSemaphores = nullptr,
    };

    {
        android::base::AutoLock lock(*sVkEmulation->queueLock);
        VK_CHECK(vk->vkQueueSubmit(sVkEmulation->queue, 1, &submitInfo,
                                   sVkEmulation->commandBufferFence));
    }

    static constexpr uint64_t ANB_MAX_WAIT_NS = 5ULL * 1000ULL * 1000ULL * 1000ULL;

    VK_CHECK(vk->vkWaitForFences(sVkEmulation->device, 1, &sVkEmulation->commandBufferFence,
                                 VK_TRUE, ANB_MAX_WAIT_NS));

    VK_CHECK(vk->vkResetFences(sVkEmulation->device, 1, &sVkEmulation->commandBufferFence));

    const VkMappedMemoryRange toInvalidate = {
        .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
        .pNext = nullptr,
        .memory = sVkEmulation->staging.memory.memory,
        .offset = 0,
        .size = VK_WHOLE_SIZE,
    };

    VK_CHECK(vk->vkInvalidateMappedMemoryRanges(sVkEmulation->device, 1, &toInvalidate));

    const auto* stagingBufferPtr = sVkEmulation->staging.memory.mappedPtr;
    std::memcpy(outPixels, stagingBufferPtr, bufferCopySize);

    return true;
}

bool updateColorBufferFromBytes(uint32_t colorBufferHandle, const std::vector<uint8_t>& bytes) {
    if (!sVkEmulation || !sVkEmulation->live) {
        VERBOSE("VkEmulation not available.");
        return false;
    }

    AutoLock lock(sVkEmulationLock);

    auto colorBufferInfo = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
    if (!colorBufferInfo) {
        VERBOSE("Failed to update ColorBuffer:%d, not found.", colorBufferHandle);
        return false;
    }

    return updateColorBufferFromBytesLocked(
        colorBufferHandle, 0, 0, colorBufferInfo->imageCreateInfoShallow.extent.width,
        colorBufferInfo->imageCreateInfoShallow.extent.height, bytes.data(), bytes.size());
}

bool updateColorBufferFromBytes(uint32_t colorBufferHandle, uint32_t x, uint32_t y, uint32_t w,
                                uint32_t h, const void* pixels) {
    if (!sVkEmulation || !sVkEmulation->live) {
        ERR("VkEmulation not available.");
        return false;
    }

    AutoLock lock(sVkEmulationLock);
    return updateColorBufferFromBytesLocked(colorBufferHandle, x, y, w, h, pixels, 0);
}

static void convertRgbToRgbaPixels(void* dst, const void* src, uint32_t w, uint32_t h) {
    const size_t pixelCount = w * h;
    const uint8_t* srcBytes = reinterpret_cast<const uint8_t*>(src);
    uint32_t* dstPixels = reinterpret_cast<uint32_t*>(dst);
    for (size_t i = 0; i < pixelCount; ++i) {
        const uint8_t r = *(srcBytes++);
        const uint8_t g = *(srcBytes++);
        const uint8_t b = *(srcBytes++);
        *(dstPixels++) = 0xff000000 | (b << 16) | (g << 8) | r;
    }
}

static bool updateColorBufferFromBytesLocked(uint32_t colorBufferHandle, uint32_t x, uint32_t y,
                                             uint32_t w, uint32_t h, const void* pixels,
                                             size_t inputPixelsSize) {
    if (!sVkEmulation || !sVkEmulation->live) {
        ERR("VkEmulation not available.");
        return false;
    }

    auto vk = sVkEmulation->dvk;

    auto colorBufferInfo = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
    if (!colorBufferInfo) {
        ERR("Failed to update ColorBuffer:%d, not found.", colorBufferHandle);
        return false;
    }

    if (!colorBufferInfo->image) {
        ERR("Failed to update ColorBuffer:%d, no VkImage.", colorBufferHandle);
        return false;
    }

    if (x != 0 || y != 0 || w != colorBufferInfo->imageCreateInfoShallow.extent.width ||
        h != colorBufferInfo->imageCreateInfoShallow.extent.height) {
        ERR("Failed to update ColorBuffer:%d, unhandled subrect.", colorBufferHandle);
        return false;
    }

    VkDeviceSize dstBufferSize = 0;
    std::vector<VkBufferImageCopy> bufferImageCopies;
    if (!getFormatTransferInfo(colorBufferInfo->imageCreateInfoShallow.format,
                               colorBufferInfo->imageCreateInfoShallow.extent.width,
                               colorBufferInfo->imageCreateInfoShallow.extent.height,
                               &dstBufferSize, &bufferImageCopies)) {
        ERR("Failed to update ColorBuffer:%d, unable to get transfer info.", colorBufferHandle);
        return false;
    }

    const VkDeviceSize stagingBufferSize = sVkEmulation->staging.size;
    if (dstBufferSize > stagingBufferSize) {
        ERR("Failed to update ColorBuffer:%d, transfer size %" PRIu64
            " too large for staging buffer size:%" PRIu64 ".",
            colorBufferHandle, dstBufferSize, stagingBufferSize);
        return false;
    }

    bool isThreeByteRgb =
        (colorBufferInfo->internalFormat == GL_RGB || colorBufferInfo->internalFormat == GL_RGB8);
    size_t expectedInputSize = (isThreeByteRgb ? dstBufferSize / 4 * 3 : dstBufferSize);

    if (inputPixelsSize != 0 && inputPixelsSize != expectedInputSize) {
        ERR("Unexpected contents size when trying to update ColorBuffer:%d, "
            "provided:%zu expected:%zu",
            colorBufferHandle, inputPixelsSize, expectedInputSize);
        return false;
    }

    auto* stagingBufferPtr = sVkEmulation->staging.memory.mappedPtr;

    if (isThreeByteRgb) {
        // Convert RGB to RGBA, since only for these types glFormat2VkFormat() makes
        // an incompatible choice of 4-byte backing VK_FORMAT_R8G8B8A8_UNORM.
        // b/281550953
        convertRgbToRgbaPixels(stagingBufferPtr, pixels, w, h);
    } else {
        std::memcpy(stagingBufferPtr, pixels, dstBufferSize);
    }

    // NOTE: Host vulkan state might not know the correct layout of the
    // destination image, as guest grallocs are designed to be used by either
    // GL or Vulkan. Consequently, we typically avoid image transitions from
    // VK_IMAGE_LAYOUT_UNDEFINED as Vulkan spec allows the contents to be
    // discarded (and some drivers have been observed doing it). You can
    // check go/ahb-vkimagelayout for more information. But since this
    // function does not allow subrects (see above), it will write the
    // provided contents onto the entirety of the target buffer, meaning this
    // risk of discarding data should not impact anything.

    // Record our synchronization commands.
    const VkCommandBufferBeginInfo beginInfo = {
        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
        .pNext = nullptr,
        .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
    };

    VkCommandBuffer commandBuffer = sVkEmulation->commandBuffer;

    VK_CHECK(vk->vkBeginCommandBuffer(commandBuffer, &beginInfo));

    sVkEmulation->debugUtilsHelper.cmdBeginDebugLabel(
        commandBuffer, "updateColorBufferFromBytes(ColorBuffer:%d)", colorBufferHandle);

    bool isSnapshotLoad =
        VkDecoderGlobalState::get()->getSnapshotState() == VkDecoderGlobalState::Loading;
    VkImageLayout currentLayout = colorBufferInfo->currentLayout;
    if (isSnapshotLoad) {
        currentLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    }
    const VkImageMemoryBarrier toTransferDstImageBarrier = {
        .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
        .pNext = nullptr,
        .srcAccessMask = 0,
        .dstAccessMask = VK_ACCESS_HOST_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
        .oldLayout = currentLayout,
        .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
        .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
        .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
        .image = colorBufferInfo->image,
        .subresourceRange =
            {
                .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
                .baseMipLevel = 0,
                .levelCount = 1,
                .baseArrayLayer = 0,
                .layerCount = 1,
            },
    };

    vk->vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
                             VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 0, nullptr, 1,
                             &toTransferDstImageBarrier);

    // Copy from staging buffer to color buffer image
    vk->vkCmdCopyBufferToImage(commandBuffer, sVkEmulation->staging.buffer, colorBufferInfo->image,
                               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, bufferImageCopies.size(),
                               bufferImageCopies.data());

    if (colorBufferInfo->currentLayout != VK_IMAGE_LAYOUT_UNDEFINED) {
        const VkImageMemoryBarrier toCurrentLayoutImageBarrier = {
            .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
            .pNext = nullptr,
            .srcAccessMask = VK_ACCESS_HOST_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
            .dstAccessMask = VK_ACCESS_NONE_KHR,
            .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
            .newLayout = colorBufferInfo->currentLayout,
            .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
            .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
            .image = colorBufferInfo->image,
            .subresourceRange =
                {
                    .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
                    .baseMipLevel = 0,
                    .levelCount = 1,
                    .baseArrayLayer = 0,
                    .layerCount = 1,
                },
        };
        vk->vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_HOST_BIT,
                                 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1,
                                 &toCurrentLayoutImageBarrier);
    } else {
        colorBufferInfo->currentLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
    }

    sVkEmulation->debugUtilsHelper.cmdEndDebugLabel(commandBuffer);

    VK_CHECK(vk->vkEndCommandBuffer(commandBuffer));

    const VkSubmitInfo submitInfo = {
        .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
        .pNext = nullptr,
        .waitSemaphoreCount = 0,
        .pWaitSemaphores = nullptr,
        .pWaitDstStageMask = nullptr,
        .commandBufferCount = 1,
        .pCommandBuffers = &commandBuffer,
        .signalSemaphoreCount = 0,
        .pSignalSemaphores = nullptr,
    };

    {
        android::base::AutoLock lock(*sVkEmulation->queueLock);
        VK_CHECK(vk->vkQueueSubmit(sVkEmulation->queue, 1, &submitInfo,
                                   sVkEmulation->commandBufferFence));
    }

    static constexpr uint64_t ANB_MAX_WAIT_NS = 5ULL * 1000ULL * 1000ULL * 1000ULL;

    VK_CHECK(vk->vkWaitForFences(sVkEmulation->device, 1, &sVkEmulation->commandBufferFence,
                                 VK_TRUE, ANB_MAX_WAIT_NS));

    VK_CHECK(vk->vkResetFences(sVkEmulation->device, 1, &sVkEmulation->commandBufferFence));

    const VkMappedMemoryRange toInvalidate = {
        .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
        .pNext = nullptr,
        .memory = sVkEmulation->staging.memory.memory,
        .offset = 0,
        .size = VK_WHOLE_SIZE,
    };
    VK_CHECK(vk->vkInvalidateMappedMemoryRanges(sVkEmulation->device, 1, &toInvalidate));

    return true;
}

VK_EXT_MEMORY_HANDLE getColorBufferExtMemoryHandle(uint32_t colorBuffer) {
    if (!sVkEmulation || !sVkEmulation->live) return VK_EXT_MEMORY_HANDLE_INVALID;

    AutoLock lock(sVkEmulationLock);

    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBuffer);

    if (!infoPtr) {
        // Color buffer not found; this is usually OK.
        return VK_EXT_MEMORY_HANDLE_INVALID;
    }

    return infoPtr->memory.externalHandle;
}

#ifdef __APPLE__
MTLBufferRef getColorBufferMetalMemoryHandle(uint32_t colorBuffer) {
    if (!sVkEmulation || !sVkEmulation->live) return nullptr;

    AutoLock lock(sVkEmulationLock);

    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBuffer);

    if (!infoPtr) {
        // Color buffer not found; this is usually OK.
        return nullptr;
    }

    return infoPtr->memory.externalMetalHandle;
}

MTLTextureRef getColorBufferMTLTexture(uint32_t colorBufferHandle) {
    if (!sVkEmulation || !sVkEmulation->live) return nullptr;

    AutoLock lock(sVkEmulationLock);

    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);

    if (!infoPtr) {
        // Color buffer not found; this is usually OK.
        return nullptr;
    }

    CFRetain(infoPtr->mtlTexture);
    return infoPtr->mtlTexture;
}

// TODO(b/333460957): Temporary function for MoltenVK
VkImage getColorBufferVkImage(uint32_t colorBufferHandle) {
    if (!sVkEmulation || !sVkEmulation->live) return nullptr;

    AutoLock lock(sVkEmulationLock);

    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);

    if (!infoPtr) {
        // Color buffer not found; this is usually OK.
        return nullptr;
    }

    return infoPtr->image;
}
#endif  // __APPLE__

bool setColorBufferVulkanMode(uint32_t colorBuffer, uint32_t vulkanMode) {
    if (!sVkEmulation || !sVkEmulation->live) return false;

    AutoLock lock(sVkEmulationLock);

    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBuffer);

    if (!infoPtr) {
        return false;
    }

    infoPtr->vulkanMode = static_cast<VkEmulation::VulkanMode>(vulkanMode);

    return true;
}

int32_t mapGpaToBufferHandle(uint32_t bufferHandle, uint64_t gpa, uint64_t size) {
    if (!sVkEmulation || !sVkEmulation->live) return VK_ERROR_DEVICE_LOST;

    AutoLock lock(sVkEmulationLock);

    VkEmulation::ExternalMemoryInfo* memoryInfoPtr = nullptr;

    auto colorBufferInfoPtr = android::base::find(sVkEmulation->colorBuffers, bufferHandle);
    if (colorBufferInfoPtr) {
        memoryInfoPtr = &colorBufferInfoPtr->memory;
    }
    auto bufferInfoPtr = android::base::find(sVkEmulation->buffers, bufferHandle);
    if (bufferInfoPtr) {
        memoryInfoPtr = &bufferInfoPtr->memory;
    }

    if (!memoryInfoPtr) {
        return VK_ERROR_INVALID_EXTERNAL_HANDLE;
    }

    // memory should be already mapped to host.
    if (!memoryInfoPtr->mappedPtr) {
        return VK_ERROR_MEMORY_MAP_FAILED;
    }

    memoryInfoPtr->gpa = gpa;
    memoryInfoPtr->pageAlignedHva =
        reinterpret_cast<uint8_t*>(memoryInfoPtr->mappedPtr) + memoryInfoPtr->bindOffset;

    size_t rawSize = memoryInfoPtr->size + memoryInfoPtr->pageOffset;
    if (size && size < rawSize) {
        rawSize = size;
    }

    memoryInfoPtr->sizeToPage = ((rawSize + kPageSize - 1) >> kPageBits) << kPageBits;

    VERBOSE("mapGpaToColorBuffer: hva = %p, pageAlignedHva = %p -> [ 0x%" PRIxPTR ", 0x%" PRIxPTR
            " ]",
            memoryInfoPtr->mappedPtr, memoryInfoPtr->pageAlignedHva, memoryInfoPtr->gpa,
            memoryInfoPtr->gpa + memoryInfoPtr->sizeToPage);

    if (sVkEmulation->occupiedGpas.find(gpa) != sVkEmulation->occupiedGpas.end()) {
        // emugl::emugl_crash_reporter("FATAL: already mapped gpa 0x%lx! ", gpa);
        return VK_ERROR_MEMORY_MAP_FAILED;
    }

    get_emugl_vm_operations().mapUserBackedRam(gpa, memoryInfoPtr->pageAlignedHva,
                                               memoryInfoPtr->sizeToPage);

    sVkEmulation->occupiedGpas.insert(gpa);

    return memoryInfoPtr->pageOffset;
}

bool getBufferAllocationInfo(uint32_t bufferHandle, VkDeviceSize* outSize,
                             uint32_t* outMemoryTypeIndex, bool* outMemoryIsDedicatedAlloc) {
    if (!sVkEmulation || !sVkEmulation->live) {
        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Vulkan emulation not available.";
    }

    AutoLock lock(sVkEmulationLock);

    auto info = android::base::find(sVkEmulation->buffers, bufferHandle);
    if (!info) {
        return false;
    }

    if (outSize) {
        *outSize = info->memory.size;
    }

    if (outMemoryTypeIndex) {
        *outMemoryTypeIndex = info->memory.typeIndex;
    }

    if (outMemoryIsDedicatedAlloc) {
        *outMemoryIsDedicatedAlloc = info->memory.dedicatedAllocation;
    }

    return true;
}

bool setupVkBuffer(uint64_t size, uint32_t bufferHandle, bool vulkanOnly, uint32_t memoryProperty) {
    if (vulkanOnly == false) {
        ERR("Data buffers should be vulkanOnly. Setup failed.");
        return false;
    }

    auto vk = sVkEmulation->dvk;

    AutoLock lock(sVkEmulationLock);

    auto infoPtr = android::base::find(sVkEmulation->buffers, bufferHandle);

    // Already setup
    if (infoPtr) {
        return true;
    }

    VkEmulation::BufferInfo res;

    res.handle = bufferHandle;

    res.size = size;
    res.usageFlags = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
                     VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT |
                     VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
    res.createFlags = 0;

    res.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

    // Create the buffer. If external memory is supported, make it external.
    VkExternalMemoryBufferCreateInfo extBufferCi = {
        VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
        0,
        VK_EXT_MEMORY_HANDLE_TYPE_BIT,
    };
    void* extBufferCiPtr = nullptr;
    if (sVkEmulation->deviceInfo.supportsExternalMemoryImport ||
        sVkEmulation->deviceInfo.supportsExternalMemoryExport) {
        extBufferCiPtr = &extBufferCi;
    }

    VkBufferCreateInfo bufferCi = {
        VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
        extBufferCiPtr,
        res.createFlags,
        res.size,
        res.usageFlags,
        res.sharingMode,
        /* queueFamilyIndexCount */ 0,
        /* pQueueFamilyIndices */ nullptr,
    };

    VkResult createRes = vk->vkCreateBuffer(sVkEmulation->device, &bufferCi, nullptr, &res.buffer);

    if (createRes != VK_SUCCESS) {
        WARN("Failed to create Vulkan Buffer for Buffer %d, Error: %s", bufferHandle,
             string_VkResult(createRes));
        return false;
    }
    bool useDedicated = false;
    if (vk->vkGetBufferMemoryRequirements2KHR) {
        VkMemoryDedicatedRequirements dedicated_reqs{
            VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, nullptr};
        VkMemoryRequirements2 reqs{VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, &dedicated_reqs};

        VkBufferMemoryRequirementsInfo2 info{VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
                                             nullptr, res.buffer};
        vk->vkGetBufferMemoryRequirements2KHR(sVkEmulation->device, &info, &reqs);
        useDedicated = dedicated_reqs.requiresDedicatedAllocation;
        res.memReqs = reqs.memoryRequirements;
    } else {
        vk->vkGetBufferMemoryRequirements(sVkEmulation->device, res.buffer, &res.memReqs);
    }

    // Currently we only care about two memory properties: DEVICE_LOCAL
    // and HOST_VISIBLE; other memory properties specified in
    // rcSetColorBufferVulkanMode2() call will be ignored for now.
    memoryProperty = memoryProperty &
                     (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);

    res.memory.size = res.memReqs.size;

    // Determine memory type.
    res.memory.typeIndex = getValidMemoryTypeIndex(res.memReqs.memoryTypeBits, memoryProperty);

    VERBOSE(
        "Buffer %d "
        "allocation size and type index: %lu, %d, "
        "allocated memory property: %d, "
        "requested memory property: %d",
        bufferHandle, res.memory.size, res.memory.typeIndex,
        sVkEmulation->deviceInfo.memProps.memoryTypes[res.memory.typeIndex].propertyFlags,
        memoryProperty);

    bool isHostVisible = memoryProperty & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
    Optional<uint64_t> deviceAlignment =
        isHostVisible ? Optional<uint64_t>(res.memReqs.alignment) : kNullopt;
    Optional<VkBuffer> dedicated_buffer = useDedicated ? Optional<VkBuffer>(res.buffer) : kNullopt;
    bool allocRes = allocExternalMemory(vk, &res.memory, true /* actuallyExternal */,
                                        deviceAlignment, dedicated_buffer);

    if (!allocRes) {
        WARN("Failed to allocate ColorBuffer with Vulkan backing.");
    }

    res.memory.pageOffset = reinterpret_cast<uint64_t>(res.memory.mappedPtr) % kPageSize;
    res.memory.bindOffset = res.memory.pageOffset ? kPageSize - res.memory.pageOffset : 0u;

    VkResult bindBufferMemoryRes =
        vk->vkBindBufferMemory(sVkEmulation->device, res.buffer, res.memory.memory, 0);

    if (bindBufferMemoryRes != VK_SUCCESS) {
        ERR("Failed to bind buffer memory. Error: %s\n", string_VkResult(bindBufferMemoryRes));
        return bindBufferMemoryRes;
    }

    bool isHostVisibleMemory = memoryProperty & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;

    if (isHostVisibleMemory) {
        VkResult mapMemoryRes = vk->vkMapMemory(sVkEmulation->device, res.memory.memory, 0,
                                                res.memory.size, {}, &res.memory.mappedPtr);

        if (mapMemoryRes != VK_SUCCESS) {
            ERR("Failed to map image memory. Error: %s\n", string_VkResult(mapMemoryRes));
            return false;
        }
    }

    res.glExported = false;

    sVkEmulation->buffers[bufferHandle] = res;

    sVkEmulation->debugUtilsHelper.addDebugLabel(res.buffer, "Buffer:%d", bufferHandle);
    sVkEmulation->debugUtilsHelper.addDebugLabel(res.memory.memory, "Buffer:%d", bufferHandle);

    return allocRes;
}

bool teardownVkBuffer(uint32_t bufferHandle) {
    if (!sVkEmulation || !sVkEmulation->live) return false;

    auto vk = sVkEmulation->dvk;
    AutoLock lock(sVkEmulationLock);

    auto infoPtr = android::base::find(sVkEmulation->buffers, bufferHandle);
    if (!infoPtr) return false;
    {
        android::base::AutoLock lock(*sVkEmulation->queueLock);
        VK_CHECK(vk->vkQueueWaitIdle(sVkEmulation->queue));
    }
    auto& info = *infoPtr;

    vk->vkDestroyBuffer(sVkEmulation->device, info.buffer, nullptr);
    freeExternalMemoryLocked(vk, &info.memory);
    sVkEmulation->buffers.erase(bufferHandle);

    return true;
}

VK_EXT_MEMORY_HANDLE getBufferExtMemoryHandle(uint32_t bufferHandle,
                                              uint32_t* outStreamHandleType) {
    if (!sVkEmulation || !sVkEmulation->live) return VK_EXT_MEMORY_HANDLE_INVALID;

    AutoLock lock(sVkEmulationLock);

    auto infoPtr = android::base::find(sVkEmulation->buffers, bufferHandle);
    if (!infoPtr) {
        // Color buffer not found; this is usually OK.
        return VK_EXT_MEMORY_HANDLE_INVALID;
    }

    *outStreamHandleType = infoPtr->memory.streamHandleType;
    return infoPtr->memory.externalHandle;
}

#ifdef __APPLE__
MTLBufferRef getBufferMetalMemoryHandle(uint32_t bufferHandle) {
    if (!sVkEmulation || !sVkEmulation->live) return nullptr;

    AutoLock lock(sVkEmulationLock);

    auto infoPtr = android::base::find(sVkEmulation->buffers, bufferHandle);
    if (!infoPtr) {
        // Color buffer not found; this is usually OK.
        return nullptr;
    }

    return infoPtr->memory.externalMetalHandle;
}
#endif

bool readBufferToBytes(uint32_t bufferHandle, uint64_t offset, uint64_t size, void* outBytes) {
    if (!sVkEmulation || !sVkEmulation->live) {
        ERR("VkEmulation not available.");
        return false;
    }

    auto vk = sVkEmulation->dvk;

    AutoLock lock(sVkEmulationLock);

    auto bufferInfo = android::base::find(sVkEmulation->buffers, bufferHandle);
    if (!bufferInfo) {
        ERR("Failed to read from Buffer:%d, not found.", bufferHandle);
        return false;
    }

    const auto& stagingBufferInfo = sVkEmulation->staging;
    if (size > stagingBufferInfo.size) {
        ERR("Failed to read from Buffer:%d, staging buffer too small.", bufferHandle);
        return false;
    }

    const VkCommandBufferBeginInfo beginInfo = {
        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
        .pNext = nullptr,
        .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
    };

    VkCommandBuffer commandBuffer = sVkEmulation->commandBuffer;

    VK_CHECK(vk->vkBeginCommandBuffer(commandBuffer, &beginInfo));

    sVkEmulation->debugUtilsHelper.cmdBeginDebugLabel(commandBuffer, "readBufferToBytes(Buffer:%d)",
                                                      bufferHandle);

    const VkBufferCopy bufferCopy = {
        .srcOffset = offset,
        .dstOffset = 0,
        .size = size,
    };
    vk->vkCmdCopyBuffer(commandBuffer, bufferInfo->buffer, stagingBufferInfo.buffer, 1,
                        &bufferCopy);

    sVkEmulation->debugUtilsHelper.cmdEndDebugLabel(commandBuffer);

    VK_CHECK(vk->vkEndCommandBuffer(commandBuffer));

    const VkSubmitInfo submitInfo = {
        .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
        .pNext = nullptr,
        .waitSemaphoreCount = 0,
        .pWaitSemaphores = nullptr,
        .pWaitDstStageMask = nullptr,
        .commandBufferCount = 1,
        .pCommandBuffers = &commandBuffer,
        .signalSemaphoreCount = 0,
        .pSignalSemaphores = nullptr,
    };

    {
        android::base::AutoLock lock(*sVkEmulation->queueLock);
        VK_CHECK(vk->vkQueueSubmit(sVkEmulation->queue, 1, &submitInfo,
                                   sVkEmulation->commandBufferFence));
    }

    static constexpr uint64_t ANB_MAX_WAIT_NS = 5ULL * 1000ULL * 1000ULL * 1000ULL;

    VK_CHECK(vk->vkWaitForFences(sVkEmulation->device, 1, &sVkEmulation->commandBufferFence,
                                 VK_TRUE, ANB_MAX_WAIT_NS));

    VK_CHECK(vk->vkResetFences(sVkEmulation->device, 1, &sVkEmulation->commandBufferFence));

    const VkMappedMemoryRange toInvalidate = {
        .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
        .pNext = nullptr,
        .memory = stagingBufferInfo.memory.memory,
        .offset = 0,
        .size = size,
    };

    VK_CHECK(vk->vkInvalidateMappedMemoryRanges(sVkEmulation->device, 1, &toInvalidate));

    const void* srcPtr = reinterpret_cast<const void*>(
        reinterpret_cast<const char*>(stagingBufferInfo.memory.mappedPtr));
    void* dstPtr = outBytes;
    void* dstPtrOffset = reinterpret_cast<void*>(reinterpret_cast<char*>(dstPtr) + offset);
    std::memcpy(dstPtrOffset, srcPtr, size);

    return true;
}

bool updateBufferFromBytes(uint32_t bufferHandle, uint64_t offset, uint64_t size,
                           const void* bytes) {
    if (!sVkEmulation || !sVkEmulation->live) {
        ERR("VkEmulation not available.");
        return false;
    }

    auto vk = sVkEmulation->dvk;

    AutoLock lock(sVkEmulationLock);

    auto bufferInfo = android::base::find(sVkEmulation->buffers, bufferHandle);
    if (!bufferInfo) {
        ERR("Failed to update Buffer:%d, not found.", bufferHandle);
        return false;
    }

    const auto& stagingBufferInfo = sVkEmulation->staging;
    if (size > stagingBufferInfo.size) {
        ERR("Failed to update Buffer:%d, staging buffer too small.", bufferHandle);
        return false;
    }

    const void* srcPtr = bytes;
    const void* srcPtrOffset =
        reinterpret_cast<const void*>(reinterpret_cast<const char*>(srcPtr) + offset);
    void* dstPtr = stagingBufferInfo.memory.mappedPtr;
    std::memcpy(dstPtr, srcPtrOffset, size);

    const VkMappedMemoryRange toFlush = {
        .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
        .pNext = nullptr,
        .memory = stagingBufferInfo.memory.memory,
        .offset = 0,
        .size = size,
    };
    VK_CHECK(vk->vkFlushMappedMemoryRanges(sVkEmulation->device, 1, &toFlush));

    const VkCommandBufferBeginInfo beginInfo = {
        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
        .pNext = nullptr,
        .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
    };

    VkCommandBuffer commandBuffer = sVkEmulation->commandBuffer;

    VK_CHECK(vk->vkBeginCommandBuffer(commandBuffer, &beginInfo));

    sVkEmulation->debugUtilsHelper.cmdBeginDebugLabel(
        commandBuffer, "updateBufferFromBytes(Buffer:%d)", bufferHandle);

    const VkBufferCopy bufferCopy = {
        .srcOffset = 0,
        .dstOffset = offset,
        .size = size,
    };
    vk->vkCmdCopyBuffer(commandBuffer, stagingBufferInfo.buffer, bufferInfo->buffer, 1,
                        &bufferCopy);

    sVkEmulation->debugUtilsHelper.cmdEndDebugLabel(commandBuffer);

    VK_CHECK(vk->vkEndCommandBuffer(commandBuffer));

    const VkSubmitInfo submitInfo = {
        .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
        .pNext = nullptr,
        .waitSemaphoreCount = 0,
        .pWaitSemaphores = nullptr,
        .pWaitDstStageMask = nullptr,
        .commandBufferCount = 1,
        .pCommandBuffers = &commandBuffer,
        .signalSemaphoreCount = 0,
        .pSignalSemaphores = nullptr,
    };

    {
        android::base::AutoLock lock(*sVkEmulation->queueLock);
        VK_CHECK(vk->vkQueueSubmit(sVkEmulation->queue, 1, &submitInfo,
                                   sVkEmulation->commandBufferFence));
    }

    static constexpr uint64_t ANB_MAX_WAIT_NS = 5ULL * 1000ULL * 1000ULL * 1000ULL;

    VK_CHECK(vk->vkWaitForFences(sVkEmulation->device, 1, &sVkEmulation->commandBufferFence,
                                 VK_TRUE, ANB_MAX_WAIT_NS));

    VK_CHECK(vk->vkResetFences(sVkEmulation->device, 1, &sVkEmulation->commandBufferFence));

    return true;
}

VkExternalMemoryHandleTypeFlags transformExternalMemoryHandleTypeFlags_tohost(
    VkExternalMemoryHandleTypeFlags bits) {
    VkExternalMemoryHandleTypeFlags res = bits;

    // Transform Android/Fuchsia/Linux bits to host bits.
    if (bits & VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT) {
        res &= ~VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
    }

#ifdef _WIN32
    res &= ~VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
    res &= ~VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT;
#endif

    if (bits & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) {
        res &= ~VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;

        VkExternalMemoryHandleTypeFlagBits handleTypeNeeded = VK_EXT_MEMORY_HANDLE_TYPE_BIT;
#if defined(__APPLE__)
        if (sVkEmulation->instanceSupportsMoltenVK) {
            // Using a different handle type when in MoltenVK mode
            handleTypeNeeded = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR;
        }
#endif
        res |= handleTypeNeeded;
    }

    if (bits & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA) {
        res &= ~VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA;
        res |= VK_EXT_MEMORY_HANDLE_TYPE_BIT;
    }

#if defined(__QNX__)
    // QNX only: Replace DMA_BUF_BIT_EXT with SCREEN_BUFFER_BIT_QNX for host calls
    if (bits & VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT) {
        res &= ~VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
        res |= VK_EXT_MEMORY_HANDLE_TYPE_BIT;
    }
#endif

    return res;
}

VkExternalMemoryHandleTypeFlags transformExternalMemoryHandleTypeFlags_fromhost(
    VkExternalMemoryHandleTypeFlags hostBits,
    VkExternalMemoryHandleTypeFlags wantedGuestHandleType) {
    VkExternalMemoryHandleTypeFlags res = hostBits;

    VkExternalMemoryHandleTypeFlagBits handleTypeUsed = VK_EXT_MEMORY_HANDLE_TYPE_BIT;
#if defined(__APPLE__)
    if (sVkEmulation->instanceSupportsMoltenVK) {
        // Using a different handle type when in MoltenVK mode
        handleTypeUsed = VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR;
    }
#endif
    if ((res & handleTypeUsed) == handleTypeUsed) {
        res &= ~handleTypeUsed;
        res |= wantedGuestHandleType;
    }

#ifdef _WIN32
    res &= ~VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
    res &= ~VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT;
#endif

    return res;
}

VkExternalMemoryProperties transformExternalMemoryProperties_tohost(
    VkExternalMemoryProperties props) {
    VkExternalMemoryProperties res = props;
    res.exportFromImportedHandleTypes =
        transformExternalMemoryHandleTypeFlags_tohost(props.exportFromImportedHandleTypes);
    res.compatibleHandleTypes =
        transformExternalMemoryHandleTypeFlags_tohost(props.compatibleHandleTypes);
    return res;
}

VkExternalMemoryProperties transformExternalMemoryProperties_fromhost(
    VkExternalMemoryProperties props, VkExternalMemoryHandleTypeFlags wantedGuestHandleType) {
    VkExternalMemoryProperties res = props;
    res.exportFromImportedHandleTypes = transformExternalMemoryHandleTypeFlags_fromhost(
        props.exportFromImportedHandleTypes, wantedGuestHandleType);
    res.compatibleHandleTypes = transformExternalMemoryHandleTypeFlags_fromhost(
        props.compatibleHandleTypes, wantedGuestHandleType);
    return res;
}

void setColorBufferCurrentLayout(uint32_t colorBufferHandle, VkImageLayout layout) {
    AutoLock lock(sVkEmulationLock);

    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
    if (!infoPtr) {
        ERR("Invalid ColorBuffer handle %d.", static_cast<int>(colorBufferHandle));
        return;
    }
    infoPtr->currentLayout = layout;
}

VkImageLayout getColorBufferCurrentLayout(uint32_t colorBufferHandle) {
    AutoLock lock(sVkEmulationLock);

    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
    if (!infoPtr) {
        ERR("Invalid ColorBuffer handle %d.", static_cast<int>(colorBufferHandle));
        return VK_IMAGE_LAYOUT_UNDEFINED;
    }
    return infoPtr->currentLayout;
}

void setColorBufferLatestUse(uint32_t colorBufferHandle, DeviceOpWaitable waitable,
                             DeviceOpTrackerPtr tracker) {
    AutoLock lock(sVkEmulationLock);
    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
    if (!infoPtr) {
        ERR("Invalid ColorBuffer handle %d.", static_cast<int>(colorBufferHandle));
        return;
    }

    infoPtr->latestUse = waitable;
    infoPtr->latestUseTracker = tracker;
}

int waitSyncVkColorBuffer(uint32_t colorBufferHandle) {
    AutoLock lock(sVkEmulationLock);
    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
    if (!infoPtr) {
        ERR("Invalid ColorBuffer handle %d.", static_cast<int>(colorBufferHandle));
        return -1;
    }

    if (infoPtr->latestUse && infoPtr->latestUseTracker) {
        while (!IsDone(*infoPtr->latestUse)) {
            infoPtr->latestUseTracker->Poll();
        }
    }

    return 0;
}

// Allocate a ready to use VkCommandBuffer for queue transfer. The caller needs
// to signal the returned VkFence when the VkCommandBuffer completes.
static std::tuple<VkCommandBuffer, VkFence> allocateQueueTransferCommandBuffer_locked() {
    auto vk = sVkEmulation->dvk;
    // Check if a command buffer in the pool is ready to use. If the associated
    // VkFence is ready, vkGetFenceStatus will return VK_SUCCESS, and the
    // associated command buffer should be ready to use, so we return that
    // command buffer with the associated VkFence. If the associated VkFence is
    // not ready, vkGetFenceStatus will return VK_NOT_READY, we will continue to
    // search and test the next command buffer. If the VkFence is in an error
    // state, vkGetFenceStatus will return with other VkResult variants, we will
    // abort.
    for (auto& [commandBuffer, fence] : sVkEmulation->transferQueueCommandBufferPool) {
        auto res = vk->vkGetFenceStatus(sVkEmulation->device, fence);
        if (res == VK_SUCCESS) {
            VK_CHECK(vk->vkResetFences(sVkEmulation->device, 1, &fence));
            VK_CHECK(vk->vkResetCommandBuffer(commandBuffer,
                                              VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT));
            return std::make_tuple(commandBuffer, fence);
        }
        if (res == VK_NOT_READY) {
            continue;
        }
        // We either have a device lost, or an invalid fence state. For the device lost case,
        // VK_CHECK will ensure we capture the relevant streams.
        VK_CHECK(res);
    }
    VkCommandBuffer commandBuffer;
    VkCommandBufferAllocateInfo allocateInfo = {
        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
        .pNext = nullptr,
        .commandPool = sVkEmulation->commandPool,
        .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
        .commandBufferCount = 1,
    };
    VK_CHECK(vk->vkAllocateCommandBuffers(sVkEmulation->device, &allocateInfo, &commandBuffer));
    VkFence fence;
    VkFenceCreateInfo fenceCi = {
        .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
        .pNext = nullptr,
        .flags = 0,
    };
    VK_CHECK(vk->vkCreateFence(sVkEmulation->device, &fenceCi, nullptr, &fence));

    const int cbIndex = static_cast<int>(sVkEmulation->transferQueueCommandBufferPool.size());
    sVkEmulation->transferQueueCommandBufferPool.emplace_back(commandBuffer, fence);

    VERBOSE(
        "Create a new command buffer for queue transfer for a total of %d "
        "transfer command buffers",
        (cbIndex + 1));

    sVkEmulation->debugUtilsHelper.addDebugLabel(commandBuffer, "QueueTransferCommandBuffer:%d",
                                                 cbIndex);

    return std::make_tuple(commandBuffer, fence);
}

const VkImageLayout kGuestUseDefaultImageLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;

void releaseColorBufferForGuestUse(uint32_t colorBufferHandle) {
    if (!sVkEmulation || !sVkEmulation->live) {
        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Host Vulkan device lost";
    }

    AutoLock lock(sVkEmulationLock);

    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
    if (!infoPtr) {
        ERR("Failed to find ColorBuffer handle %d.", static_cast<int>(colorBufferHandle));
        return;
    }

    std::optional<VkImageMemoryBarrier> layoutTransitionBarrier;
    if (infoPtr->currentLayout != kGuestUseDefaultImageLayout) {
        layoutTransitionBarrier = VkImageMemoryBarrier{
            .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
            .pNext = nullptr,
            .srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
            .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
            .oldLayout = infoPtr->currentLayout,
            .newLayout = kGuestUseDefaultImageLayout,
            .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
            .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
            .image = infoPtr->image,
            .subresourceRange =
                {
                    .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
                    .baseMipLevel = 0,
                    .levelCount = 1,
                    .baseArrayLayer = 0,
                    .layerCount = 1,
                },
        };
        infoPtr->currentLayout = kGuestUseDefaultImageLayout;
    }

    std::optional<VkImageMemoryBarrier> queueTransferBarrier;
    if (infoPtr->currentQueueFamilyIndex != VK_QUEUE_FAMILY_EXTERNAL) {
        queueTransferBarrier = VkImageMemoryBarrier{
            .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
            .pNext = nullptr,
            .srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
            .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
            .oldLayout = infoPtr->currentLayout,
            .newLayout = infoPtr->currentLayout,
            .srcQueueFamilyIndex = infoPtr->currentQueueFamilyIndex,
            .dstQueueFamilyIndex = VK_QUEUE_FAMILY_EXTERNAL,
            .image = infoPtr->image,
            .subresourceRange =
                {
                    .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
                    .baseMipLevel = 0,
                    .levelCount = 1,
                    .baseArrayLayer = 0,
                    .layerCount = 1,
                },
        };
        infoPtr->currentQueueFamilyIndex = VK_QUEUE_FAMILY_EXTERNAL;
    }

    if (!layoutTransitionBarrier && !queueTransferBarrier) {
        return;
    }

    auto vk = sVkEmulation->dvk;
    auto [commandBuffer, fence] = allocateQueueTransferCommandBuffer_locked();

    VK_CHECK(vk->vkResetCommandBuffer(commandBuffer, 0));

    const VkCommandBufferBeginInfo beginInfo = {
        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
        .pNext = nullptr,
        .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
        .pInheritanceInfo = nullptr,
    };
    VK_CHECK(vk->vkBeginCommandBuffer(commandBuffer, &beginInfo));

    sVkEmulation->debugUtilsHelper.cmdBeginDebugLabel(
        commandBuffer, "releaseColorBufferForGuestUse(ColorBuffer:%d)", colorBufferHandle);

    if (layoutTransitionBarrier) {
        vk->vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
                                 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
                                 &layoutTransitionBarrier.value());
    }
    if (queueTransferBarrier) {
        vk->vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
                                 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
                                 &queueTransferBarrier.value());
    }

    sVkEmulation->debugUtilsHelper.cmdEndDebugLabel(commandBuffer);

    VK_CHECK(vk->vkEndCommandBuffer(commandBuffer));

    const VkSubmitInfo submitInfo = {
        .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
        .pNext = nullptr,
        .waitSemaphoreCount = 0,
        .pWaitSemaphores = nullptr,
        .pWaitDstStageMask = nullptr,
        .commandBufferCount = 1,
        .pCommandBuffers = &commandBuffer,
        .signalSemaphoreCount = 0,
        .pSignalSemaphores = nullptr,
    };
    {
        android::base::AutoLock lock(*sVkEmulation->queueLock);
        VK_CHECK(vk->vkQueueSubmit(sVkEmulation->queue, 1, &submitInfo, fence));
    }

    static constexpr uint64_t ANB_MAX_WAIT_NS = 5ULL * 1000ULL * 1000ULL * 1000ULL;
    VK_CHECK(vk->vkWaitForFences(sVkEmulation->device, 1, &fence, VK_TRUE, ANB_MAX_WAIT_NS));
}

std::unique_ptr<BorrowedImageInfoVk> borrowColorBufferForComposition(uint32_t colorBufferHandle,
                                                                     bool colorBufferIsTarget) {
    AutoLock lock(sVkEmulationLock);

    auto colorBufferInfo = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
    if (!colorBufferInfo) {
        ERR("Invalid ColorBuffer handle %d.", static_cast<int>(colorBufferHandle));
        return nullptr;
    }

    auto compositorInfo = std::make_unique<BorrowedImageInfoVk>();
    compositorInfo->id = colorBufferInfo->handle;
    compositorInfo->width = colorBufferInfo->imageCreateInfoShallow.extent.width;
    compositorInfo->height = colorBufferInfo->imageCreateInfoShallow.extent.height;
    compositorInfo->image = colorBufferInfo->image;
    compositorInfo->imageView = colorBufferInfo->imageView;
    compositorInfo->imageCreateInfo = colorBufferInfo->imageCreateInfoShallow;
    compositorInfo->preBorrowLayout = colorBufferInfo->currentLayout;
    compositorInfo->preBorrowQueueFamilyIndex = colorBufferInfo->currentQueueFamilyIndex;
    if (colorBufferIsTarget && sVkEmulation->displayVk) {
        // Instruct the compositor to perform the layout transition after use so
        // that it is ready to be blitted to the display.
        compositorInfo->postBorrowQueueFamilyIndex = sVkEmulation->queueFamilyIndex;
        compositorInfo->postBorrowLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
    } else {
        // Instruct the compositor to perform the queue transfer release after use
        // so that the color buffer can be acquired by the guest.
        compositorInfo->postBorrowQueueFamilyIndex = VK_QUEUE_FAMILY_EXTERNAL;
        compositorInfo->postBorrowLayout = colorBufferInfo->currentLayout;

        if (compositorInfo->postBorrowLayout == VK_IMAGE_LAYOUT_UNDEFINED) {
            compositorInfo->postBorrowLayout = kGuestUseDefaultImageLayout;
        }
    }

    colorBufferInfo->currentLayout = compositorInfo->postBorrowLayout;
    colorBufferInfo->currentQueueFamilyIndex = compositorInfo->postBorrowQueueFamilyIndex;

    return compositorInfo;
}

std::unique_ptr<BorrowedImageInfoVk> borrowColorBufferForDisplay(uint32_t colorBufferHandle) {
    AutoLock lock(sVkEmulationLock);

    auto colorBufferInfo = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
    if (!colorBufferInfo) {
        ERR("Invalid ColorBuffer handle %d.", static_cast<int>(colorBufferHandle));
        return nullptr;
    }

    auto compositorInfo = std::make_unique<BorrowedImageInfoVk>();
    compositorInfo->id = colorBufferInfo->handle;
    compositorInfo->width = colorBufferInfo->imageCreateInfoShallow.extent.width;
    compositorInfo->height = colorBufferInfo->imageCreateInfoShallow.extent.height;
    compositorInfo->image = colorBufferInfo->image;
    compositorInfo->imageView = colorBufferInfo->imageView;
    compositorInfo->imageCreateInfo = colorBufferInfo->imageCreateInfoShallow;
    compositorInfo->preBorrowLayout = colorBufferInfo->currentLayout;
    compositorInfo->preBorrowQueueFamilyIndex = sVkEmulation->queueFamilyIndex;

    // Instruct the display to perform the queue transfer release after use so
    // that the color buffer can be acquired by the guest.
    compositorInfo->postBorrowQueueFamilyIndex = VK_QUEUE_FAMILY_EXTERNAL;
    compositorInfo->postBorrowLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;

    colorBufferInfo->currentLayout = compositorInfo->postBorrowLayout;
    colorBufferInfo->currentQueueFamilyIndex = compositorInfo->postBorrowQueueFamilyIndex;

    return compositorInfo;
}

std::optional<VkEmulation::RepresentativeColorBufferMemoryTypeInfo>
findRepresentativeColorBufferMemoryTypeIndexLocked() {
    constexpr const uint32_t kArbitraryWidth = 64;
    constexpr const uint32_t kArbitraryHeight = 64;
    constexpr const uint32_t kArbitraryHandle = std::numeric_limits<uint32_t>::max();
    if (!createVkColorBufferLocked(kArbitraryWidth, kArbitraryHeight, GL_RGBA8,
                                   FrameworkFormat::FRAMEWORK_FORMAT_GL_COMPATIBLE,
                                   kArbitraryHandle, true, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
        ERR("Failed to setup memory type index test ColorBuffer.");
        return std::nullopt;
    }
    if (!initializeVkColorBufferLocked(kArbitraryHandle)) {
        ERR("Failed to initialize memory type index test ColorBuffer.");
        return std::nullopt;
    }

    uint32_t hostMemoryTypeIndex = 0;
    if (!getColorBufferAllocationInfoLocked(kArbitraryHandle, nullptr, &hostMemoryTypeIndex,
                                            nullptr, nullptr)) {
        ERR("Failed to lookup memory type index test ColorBuffer.");
        return std::nullopt;
    }

    if (!teardownVkColorBufferLocked(kArbitraryHandle)) {
        ERR("Failed to clean up memory type index test ColorBuffer.");
        return std::nullopt;
    }

    EmulatedPhysicalDeviceMemoryProperties helper(sVkEmulation->deviceInfo.memProps,
                                                  hostMemoryTypeIndex, sVkEmulation->features);
    uint32_t guestMemoryTypeIndex = helper.getGuestColorBufferMemoryTypeIndex();

    return VkEmulation::RepresentativeColorBufferMemoryTypeInfo{
        .hostMemoryTypeIndex = hostMemoryTypeIndex,
        .guestMemoryTypeIndex = guestMemoryTypeIndex,
    };
}

}  // namespace vk
}  // namespace gfxstream
