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

#include "ResourceTracker.h"

#include "../OpenglSystemCommon/EmulatorFeatureInfo.h"
#include "../OpenglSystemCommon/HostConnection.h"
#include "CommandBufferStagingStream.h"
#include "DescriptorSetVirtualization.h"
#include "HostVisibleMemoryVirtualization.h"
#include "Resources.h"
#include "VkEncoder.h"
#include "aemu/base/AlignedBuf.h"
#include "gfxstream_vk_private.h"
#include "goldfish_address_space.h"
#include "goldfish_vk_private_defs.h"
#include "util.h"
#include "virtgpu_gfxstream_protocol.h"
#include "vulkan/vk_enum_string_helper.h"
#include "vulkan/vulkan_core.h"

#ifdef VK_USE_PLATFORM_ANDROID_KHR
#include "vk_format_info.h"
#endif
#include <stdlib.h>
#include <vndk/hardware_buffer.h>

#include <algorithm>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>

#include "vk_struct_id.h"
#include "vk_util.h"

#if defined(__ANDROID__) || defined(__linux__) || defined(__APPLE__)

#include <sys/mman.h>
#include <sys/syscall.h>


static inline int inline_memfd_create(const char* name, unsigned int flags) {
#if defined(__ANDROID__)
    return syscall(SYS_memfd_create, name, flags);
#else
    return -1;
#endif
}

#define memfd_create inline_memfd_create
#endif

#ifndef VK_USE_PLATFORM_FUCHSIA
void zx_handle_close(zx_handle_t) {}
void zx_event_create(int, zx_handle_t*) {}
#endif

static constexpr uint32_t kDefaultApiVersion = VK_MAKE_VERSION(1, 1, 0);

namespace gfxstream {
namespace vk {

#define MAKE_HANDLE_MAPPING_FOREACH(type_name, map_impl, map_to_u64_impl, map_from_u64_impl)       \
    void mapHandles_##type_name(type_name* handles, size_t count) override {                       \
        for (size_t i = 0; i < count; ++i) {                                                       \
            map_impl;                                                                              \
        }                                                                                          \
    }                                                                                              \
    void mapHandles_##type_name##_u64(const type_name* handles, uint64_t* handle_u64s,             \
                                      size_t count) override {                                     \
        for (size_t i = 0; i < count; ++i) {                                                       \
            map_to_u64_impl;                                                                       \
        }                                                                                          \
    }                                                                                              \
    void mapHandles_u64_##type_name(const uint64_t* handle_u64s, type_name* handles, size_t count) \
        override {                                                                                 \
        for (size_t i = 0; i < count; ++i) {                                                       \
            map_from_u64_impl;                                                                     \
        }                                                                                          \
    }

#define DEFINE_RESOURCE_TRACKING_CLASS(class_name, impl) \
    class class_name : public VulkanHandleMapping {      \
       public:                                           \
        virtual ~class_name() {}                         \
        GOLDFISH_VK_LIST_HANDLE_TYPES(impl)              \
    };

#define CREATE_MAPPING_IMPL_FOR_TYPE(type_name)                                \
    MAKE_HANDLE_MAPPING_FOREACH(                                               \
        type_name, handles[i] = new_from_host_##type_name(handles[i]);         \
        ResourceTracker::get()->register_##type_name(handles[i]);              \
        , handle_u64s[i] = (uint64_t)new_from_host_##type_name(handles[i]),    \
        handles[i] = (type_name)new_from_host_u64_##type_name(handle_u64s[i]); \
        ResourceTracker::get()->register_##type_name(handles[i]);)

#define UNWRAP_MAPPING_IMPL_FOR_TYPE(type_name)                          \
    MAKE_HANDLE_MAPPING_FOREACH(                                         \
        type_name, handles[i] = get_host_##type_name(handles[i]),        \
        handle_u64s[i] = (uint64_t)get_host_u64_##type_name(handles[i]), \
        handles[i] = (type_name)get_host_##type_name((type_name)handle_u64s[i]))

#define DESTROY_MAPPING_IMPL_FOR_TYPE(type_name)                                               \
    MAKE_HANDLE_MAPPING_FOREACH(type_name,                                                     \
                                ResourceTracker::get()->unregister_##type_name(handles[i]);    \
                                delete_goldfish_##type_name(handles[i]), (void)handle_u64s[i]; \
                                delete_goldfish_##type_name(handles[i]), (void)handles[i];     \
                                delete_goldfish_##type_name((type_name)handle_u64s[i]))

DEFINE_RESOURCE_TRACKING_CLASS(CreateMapping, CREATE_MAPPING_IMPL_FOR_TYPE)
DEFINE_RESOURCE_TRACKING_CLASS(DestroyMapping, DESTROY_MAPPING_IMPL_FOR_TYPE)

static uint32_t* sSeqnoPtr = nullptr;

// static
uint32_t ResourceTracker::streamFeatureBits = 0;
ResourceTracker::ThreadingCallbacks ResourceTracker::threadingCallbacks;

struct StagingInfo {
    std::mutex mLock;
    std::vector<CommandBufferStagingStream*> streams;
    std::vector<VkEncoder*> encoders;
    /// \brief sets alloc and free callbacks for memory allocation for CommandBufferStagingStream(s)
    /// \param allocFn is the callback to allocate memory
    /// \param freeFn is the callback to free memory
    void setAllocFree(CommandBufferStagingStream::Alloc&& allocFn,
                      CommandBufferStagingStream::Free&& freeFn) {
        mAlloc = allocFn;
        mFree = freeFn;
    }

    ~StagingInfo() {
        for (auto stream : streams) {
            delete stream;
        }

        for (auto encoder : encoders) {
            delete encoder;
        }
    }

    void pushStaging(CommandBufferStagingStream* stream, VkEncoder* encoder) {
        std::lock_guard<std::mutex> lock(mLock);
        stream->reset();
        streams.push_back(stream);
        encoders.push_back(encoder);
    }

    void popStaging(CommandBufferStagingStream** streamOut, VkEncoder** encoderOut) {
        std::lock_guard<std::mutex> lock(mLock);
        CommandBufferStagingStream* stream;
        VkEncoder* encoder;
        if (streams.empty()) {
            if (mAlloc && mFree) {
                // if custom allocators are provided, forward them to CommandBufferStagingStream
                stream = new CommandBufferStagingStream(mAlloc, mFree);
            } else {
                stream = new CommandBufferStagingStream;
            }
            encoder = new VkEncoder(stream);
        } else {
            stream = streams.back();
            encoder = encoders.back();
            streams.pop_back();
            encoders.pop_back();
        }
        *streamOut = stream;
        *encoderOut = encoder;
    }

   private:
    CommandBufferStagingStream::Alloc mAlloc = nullptr;
    CommandBufferStagingStream::Free mFree = nullptr;
};

static StagingInfo sStaging;

struct CommandBufferPendingDescriptorSets {
    std::unordered_set<VkDescriptorSet> sets;
};

#define HANDLE_REGISTER_IMPL_IMPL(type)                    \
    void ResourceTracker::register_##type(type obj) {      \
        std::lock_guard<std::recursive_mutex> lock(mLock); \
        info_##type[obj] = type##_Info();                  \
    }

#define HANDLE_UNREGISTER_IMPL_IMPL(type)                  \
    void ResourceTracker::unregister_##type(type obj) {    \
        std::lock_guard<std::recursive_mutex> lock(mLock); \
        info_##type.erase(obj);                            \
    }

GOLDFISH_VK_LIST_HANDLE_TYPES(HANDLE_REGISTER_IMPL_IMPL)
GOLDFISH_VK_LIST_TRIVIAL_HANDLE_TYPES(HANDLE_UNREGISTER_IMPL_IMPL)
uint32_t getWaitSemaphoreCount(const VkSubmitInfo& pSubmit) { return pSubmit.waitSemaphoreCount; }

uint32_t getWaitSemaphoreCount(const VkSubmitInfo2& pSubmit) {
    return pSubmit.waitSemaphoreInfoCount;
}

uint32_t getCommandBufferCount(const VkSubmitInfo& pSubmit) { return pSubmit.commandBufferCount; }

uint32_t getCommandBufferCount(const VkSubmitInfo2& pSubmit) {
    return pSubmit.commandBufferInfoCount;
}

uint32_t getSignalSemaphoreCount(const VkSubmitInfo& pSubmit) {
    return pSubmit.signalSemaphoreCount;
}

uint32_t getSignalSemaphoreCount(const VkSubmitInfo2& pSubmit) {
    return pSubmit.signalSemaphoreInfoCount;
}

VkSemaphore getWaitSemaphore(const VkSubmitInfo& pSubmit, int i) {
    return pSubmit.pWaitSemaphores[i];
}

VkSemaphore getWaitSemaphore(const VkSubmitInfo2& pSubmit, int i) {
    return pSubmit.pWaitSemaphoreInfos[i].semaphore;
}

VkSemaphore getSignalSemaphore(const VkSubmitInfo& pSubmit, int i) {
    return pSubmit.pSignalSemaphores[i];
}

VkSemaphore getSignalSemaphore(const VkSubmitInfo2& pSubmit, int i) {
    return pSubmit.pSignalSemaphoreInfos[i].semaphore;
}

VkCommandBuffer getCommandBuffer(const VkSubmitInfo& pSubmit, int i) {
    return pSubmit.pCommandBuffers[i];
}

VkCommandBuffer getCommandBuffer(const VkSubmitInfo2& pSubmit, int i) {
    return pSubmit.pCommandBufferInfos[i].commandBuffer;
}

bool descriptorPoolSupportsIndividualFreeLocked(VkDescriptorPool pool) {
    return as_goldfish_VkDescriptorPool(pool)->allocInfo->createFlags &
           VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
}

VkDescriptorImageInfo createImmutableSamplersFilteredImageInfo(
    VkDescriptorType descType, VkDescriptorSet descSet, uint32_t binding,
    const VkDescriptorImageInfo* pImageInfo) {
    VkDescriptorImageInfo res = *pImageInfo;

    if (descType != VK_DESCRIPTOR_TYPE_SAMPLER &&
        descType != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
        return res;

    bool immutableSampler =
        as_goldfish_VkDescriptorSet(descSet)->reified->bindingIsImmutableSampler[binding];

    if (!immutableSampler) return res;

    res.sampler = 0;

    return res;
}

bool descriptorBindingIsImmutableSampler(VkDescriptorSet dstSet, uint32_t dstBinding) {
    return as_goldfish_VkDescriptorSet(dstSet)->reified->bindingIsImmutableSampler[dstBinding];
}

VkDescriptorImageInfo ResourceTracker::filterNonexistentSampler(
    const VkDescriptorImageInfo& inputInfo) {
    VkSampler sampler = inputInfo.sampler;

    VkDescriptorImageInfo res = inputInfo;

    if (sampler) {
        auto it = info_VkSampler.find(sampler);
        bool samplerExists = it != info_VkSampler.end();
        if (!samplerExists) res.sampler = 0;
    }

    return res;
}

void ResourceTracker::emitDeviceMemoryReport(VkDevice_Info info,
                                             VkDeviceMemoryReportEventTypeEXT type,
                                             uint64_t memoryObjectId, VkDeviceSize size,
                                             VkObjectType objectType, uint64_t objectHandle,
                                             uint32_t heapIndex) {
    if (info.deviceMemoryReportCallbacks.empty()) return;

    const VkDeviceMemoryReportCallbackDataEXT callbackData = {
        VK_STRUCTURE_TYPE_DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT,  // sType
        nullptr,                                                   // pNext
        0,                                                         // flags
        type,                                                      // type
        memoryObjectId,                                            // memoryObjectId
        size,                                                      // size
        objectType,                                                // objectType
        objectHandle,                                              // objectHandle
        heapIndex,                                                 // heapIndex
    };
    for (const auto& callback : info.deviceMemoryReportCallbacks) {
        callback.first(&callbackData, callback.second);
    }
}

#ifdef VK_USE_PLATFORM_FUCHSIA
inline fuchsia_sysmem::wire::BufferCollectionConstraints defaultBufferCollectionConstraints(
    size_t minSizeBytes, size_t minBufferCount, size_t maxBufferCount = 0u,
    size_t minBufferCountForCamping = 0u, size_t minBufferCountForDedicatedSlack = 0u,
    size_t minBufferCountForSharedSlack = 0u) {
    fuchsia_sysmem::wire::BufferCollectionConstraints constraints = {};
    constraints.min_buffer_count = minBufferCount;
    if (maxBufferCount > 0) {
        constraints.max_buffer_count = maxBufferCount;
    }
    if (minBufferCountForCamping) {
        constraints.min_buffer_count_for_camping = minBufferCountForCamping;
    }
    if (minBufferCountForSharedSlack) {
        constraints.min_buffer_count_for_shared_slack = minBufferCountForSharedSlack;
    }
    constraints.has_buffer_memory_constraints = true;
    fuchsia_sysmem::wire::BufferMemoryConstraints& buffer_constraints =
        constraints.buffer_memory_constraints;

    buffer_constraints.min_size_bytes = minSizeBytes;
    buffer_constraints.max_size_bytes = 0xffffffff;
    buffer_constraints.physically_contiguous_required = false;
    buffer_constraints.secure_required = false;

    // No restrictions on coherency domain or Heaps.
    buffer_constraints.ram_domain_supported = true;
    buffer_constraints.cpu_domain_supported = true;
    buffer_constraints.inaccessible_domain_supported = true;
    buffer_constraints.heap_permitted_count = 2;
    buffer_constraints.heap_permitted[0] = fuchsia_sysmem::wire::HeapType::kGoldfishDeviceLocal;
    buffer_constraints.heap_permitted[1] = fuchsia_sysmem::wire::HeapType::kGoldfishHostVisible;

    return constraints;
}

uint32_t getBufferCollectionConstraintsVulkanImageUsage(const VkImageCreateInfo* pImageInfo) {
    uint32_t usage = 0u;
    VkImageUsageFlags imageUsage = pImageInfo->usage;

#define SetUsageBit(BIT, VALUE)                                  \
    if (imageUsage & VK_IMAGE_USAGE_##BIT##_BIT) {               \
        usage |= fuchsia_sysmem::wire::kVulkanImageUsage##VALUE; \
    }

    SetUsageBit(COLOR_ATTACHMENT, ColorAttachment);
    SetUsageBit(TRANSFER_SRC, TransferSrc);
    SetUsageBit(TRANSFER_DST, TransferDst);
    SetUsageBit(SAMPLED, Sampled);

#undef SetUsageBit
    return usage;
}

uint32_t getBufferCollectionConstraintsVulkanBufferUsage(VkBufferUsageFlags bufferUsage) {
    uint32_t usage = 0u;

#define SetUsageBit(BIT, VALUE)                                   \
    if (bufferUsage & VK_BUFFER_USAGE_##BIT##_BIT) {              \
        usage |= fuchsia_sysmem::wire::kVulkanBufferUsage##VALUE; \
    }

    SetUsageBit(TRANSFER_SRC, TransferSrc);
    SetUsageBit(TRANSFER_DST, TransferDst);
    SetUsageBit(UNIFORM_TEXEL_BUFFER, UniformTexelBuffer);
    SetUsageBit(STORAGE_TEXEL_BUFFER, StorageTexelBuffer);
    SetUsageBit(UNIFORM_BUFFER, UniformBuffer);
    SetUsageBit(STORAGE_BUFFER, StorageBuffer);
    SetUsageBit(INDEX_BUFFER, IndexBuffer);
    SetUsageBit(VERTEX_BUFFER, VertexBuffer);
    SetUsageBit(INDIRECT_BUFFER, IndirectBuffer);

#undef SetUsageBit
    return usage;
}

uint32_t getBufferCollectionConstraintsVulkanBufferUsage(
    const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo) {
    VkBufferUsageFlags bufferUsage = pBufferConstraintsInfo->createInfo.usage;
    return getBufferCollectionConstraintsVulkanBufferUsage(bufferUsage);
}

static fuchsia_sysmem::wire::PixelFormatType vkFormatTypeToSysmem(VkFormat format) {
    switch (format) {
        case VK_FORMAT_B8G8R8A8_SINT:
        case VK_FORMAT_B8G8R8A8_UNORM:
        case VK_FORMAT_B8G8R8A8_SRGB:
        case VK_FORMAT_B8G8R8A8_SNORM:
        case VK_FORMAT_B8G8R8A8_SSCALED:
        case VK_FORMAT_B8G8R8A8_USCALED:
            return fuchsia_sysmem::wire::PixelFormatType::kBgra32;
        case VK_FORMAT_R8G8B8A8_SINT:
        case VK_FORMAT_R8G8B8A8_UNORM:
        case VK_FORMAT_R8G8B8A8_SRGB:
        case VK_FORMAT_R8G8B8A8_SNORM:
        case VK_FORMAT_R8G8B8A8_SSCALED:
        case VK_FORMAT_R8G8B8A8_USCALED:
            return fuchsia_sysmem::wire::PixelFormatType::kR8G8B8A8;
        case VK_FORMAT_R8_UNORM:
        case VK_FORMAT_R8_UINT:
        case VK_FORMAT_R8_USCALED:
        case VK_FORMAT_R8_SNORM:
        case VK_FORMAT_R8_SINT:
        case VK_FORMAT_R8_SSCALED:
        case VK_FORMAT_R8_SRGB:
            return fuchsia_sysmem::wire::PixelFormatType::kR8;
        case VK_FORMAT_R8G8_UNORM:
        case VK_FORMAT_R8G8_UINT:
        case VK_FORMAT_R8G8_USCALED:
        case VK_FORMAT_R8G8_SNORM:
        case VK_FORMAT_R8G8_SINT:
        case VK_FORMAT_R8G8_SSCALED:
        case VK_FORMAT_R8G8_SRGB:
            return fuchsia_sysmem::wire::PixelFormatType::kR8G8;
        default:
            return fuchsia_sysmem::wire::PixelFormatType::kInvalid;
    }
}

static bool vkFormatMatchesSysmemFormat(VkFormat vkFormat,
                                        fuchsia_sysmem::wire::PixelFormatType sysmemFormat) {
    switch (vkFormat) {
        case VK_FORMAT_B8G8R8A8_SINT:
        case VK_FORMAT_B8G8R8A8_UNORM:
        case VK_FORMAT_B8G8R8A8_SRGB:
        case VK_FORMAT_B8G8R8A8_SNORM:
        case VK_FORMAT_B8G8R8A8_SSCALED:
        case VK_FORMAT_B8G8R8A8_USCALED:
            return sysmemFormat == fuchsia_sysmem::wire::PixelFormatType::kBgra32;
        case VK_FORMAT_R8G8B8A8_SINT:
        case VK_FORMAT_R8G8B8A8_UNORM:
        case VK_FORMAT_R8G8B8A8_SRGB:
        case VK_FORMAT_R8G8B8A8_SNORM:
        case VK_FORMAT_R8G8B8A8_SSCALED:
        case VK_FORMAT_R8G8B8A8_USCALED:
            return sysmemFormat == fuchsia_sysmem::wire::PixelFormatType::kR8G8B8A8;
        case VK_FORMAT_R8_UNORM:
        case VK_FORMAT_R8_UINT:
        case VK_FORMAT_R8_USCALED:
        case VK_FORMAT_R8_SNORM:
        case VK_FORMAT_R8_SINT:
        case VK_FORMAT_R8_SSCALED:
        case VK_FORMAT_R8_SRGB:
            return sysmemFormat == fuchsia_sysmem::wire::PixelFormatType::kR8 ||
                   sysmemFormat == fuchsia_sysmem::wire::PixelFormatType::kL8;
        case VK_FORMAT_R8G8_UNORM:
        case VK_FORMAT_R8G8_UINT:
        case VK_FORMAT_R8G8_USCALED:
        case VK_FORMAT_R8G8_SNORM:
        case VK_FORMAT_R8G8_SINT:
        case VK_FORMAT_R8G8_SSCALED:
        case VK_FORMAT_R8G8_SRGB:
            return sysmemFormat == fuchsia_sysmem::wire::PixelFormatType::kR8G8;
        default:
            return false;
    }
}

static VkFormat sysmemPixelFormatTypeToVk(fuchsia_sysmem::wire::PixelFormatType format) {
    switch (format) {
        case fuchsia_sysmem::wire::PixelFormatType::kBgra32:
            return VK_FORMAT_B8G8R8A8_SRGB;
        case fuchsia_sysmem::wire::PixelFormatType::kR8G8B8A8:
            return VK_FORMAT_R8G8B8A8_SRGB;
        case fuchsia_sysmem::wire::PixelFormatType::kL8:
        case fuchsia_sysmem::wire::PixelFormatType::kR8:
            return VK_FORMAT_R8_UNORM;
        case fuchsia_sysmem::wire::PixelFormatType::kR8G8:
            return VK_FORMAT_R8G8_UNORM;
        default:
            return VK_FORMAT_UNDEFINED;
    }
}

// TODO(fxbug.dev/42172354): This is currently only used for allocating
// memory for dedicated external images. It should be migrated to use
// SetBufferCollectionImageConstraintsFUCHSIA.
VkResult ResourceTracker::setBufferCollectionConstraintsFUCHSIA(
    VkEncoder* enc, VkDevice device,
    fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>* collection,
    const VkImageCreateInfo* pImageInfo) {
    if (pImageInfo == nullptr) {
        mesa_loge("setBufferCollectionConstraints: pImageInfo cannot be null.");
        return VK_ERROR_OUT_OF_DEVICE_MEMORY;
    }

    const VkSysmemColorSpaceFUCHSIA kDefaultColorSpace = {
        .sType = VK_STRUCTURE_TYPE_SYSMEM_COLOR_SPACE_FUCHSIA,
        .pNext = nullptr,
        .colorSpace = static_cast<uint32_t>(fuchsia_sysmem::wire::ColorSpaceType::kSrgb),
    };

    std::vector<VkImageFormatConstraintsInfoFUCHSIA> formatInfos;
    if (pImageInfo->format == VK_FORMAT_UNDEFINED) {
        const auto kFormats = {
            VK_FORMAT_B8G8R8A8_SRGB,
            VK_FORMAT_R8G8B8A8_SRGB,
        };
        for (auto format : kFormats) {
            // shallow copy, using pNext from pImageInfo directly.
            auto createInfo = *pImageInfo;
            createInfo.format = format;
            formatInfos.push_back(VkImageFormatConstraintsInfoFUCHSIA{
                .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_CONSTRAINTS_INFO_FUCHSIA,
                .pNext = nullptr,
                .imageCreateInfo = createInfo,
                .colorSpaceCount = 1,
                .pColorSpaces = &kDefaultColorSpace,
            });
        }
    } else {
        formatInfos.push_back(VkImageFormatConstraintsInfoFUCHSIA{
            .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_CONSTRAINTS_INFO_FUCHSIA,
            .pNext = nullptr,
            .imageCreateInfo = *pImageInfo,
            .colorSpaceCount = 1,
            .pColorSpaces = &kDefaultColorSpace,
        });
    }

    VkImageConstraintsInfoFUCHSIA imageConstraints = {
        .sType = VK_STRUCTURE_TYPE_IMAGE_CONSTRAINTS_INFO_FUCHSIA,
        .pNext = nullptr,
        .formatConstraintsCount = static_cast<uint32_t>(formatInfos.size()),
        .pFormatConstraints = formatInfos.data(),
        .bufferCollectionConstraints =
            VkBufferCollectionConstraintsInfoFUCHSIA{
                .sType = VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CONSTRAINTS_INFO_FUCHSIA,
                .pNext = nullptr,
                .minBufferCount = 1,
                .maxBufferCount = 0,
                .minBufferCountForCamping = 0,
                .minBufferCountForDedicatedSlack = 0,
                .minBufferCountForSharedSlack = 0,
            },
        .flags = 0u,
    };

    return setBufferCollectionImageConstraintsFUCHSIA(enc, device, collection, &imageConstraints);
}

VkResult addImageBufferCollectionConstraintsFUCHSIA(
    VkEncoder* enc, VkDevice device, VkPhysicalDevice physicalDevice,
    const VkImageFormatConstraintsInfoFUCHSIA* formatConstraints,  // always non-zero
    VkImageTiling tiling, fuchsia_sysmem::wire::BufferCollectionConstraints* constraints) {
    // First check if the format, tiling and usage is supported on host.
    VkImageFormatProperties imageFormatProperties;
    auto createInfo = &formatConstraints->imageCreateInfo;
    auto result = enc->vkGetPhysicalDeviceImageFormatProperties(
        physicalDevice, createInfo->format, createInfo->imageType, tiling, createInfo->usage,
        createInfo->flags, &imageFormatProperties, true /* do lock */);
    if (result != VK_SUCCESS) {
        mesa_logd(
            "%s: Image format (%u) type (%u) tiling (%u) "
            "usage (%u) flags (%u) not supported by physical "
            "device",
            __func__, static_cast<uint32_t>(createInfo->format),
            static_cast<uint32_t>(createInfo->imageType), static_cast<uint32_t>(tiling),
            static_cast<uint32_t>(createInfo->usage), static_cast<uint32_t>(createInfo->flags));
        return VK_ERROR_FORMAT_NOT_SUPPORTED;
    }

    // Check if format constraints contains unsupported format features.
    {
        VkFormatProperties formatProperties;
        enc->vkGetPhysicalDeviceFormatProperties(physicalDevice, createInfo->format,
                                                 &formatProperties, true /* do lock */);

        auto supportedFeatures = (tiling == VK_IMAGE_TILING_LINEAR)
                                     ? formatProperties.linearTilingFeatures
                                     : formatProperties.optimalTilingFeatures;
        auto requiredFeatures = formatConstraints->requiredFormatFeatures;
        if ((~supportedFeatures) & requiredFeatures) {
            mesa_logd(
                "%s: Host device support features for %s tiling: %08x, "
                "required features: %08x, feature bits %08x missing",
                __func__, tiling == VK_IMAGE_TILING_LINEAR ? "LINEAR" : "OPTIMAL",
                static_cast<uint32_t>(requiredFeatures), static_cast<uint32_t>(supportedFeatures),
                static_cast<uint32_t>((~supportedFeatures) & requiredFeatures));
            return VK_ERROR_FORMAT_NOT_SUPPORTED;
        }
    }

    fuchsia_sysmem::wire::ImageFormatConstraints imageConstraints;
    if (formatConstraints->sysmemPixelFormat != 0) {
        auto pixelFormat = static_cast<fuchsia_sysmem::wire::PixelFormatType>(
            formatConstraints->sysmemPixelFormat);
        if (createInfo->format != VK_FORMAT_UNDEFINED &&
            !vkFormatMatchesSysmemFormat(createInfo->format, pixelFormat)) {
            mesa_logd("%s: VkFormat %u doesn't match sysmem pixelFormat %lu", __func__,
                  static_cast<uint32_t>(createInfo->format), formatConstraints->sysmemPixelFormat);
            return VK_ERROR_FORMAT_NOT_SUPPORTED;
        }
        imageConstraints.pixel_format.type = pixelFormat;
    } else {
        auto pixel_format = vkFormatTypeToSysmem(createInfo->format);
        if (pixel_format == fuchsia_sysmem::wire::PixelFormatType::kInvalid) {
            mesa_logd("%s: Unsupported VkFormat %u", __func__,
                  static_cast<uint32_t>(createInfo->format));
            return VK_ERROR_FORMAT_NOT_SUPPORTED;
        }
        imageConstraints.pixel_format.type = pixel_format;
    }

    imageConstraints.color_spaces_count = formatConstraints->colorSpaceCount;
    for (size_t i = 0; i < formatConstraints->colorSpaceCount; i++) {
        imageConstraints.color_space[0].type = static_cast<fuchsia_sysmem::wire::ColorSpaceType>(
            formatConstraints->pColorSpaces[i].colorSpace);
    }

    // Get row alignment from host GPU.
    VkDeviceSize offset = 0;
    VkDeviceSize rowPitchAlignment = 1u;

    if (tiling == VK_IMAGE_TILING_LINEAR) {
        VkImageCreateInfo createInfoDup = *createInfo;
        createInfoDup.pNext = nullptr;
        enc->vkGetLinearImageLayout2GOOGLE(device, &createInfoDup, &offset, &rowPitchAlignment,
                                           true /* do lock */);
        mesa_logd(
            "vkGetLinearImageLayout2GOOGLE: format %d offset %lu "
            "rowPitchAlignment = %lu",
            (int)createInfo->format, offset, rowPitchAlignment);
    }

    imageConstraints.min_coded_width = createInfo->extent.width;
    imageConstraints.max_coded_width = 0xfffffff;
    imageConstraints.min_coded_height = createInfo->extent.height;
    imageConstraints.max_coded_height = 0xffffffff;
    // The min_bytes_per_row can be calculated by sysmem using
    // |min_coded_width|, |bytes_per_row_divisor| and color format.
    imageConstraints.min_bytes_per_row = 0;
    imageConstraints.max_bytes_per_row = 0xffffffff;
    imageConstraints.max_coded_width_times_coded_height = 0xffffffff;

    imageConstraints.layers = 1;
    imageConstraints.coded_width_divisor = 1;
    imageConstraints.coded_height_divisor = 1;
    imageConstraints.bytes_per_row_divisor = rowPitchAlignment;
    imageConstraints.start_offset_divisor = 1;
    imageConstraints.display_width_divisor = 1;
    imageConstraints.display_height_divisor = 1;
    imageConstraints.pixel_format.has_format_modifier = true;
    imageConstraints.pixel_format.format_modifier.value =
        (tiling == VK_IMAGE_TILING_LINEAR)
            ? fuchsia_sysmem::wire::kFormatModifierLinear
            : fuchsia_sysmem::wire::kFormatModifierGoogleGoldfishOptimal;

    constraints->image_format_constraints[constraints->image_format_constraints_count++] =
        imageConstraints;
    return VK_SUCCESS;
}

SetBufferCollectionBufferConstraintsResult setBufferCollectionBufferConstraintsImpl(
    fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>* pCollection,
    const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo) {
    const auto& collection = *pCollection;
    if (pBufferConstraintsInfo == nullptr) {
        mesa_loge(
            "setBufferCollectionBufferConstraints: "
            "pBufferConstraintsInfo cannot be null.");
        return {VK_ERROR_OUT_OF_DEVICE_MEMORY};
    }

    fuchsia_sysmem::wire::BufferCollectionConstraints constraints =
        defaultBufferCollectionConstraints(
            /* min_size_bytes */ pBufferConstraintsInfo->createInfo.size,
            /* buffer_count */ pBufferConstraintsInfo->bufferCollectionConstraints.minBufferCount);
    constraints.usage.vulkan =
        getBufferCollectionConstraintsVulkanBufferUsage(pBufferConstraintsInfo);

    constexpr uint32_t kVulkanPriority = 5;
    const char kName[] = "GoldfishBufferSysmemShared";
    collection->SetName(kVulkanPriority, fidl::StringView(kName));

    auto result = collection->SetConstraints(true, constraints);
    if (!result.ok()) {
        mesa_loge("setBufferCollectionConstraints: SetConstraints failed: %d", result.status());
        return {VK_ERROR_OUT_OF_DEVICE_MEMORY};
    }

    return {VK_SUCCESS, constraints};
}
#endif

uint64_t getAHardwareBufferId(AHardwareBuffer* ahw) {
    uint64_t id = 0;
#if defined(ANDROID)
    auto* gralloc = ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->grallocHelper();
    gralloc->getId(ahw, &id);
#else
    (void)ahw;
#endif
    return id;
}

void transformExternalResourceMemoryDedicatedRequirementsForGuest(
    VkMemoryDedicatedRequirements* dedicatedReqs) {
    dedicatedReqs->prefersDedicatedAllocation = VK_TRUE;
    dedicatedReqs->requiresDedicatedAllocation = VK_TRUE;
}

void ResourceTracker::transformImageMemoryRequirementsForGuestLocked(VkImage image,
                                                                     VkMemoryRequirements* reqs) {
#ifdef VK_USE_PLATFORM_FUCHSIA
    auto it = info_VkImage.find(image);
    if (it == info_VkImage.end()) return;
    auto& info = it->second;
    if (info.isSysmemBackedMemory) {
        auto width = info.createInfo.extent.width;
        auto height = info.createInfo.extent.height;
        reqs->size = width * height * 4;
    }
#else
    // Bypass "unused parameter" checks.
    (void)image;
    (void)reqs;
#endif
}

CoherentMemoryPtr ResourceTracker::freeCoherentMemoryLocked(VkDeviceMemory memory,
                                                            VkDeviceMemory_Info& info) {
    if (info.coherentMemory && info.ptr) {
        if (info.coherentMemory->getDeviceMemory() != memory) {
            delete_goldfish_VkDeviceMemory(memory);
        }

        if (info.ptr) {
            info.coherentMemory->release(info.ptr);
            info.ptr = nullptr;
        }

        return std::move(info.coherentMemory);
    }

    return nullptr;
}

VkResult acquireSync(uint64_t syncId, int64_t& osHandle) {
    struct VirtGpuExecBuffer exec = {};
    struct gfxstreamAcquireSync acquireSync = {};
    VirtGpuDevice* instance = VirtGpuDevice::getInstance();

    acquireSync.hdr.opCode = GFXSTREAM_ACQUIRE_SYNC;
    acquireSync.syncId = syncId;

    exec.command = static_cast<void*>(&acquireSync);
    exec.command_size = sizeof(acquireSync);
    exec.flags = kFenceOut | kRingIdx | kShareableOut;

    if (instance->execBuffer(exec, nullptr)) return VK_ERROR_OUT_OF_HOST_MEMORY;

    osHandle = exec.handle.osHandle;
    return VK_SUCCESS;
}

VkResult createFence(VkDevice device, uint64_t hostFenceHandle, int64_t& osHandle) {
    struct VirtGpuExecBuffer exec = {};
    struct gfxstreamCreateExportSyncVK exportSync = {};
    VirtGpuDevice* instance = VirtGpuDevice::getInstance();

    uint64_t hostDeviceHandle = get_host_u64_VkDevice(device);

    exportSync.hdr.opCode = GFXSTREAM_CREATE_EXPORT_SYNC_VK;
    exportSync.deviceHandleLo = (uint32_t)hostDeviceHandle;
    exportSync.deviceHandleHi = (uint32_t)(hostDeviceHandle >> 32);
    exportSync.fenceHandleLo = (uint32_t)hostFenceHandle;
    exportSync.fenceHandleHi = (uint32_t)(hostFenceHandle >> 32);

    exec.command = static_cast<void*>(&exportSync);
    exec.command_size = sizeof(exportSync);
    exec.flags = kFenceOut | kRingIdx;
    if (instance->execBuffer(exec, nullptr)) return VK_ERROR_OUT_OF_HOST_MEMORY;

    osHandle = exec.handle.osHandle;
    return VK_SUCCESS;
}

void collectAllPendingDescriptorSetsBottomUp(const std::vector<VkCommandBuffer>& workingSet,
                                             std::unordered_set<VkDescriptorSet>& allDs) {
    if (workingSet.empty()) return;

    std::vector<VkCommandBuffer> nextLevel;
    for (auto commandBuffer : workingSet) {
        struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(commandBuffer);
        forAllObjects(cb->subObjects, [&nextLevel](void* secondary) {
            nextLevel.push_back((VkCommandBuffer)secondary);
        });
    }

    collectAllPendingDescriptorSetsBottomUp(nextLevel, allDs);

    for (auto cmdbuf : workingSet) {
        struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(cmdbuf);

        if (!cb->userPtr) {
            continue;  // No descriptors to update.
        }

        CommandBufferPendingDescriptorSets* pendingDescriptorSets =
            (CommandBufferPendingDescriptorSets*)(cb->userPtr);

        if (pendingDescriptorSets->sets.empty()) {
            continue;  // No descriptors to update.
        }

        allDs.insert(pendingDescriptorSets->sets.begin(), pendingDescriptorSets->sets.end());
    }
}

void commitDescriptorSetUpdates(void* context, VkQueue queue,
                                const std::unordered_set<VkDescriptorSet>& sets) {
    VkEncoder* enc = (VkEncoder*)context;

    std::unordered_map<VkDescriptorPool, uint32_t> poolSet;
    std::vector<VkDescriptorPool> pools;
    std::vector<VkDescriptorSetLayout> setLayouts;
    std::vector<uint64_t> poolIds;
    std::vector<uint32_t> descriptorSetWhichPool;
    std::vector<uint32_t> pendingAllocations;
    std::vector<uint32_t> writeStartingIndices;
    std::vector<VkWriteDescriptorSet> writesForHost;

    uint32_t poolIndex = 0;
    uint32_t currentWriteIndex = 0;
    for (auto set : sets) {
        ReifiedDescriptorSet* reified = as_goldfish_VkDescriptorSet(set)->reified;
        VkDescriptorPool pool = reified->pool;
        VkDescriptorSetLayout setLayout = reified->setLayout;

        auto it = poolSet.find(pool);
        if (it == poolSet.end()) {
            poolSet[pool] = poolIndex;
            descriptorSetWhichPool.push_back(poolIndex);
            pools.push_back(pool);
            ++poolIndex;
        } else {
            uint32_t savedPoolIndex = it->second;
            descriptorSetWhichPool.push_back(savedPoolIndex);
        }

        poolIds.push_back(reified->poolId);
        setLayouts.push_back(setLayout);
        pendingAllocations.push_back(reified->allocationPending ? 1 : 0);
        writeStartingIndices.push_back(currentWriteIndex);

        auto& writes = reified->allWrites;

        for (size_t i = 0; i < writes.size(); ++i) {
            uint32_t binding = i;

            for (size_t j = 0; j < writes[i].size(); ++j) {
                auto& write = writes[i][j];

                if (write.type == DescriptorWriteType::Empty) continue;

                uint32_t dstArrayElement = 0;

                VkDescriptorImageInfo* imageInfo = nullptr;
                VkDescriptorBufferInfo* bufferInfo = nullptr;
                VkBufferView* bufferView = nullptr;

                switch (write.type) {
                    case DescriptorWriteType::Empty:
                        break;
                    case DescriptorWriteType::ImageInfo:
                        dstArrayElement = j;
                        imageInfo = &write.imageInfo;
                        break;
                    case DescriptorWriteType::BufferInfo:
                        dstArrayElement = j;
                        bufferInfo = &write.bufferInfo;
                        break;
                    case DescriptorWriteType::BufferView:
                        dstArrayElement = j;
                        bufferView = &write.bufferView;
                        break;
                    case DescriptorWriteType::InlineUniformBlock:
                    case DescriptorWriteType::AccelerationStructure:
                        // TODO
                        mesa_loge(
                            "Encountered pending inline uniform block or acceleration structure "
                            "desc write, abort (NYI)\n");
                        abort();
                    default:
                        break;
                }

                // TODO: Combine multiple writes into one VkWriteDescriptorSet.
                VkWriteDescriptorSet forHost = {
                    VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
                    0 /* TODO: inline uniform block */,
                    set,
                    binding,
                    dstArrayElement,
                    1,
                    write.descriptorType,
                    imageInfo,
                    bufferInfo,
                    bufferView,
                };

                writesForHost.push_back(forHost);
                ++currentWriteIndex;

                // Set it back to empty.
                write.type = DescriptorWriteType::Empty;
            }
        }
    }

    // Skip out if there's nothing to VkWriteDescriptorSet home about.
    if (writesForHost.empty()) {
        return;
    }

    enc->vkQueueCommitDescriptorSetUpdatesGOOGLE(
        queue, (uint32_t)pools.size(), pools.data(), (uint32_t)sets.size(), setLayouts.data(),
        poolIds.data(), descriptorSetWhichPool.data(), pendingAllocations.data(),
        writeStartingIndices.data(), (uint32_t)writesForHost.size(), writesForHost.data(),
        false /* no lock */);

    // If we got here, then we definitely serviced the allocations.
    for (auto set : sets) {
        ReifiedDescriptorSet* reified = as_goldfish_VkDescriptorSet(set)->reified;
        reified->allocationPending = false;
    }
}

uint32_t ResourceTracker::syncEncodersForCommandBuffer(VkCommandBuffer commandBuffer,
                                                       VkEncoder* currentEncoder) {
    struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(commandBuffer);
    if (!cb) return 0;

    auto lastEncoder = cb->lastUsedEncoder;

    if (lastEncoder == currentEncoder) return 0;

    currentEncoder->incRef();

    cb->lastUsedEncoder = currentEncoder;

    if (!lastEncoder) return 0;

    auto oldSeq = cb->sequenceNumber;
    cb->sequenceNumber += 2;
    lastEncoder->vkCommandBufferHostSyncGOOGLE(commandBuffer, false, oldSeq + 1,
                                               true /* do lock */);
    lastEncoder->flush();
    currentEncoder->vkCommandBufferHostSyncGOOGLE(commandBuffer, true, oldSeq + 2,
                                                  true /* do lock */);

    if (lastEncoder->decRef()) {
        cb->lastUsedEncoder = nullptr;
    }
    return 0;
}

void addPendingDescriptorSets(VkCommandBuffer commandBuffer, uint32_t descriptorSetCount,
                              const VkDescriptorSet* pDescriptorSets) {
    struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(commandBuffer);

    if (!cb->userPtr) {
        CommandBufferPendingDescriptorSets* newPendingSets = new CommandBufferPendingDescriptorSets;
        cb->userPtr = newPendingSets;
    }

    CommandBufferPendingDescriptorSets* pendingSets =
        (CommandBufferPendingDescriptorSets*)cb->userPtr;

    for (uint32_t i = 0; i < descriptorSetCount; ++i) {
        pendingSets->sets.insert(pDescriptorSets[i]);
    }
}

void decDescriptorSetLayoutRef(void* context, VkDevice device,
                               VkDescriptorSetLayout descriptorSetLayout,
                               const VkAllocationCallbacks* pAllocator) {
    if (!descriptorSetLayout) return;

    struct goldfish_VkDescriptorSetLayout* setLayout =
        as_goldfish_VkDescriptorSetLayout(descriptorSetLayout);

    if (0 == --setLayout->layoutInfo->refcount) {
        VkEncoder* enc = (VkEncoder*)context;
        enc->vkDestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator,
                                          true /* do lock */);
    }
}

void ResourceTracker::ensureSyncDeviceFd() {
#if GFXSTREAM_ENABLE_GUEST_GOLDFISH
    if (mSyncDeviceFd >= 0) return;
    mSyncDeviceFd = goldfish_sync_open();
    if (mSyncDeviceFd >= 0) {
        mesa_logd("%s: created sync device for current Vulkan process: %d\n", __func__, mSyncDeviceFd);
    } else {
        mesa_logd("%s: failed to create sync device for current Vulkan process\n", __func__);
    }
#endif
}

void ResourceTracker::unregister_VkInstance(VkInstance instance) {
    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto it = info_VkInstance.find(instance);
    if (it == info_VkInstance.end()) return;
    auto info = it->second;
    info_VkInstance.erase(instance);
}

void ResourceTracker::unregister_VkDevice(VkDevice device) {
    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto it = info_VkDevice.find(device);
    if (it == info_VkDevice.end()) return;
    auto info = it->second;
    info_VkDevice.erase(device);
}

void ResourceTracker::unregister_VkCommandPool(VkCommandPool pool) {
    if (!pool) return;

    clearCommandPool(pool);

    std::lock_guard<std::recursive_mutex> lock(mLock);
    info_VkCommandPool.erase(pool);
}

void ResourceTracker::unregister_VkSampler(VkSampler sampler) {
    if (!sampler) return;

    std::lock_guard<std::recursive_mutex> lock(mLock);
    info_VkSampler.erase(sampler);
}

void ResourceTracker::unregister_VkCommandBuffer(VkCommandBuffer commandBuffer) {
    resetCommandBufferStagingInfo(commandBuffer, true /* also reset primaries */,
                                  true /* also clear pending descriptor sets */);

    struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(commandBuffer);
    if (!cb) return;
    if (cb->lastUsedEncoder) {
        cb->lastUsedEncoder->decRef();
    }
    eraseObjects(&cb->subObjects);
    forAllObjects(cb->poolObjects, [cb](void* commandPool) {
        struct goldfish_VkCommandPool* p = as_goldfish_VkCommandPool((VkCommandPool)commandPool);
        eraseObject(&p->subObjects, (void*)cb);
    });
    eraseObjects(&cb->poolObjects);

    if (cb->userPtr) {
        CommandBufferPendingDescriptorSets* pendingSets =
            (CommandBufferPendingDescriptorSets*)cb->userPtr;
        delete pendingSets;
    }

    std::lock_guard<std::recursive_mutex> lock(mLock);
    info_VkCommandBuffer.erase(commandBuffer);
}

void ResourceTracker::unregister_VkQueue(VkQueue queue) {
    struct goldfish_VkQueue* q = as_goldfish_VkQueue(queue);
    if (!q) return;
    if (q->lastUsedEncoder) {
        q->lastUsedEncoder->decRef();
    }

    std::lock_guard<std::recursive_mutex> lock(mLock);
    info_VkQueue.erase(queue);
}

void ResourceTracker::unregister_VkDeviceMemory(VkDeviceMemory mem) {
    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto it = info_VkDeviceMemory.find(mem);
    if (it == info_VkDeviceMemory.end()) return;

    auto& memInfo = it->second;

#ifdef VK_USE_PLATFORM_ANDROID_KHR
    if (memInfo.ahw) {
        auto* gralloc =
            ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->grallocHelper();
        gralloc->release(memInfo.ahw);
    }
#endif

    if (memInfo.vmoHandle != ZX_HANDLE_INVALID) {
        zx_handle_close(memInfo.vmoHandle);
    }

    info_VkDeviceMemory.erase(mem);
}

void ResourceTracker::unregister_VkImage(VkImage img) {
    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto it = info_VkImage.find(img);
    if (it == info_VkImage.end()) return;

    auto& imageInfo = it->second;

    info_VkImage.erase(img);
}

void ResourceTracker::unregister_VkBuffer(VkBuffer buf) {
    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto it = info_VkBuffer.find(buf);
    if (it == info_VkBuffer.end()) return;

    info_VkBuffer.erase(buf);
}

void ResourceTracker::unregister_VkSemaphore(VkSemaphore sem) {
    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto it = info_VkSemaphore.find(sem);
    if (it == info_VkSemaphore.end()) return;

    auto& semInfo = it->second;

    if (semInfo.eventHandle != ZX_HANDLE_INVALID) {
        zx_handle_close(semInfo.eventHandle);
    }

#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
    if (semInfo.syncFd.value_or(-1) >= 0) {
        auto* syncHelper =
            ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->syncHelper();
        syncHelper->close(semInfo.syncFd.value());
    }
#endif

    info_VkSemaphore.erase(sem);
}

void ResourceTracker::unregister_VkDescriptorUpdateTemplate(VkDescriptorUpdateTemplate templ) {
    std::lock_guard<std::recursive_mutex> lock(mLock);
    auto it = info_VkDescriptorUpdateTemplate.find(templ);
    if (it == info_VkDescriptorUpdateTemplate.end()) return;

    auto& info = it->second;
    if (info.templateEntryCount) delete[] info.templateEntries;
    if (info.imageInfoCount) {
        delete[] info.imageInfoIndices;
        delete[] info.imageInfos;
    }
    if (info.bufferInfoCount) {
        delete[] info.bufferInfoIndices;
        delete[] info.bufferInfos;
    }
    if (info.bufferViewCount) {
        delete[] info.bufferViewIndices;
        delete[] info.bufferViews;
    }
    info_VkDescriptorUpdateTemplate.erase(it);
}

void ResourceTracker::unregister_VkFence(VkFence fence) {
    std::lock_guard<std::recursive_mutex> lock(mLock);
    auto it = info_VkFence.find(fence);
    if (it == info_VkFence.end()) return;

    auto& fenceInfo = it->second;
    (void)fenceInfo;

#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
    if (fenceInfo.syncFd >= 0) {
        auto* syncHelper =
            ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->syncHelper();
        syncHelper->close(fenceInfo.syncFd);
    }
#endif

    info_VkFence.erase(fence);
}

#ifdef VK_USE_PLATFORM_FUCHSIA
void ResourceTracker::unregister_VkBufferCollectionFUCHSIA(VkBufferCollectionFUCHSIA collection) {
    std::lock_guard<std::recursive_mutex> lock(mLock);
    info_VkBufferCollectionFUCHSIA.erase(collection);
}
#endif

void ResourceTracker::unregister_VkDescriptorSet_locked(VkDescriptorSet set) {
    struct goldfish_VkDescriptorSet* ds = as_goldfish_VkDescriptorSet(set);
    delete ds->reified;
    info_VkDescriptorSet.erase(set);
}

void ResourceTracker::unregister_VkDescriptorSet(VkDescriptorSet set) {
    if (!set) return;

    std::lock_guard<std::recursive_mutex> lock(mLock);
    unregister_VkDescriptorSet_locked(set);
}

void ResourceTracker::unregister_VkDescriptorSetLayout(VkDescriptorSetLayout setLayout) {
    if (!setLayout) return;

    std::lock_guard<std::recursive_mutex> lock(mLock);
    delete as_goldfish_VkDescriptorSetLayout(setLayout)->layoutInfo;
    info_VkDescriptorSetLayout.erase(setLayout);
}

void ResourceTracker::freeDescriptorSetsIfHostAllocated(VkEncoder* enc, VkDevice device,
                                                        uint32_t descriptorSetCount,
                                                        const VkDescriptorSet* sets) {
    for (uint32_t i = 0; i < descriptorSetCount; ++i) {
        struct goldfish_VkDescriptorSet* ds = as_goldfish_VkDescriptorSet(sets[i]);
        if (ds->reified->allocationPending) {
            unregister_VkDescriptorSet(sets[i]);
            delete_goldfish_VkDescriptorSet(sets[i]);
        } else {
            enc->vkFreeDescriptorSets(device, ds->reified->pool, 1, &sets[i], false /* no lock */);
        }
    }
}

void ResourceTracker::clearDescriptorPoolAndUnregisterDescriptorSets(void* context, VkDevice device,
                                                                     VkDescriptorPool pool) {
    std::vector<VkDescriptorSet> toClear =
        clearDescriptorPool(pool, mFeatureInfo->hasVulkanBatchedDescriptorSetUpdate);

    for (auto set : toClear) {
        if (mFeatureInfo->hasVulkanBatchedDescriptorSetUpdate) {
            VkDescriptorSetLayout setLayout = as_goldfish_VkDescriptorSet(set)->reified->setLayout;
            decDescriptorSetLayoutRef(context, device, setLayout, nullptr);
        }
        unregister_VkDescriptorSet(set);
        delete_goldfish_VkDescriptorSet(set);
    }
}

void ResourceTracker::unregister_VkDescriptorPool(VkDescriptorPool pool) {
    if (!pool) return;

    std::lock_guard<std::recursive_mutex> lock(mLock);

    struct goldfish_VkDescriptorPool* dp = as_goldfish_VkDescriptorPool(pool);
    delete dp->allocInfo;

    info_VkDescriptorPool.erase(pool);
}

void ResourceTracker::deviceMemoryTransform_fromhost(VkDeviceMemory* memory, uint32_t memoryCount,
                                                     VkDeviceSize* offset, uint32_t offsetCount,
                                                     VkDeviceSize* size, uint32_t sizeCount,
                                                     uint32_t* typeIndex, uint32_t typeIndexCount,
                                                     uint32_t* typeBits, uint32_t typeBitsCount) {
    (void)memory;
    (void)memoryCount;
    (void)offset;
    (void)offsetCount;
    (void)size;
    (void)sizeCount;
    (void)typeIndex;
    (void)typeIndexCount;
    (void)typeBits;
    (void)typeBitsCount;
}

void ResourceTracker::transformImpl_VkExternalMemoryProperties_fromhost(
    VkExternalMemoryProperties* pProperties, uint32_t) {
    VkExternalMemoryHandleTypeFlags supportedHandleType = 0u;
#ifdef VK_USE_PLATFORM_FUCHSIA
    supportedHandleType |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA;
#endif  // VK_USE_PLATFORM_FUCHSIA
#ifdef VK_USE_PLATFORM_ANDROID_KHR
    supportedHandleType |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
                           VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
#endif  // VK_USE_PLATFORM_ANDROID_KHR
    if (supportedHandleType) {
        pProperties->compatibleHandleTypes &= supportedHandleType;
        pProperties->exportFromImportedHandleTypes &= supportedHandleType;
    }
}

void ResourceTracker::setInstanceInfo(VkInstance instance, uint32_t enabledExtensionCount,
                                      const char* const* ppEnabledExtensionNames,
                                      uint32_t apiVersion) {
    std::lock_guard<std::recursive_mutex> lock(mLock);
    auto& info = info_VkInstance[instance];
    info.highestApiVersion = apiVersion;

    if (!ppEnabledExtensionNames) return;

    for (uint32_t i = 0; i < enabledExtensionCount; ++i) {
        info.enabledExtensions.insert(ppEnabledExtensionNames[i]);
    }
}

void ResourceTracker::setDeviceInfo(VkDevice device, VkPhysicalDevice physdev,
                                    VkPhysicalDeviceProperties props,
                                    VkPhysicalDeviceMemoryProperties memProps,
                                    uint32_t enabledExtensionCount,
                                    const char* const* ppEnabledExtensionNames, const void* pNext) {
    std::lock_guard<std::recursive_mutex> lock(mLock);
    auto& info = info_VkDevice[device];
    info.physdev = physdev;
    info.props = props;
    info.memProps = memProps;
    info.apiVersion = props.apiVersion;

    const VkBaseInStructure* extensionCreateInfo =
        reinterpret_cast<const VkBaseInStructure*>(pNext);
    while (extensionCreateInfo) {
        if (extensionCreateInfo->sType ==
            VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT) {
            auto deviceMemoryReportCreateInfo =
                reinterpret_cast<const VkDeviceDeviceMemoryReportCreateInfoEXT*>(
                    extensionCreateInfo);
            if (deviceMemoryReportCreateInfo->pfnUserCallback != nullptr) {
                info.deviceMemoryReportCallbacks.emplace_back(
                    deviceMemoryReportCreateInfo->pfnUserCallback,
                    deviceMemoryReportCreateInfo->pUserData);
            }
        }
        extensionCreateInfo = extensionCreateInfo->pNext;
    }

    if (!ppEnabledExtensionNames) return;

    for (uint32_t i = 0; i < enabledExtensionCount; ++i) {
        info.enabledExtensions.insert(ppEnabledExtensionNames[i]);
    }
}

void ResourceTracker::setDeviceMemoryInfo(VkDevice device, VkDeviceMemory memory,
                                          VkDeviceSize allocationSize, uint8_t* ptr,
                                          uint32_t memoryTypeIndex, AHardwareBuffer* ahw,
                                          bool imported, zx_handle_t vmoHandle,
                                          VirtGpuResourcePtr blobPtr) {
    std::lock_guard<std::recursive_mutex> lock(mLock);
    auto& info = info_VkDeviceMemory[memory];

    info.device = device;
    info.allocationSize = allocationSize;
    info.ptr = ptr;
    info.memoryTypeIndex = memoryTypeIndex;
#ifdef VK_USE_PLATFORM_ANDROID_KHR
    info.ahw = ahw;
#endif
    info.imported = imported;
    info.vmoHandle = vmoHandle;
    info.blobPtr = blobPtr;
}

void ResourceTracker::setImageInfo(VkImage image, VkDevice device,
                                   const VkImageCreateInfo* pCreateInfo) {
    std::lock_guard<std::recursive_mutex> lock(mLock);
    auto& info = info_VkImage[image];

    info.device = device;
    info.createInfo = *pCreateInfo;
}

uint8_t* ResourceTracker::getMappedPointer(VkDeviceMemory memory) {
    std::lock_guard<std::recursive_mutex> lock(mLock);
    const auto it = info_VkDeviceMemory.find(memory);
    if (it == info_VkDeviceMemory.end()) return nullptr;

    const auto& info = it->second;
    return info.ptr;
}

VkDeviceSize ResourceTracker::getMappedSize(VkDeviceMemory memory) {
    std::lock_guard<std::recursive_mutex> lock(mLock);
    const auto it = info_VkDeviceMemory.find(memory);
    if (it == info_VkDeviceMemory.end()) return 0;

    const auto& info = it->second;
    return info.allocationSize;
}

bool ResourceTracker::isValidMemoryRange(const VkMappedMemoryRange& range) {
    std::lock_guard<std::recursive_mutex> lock(mLock);
    const auto it = info_VkDeviceMemory.find(range.memory);
    if (it == info_VkDeviceMemory.end()) return false;
    const auto& info = it->second;

    if (!info.ptr) return false;

    VkDeviceSize offset = range.offset;
    VkDeviceSize size = range.size;

    if (size == VK_WHOLE_SIZE) {
        return offset <= info.allocationSize;
    }

    return offset + size <= info.allocationSize;
}

void ResourceTracker::setupCaps(uint32_t& noRenderControlEnc) {
    VirtGpuDevice* instance = VirtGpuDevice::getInstance(kCapsetGfxStreamVulkan);
    mCaps = instance->getCaps();

    // Delete once goldfish Linux drivers are gone
    if (mCaps.vulkanCapset.protocolVersion == 0) {
        mCaps.vulkanCapset.colorBufferMemoryIndex = 0xFFFFFFFF;
    } else {
        // Don't query the render control encoder for features, since for virtio-gpu the
        // capabilities provide versioning. Set features to be unconditionally true, since
        // using virtio-gpu encompasses all prior goldfish features.  mFeatureInfo should be
        // deprecated in favor of caps.

        mFeatureInfo.reset(new EmulatorFeatureInfo);

        mFeatureInfo->hasVulkanNullOptionalStrings = true;
        mFeatureInfo->hasVulkanIgnoredHandles = true;
        mFeatureInfo->hasVulkanShaderFloat16Int8 = true;
        mFeatureInfo->hasVulkanQueueSubmitWithCommands = true;
        mFeatureInfo->hasDeferredVulkanCommands = true;
        mFeatureInfo->hasVulkanAsyncQueueSubmit = true;
        mFeatureInfo->hasVulkanCreateResourcesWithRequirements = true;
        mFeatureInfo->hasVirtioGpuNext = true;
        mFeatureInfo->hasVirtioGpuNativeSync = true;
        mFeatureInfo->hasVulkanBatchedDescriptorSetUpdate = true;
        mFeatureInfo->hasVulkanAsyncQsri = true;

        ResourceTracker::streamFeatureBits |= VULKAN_STREAM_FEATURE_NULL_OPTIONAL_STRINGS_BIT;
        ResourceTracker::streamFeatureBits |= VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT;
        ResourceTracker::streamFeatureBits |= VULKAN_STREAM_FEATURE_SHADER_FLOAT16_INT8_BIT;
        ResourceTracker::streamFeatureBits |= VULKAN_STREAM_FEATURE_QUEUE_SUBMIT_WITH_COMMANDS_BIT;
    }

    noRenderControlEnc = mCaps.vulkanCapset.noRenderControlEnc;
}

void ResourceTracker::setupFeatures(const EmulatorFeatureInfo* features) {
    if (!features || mFeatureInfo) return;
    mFeatureInfo.reset(new EmulatorFeatureInfo);
    *mFeatureInfo = *features;

#if defined(__ANDROID__)
    if (mFeatureInfo->hasDirectMem) {
        mGoldfishAddressSpaceBlockProvider.reset(
            new GoldfishAddressSpaceBlockProvider(GoldfishAddressSpaceSubdeviceType::NoSubdevice));
    }
#endif  // defined(__ANDROID__)

#ifdef VK_USE_PLATFORM_FUCHSIA
    if (mFeatureInfo->hasVulkan) {
        fidl::ClientEnd<fuchsia_hardware_goldfish::ControlDevice> channel{zx::channel(
            GetConnectToServiceFunction()("/loader-gpu-devices/class/goldfish-control/000"))};
        if (!channel) {
            mesa_loge("failed to open control device");
            abort();
        }
        mControlDevice =
            fidl::WireSyncClient<fuchsia_hardware_goldfish::ControlDevice>(std::move(channel));

        fidl::ClientEnd<fuchsia_sysmem::Allocator> sysmem_channel{
            zx::channel(GetConnectToServiceFunction()("/svc/fuchsia.sysmem.Allocator"))};
        if (!sysmem_channel) {
            mesa_loge("failed to open sysmem connection");
        }
        mSysmemAllocator =
            fidl::WireSyncClient<fuchsia_sysmem::Allocator>(std::move(sysmem_channel));
        char name[ZX_MAX_NAME_LEN] = {};
        zx_object_get_property(zx_process_self(), ZX_PROP_NAME, name, sizeof(name));
        std::string client_name(name);
        client_name += "-goldfish";
        zx_info_handle_basic_t info;
        zx_object_get_info(zx_process_self(), ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr,
                           nullptr);
        mSysmemAllocator->SetDebugClientInfo(fidl::StringView::FromExternal(client_name),
                                             info.koid);
    }
#endif

    if (mFeatureInfo->hasVulkanNullOptionalStrings) {
        ResourceTracker::streamFeatureBits |= VULKAN_STREAM_FEATURE_NULL_OPTIONAL_STRINGS_BIT;
    }
    if (mFeatureInfo->hasVulkanIgnoredHandles) {
        ResourceTracker::streamFeatureBits |= VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT;
    }
    if (mFeatureInfo->hasVulkanShaderFloat16Int8) {
        ResourceTracker::streamFeatureBits |= VULKAN_STREAM_FEATURE_SHADER_FLOAT16_INT8_BIT;
    }
    if (mFeatureInfo->hasVulkanQueueSubmitWithCommands) {
        ResourceTracker::streamFeatureBits |= VULKAN_STREAM_FEATURE_QUEUE_SUBMIT_WITH_COMMANDS_BIT;
    }
}

void ResourceTracker::setThreadingCallbacks(const ResourceTracker::ThreadingCallbacks& callbacks) {
    ResourceTracker::threadingCallbacks = callbacks;
}

bool ResourceTracker::hostSupportsVulkan() const {
    if (!mFeatureInfo) return false;

    return mFeatureInfo->hasVulkan;
}

bool ResourceTracker::usingDirectMapping() const { return true; }

uint32_t ResourceTracker::getStreamFeatures() const { return ResourceTracker::streamFeatureBits; }

bool ResourceTracker::supportsDeferredCommands() const {
    if (!mFeatureInfo) return false;
    return mFeatureInfo->hasDeferredVulkanCommands;
}

bool ResourceTracker::supportsAsyncQueueSubmit() const {
    if (!mFeatureInfo) return false;
    return mFeatureInfo->hasVulkanAsyncQueueSubmit;
}

bool ResourceTracker::supportsCreateResourcesWithRequirements() const {
    if (!mFeatureInfo) return false;
    return mFeatureInfo->hasVulkanCreateResourcesWithRequirements;
}

int ResourceTracker::getHostInstanceExtensionIndex(const std::string& extName) const {
    int i = 0;
    for (const auto& prop : mHostInstanceExtensions) {
        if (extName == std::string(prop.extensionName)) {
            return i;
        }
        ++i;
    }
    return -1;
}

int ResourceTracker::getHostDeviceExtensionIndex(const std::string& extName) const {
    int i = 0;
    for (const auto& prop : mHostDeviceExtensions) {
        if (extName == std::string(prop.extensionName)) {
            return i;
        }
        ++i;
    }
    return -1;
}

void ResourceTracker::deviceMemoryTransform_tohost(VkDeviceMemory* memory, uint32_t memoryCount,
                                                   VkDeviceSize* offset, uint32_t offsetCount,
                                                   VkDeviceSize* size, uint32_t sizeCount,
                                                   uint32_t* typeIndex, uint32_t typeIndexCount,
                                                   uint32_t* typeBits, uint32_t typeBitsCount) {
    (void)memoryCount;
    (void)offsetCount;
    (void)sizeCount;
    (void)typeIndex;
    (void)typeIndexCount;
    (void)typeBits;
    (void)typeBitsCount;

    if (memory) {
        std::lock_guard<std::recursive_mutex> lock(mLock);

        for (uint32_t i = 0; i < memoryCount; ++i) {
            VkDeviceMemory mem = memory[i];

            auto it = info_VkDeviceMemory.find(mem);
            if (it == info_VkDeviceMemory.end()) return;

            const auto& info = it->second;

            if (!info.coherentMemory) continue;

            memory[i] = info.coherentMemory->getDeviceMemory();

            if (offset) {
                offset[i] = info.coherentMemoryOffset + offset[i];
            }

            if (size && size[i] == VK_WHOLE_SIZE) {
                size[i] = info.allocationSize;
            }

            // TODO
            (void)memory;
            (void)offset;
            (void)size;
        }
    }
}

uint32_t ResourceTracker::getColorBufferMemoryIndex(void* context, VkDevice device) {
    // Create test image to get the memory requirements
    VkEncoder* enc = (VkEncoder*)context;
    VkImageCreateInfo createInfo = {
        .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
        .imageType = VK_IMAGE_TYPE_2D,
        .format = VK_FORMAT_R8G8B8A8_UNORM,
        .extent = {64, 64, 1},
        .mipLevels = 1,
        .arrayLayers = 1,
        .samples = VK_SAMPLE_COUNT_1_BIT,
        .tiling = VK_IMAGE_TILING_OPTIMAL,
        .usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
                 VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
                 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
        .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
    };
    VkImage image = VK_NULL_HANDLE;
    VkResult res = enc->vkCreateImage(device, &createInfo, nullptr, &image, true /* do lock */);

    if (res != VK_SUCCESS) {
        return 0;
    }

    VkMemoryRequirements memReqs;
    enc->vkGetImageMemoryRequirements(device, image, &memReqs, true /* do lock */);
    enc->vkDestroyImage(device, image, nullptr, true /* do lock */);

    const VkPhysicalDeviceMemoryProperties& memProps =
        getPhysicalDeviceMemoryProperties(context, device, VK_NULL_HANDLE);

    // Currently, host looks for the last index that has with memory
    // property type VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
    VkMemoryPropertyFlags memoryProperty = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
    for (int i = VK_MAX_MEMORY_TYPES - 1; i >= 0; --i) {
        if ((memReqs.memoryTypeBits & (1u << i)) &&
            (memProps.memoryTypes[i].propertyFlags & memoryProperty)) {
            return i;
        }
    }

    return 0;
}

VkResult ResourceTracker::on_vkEnumerateInstanceExtensionProperties(
    void* context, VkResult, const char*, uint32_t* pPropertyCount,
    VkExtensionProperties* pProperties) {
    std::vector<const char*> allowedExtensionNames = {
        "VK_KHR_get_physical_device_properties2",
        "VK_KHR_sampler_ycbcr_conversion",
#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
        "VK_KHR_external_semaphore_capabilities",
        "VK_KHR_external_memory_capabilities",
        "VK_KHR_external_fence_capabilities",
        "VK_EXT_debug_utils",
#endif
    };

    VkEncoder* enc = (VkEncoder*)context;

    // Only advertise a select set of extensions.
    if (mHostInstanceExtensions.empty()) {
        uint32_t hostPropCount = 0;
        enc->vkEnumerateInstanceExtensionProperties(nullptr, &hostPropCount, nullptr,
                                                    true /* do lock */);
        mHostInstanceExtensions.resize(hostPropCount);

        VkResult hostRes = enc->vkEnumerateInstanceExtensionProperties(
            nullptr, &hostPropCount, mHostInstanceExtensions.data(), true /* do lock */);

        if (hostRes != VK_SUCCESS) {
            return hostRes;
        }
    }

    std::vector<VkExtensionProperties> filteredExts;

    for (size_t i = 0; i < allowedExtensionNames.size(); ++i) {
        auto extIndex = getHostInstanceExtensionIndex(allowedExtensionNames[i]);
        if (extIndex != -1) {
            filteredExts.push_back(mHostInstanceExtensions[extIndex]);
        }
    }

    VkExtensionProperties anbExtProps[] = {
#ifdef VK_USE_PLATFORM_FUCHSIA
        {"VK_KHR_external_memory_capabilities", 1},
        {"VK_KHR_external_semaphore_capabilities", 1},
#endif
    };

    for (auto& anbExtProp : anbExtProps) {
        filteredExts.push_back(anbExtProp);
    }

    // Spec:
    //
    // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkEnumerateInstanceExtensionProperties.html
    //
    // If pProperties is NULL, then the number of extensions properties
    // available is returned in pPropertyCount. Otherwise, pPropertyCount
    // must point to a variable set by the user to the number of elements
    // in the pProperties array, and on return the variable is overwritten
    // with the number of structures actually written to pProperties. If
    // pPropertyCount is less than the number of extension properties
    // available, at most pPropertyCount structures will be written. If
    // pPropertyCount is smaller than the number of extensions available,
    // VK_INCOMPLETE will be returned instead of VK_SUCCESS, to indicate
    // that not all the available properties were returned.
    //
    // pPropertyCount must be a valid pointer to a uint32_t value
    if (!pPropertyCount) return VK_ERROR_INITIALIZATION_FAILED;

    if (!pProperties) {
        *pPropertyCount = (uint32_t)filteredExts.size();
        return VK_SUCCESS;
    } else {
        auto actualExtensionCount = (uint32_t)filteredExts.size();
        if (*pPropertyCount > actualExtensionCount) {
            *pPropertyCount = actualExtensionCount;
        }

        for (uint32_t i = 0; i < *pPropertyCount; ++i) {
            pProperties[i] = filteredExts[i];
        }

        if (actualExtensionCount > *pPropertyCount) {
            return VK_INCOMPLETE;
        }

        return VK_SUCCESS;
    }
}

VkResult ResourceTracker::on_vkEnumerateDeviceExtensionProperties(
    void* context, VkResult, VkPhysicalDevice physdev, const char*, uint32_t* pPropertyCount,
    VkExtensionProperties* pProperties) {
    std::vector<const char*> allowedExtensionNames = {
        "VK_KHR_vulkan_memory_model",
        "VK_KHR_buffer_device_address",
        "VK_KHR_maintenance1",
        "VK_KHR_maintenance2",
        "VK_KHR_maintenance3",
        "VK_KHR_bind_memory2",
        "VK_KHR_dedicated_allocation",
        "VK_KHR_get_memory_requirements2",
        "VK_KHR_sampler_ycbcr_conversion",
        "VK_KHR_shader_float16_int8",
    // Timeline semaphores buggy in newer NVIDIA drivers
    // (vkWaitSemaphoresKHR causes further vkCommandBuffer dispatches to deadlock)
#ifndef VK_USE_PLATFORM_ANDROID_KHR
        "VK_KHR_timeline_semaphore",
#endif
        "VK_AMD_gpu_shader_half_float",
        "VK_NV_shader_subgroup_partitioned",
        "VK_KHR_shader_subgroup_extended_types",
        "VK_EXT_subgroup_size_control",
        "VK_EXT_provoking_vertex",
        "VK_EXT_line_rasterization",
        "VK_KHR_shader_terminate_invocation",
        "VK_EXT_transform_feedback",
        "VK_EXT_primitive_topology_list_restart",
        "VK_EXT_index_type_uint8",
        "VK_EXT_load_store_op_none",
        "VK_EXT_swapchain_colorspace",
        "VK_EXT_image_robustness",
        "VK_EXT_custom_border_color",
        "VK_EXT_shader_stencil_export",
        "VK_KHR_image_format_list",
        "VK_KHR_incremental_present",
        "VK_KHR_pipeline_executable_properties",
        "VK_EXT_queue_family_foreign",
        "VK_EXT_scalar_block_layout",
        "VK_KHR_descriptor_update_template",
        "VK_KHR_storage_buffer_storage_class",
        "VK_EXT_depth_clip_enable",
        "VK_KHR_create_renderpass2",
        "VK_EXT_vertex_attribute_divisor",
        "VK_EXT_host_query_reset",
#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
        "VK_KHR_external_semaphore",
        "VK_KHR_external_semaphore_fd",
        // "VK_KHR_external_semaphore_win32", not exposed because it's translated to fd
        "VK_KHR_external_memory",
        "VK_KHR_external_fence",
        "VK_KHR_external_fence_fd",
        "VK_EXT_device_memory_report",
#endif
#if defined(__linux__) && !defined(VK_USE_PLATFORM_ANDROID_KHR)
        "VK_KHR_imageless_framebuffer",
#endif
        // Vulkan 1.3
        "VK_KHR_synchronization2",
        "VK_EXT_private_data",
        "VK_EXT_color_write_enable",
    };

    VkEncoder* enc = (VkEncoder*)context;

    if (mHostDeviceExtensions.empty()) {
        uint32_t hostPropCount = 0;
        enc->vkEnumerateDeviceExtensionProperties(physdev, nullptr, &hostPropCount, nullptr,
                                                  true /* do lock */);
        mHostDeviceExtensions.resize(hostPropCount);

        VkResult hostRes = enc->vkEnumerateDeviceExtensionProperties(
            physdev, nullptr, &hostPropCount, mHostDeviceExtensions.data(), true /* do lock */);

        if (hostRes != VK_SUCCESS) {
            return hostRes;
        }
    }

    std::vector<VkExtensionProperties> filteredExts;

    for (size_t i = 0; i < allowedExtensionNames.size(); ++i) {
        auto extIndex = getHostDeviceExtensionIndex(allowedExtensionNames[i]);
        if (extIndex != -1) {
            filteredExts.push_back(mHostDeviceExtensions[extIndex]);
        }
    }

    VkExtensionProperties anbExtProps[] = {
#ifdef VK_USE_PLATFORM_ANDROID_KHR
        {"VK_ANDROID_native_buffer", 7},
#endif
#ifdef VK_USE_PLATFORM_FUCHSIA
        {"VK_KHR_external_memory", 1},
        {"VK_KHR_external_semaphore", 1},
        {"VK_FUCHSIA_external_semaphore", 1},
#endif
    };

    for (auto& anbExtProp : anbExtProps) {
        filteredExts.push_back(anbExtProp);
    }

    /*
     * GfxstreamEnd2EndVkTest::DeviceMemoryReport always assumes the memory report
     * extension is present.  It's is filtered out when sent host side, since for a
     * virtual GPU this is quite difficult to implement.
     *
     * Mesa runtime checks physical device features.  So if the test tries to enable
     * device level extension without it definitely existing, the test will fail.
     *
     * The test can also be modified to check VkPhysicalDeviceDeviceMemoryReportFeaturesEXT,
     * but that's more involved.  Work around this by always advertising the extension.
     * Tracking bug: b/338270042
     */
    filteredExts.push_back(VkExtensionProperties{"VK_EXT_device_memory_report", 1});

#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
    bool hostSupportsExternalFenceFd =
        getHostDeviceExtensionIndex("VK_KHR_external_fence_fd") != -1;
    if (!hostSupportsExternalFenceFd) {
        filteredExts.push_back(VkExtensionProperties{"VK_KHR_external_fence_fd", 1});
    }
#endif

#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
    bool hostHasPosixExternalSemaphore =
        getHostDeviceExtensionIndex("VK_KHR_external_semaphore_fd") != -1;
    if (!hostHasPosixExternalSemaphore) {
        // Always advertise posix external semaphore capabilities on Android/Linux.
        // SYNC_FD handles will always work, regardless of host support. Support
        // for non-sync, opaque FDs, depends on host driver support, but will
        // be handled accordingly by host.
        filteredExts.push_back(VkExtensionProperties{"VK_KHR_external_semaphore_fd", 1});
    }
#endif

    bool win32ExtMemAvailable = getHostDeviceExtensionIndex("VK_KHR_external_memory_win32") != -1;
    bool posixExtMemAvailable = getHostDeviceExtensionIndex("VK_KHR_external_memory_fd") != -1;
    //TODO(b/349066492): this should check external_memory_metal extension when it's ready
    bool moltenVkExtAvailable = getHostDeviceExtensionIndex("VK_MVK_moltenvk") != -1;
    bool qnxExtMemAvailable =
        getHostDeviceExtensionIndex("VK_QNX_external_memory_screen_buffer") != -1;

    bool hostHasExternalMemorySupport =
        win32ExtMemAvailable || posixExtMemAvailable || moltenVkExtAvailable || qnxExtMemAvailable;

    if (hostHasExternalMemorySupport) {
#ifdef VK_USE_PLATFORM_ANDROID_KHR
        filteredExts.push_back(
            VkExtensionProperties{"VK_ANDROID_external_memory_android_hardware_buffer", 7});
        filteredExts.push_back(VkExtensionProperties{"VK_EXT_queue_family_foreign", 1});
#endif
#ifdef VK_USE_PLATFORM_FUCHSIA
        filteredExts.push_back(VkExtensionProperties{"VK_FUCHSIA_external_memory", 1});
        filteredExts.push_back(VkExtensionProperties{"VK_FUCHSIA_buffer_collection", 1});
#endif
#if !defined(VK_USE_PLATFORM_ANDROID_KHR) && defined(__linux__)
        filteredExts.push_back(VkExtensionProperties{"VK_KHR_external_memory_fd", 1});
        filteredExts.push_back(VkExtensionProperties{"VK_EXT_external_memory_dma_buf", 1});
#endif
    }

    // NOTE: the Vulkan Loader's trampoline functions will remove duplicates. This can lead
    // to lead errors if this function returns VK_SUCCESS with N elements (including a duplicate)
    // but the Vulkan Loader's trampoline function returns VK_INCOMPLETE with N-1 elements
    // (without the duplicate).
    std::sort(filteredExts.begin(),
              filteredExts.end(),
              [](const VkExtensionProperties& a,
                 const VkExtensionProperties& b) {
                  return strcmp(a.extensionName, b.extensionName) < 0;
              });
    filteredExts.erase(std::unique(filteredExts.begin(),
                                   filteredExts.end(),
                                   [](const VkExtensionProperties& a,
                                      const VkExtensionProperties& b) {
                                       return strcmp(a.extensionName, b.extensionName) == 0;
                                   }),
                       filteredExts.end());

    // Spec:
    //
    // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkEnumerateDeviceExtensionProperties.html
    //
    // pPropertyCount is a pointer to an integer related to the number of
    // extension properties available or queried, and is treated in the
    // same fashion as the
    // vkEnumerateInstanceExtensionProperties::pPropertyCount parameter.
    //
    // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkEnumerateInstanceExtensionProperties.html
    //
    // If pProperties is NULL, then the number of extensions properties
    // available is returned in pPropertyCount. Otherwise, pPropertyCount
    // must point to a variable set by the user to the number of elements
    // in the pProperties array, and on return the variable is overwritten
    // with the number of structures actually written to pProperties. If
    // pPropertyCount is less than the number of extension properties
    // available, at most pPropertyCount structures will be written. If
    // pPropertyCount is smaller than the number of extensions available,
    // VK_INCOMPLETE will be returned instead of VK_SUCCESS, to indicate
    // that not all the available properties were returned.
    //
    // pPropertyCount must be a valid pointer to a uint32_t value

    if (!pPropertyCount) return VK_ERROR_INITIALIZATION_FAILED;

    if (!pProperties) {
        *pPropertyCount = (uint32_t)filteredExts.size();
        return VK_SUCCESS;
    } else {
        auto actualExtensionCount = (uint32_t)filteredExts.size();
        if (*pPropertyCount > actualExtensionCount) {
            *pPropertyCount = actualExtensionCount;
        }

        for (uint32_t i = 0; i < *pPropertyCount; ++i) {
            pProperties[i] = filteredExts[i];
        }

        if (actualExtensionCount > *pPropertyCount) {
            return VK_INCOMPLETE;
        }

        return VK_SUCCESS;
    }
}

VkResult ResourceTracker::on_vkEnumeratePhysicalDevices(void* context, VkResult,
                                                        VkInstance instance,
                                                        uint32_t* pPhysicalDeviceCount,
                                                        VkPhysicalDevice* pPhysicalDevices) {
    VkEncoder* enc = (VkEncoder*)context;

    if (!instance) return VK_ERROR_INITIALIZATION_FAILED;

    if (!pPhysicalDeviceCount) return VK_ERROR_INITIALIZATION_FAILED;

    std::unique_lock<std::recursive_mutex> lock(mLock);

    // When this function is called, we actually need to do two things:
    // - Get full information about physical devices from the host,
    // even if the guest did not ask for it
    // - Serve the guest query according to the spec:
    //
    // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkEnumeratePhysicalDevices.html

    auto it = info_VkInstance.find(instance);

    if (it == info_VkInstance.end()) return VK_ERROR_INITIALIZATION_FAILED;

    auto& info = it->second;

    // Get the full host information here if it doesn't exist already.
    if (info.physicalDevices.empty()) {
        uint32_t hostPhysicalDeviceCount = 0;

        lock.unlock();
        VkResult countRes = enc->vkEnumeratePhysicalDevices(instance, &hostPhysicalDeviceCount,
                                                            nullptr, false /* no lock */);
        lock.lock();

        if (countRes != VK_SUCCESS) {
            mesa_loge(
                "%s: failed: could not count host physical devices. "
                "Error %d\n",
                __func__, countRes);
            return countRes;
        }

        info.physicalDevices.resize(hostPhysicalDeviceCount);

        lock.unlock();
        VkResult enumRes = enc->vkEnumeratePhysicalDevices(
            instance, &hostPhysicalDeviceCount, info.physicalDevices.data(), false /* no lock */);
        lock.lock();

        if (enumRes != VK_SUCCESS) {
            mesa_loge(
                "%s: failed: could not retrieve host physical devices. "
                "Error %d\n",
                __func__, enumRes);
            return enumRes;
        }
    }

    // Serve the guest query according to the spec.
    //
    // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkEnumeratePhysicalDevices.html
    //
    // If pPhysicalDevices is NULL, then the number of physical devices
    // available is returned in pPhysicalDeviceCount. Otherwise,
    // pPhysicalDeviceCount must point to a variable set by the user to the
    // number of elements in the pPhysicalDevices array, and on return the
    // variable is overwritten with the number of handles actually written
    // to pPhysicalDevices. If pPhysicalDeviceCount is less than the number
    // of physical devices available, at most pPhysicalDeviceCount
    // structures will be written.  If pPhysicalDeviceCount is smaller than
    // the number of physical devices available, VK_INCOMPLETE will be
    // returned instead of VK_SUCCESS, to indicate that not all the
    // available physical devices were returned.

    if (!pPhysicalDevices) {
        *pPhysicalDeviceCount = (uint32_t)info.physicalDevices.size();
        return VK_SUCCESS;
    } else {
        uint32_t actualDeviceCount = (uint32_t)info.physicalDevices.size();
        uint32_t toWrite =
            actualDeviceCount < *pPhysicalDeviceCount ? actualDeviceCount : *pPhysicalDeviceCount;

        for (uint32_t i = 0; i < toWrite; ++i) {
            pPhysicalDevices[i] = info.physicalDevices[i];
        }

        *pPhysicalDeviceCount = toWrite;

        if (actualDeviceCount > *pPhysicalDeviceCount) {
            return VK_INCOMPLETE;
        }

        return VK_SUCCESS;
    }
}

void ResourceTracker::on_vkGetPhysicalDeviceProperties(void*, VkPhysicalDevice,
                                                       VkPhysicalDeviceProperties* pProperties) {
#if defined(__linux__) && !defined(VK_USE_PLATFORM_ANDROID_KHR)
    if (pProperties) {
        if (VK_PHYSICAL_DEVICE_TYPE_CPU == pProperties->deviceType) {
            /* For Linux guest: Even if host driver reports DEVICE_TYPE_CPU,
             * override this to VIRTUAL_GPU, otherwise Linux DRM interfaces
             * will take unexpected code paths to deal with "software" driver
             */
            pProperties->deviceType = VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU;
        }
    }
#endif
}

void ResourceTracker::on_vkGetPhysicalDeviceFeatures2(void*, VkPhysicalDevice,
                                                      VkPhysicalDeviceFeatures2* pFeatures) {
    if (pFeatures) {
        VkPhysicalDeviceDeviceMemoryReportFeaturesEXT* memoryReportFeaturesEXT =
            vk_find_struct<VkPhysicalDeviceDeviceMemoryReportFeaturesEXT>(pFeatures);
        if (memoryReportFeaturesEXT) {
            memoryReportFeaturesEXT->deviceMemoryReport = VK_TRUE;
        }
    }
}

void ResourceTracker::on_vkGetPhysicalDeviceFeatures2KHR(void* context,
                                                         VkPhysicalDevice physicalDevice,
                                                         VkPhysicalDeviceFeatures2* pFeatures) {
    on_vkGetPhysicalDeviceFeatures2(context, physicalDevice, pFeatures);
}

void ResourceTracker::on_vkGetPhysicalDeviceProperties2(void* context,
                                                        VkPhysicalDevice physicalDevice,
                                                        VkPhysicalDeviceProperties2* pProperties) {
    if (pProperties) {
        VkPhysicalDeviceDeviceMemoryReportFeaturesEXT* memoryReportFeaturesEXT =
            vk_find_struct<VkPhysicalDeviceDeviceMemoryReportFeaturesEXT>(pProperties);
        if (memoryReportFeaturesEXT) {
            memoryReportFeaturesEXT->deviceMemoryReport = VK_TRUE;
        }
        on_vkGetPhysicalDeviceProperties(context, physicalDevice, &pProperties->properties);
    }
}

void ResourceTracker::on_vkGetPhysicalDeviceProperties2KHR(
    void* context, VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties) {
    on_vkGetPhysicalDeviceProperties2(context, physicalDevice, pProperties);
}

void ResourceTracker::on_vkGetPhysicalDeviceMemoryProperties(
    void* context, VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* out) {
    // gfxstream decides which physical device to expose to the guest on startup.
    // Otherwise, we would need a physical device to properties mapping.
    *out = getPhysicalDeviceMemoryProperties(context, VK_NULL_HANDLE, physicalDevice);
}

void ResourceTracker::on_vkGetPhysicalDeviceMemoryProperties2(
    void*, VkPhysicalDevice physdev, VkPhysicalDeviceMemoryProperties2* out) {
    on_vkGetPhysicalDeviceMemoryProperties(nullptr, physdev, &out->memoryProperties);
}

void ResourceTracker::on_vkGetDeviceQueue(void*, VkDevice device, uint32_t, uint32_t,
                                          VkQueue* pQueue) {
    std::lock_guard<std::recursive_mutex> lock(mLock);
    info_VkQueue[*pQueue].device = device;
}

void ResourceTracker::on_vkGetDeviceQueue2(void*, VkDevice device, const VkDeviceQueueInfo2*,
                                           VkQueue* pQueue) {
    std::lock_guard<std::recursive_mutex> lock(mLock);
    info_VkQueue[*pQueue].device = device;
}

VkResult ResourceTracker::on_vkCreateInstance(void* context, VkResult input_result,
                                              const VkInstanceCreateInfo* createInfo,
                                              const VkAllocationCallbacks*, VkInstance* pInstance) {
    if (input_result != VK_SUCCESS) return input_result;

    VkEncoder* enc = (VkEncoder*)context;

    uint32_t apiVersion;
    VkResult enumInstanceVersionRes =
        enc->vkEnumerateInstanceVersion(&apiVersion, false /* no lock */);

    setInstanceInfo(*pInstance, createInfo->enabledExtensionCount,
                    createInfo->ppEnabledExtensionNames, apiVersion);

    return input_result;
}

VkResult ResourceTracker::on_vkCreateDevice(void* context, VkResult input_result,
                                            VkPhysicalDevice physicalDevice,
                                            const VkDeviceCreateInfo* pCreateInfo,
                                            const VkAllocationCallbacks*, VkDevice* pDevice) {
    if (input_result != VK_SUCCESS) return input_result;

    VkEncoder* enc = (VkEncoder*)context;

    VkPhysicalDeviceProperties props;
    VkPhysicalDeviceMemoryProperties memProps;
    enc->vkGetPhysicalDeviceProperties(physicalDevice, &props, false /* no lock */);
    enc->vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProps, false /* no lock */);

    setDeviceInfo(*pDevice, physicalDevice, props, memProps, pCreateInfo->enabledExtensionCount,
                  pCreateInfo->ppEnabledExtensionNames, pCreateInfo->pNext);

    return input_result;
}

void ResourceTracker::on_vkDestroyDevice_pre(void* context, VkDevice device,
                                             const VkAllocationCallbacks*) {
    (void)context;
    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto it = info_VkDevice.find(device);
    if (it == info_VkDevice.end()) return;

    for (auto itr = info_VkDeviceMemory.cbegin(); itr != info_VkDeviceMemory.cend();) {
        auto& memInfo = itr->second;
        if (memInfo.device == device) {
            itr = info_VkDeviceMemory.erase(itr);
        } else {
            itr++;
        }
    }
}

#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
void updateMemoryTypeBits(uint32_t* memoryTypeBits, uint32_t memoryIndex) {
    *memoryTypeBits = 1u << memoryIndex;
}
#endif

#ifdef VK_USE_PLATFORM_ANDROID_KHR

VkResult ResourceTracker::on_vkGetAndroidHardwareBufferPropertiesANDROID(
    void* context, VkResult, VkDevice device, const AHardwareBuffer* buffer,
    VkAndroidHardwareBufferPropertiesANDROID* pProperties) {
    auto grallocHelper =
        ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->grallocHelper();

    // Delete once goldfish Linux drivers are gone
    if (mCaps.vulkanCapset.colorBufferMemoryIndex == 0xFFFFFFFF) {
        mCaps.vulkanCapset.colorBufferMemoryIndex = getColorBufferMemoryIndex(context, device);
    }

    updateMemoryTypeBits(&pProperties->memoryTypeBits, mCaps.vulkanCapset.colorBufferMemoryIndex);

    return getAndroidHardwareBufferPropertiesANDROID(grallocHelper, buffer, pProperties);
}

VkResult ResourceTracker::on_vkGetMemoryAndroidHardwareBufferANDROID(
    void*, VkResult, VkDevice device, const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo,
    struct AHardwareBuffer** pBuffer) {
    if (!pInfo) return VK_ERROR_INITIALIZATION_FAILED;
    if (!pInfo->memory) return VK_ERROR_INITIALIZATION_FAILED;

    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto deviceIt = info_VkDevice.find(device);

    if (deviceIt == info_VkDevice.end()) {
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    auto memoryIt = info_VkDeviceMemory.find(pInfo->memory);

    if (memoryIt == info_VkDeviceMemory.end()) {
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    auto& info = memoryIt->second;

    auto* gralloc = ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->grallocHelper();
    VkResult queryRes = getMemoryAndroidHardwareBufferANDROID(gralloc, &info.ahw);

    if (queryRes != VK_SUCCESS) return queryRes;

    *pBuffer = info.ahw;

    return queryRes;
}
#endif

#ifdef VK_USE_PLATFORM_FUCHSIA
VkResult ResourceTracker::on_vkGetMemoryZirconHandleFUCHSIA(
    void*, VkResult, VkDevice device, const VkMemoryGetZirconHandleInfoFUCHSIA* pInfo,
    uint32_t* pHandle) {
    if (!pInfo) return VK_ERROR_INITIALIZATION_FAILED;
    if (!pInfo->memory) return VK_ERROR_INITIALIZATION_FAILED;

    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto deviceIt = info_VkDevice.find(device);

    if (deviceIt == info_VkDevice.end()) {
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    auto memoryIt = info_VkDeviceMemory.find(pInfo->memory);

    if (memoryIt == info_VkDeviceMemory.end()) {
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    auto& info = memoryIt->second;

    if (info.vmoHandle == ZX_HANDLE_INVALID) {
        mesa_loge("%s: memory cannot be exported", __func__);
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    *pHandle = ZX_HANDLE_INVALID;
    zx_handle_duplicate(info.vmoHandle, ZX_RIGHT_SAME_RIGHTS, pHandle);
    return VK_SUCCESS;
}

VkResult ResourceTracker::on_vkGetMemoryZirconHandlePropertiesFUCHSIA(
    void*, VkResult, VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType,
    uint32_t handle, VkMemoryZirconHandlePropertiesFUCHSIA* pProperties) {
    using fuchsia_hardware_goldfish::wire::kMemoryPropertyDeviceLocal;
    using fuchsia_hardware_goldfish::wire::kMemoryPropertyHostVisible;

    if (handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA) {
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    zx_info_handle_basic_t handleInfo;
    zx_status_t status = zx::unowned_vmo(handle)->get_info(ZX_INFO_HANDLE_BASIC, &handleInfo,
                                                           sizeof(handleInfo), nullptr, nullptr);
    if (status != ZX_OK || handleInfo.type != ZX_OBJ_TYPE_VMO) {
        return VK_ERROR_INVALID_EXTERNAL_HANDLE;
    }

    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto deviceIt = info_VkDevice.find(device);

    if (deviceIt == info_VkDevice.end()) {
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    auto& info = deviceIt->second;

    zx::vmo vmo_dup;
    status = zx::unowned_vmo(handle)->duplicate(ZX_RIGHT_SAME_RIGHTS, &vmo_dup);
    if (status != ZX_OK) {
        mesa_loge("zx_handle_duplicate() error: %d", status);
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    uint32_t memoryProperty = 0u;

    auto result = mControlDevice->GetBufferHandleInfo(std::move(vmo_dup));
    if (!result.ok()) {
        mesa_loge("mControlDevice->GetBufferHandleInfo fatal error: epitaph: %d", result.status());
        return VK_ERROR_INITIALIZATION_FAILED;
    }
    if (result.value().is_ok()) {
        memoryProperty = result.value().value()->info.memory_property();
    } else if (result.value().error_value() == ZX_ERR_NOT_FOUND) {
        // If a VMO is allocated while ColorBuffer/Buffer is not created,
        // it must be a device-local buffer, since for host-visible buffers,
        // ColorBuffer/Buffer is created at sysmem allocation time.
        memoryProperty = kMemoryPropertyDeviceLocal;
    } else {
        // Importing read-only host memory into the Vulkan driver should not
        // work, but it is not an error to try to do so. Returning a
        // VkMemoryZirconHandlePropertiesFUCHSIA with no available
        // memoryType bits should be enough for clients. See fxbug.dev/42098398
        // for other issues this this flow.
        mesa_logw("GetBufferHandleInfo failed: %d", result.value().error_value());
        pProperties->memoryTypeBits = 0;
        return VK_SUCCESS;
    }

    pProperties->memoryTypeBits = 0;
    for (uint32_t i = 0; i < info.memProps.memoryTypeCount; ++i) {
        if (((memoryProperty & kMemoryPropertyDeviceLocal) &&
             (info.memProps.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) ||
            ((memoryProperty & kMemoryPropertyHostVisible) &&
             (info.memProps.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))) {
            pProperties->memoryTypeBits |= 1ull << i;
        }
    }
    return VK_SUCCESS;
}

zx_koid_t getEventKoid(zx_handle_t eventHandle) {
    if (eventHandle == ZX_HANDLE_INVALID) {
        return ZX_KOID_INVALID;
    }

    zx_info_handle_basic_t info;
    zx_status_t status = zx_object_get_info(eventHandle, ZX_INFO_HANDLE_BASIC, &info, sizeof(info),
                                            nullptr, nullptr);
    if (status != ZX_OK) {
        mesa_loge("Cannot get object info of handle %u: %d", eventHandle, status);
        return ZX_KOID_INVALID;
    }
    return info.koid;
}

VkResult ResourceTracker::on_vkImportSemaphoreZirconHandleFUCHSIA(
    void*, VkResult, VkDevice device, const VkImportSemaphoreZirconHandleInfoFUCHSIA* pInfo) {
    if (!pInfo) return VK_ERROR_INITIALIZATION_FAILED;
    if (!pInfo->semaphore) return VK_ERROR_INITIALIZATION_FAILED;

    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto deviceIt = info_VkDevice.find(device);

    if (deviceIt == info_VkDevice.end()) {
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    auto semaphoreIt = info_VkSemaphore.find(pInfo->semaphore);

    if (semaphoreIt == info_VkSemaphore.end()) {
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    auto& info = semaphoreIt->second;

    if (info.eventHandle != ZX_HANDLE_INVALID) {
        zx_handle_close(info.eventHandle);
    }
#if VK_HEADER_VERSION < 174
    info.eventHandle = pInfo->handle;
#else   // VK_HEADER_VERSION >= 174
    info.eventHandle = pInfo->zirconHandle;
#endif  // VK_HEADER_VERSION < 174
    if (info.eventHandle != ZX_HANDLE_INVALID) {
        info.eventKoid = getEventKoid(info.eventHandle);
    }

    return VK_SUCCESS;
}

VkResult ResourceTracker::on_vkGetSemaphoreZirconHandleFUCHSIA(
    void*, VkResult, VkDevice device, const VkSemaphoreGetZirconHandleInfoFUCHSIA* pInfo,
    uint32_t* pHandle) {
    if (!pInfo) return VK_ERROR_INITIALIZATION_FAILED;
    if (!pInfo->semaphore) return VK_ERROR_INITIALIZATION_FAILED;

    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto deviceIt = info_VkDevice.find(device);

    if (deviceIt == info_VkDevice.end()) {
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    auto semaphoreIt = info_VkSemaphore.find(pInfo->semaphore);

    if (semaphoreIt == info_VkSemaphore.end()) {
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    auto& info = semaphoreIt->second;

    if (info.eventHandle == ZX_HANDLE_INVALID) {
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    *pHandle = ZX_HANDLE_INVALID;
    zx_handle_duplicate(info.eventHandle, ZX_RIGHT_SAME_RIGHTS, pHandle);
    return VK_SUCCESS;
}

VkResult ResourceTracker::on_vkCreateBufferCollectionFUCHSIA(
    void*, VkResult, VkDevice, const VkBufferCollectionCreateInfoFUCHSIA* pInfo,
    const VkAllocationCallbacks*, VkBufferCollectionFUCHSIA* pCollection) {
    fidl::ClientEnd<::fuchsia_sysmem::BufferCollectionToken> token_client;

    if (pInfo->collectionToken) {
        token_client = fidl::ClientEnd<::fuchsia_sysmem::BufferCollectionToken>(
            zx::channel(pInfo->collectionToken));
    } else {
        auto endpoints = fidl::CreateEndpoints<::fuchsia_sysmem::BufferCollectionToken>();
        if (!endpoints.is_ok()) {
            mesa_loge("zx_channel_create failed: %d", endpoints.status_value());
            return VK_ERROR_INITIALIZATION_FAILED;
        }

        auto result = mSysmemAllocator->AllocateSharedCollection(std::move(endpoints->server));
        if (!result.ok()) {
            mesa_loge("AllocateSharedCollection failed: %d", result.status());
            return VK_ERROR_INITIALIZATION_FAILED;
        }
        token_client = std::move(endpoints->client);
    }

    auto endpoints = fidl::CreateEndpoints<::fuchsia_sysmem::BufferCollection>();
    if (!endpoints.is_ok()) {
        mesa_loge("zx_channel_create failed: %d", endpoints.status_value());
        return VK_ERROR_INITIALIZATION_FAILED;
    }
    auto [collection_client, collection_server] = std::move(endpoints.value());

    auto result = mSysmemAllocator->BindSharedCollection(std::move(token_client),
                                                         std::move(collection_server));
    if (!result.ok()) {
        mesa_loge("BindSharedCollection failed: %d", result.status());
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    auto* sysmem_collection =
        new fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>(std::move(collection_client));
    *pCollection = reinterpret_cast<VkBufferCollectionFUCHSIA>(sysmem_collection);

    register_VkBufferCollectionFUCHSIA(*pCollection);
    return VK_SUCCESS;
}

void ResourceTracker::on_vkDestroyBufferCollectionFUCHSIA(void*, VkResult, VkDevice,
                                                          VkBufferCollectionFUCHSIA collection,
                                                          const VkAllocationCallbacks*) {
    auto sysmem_collection =
        reinterpret_cast<fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>*>(collection);
    if (sysmem_collection) {
        (*sysmem_collection)->Close();
    }
    delete sysmem_collection;

    unregister_VkBufferCollectionFUCHSIA(collection);
}

SetBufferCollectionImageConstraintsResult ResourceTracker::setBufferCollectionImageConstraintsImpl(
    VkEncoder* enc, VkDevice device,
    fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>* pCollection,
    const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo) {
    const auto& collection = *pCollection;
    if (!pImageConstraintsInfo ||
        pImageConstraintsInfo->sType != VK_STRUCTURE_TYPE_IMAGE_CONSTRAINTS_INFO_FUCHSIA) {
        mesa_loge("%s: invalid pImageConstraintsInfo", __func__);
        return {VK_ERROR_INITIALIZATION_FAILED};
    }

    if (pImageConstraintsInfo->formatConstraintsCount == 0) {
        mesa_loge("%s: formatConstraintsCount must be greater than 0", __func__);
        abort();
    }

    fuchsia_sysmem::wire::BufferCollectionConstraints constraints =
        defaultBufferCollectionConstraints(
            /* min_size_bytes */ 0,
            pImageConstraintsInfo->bufferCollectionConstraints.minBufferCount,
            pImageConstraintsInfo->bufferCollectionConstraints.maxBufferCount,
            pImageConstraintsInfo->bufferCollectionConstraints.minBufferCountForCamping,
            pImageConstraintsInfo->bufferCollectionConstraints.minBufferCountForDedicatedSlack,
            pImageConstraintsInfo->bufferCollectionConstraints.minBufferCountForSharedSlack);

    std::vector<fuchsia_sysmem::wire::ImageFormatConstraints> format_constraints;

    VkPhysicalDevice physicalDevice;
    {
        std::lock_guard<std::recursive_mutex> lock(mLock);
        auto deviceIt = info_VkDevice.find(device);
        if (deviceIt == info_VkDevice.end()) {
            return {VK_ERROR_INITIALIZATION_FAILED};
        }
        physicalDevice = deviceIt->second.physdev;
    }

    std::vector<uint32_t> createInfoIndex;

    bool hasOptimalTiling = false;
    for (uint32_t i = 0; i < pImageConstraintsInfo->formatConstraintsCount; i++) {
        const VkImageCreateInfo* createInfo =
            &pImageConstraintsInfo->pFormatConstraints[i].imageCreateInfo;
        const VkImageFormatConstraintsInfoFUCHSIA* formatConstraints =
            &pImageConstraintsInfo->pFormatConstraints[i];

        // add ImageFormatConstraints for *optimal* tiling
        VkResult optimalResult = VK_ERROR_FORMAT_NOT_SUPPORTED;
        if (createInfo->tiling == VK_IMAGE_TILING_OPTIMAL) {
            optimalResult = addImageBufferCollectionConstraintsFUCHSIA(
                enc, device, physicalDevice, formatConstraints, VK_IMAGE_TILING_OPTIMAL,
                &constraints);
            if (optimalResult == VK_SUCCESS) {
                createInfoIndex.push_back(i);
                hasOptimalTiling = true;
            }
        }

        // Add ImageFormatConstraints for *linear* tiling
        VkResult linearResult = addImageBufferCollectionConstraintsFUCHSIA(
            enc, device, physicalDevice, formatConstraints, VK_IMAGE_TILING_LINEAR, &constraints);
        if (linearResult == VK_SUCCESS) {
            createInfoIndex.push_back(i);
        }

        // Update usage and BufferMemoryConstraints
        if (linearResult == VK_SUCCESS || optimalResult == VK_SUCCESS) {
            constraints.usage.vulkan |= getBufferCollectionConstraintsVulkanImageUsage(createInfo);

            if (formatConstraints && formatConstraints->flags) {
                mesa_logw(
                    "%s: Non-zero flags (%08x) in image format "
                    "constraints; this is currently not supported, see "
                    "fxbug.dev/42147900.",
                    __func__, formatConstraints->flags);
            }
        }
    }

    // Set buffer memory constraints based on optimal/linear tiling support
    // and flags.
    VkImageConstraintsInfoFlagsFUCHSIA flags = pImageConstraintsInfo->flags;
    if (flags & VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_RARELY_FUCHSIA)
        constraints.usage.cpu |= fuchsia_sysmem::wire::kCpuUsageRead;
    if (flags & VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_OFTEN_FUCHSIA)
        constraints.usage.cpu |= fuchsia_sysmem::wire::kCpuUsageReadOften;
    if (flags & VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_RARELY_FUCHSIA)
        constraints.usage.cpu |= fuchsia_sysmem::wire::kCpuUsageWrite;
    if (flags & VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_OFTEN_FUCHSIA)
        constraints.usage.cpu |= fuchsia_sysmem::wire::kCpuUsageWriteOften;

    constraints.has_buffer_memory_constraints = true;
    auto& memory_constraints = constraints.buffer_memory_constraints;
    memory_constraints.cpu_domain_supported = true;
    memory_constraints.ram_domain_supported = true;
    memory_constraints.inaccessible_domain_supported =
        hasOptimalTiling && !(flags & (VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_RARELY_FUCHSIA |
                                       VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_OFTEN_FUCHSIA |
                                       VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_RARELY_FUCHSIA |
                                       VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_OFTEN_FUCHSIA));

    if (memory_constraints.inaccessible_domain_supported) {
        memory_constraints.heap_permitted_count = 2;
        memory_constraints.heap_permitted[0] = fuchsia_sysmem::wire::HeapType::kGoldfishDeviceLocal;
        memory_constraints.heap_permitted[1] = fuchsia_sysmem::wire::HeapType::kGoldfishHostVisible;
    } else {
        memory_constraints.heap_permitted_count = 1;
        memory_constraints.heap_permitted[0] = fuchsia_sysmem::wire::HeapType::kGoldfishHostVisible;
    }

    if (constraints.image_format_constraints_count == 0) {
        mesa_loge("%s: none of the specified formats is supported by device", __func__);
        return {VK_ERROR_FORMAT_NOT_SUPPORTED};
    }

    constexpr uint32_t kVulkanPriority = 5;
    const char kName[] = "GoldfishSysmemShared";
    collection->SetName(kVulkanPriority, fidl::StringView(kName));

    auto result = collection->SetConstraints(true, constraints);
    if (!result.ok()) {
        mesa_loge("setBufferCollectionConstraints: SetConstraints failed: %d", result.status());
        return {VK_ERROR_INITIALIZATION_FAILED};
    }

    return {VK_SUCCESS, constraints, std::move(createInfoIndex)};
}

VkResult ResourceTracker::setBufferCollectionImageConstraintsFUCHSIA(
    VkEncoder* enc, VkDevice device,
    fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>* pCollection,
    const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo) {
    const auto& collection = *pCollection;

    auto setConstraintsResult =
        setBufferCollectionImageConstraintsImpl(enc, device, pCollection, pImageConstraintsInfo);
    if (setConstraintsResult.result != VK_SUCCESS) {
        return setConstraintsResult.result;
    }

    // copy constraints to info_VkBufferCollectionFUCHSIA if
    // |collection| is a valid VkBufferCollectionFUCHSIA handle.
    std::lock_guard<std::recursive_mutex> lock(mLock);
    VkBufferCollectionFUCHSIA buffer_collection =
        reinterpret_cast<VkBufferCollectionFUCHSIA>(pCollection);
    if (info_VkBufferCollectionFUCHSIA.find(buffer_collection) !=
        info_VkBufferCollectionFUCHSIA.end()) {
        info_VkBufferCollectionFUCHSIA[buffer_collection].constraints =
            std::make_optional<fuchsia_sysmem::wire::BufferCollectionConstraints>(
                std::move(setConstraintsResult.constraints));
        info_VkBufferCollectionFUCHSIA[buffer_collection].createInfoIndex =
            std::move(setConstraintsResult.createInfoIndex);
    }

    return VK_SUCCESS;
}

VkResult ResourceTracker::setBufferCollectionBufferConstraintsFUCHSIA(
    fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>* pCollection,
    const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo) {
    auto setConstraintsResult =
        setBufferCollectionBufferConstraintsImpl(pCollection, pBufferConstraintsInfo);
    if (setConstraintsResult.result != VK_SUCCESS) {
        return setConstraintsResult.result;
    }

    // copy constraints to info_VkBufferCollectionFUCHSIA if
    // |collection| is a valid VkBufferCollectionFUCHSIA handle.
    std::lock_guard<std::recursive_mutex> lock(mLock);
    VkBufferCollectionFUCHSIA buffer_collection =
        reinterpret_cast<VkBufferCollectionFUCHSIA>(pCollection);
    if (info_VkBufferCollectionFUCHSIA.find(buffer_collection) !=
        info_VkBufferCollectionFUCHSIA.end()) {
        info_VkBufferCollectionFUCHSIA[buffer_collection].constraints =
            std::make_optional<fuchsia_sysmem::wire::BufferCollectionConstraints>(
                setConstraintsResult.constraints);
    }

    return VK_SUCCESS;
}

VkResult ResourceTracker::on_vkSetBufferCollectionImageConstraintsFUCHSIA(
    void* context, VkResult, VkDevice device, VkBufferCollectionFUCHSIA collection,
    const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo) {
    VkEncoder* enc = (VkEncoder*)context;
    auto sysmem_collection =
        reinterpret_cast<fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>*>(collection);
    return setBufferCollectionImageConstraintsFUCHSIA(enc, device, sysmem_collection,
                                                      pImageConstraintsInfo);
}

VkResult ResourceTracker::on_vkSetBufferCollectionBufferConstraintsFUCHSIA(
    void*, VkResult, VkDevice, VkBufferCollectionFUCHSIA collection,
    const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo) {
    auto sysmem_collection =
        reinterpret_cast<fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>*>(collection);
    return setBufferCollectionBufferConstraintsFUCHSIA(sysmem_collection, pBufferConstraintsInfo);
}

VkResult ResourceTracker::getBufferCollectionImageCreateInfoIndexLocked(
    VkBufferCollectionFUCHSIA collection, fuchsia_sysmem::wire::BufferCollectionInfo2& info,
    uint32_t* outCreateInfoIndex) {
    if (!info_VkBufferCollectionFUCHSIA[collection].constraints.has_value()) {
        mesa_loge("%s: constraints not set", __func__);
        return VK_ERROR_OUT_OF_DEVICE_MEMORY;
    }

    if (!info.settings.has_image_format_constraints) {
        // no image format constraints, skip getting createInfoIndex.
        return VK_SUCCESS;
    }

    const auto& constraints = *info_VkBufferCollectionFUCHSIA[collection].constraints;
    const auto& createInfoIndices = info_VkBufferCollectionFUCHSIA[collection].createInfoIndex;
    const auto& out = info.settings.image_format_constraints;
    bool foundCreateInfo = false;

    for (size_t imageFormatIndex = 0; imageFormatIndex < constraints.image_format_constraints_count;
         imageFormatIndex++) {
        const auto& in = constraints.image_format_constraints[imageFormatIndex];
        // These checks are sorted in order of how often they're expected to
        // mismatch, from most likely to least likely. They aren't always
        // equality comparisons, since sysmem may change some values in
        // compatible ways on behalf of the other participants.
        if ((out.pixel_format.type != in.pixel_format.type) ||
            (out.pixel_format.has_format_modifier != in.pixel_format.has_format_modifier) ||
            (out.pixel_format.format_modifier.value != in.pixel_format.format_modifier.value) ||
            (out.min_bytes_per_row < in.min_bytes_per_row) ||
            (out.required_max_coded_width < in.required_max_coded_width) ||
            (out.required_max_coded_height < in.required_max_coded_height) ||
            (in.bytes_per_row_divisor != 0 &&
             out.bytes_per_row_divisor % in.bytes_per_row_divisor != 0)) {
            continue;
        }
        // Check if the out colorspaces are a subset of the in color spaces.
        bool all_color_spaces_found = true;
        for (uint32_t j = 0; j < out.color_spaces_count; j++) {
            bool found_matching_color_space = false;
            for (uint32_t k = 0; k < in.color_spaces_count; k++) {
                if (out.color_space[j].type == in.color_space[k].type) {
                    found_matching_color_space = true;
                    break;
                }
            }
            if (!found_matching_color_space) {
                all_color_spaces_found = false;
                break;
            }
        }
        if (!all_color_spaces_found) {
            continue;
        }

        // Choose the first valid format for now.
        *outCreateInfoIndex = createInfoIndices[imageFormatIndex];
        return VK_SUCCESS;
    }

    mesa_loge("%s: cannot find a valid image format in constraints", __func__);
    return VK_ERROR_OUT_OF_DEVICE_MEMORY;
}

VkResult ResourceTracker::on_vkGetBufferCollectionPropertiesFUCHSIA(
    void* context, VkResult, VkDevice device, VkBufferCollectionFUCHSIA collection,
    VkBufferCollectionPropertiesFUCHSIA* pProperties) {
    VkEncoder* enc = (VkEncoder*)context;
    const auto& sysmem_collection =
        *reinterpret_cast<fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>*>(collection);

    auto result = sysmem_collection->WaitForBuffersAllocated();
    if (!result.ok() || result->status != ZX_OK) {
        mesa_loge("Failed wait for allocation: %d %d", result.status(),
                  GET_STATUS_SAFE(result, status));
        return VK_ERROR_INITIALIZATION_FAILED;
    }
    fuchsia_sysmem::wire::BufferCollectionInfo2 info = std::move(result->buffer_collection_info);

    bool is_host_visible =
        info.settings.buffer_settings.heap == fuchsia_sysmem::wire::HeapType::kGoldfishHostVisible;
    bool is_device_local =
        info.settings.buffer_settings.heap == fuchsia_sysmem::wire::HeapType::kGoldfishDeviceLocal;
    if (!is_host_visible && !is_device_local) {
        mesa_loge("buffer collection uses a non-goldfish heap (type 0x%lu)",
                  static_cast<uint64_t>(info.settings.buffer_settings.heap));
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    // memoryTypeBits
    // ====================================================================
    {
        std::lock_guard<std::recursive_mutex> lock(mLock);
        auto deviceIt = info_VkDevice.find(device);
        if (deviceIt == info_VkDevice.end()) {
            return VK_ERROR_INITIALIZATION_FAILED;
        }
        auto& deviceInfo = deviceIt->second;

        // Device local memory type supported.
        pProperties->memoryTypeBits = 0;
        for (uint32_t i = 0; i < deviceInfo.memProps.memoryTypeCount; ++i) {
            if ((is_device_local && (deviceInfo.memProps.memoryTypes[i].propertyFlags &
                                     VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) ||
                (is_host_visible && (deviceInfo.memProps.memoryTypes[i].propertyFlags &
                                     VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))) {
                pProperties->memoryTypeBits |= 1ull << i;
            }
        }
    }

    // bufferCount
    // ====================================================================
    pProperties->bufferCount = info.buffer_count;

    auto storeProperties = [this, collection, pProperties]() -> VkResult {
        // store properties to storage
        std::lock_guard<std::recursive_mutex> lock(mLock);
        if (info_VkBufferCollectionFUCHSIA.find(collection) ==
            info_VkBufferCollectionFUCHSIA.end()) {
            return VK_ERROR_OUT_OF_DEVICE_MEMORY;
        }

        info_VkBufferCollectionFUCHSIA[collection].properties =
            std::make_optional<VkBufferCollectionPropertiesFUCHSIA>(*pProperties);

        // We only do a shallow copy so we should remove all pNext pointers.
        info_VkBufferCollectionFUCHSIA[collection].properties->pNext = nullptr;
        info_VkBufferCollectionFUCHSIA[collection].properties->sysmemColorSpaceIndex.pNext =
            nullptr;
        return VK_SUCCESS;
    };

    // The fields below only apply to buffer collections with image formats.
    if (!info.settings.has_image_format_constraints) {
        mesa_logd("%s: buffer collection doesn't have image format constraints", __func__);
        return storeProperties();
    }

    // sysmemFormat
    // ====================================================================

    pProperties->sysmemPixelFormat =
        static_cast<uint64_t>(info.settings.image_format_constraints.pixel_format.type);

    // colorSpace
    // ====================================================================
    if (info.settings.image_format_constraints.color_spaces_count == 0) {
        mesa_loge(
            "%s: color space missing from allocated buffer collection "
            "constraints",
            __func__);
        return VK_ERROR_OUT_OF_DEVICE_MEMORY;
    }
    // Only report first colorspace for now.
    pProperties->sysmemColorSpaceIndex.colorSpace =
        static_cast<uint32_t>(info.settings.image_format_constraints.color_space[0].type);

    // createInfoIndex
    // ====================================================================
    {
        std::lock_guard<std::recursive_mutex> lock(mLock);
        auto getIndexResult = getBufferCollectionImageCreateInfoIndexLocked(
            collection, info, &pProperties->createInfoIndex);
        if (getIndexResult != VK_SUCCESS) {
            return getIndexResult;
        }
    }

    // formatFeatures
    // ====================================================================
    VkPhysicalDevice physicalDevice;
    {
        std::lock_guard<std::recursive_mutex> lock(mLock);
        auto deviceIt = info_VkDevice.find(device);
        if (deviceIt == info_VkDevice.end()) {
            return VK_ERROR_INITIALIZATION_FAILED;
        }
        physicalDevice = deviceIt->second.physdev;
    }

    VkFormat vkFormat =
        sysmemPixelFormatTypeToVk(info.settings.image_format_constraints.pixel_format.type);
    VkFormatProperties formatProperties;
    enc->vkGetPhysicalDeviceFormatProperties(physicalDevice, vkFormat, &formatProperties,
                                             true /* do lock */);
    if (is_device_local) {
        pProperties->formatFeatures = formatProperties.optimalTilingFeatures;
    }
    if (is_host_visible) {
        pProperties->formatFeatures = formatProperties.linearTilingFeatures;
    }

    // YCbCr properties
    // ====================================================================
    // TODO(59804): Implement this correctly when we support YUV pixel
    // formats in goldfish ICD.
    pProperties->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
    pProperties->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
    pProperties->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
    pProperties->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
    pProperties->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
    pProperties->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
    pProperties->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
    pProperties->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;

    return storeProperties();
}
#endif

static uint32_t getVirglFormat(VkFormat vkFormat) {
    uint32_t virglFormat = 0;

    switch (vkFormat) {
        case VK_FORMAT_R8G8B8A8_SINT:
        case VK_FORMAT_R8G8B8A8_UNORM:
        case VK_FORMAT_R8G8B8A8_SRGB:
        case VK_FORMAT_R8G8B8A8_SNORM:
        case VK_FORMAT_R8G8B8A8_SSCALED:
        case VK_FORMAT_R8G8B8A8_USCALED:
            virglFormat = VIRGL_FORMAT_R8G8B8A8_UNORM;
            break;
        case VK_FORMAT_B8G8R8A8_SINT:
        case VK_FORMAT_B8G8R8A8_UNORM:
        case VK_FORMAT_B8G8R8A8_SRGB:
        case VK_FORMAT_B8G8R8A8_SNORM:
        case VK_FORMAT_B8G8R8A8_SSCALED:
        case VK_FORMAT_B8G8R8A8_USCALED:
            virglFormat = VIRGL_FORMAT_B8G8R8A8_UNORM;
            break;
        case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
            virglFormat = VIRGL_FORMAT_R10G10B10A2_UNORM;
            break;
        default:
            break;
    }

    return virglFormat;
}

CoherentMemoryPtr ResourceTracker::createCoherentMemory(
    VkDevice device, VkDeviceMemory mem, const VkMemoryAllocateInfo& hostAllocationInfo,
    VkEncoder* enc, VkResult& res) {
    CoherentMemoryPtr coherentMemory = nullptr;

#if defined(__ANDROID__)
    if (mFeatureInfo->hasDirectMem) {
        uint64_t gpuAddr = 0;
        GoldfishAddressSpaceBlockPtr block = nullptr;
        res = enc->vkMapMemoryIntoAddressSpaceGOOGLE(device, mem, &gpuAddr, true);
        if (res != VK_SUCCESS) {
            mesa_loge(
                "Failed to create coherent memory: vkMapMemoryIntoAddressSpaceGOOGLE "
                "returned:%d.",
                res);
            return coherentMemory;
        }
        {
            std::lock_guard<std::recursive_mutex> lock(mLock);
            auto it = info_VkDeviceMemory.find(mem);
            if (it == info_VkDeviceMemory.end()) {
                mesa_loge("Failed to create coherent memory: failed to find device memory.");
                res = VK_ERROR_OUT_OF_HOST_MEMORY;
                return coherentMemory;
            }
            auto& info = it->second;
            block = info.goldfishBlock;
            info.goldfishBlock = nullptr;

            coherentMemory = std::make_shared<CoherentMemory>(
                block, gpuAddr, hostAllocationInfo.allocationSize, device, mem);
        }
    } else
#endif  // defined(__ANDROID__)
        if (mFeatureInfo->hasVirtioGpuNext) {
            struct VirtGpuCreateBlob createBlob = {0};
            uint64_t hvaSizeId[3];
            res = enc->vkGetMemoryHostAddressInfoGOOGLE(device, mem, &hvaSizeId[0], &hvaSizeId[1],
                                                        &hvaSizeId[2], true /* do lock */);
            if (res != VK_SUCCESS) {
                mesa_loge(
                    "Failed to create coherent memory: vkMapMemoryIntoAddressSpaceGOOGLE "
                    "returned:%d.",
                    res);
                return coherentMemory;
            }
            {
                std::lock_guard<std::recursive_mutex> lock(mLock);
                VirtGpuDevice* instance = VirtGpuDevice::getInstance((enum VirtGpuCapset)3);
                createBlob.blobMem = kBlobMemHost3d;
                createBlob.flags = kBlobFlagMappable;
                createBlob.blobId = hvaSizeId[2];
                createBlob.size = hostAllocationInfo.allocationSize;

                auto blob = instance->createBlob(createBlob);
                if (!blob) {
                    mesa_loge("Failed to create coherent memory: failed to create blob.");
                    res = VK_ERROR_OUT_OF_DEVICE_MEMORY;
                    return coherentMemory;
                }

                VirtGpuResourceMappingPtr mapping = blob->createMapping();
                if (!mapping) {
                    mesa_loge("Failed to create coherent memory: failed to create blob mapping.");
                    res = VK_ERROR_OUT_OF_DEVICE_MEMORY;
                    return coherentMemory;
                }

                coherentMemory =
                    std::make_shared<CoherentMemory>(mapping, createBlob.size, device, mem);
            }
        } else {
            mesa_loge("FATAL: Unsupported virtual memory feature");
            abort();
        }
    return coherentMemory;
}

VkResult ResourceTracker::allocateCoherentMemory(VkDevice device,
                                                 const VkMemoryAllocateInfo* pAllocateInfo,
                                                 VkEncoder* enc, VkDeviceMemory* pMemory) {
    uint64_t blobId = 0;
    uint64_t offset = 0;
    uint8_t* ptr = nullptr;
    VkMemoryAllocateFlagsInfo allocFlagsInfo;
    VkMemoryOpaqueCaptureAddressAllocateInfo opaqueCaptureAddressAllocInfo;
    VkCreateBlobGOOGLE createBlobInfo;
    VirtGpuResourcePtr guestBlob = nullptr;

    memset(&createBlobInfo, 0, sizeof(struct VkCreateBlobGOOGLE));
    createBlobInfo.sType = VK_STRUCTURE_TYPE_CREATE_BLOB_GOOGLE;

    const VkMemoryAllocateFlagsInfo* allocFlagsInfoPtr =
        vk_find_struct<VkMemoryAllocateFlagsInfo>(pAllocateInfo);
    const VkMemoryOpaqueCaptureAddressAllocateInfo* opaqueCaptureAddressAllocInfoPtr =
        vk_find_struct<VkMemoryOpaqueCaptureAddressAllocateInfo>(pAllocateInfo);

    bool deviceAddressMemoryAllocation =
        allocFlagsInfoPtr &&
        ((allocFlagsInfoPtr->flags & VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT) ||
         (allocFlagsInfoPtr->flags & VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT));

    bool dedicated = deviceAddressMemoryAllocation;

    if (mCaps.vulkanCapset.deferredMapping || mCaps.params[kParamCreateGuestHandle])
        dedicated = true;

    VkMemoryAllocateInfo hostAllocationInfo = vk_make_orphan_copy(*pAllocateInfo);
    vk_struct_chain_iterator structChainIter = vk_make_chain_iterator(&hostAllocationInfo);

    if (mCaps.vulkanCapset.deferredMapping || mCaps.params[kParamCreateGuestHandle]) {
        hostAllocationInfo.allocationSize =
            ALIGN(pAllocateInfo->allocationSize, mCaps.vulkanCapset.blobAlignment);
    } else if (dedicated) {
        // Over-aligning to kLargestSize to some Windows drivers (b:152769369).  Can likely
        // have host report the desired alignment.
        hostAllocationInfo.allocationSize = ALIGN(pAllocateInfo->allocationSize, kLargestPageSize);
    } else {
        VkDeviceSize roundedUpAllocSize = ALIGN(pAllocateInfo->allocationSize, kMegaByte);
        hostAllocationInfo.allocationSize = std::max(roundedUpAllocSize, kDefaultHostMemBlockSize);
    }

    // Support device address capture/replay allocations
    if (deviceAddressMemoryAllocation) {
        if (allocFlagsInfoPtr) {
            mesa_logd("%s: has alloc flags\n", __func__);
            allocFlagsInfo = *allocFlagsInfoPtr;
            vk_append_struct(&structChainIter, &allocFlagsInfo);
        }

        if (opaqueCaptureAddressAllocInfoPtr) {
            mesa_logd("%s: has opaque capture address\n", __func__);
            opaqueCaptureAddressAllocInfo = *opaqueCaptureAddressAllocInfoPtr;
            vk_append_struct(&structChainIter, &opaqueCaptureAddressAllocInfo);
        }
    }

    if (mCaps.params[kParamCreateGuestHandle]) {
        struct VirtGpuCreateBlob createBlob = {0};
        struct VirtGpuExecBuffer exec = {};
        VirtGpuDevice* instance = VirtGpuDevice::getInstance();
        struct gfxstreamPlaceholderCommandVk placeholderCmd = {};

        createBlobInfo.blobId = ++mAtomicId;
        createBlobInfo.blobMem = kBlobMemGuest;
        createBlobInfo.blobFlags = kBlobFlagCreateGuestHandle;
        vk_append_struct(&structChainIter, &createBlobInfo);

        createBlob.blobMem = kBlobMemGuest;
        createBlob.flags = kBlobFlagCreateGuestHandle;
        createBlob.blobId = createBlobInfo.blobId;
        createBlob.size = hostAllocationInfo.allocationSize;

        guestBlob = instance->createBlob(createBlob);
        if (!guestBlob) {
            mesa_loge("Failed to allocate coherent memory: failed to create blob.");
            return VK_ERROR_OUT_OF_DEVICE_MEMORY;
        }

        placeholderCmd.hdr.opCode = GFXSTREAM_PLACEHOLDER_COMMAND_VK;
        exec.command = static_cast<void*>(&placeholderCmd);
        exec.command_size = sizeof(placeholderCmd);
        exec.flags = kRingIdx;
        exec.ring_idx = 1;
        if (instance->execBuffer(exec, guestBlob.get())) {
            mesa_loge("Failed to allocate coherent memory: failed to execbuffer for wait.");
            return VK_ERROR_OUT_OF_HOST_MEMORY;
        }

        guestBlob->wait();
    } else if (mCaps.vulkanCapset.deferredMapping) {
        createBlobInfo.blobId = ++mAtomicId;
        createBlobInfo.blobMem = kBlobMemHost3d;
        vk_append_struct(&structChainIter, &createBlobInfo);
    }

    VkDeviceMemory mem = VK_NULL_HANDLE;
    VkResult host_res =
        enc->vkAllocateMemory(device, &hostAllocationInfo, nullptr, &mem, true /* do lock */);
    if (host_res != VK_SUCCESS) {
        mesa_loge("Failed to allocate coherent memory: failed to allocate on the host: %d.",
                  host_res);
        return host_res;
    }

    struct VkDeviceMemory_Info info;
    if (mCaps.vulkanCapset.deferredMapping || mCaps.params[kParamCreateGuestHandle]) {
        info.allocationSize = pAllocateInfo->allocationSize;
        info.blobId = createBlobInfo.blobId;
    }

    if (guestBlob) {
        auto mapping = guestBlob->createMapping();
        if (!mapping) {
            mesa_loge("Failed to allocate coherent memory: failed to create blob mapping.");
            return VK_ERROR_OUT_OF_DEVICE_MEMORY;
        }

        auto coherentMemory = std::make_shared<CoherentMemory>(
            mapping, hostAllocationInfo.allocationSize, device, mem);

        coherentMemory->subAllocate(pAllocateInfo->allocationSize, &ptr, offset);
        info.coherentMemoryOffset = offset;
        info.coherentMemory = coherentMemory;
        info.ptr = ptr;
    }

    info.coherentMemorySize = hostAllocationInfo.allocationSize;
    info.memoryTypeIndex = hostAllocationInfo.memoryTypeIndex;
    info.device = device;
    info.dedicated = dedicated;
    {
        // createCoherentMemory inside need to access info_VkDeviceMemory
        // information. set it before use.
        std::lock_guard<std::recursive_mutex> lock(mLock);
        info_VkDeviceMemory[mem] = info;
    }

    if (mCaps.vulkanCapset.deferredMapping || mCaps.params[kParamCreateGuestHandle]) {
        *pMemory = mem;
        return host_res;
    }

    auto coherentMemory = createCoherentMemory(device, mem, hostAllocationInfo, enc, host_res);
    if (coherentMemory) {
        std::lock_guard<std::recursive_mutex> lock(mLock);
        coherentMemory->subAllocate(pAllocateInfo->allocationSize, &ptr, offset);
        info.allocationSize = pAllocateInfo->allocationSize;
        info.coherentMemoryOffset = offset;
        info.coherentMemory = coherentMemory;
        info.ptr = ptr;
        info_VkDeviceMemory[mem] = info;
        *pMemory = mem;
    } else {
        enc->vkFreeMemory(device, mem, nullptr, true);
        std::lock_guard<std::recursive_mutex> lock(mLock);
        info_VkDeviceMemory.erase(mem);
    }
    return host_res;
}

VkResult ResourceTracker::getCoherentMemory(const VkMemoryAllocateInfo* pAllocateInfo,
                                            VkEncoder* enc, VkDevice device,
                                            VkDeviceMemory* pMemory) {
    VkMemoryAllocateFlagsInfo allocFlagsInfo;
    VkMemoryOpaqueCaptureAddressAllocateInfo opaqueCaptureAddressAllocInfo;

    // Add buffer device address capture structs
    const VkMemoryAllocateFlagsInfo* allocFlagsInfoPtr =
        vk_find_struct<VkMemoryAllocateFlagsInfo>(pAllocateInfo);

    bool dedicated =
        allocFlagsInfoPtr &&
        ((allocFlagsInfoPtr->flags & VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT) ||
         (allocFlagsInfoPtr->flags & VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT));

    if (mCaps.vulkanCapset.deferredMapping || mCaps.params[kParamCreateGuestHandle])
        dedicated = true;

    CoherentMemoryPtr coherentMemory = nullptr;
    uint8_t* ptr = nullptr;
    uint64_t offset = 0;
    {
        std::lock_guard<std::recursive_mutex> lock(mLock);
        for (const auto& [memory, info] : info_VkDeviceMemory) {
            if (info.device != device) continue;

            if (info.memoryTypeIndex != pAllocateInfo->memoryTypeIndex) continue;

            if (info.dedicated || dedicated) continue;

            if (!info.coherentMemory) continue;

            if (!info.coherentMemory->subAllocate(pAllocateInfo->allocationSize, &ptr, offset))
                continue;

            coherentMemory = info.coherentMemory;
            break;
        }
        if (coherentMemory) {
            struct VkDeviceMemory_Info info;
            info.coherentMemoryOffset = offset;
            info.ptr = ptr;
            info.memoryTypeIndex = pAllocateInfo->memoryTypeIndex;
            info.allocationSize = pAllocateInfo->allocationSize;
            info.coherentMemory = coherentMemory;
            info.device = device;

            // for suballocated memory, create an alias VkDeviceMemory handle for application
            // memory used for suballocations will still be VkDeviceMemory associated with
            // CoherentMemory
            auto mem = new_from_host_VkDeviceMemory(VK_NULL_HANDLE);
            info_VkDeviceMemory[mem] = info;
            *pMemory = mem;
            return VK_SUCCESS;
        }
    }
    return allocateCoherentMemory(device, pAllocateInfo, enc, pMemory);
}

VkResult ResourceTracker::on_vkAllocateMemory(void* context, VkResult input_result, VkDevice device,
                                              const VkMemoryAllocateInfo* pAllocateInfo,
                                              const VkAllocationCallbacks* pAllocator,
                                              VkDeviceMemory* pMemory) {
#define _RETURN_FAILURE_WITH_DEVICE_MEMORY_REPORT(result)                                      \
    {                                                                                          \
        auto it = info_VkDevice.find(device);                                                  \
        if (it == info_VkDevice.end()) return result;                                          \
        emitDeviceMemoryReport(it->second,                                                     \
                               VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATION_FAILED_EXT, 0,    \
                               pAllocateInfo->allocationSize, VK_OBJECT_TYPE_DEVICE_MEMORY, 0, \
                               pAllocateInfo->memoryTypeIndex);                                \
        return result;                                                                         \
    }

#define _RETURN_SCUCCESS_WITH_DEVICE_MEMORY_REPORT                                         \
    {                                                                                      \
        uint64_t memoryObjectId = (uint64_t)(void*)*pMemory;                               \
        if (ahw) {                                                                         \
            memoryObjectId = getAHardwareBufferId(ahw);                                    \
        }                                                                                  \
        emitDeviceMemoryReport(info_VkDevice[device],                                      \
                               isImport ? VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_IMPORT_EXT    \
                                        : VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATE_EXT, \
                               memoryObjectId, pAllocateInfo->allocationSize,              \
                               VK_OBJECT_TYPE_DEVICE_MEMORY, (uint64_t)(void*)*pMemory,    \
                               pAllocateInfo->memoryTypeIndex);                            \
        return VK_SUCCESS;                                                                 \
    }

    if (input_result != VK_SUCCESS) _RETURN_FAILURE_WITH_DEVICE_MEMORY_REPORT(input_result);

    VkEncoder* enc = (VkEncoder*)context;

    bool hasDedicatedImage = false;
    bool hasDedicatedBuffer = false;

    VkMemoryAllocateInfo finalAllocInfo = vk_make_orphan_copy(*pAllocateInfo);
    vk_struct_chain_iterator structChainIter = vk_make_chain_iterator(&finalAllocInfo);

    VkMemoryAllocateFlagsInfo allocFlagsInfo;
    VkMemoryOpaqueCaptureAddressAllocateInfo opaqueCaptureAddressAllocInfo;

    // Add buffer device address capture structs
    const VkMemoryAllocateFlagsInfo* allocFlagsInfoPtr =
        vk_find_struct<VkMemoryAllocateFlagsInfo>(pAllocateInfo);
    const VkMemoryOpaqueCaptureAddressAllocateInfo* opaqueCaptureAddressAllocInfoPtr =
        vk_find_struct<VkMemoryOpaqueCaptureAddressAllocateInfo>(pAllocateInfo);

    if (allocFlagsInfoPtr) {
        mesa_logd("%s: has alloc flags\n", __func__);
        allocFlagsInfo = *allocFlagsInfoPtr;
        vk_append_struct(&structChainIter, &allocFlagsInfo);
    }

    if (opaqueCaptureAddressAllocInfoPtr) {
        mesa_logd("%s: has opaque capture address\n", __func__);
        opaqueCaptureAddressAllocInfo = *opaqueCaptureAddressAllocInfoPtr;
        vk_append_struct(&structChainIter, &opaqueCaptureAddressAllocInfo);
    }

    VkMemoryDedicatedAllocateInfo dedicatedAllocInfo;
    VkImportColorBufferGOOGLE importCbInfo = {
        VK_STRUCTURE_TYPE_IMPORT_COLOR_BUFFER_GOOGLE,
        0,
    };
    VkImportBufferGOOGLE importBufferInfo = {
        VK_STRUCTURE_TYPE_IMPORT_BUFFER_GOOGLE,
        0,
    };
    // VkImportPhysicalAddressGOOGLE importPhysAddrInfo = {
    //     VK_STRUCTURE_TYPE_IMPORT_PHYSICAL_ADDRESS_GOOGLE, 0,
    // };

    const VkExportMemoryAllocateInfo* exportAllocateInfoPtr =
        vk_find_struct<VkExportMemoryAllocateInfo>(pAllocateInfo);

#ifdef VK_USE_PLATFORM_ANDROID_KHR
    const VkImportAndroidHardwareBufferInfoANDROID* importAhbInfoPtr =
        vk_find_struct<VkImportAndroidHardwareBufferInfoANDROID>(pAllocateInfo);
#else
    const void* importAhbInfoPtr = nullptr;
#endif

#if defined(__linux__) && !defined(VK_USE_PLATFORM_ANDROID_KHR)
    const VkImportMemoryFdInfoKHR* importFdInfoPtr =
        vk_find_struct<VkImportMemoryFdInfoKHR>(pAllocateInfo);
#else
    const VkImportMemoryFdInfoKHR* importFdInfoPtr = nullptr;
#endif

#ifdef VK_USE_PLATFORM_FUCHSIA
    const VkImportMemoryBufferCollectionFUCHSIA* importBufferCollectionInfoPtr =
        vk_find_struct<VkImportMemoryBufferCollectionFUCHSIA>(pAllocateInfo);

    const VkImportMemoryZirconHandleInfoFUCHSIA* importVmoInfoPtr =
        vk_find_struct<VkImportMemoryZirconHandleInfoFUCHSIA>(pAllocateInfo);
#else
    const void* importBufferCollectionInfoPtr = nullptr;
    const void* importVmoInfoPtr = nullptr;
#endif  // VK_USE_PLATFORM_FUCHSIA

    const VkMemoryDedicatedAllocateInfo* dedicatedAllocInfoPtr =
        vk_find_struct<VkMemoryDedicatedAllocateInfo>(pAllocateInfo);

    // Note for AHardwareBuffers, the Vulkan spec states:
    //
    //     Android hardware buffers have intrinsic width, height, format, and usage
    //     properties, so Vulkan images bound to memory imported from an Android
    //     hardware buffer must use dedicated allocations
    //
    // so any allocation requests with a VkImportAndroidHardwareBufferInfoANDROID
    // will necessarily have a VkMemoryDedicatedAllocateInfo. However, the host
    // may or may not actually use a dedicated allocation to emulate
    // AHardwareBuffers. As such, the VkMemoryDedicatedAllocateInfo is passed to the
    // host and the host will decide whether or not to use it.

    bool shouldPassThroughDedicatedAllocInfo =
        !exportAllocateInfoPtr && !importBufferCollectionInfoPtr && !importVmoInfoPtr;

    const VkPhysicalDeviceMemoryProperties& physicalDeviceMemoryProps =
        getPhysicalDeviceMemoryProperties(context, device, VK_NULL_HANDLE);

    const bool requestedMemoryIsHostVisible =
        isHostVisible(&physicalDeviceMemoryProps, pAllocateInfo->memoryTypeIndex);

#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
    shouldPassThroughDedicatedAllocInfo &= !requestedMemoryIsHostVisible;
#endif  // VK_USE_PLATFORM_FUCHSIA

    if (shouldPassThroughDedicatedAllocInfo && dedicatedAllocInfoPtr) {
        dedicatedAllocInfo = vk_make_orphan_copy(*dedicatedAllocInfoPtr);
        vk_append_struct(&structChainIter, &dedicatedAllocInfo);
    }

    // State needed for import/export.
    bool exportAhb = false;
    bool exportVmo = false;
    bool exportDmabuf = false;
    bool importAhb = false;
    bool importBufferCollection = false;
    bool importVmo = false;
    bool importDmabuf = false;
    (void)exportVmo;

    // Even if we export allocate, the underlying operation
    // for the host is always going to be an import operation.
    // This is also how Intel's implementation works,
    // and is generally simpler;
    // even in an export allocation,
    // we perform AHardwareBuffer allocation
    // on the guest side, at this layer,
    // and then we attach a new VkDeviceMemory
    // to the AHardwareBuffer on the host via an "import" operation.
    AHardwareBuffer* ahw = nullptr;

    if (exportAllocateInfoPtr) {
        exportAhb = exportAllocateInfoPtr->handleTypes &
                    VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
#ifdef VK_USE_PLATFORM_FUCHSIA
        exportVmo = exportAllocateInfoPtr->handleTypes &
                    VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA;
#endif  // VK_USE_PLATFORM_FUCHSIA
        exportDmabuf =
            exportAllocateInfoPtr->handleTypes & (VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
                                                  VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
    } else if (importAhbInfoPtr) {
        importAhb = true;
    } else if (importBufferCollectionInfoPtr) {
        importBufferCollection = true;
    } else if (importVmoInfoPtr) {
        importVmo = true;
    }

    if (importFdInfoPtr) {
        importDmabuf =
            (importFdInfoPtr->handleType & (VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
                                            VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT));
    }
    bool isImport = importAhb || importBufferCollection || importVmo || importDmabuf;

#if defined(VK_USE_PLATFORM_ANDROID_KHR)
    if (exportAhb) {
        hasDedicatedImage =
            dedicatedAllocInfoPtr && (dedicatedAllocInfoPtr->image != VK_NULL_HANDLE);
        hasDedicatedBuffer =
            dedicatedAllocInfoPtr && (dedicatedAllocInfoPtr->buffer != VK_NULL_HANDLE);
        VkExtent3D imageExtent = {0, 0, 0};
        uint32_t imageLayers = 0;
        VkFormat imageFormat = VK_FORMAT_UNDEFINED;
        VkImageUsageFlags imageUsage = 0;
        VkImageCreateFlags imageCreateFlags = 0;
        VkDeviceSize bufferSize = 0;
        VkDeviceSize allocationInfoAllocSize = finalAllocInfo.allocationSize;

        if (hasDedicatedImage) {
            std::lock_guard<std::recursive_mutex> lock(mLock);

            auto it = info_VkImage.find(dedicatedAllocInfoPtr->image);
            if (it == info_VkImage.end())
                _RETURN_FAILURE_WITH_DEVICE_MEMORY_REPORT(VK_ERROR_INITIALIZATION_FAILED);
            const auto& info = it->second;
            const auto& imgCi = info.createInfo;

            imageExtent = imgCi.extent;
            imageLayers = imgCi.arrayLayers;
            imageFormat = imgCi.format;
            imageUsage = imgCi.usage;
            imageCreateFlags = imgCi.flags;
        }

        if (hasDedicatedBuffer) {
            std::lock_guard<std::recursive_mutex> lock(mLock);

            auto it = info_VkBuffer.find(dedicatedAllocInfoPtr->buffer);
            if (it == info_VkBuffer.end())
                _RETURN_FAILURE_WITH_DEVICE_MEMORY_REPORT(VK_ERROR_INITIALIZATION_FAILED);
            const auto& info = it->second;
            const auto& bufCi = info.createInfo;

            bufferSize = bufCi.size;
        }

        VkResult ahbCreateRes = createAndroidHardwareBuffer(
            ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->grallocHelper(),
            hasDedicatedImage, hasDedicatedBuffer, imageExtent, imageLayers, imageFormat,
            imageUsage, imageCreateFlags, bufferSize, allocationInfoAllocSize, &ahw);

        if (ahbCreateRes != VK_SUCCESS) {
            _RETURN_FAILURE_WITH_DEVICE_MEMORY_REPORT(ahbCreateRes);
        }
    }

    if (importAhb) {
        ahw = importAhbInfoPtr->buffer;
        // We still need to acquire the AHardwareBuffer.
        importAndroidHardwareBuffer(
            ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->grallocHelper(),
            importAhbInfoPtr, nullptr);
    }

    if (ahw) {
        auto* gralloc =
            ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->grallocHelper();

        const uint32_t hostHandle = gralloc->getHostHandle(ahw);
        if (gralloc->getFormat(ahw) == AHARDWAREBUFFER_FORMAT_BLOB &&
            !gralloc->treatBlobAsImage()) {
            importBufferInfo.buffer = hostHandle;
            vk_append_struct(&structChainIter, &importBufferInfo);
        } else {
            importCbInfo.colorBuffer = hostHandle;
            vk_append_struct(&structChainIter, &importCbInfo);
        }
    }
#endif
    zx_handle_t vmo_handle = ZX_HANDLE_INVALID;

#ifdef VK_USE_PLATFORM_FUCHSIA
    if (importBufferCollection) {
        const auto& collection =
            *reinterpret_cast<fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>*>(
                importBufferCollectionInfoPtr->collection);
        auto result = collection->WaitForBuffersAllocated();
        if (!result.ok() || result->status != ZX_OK) {
            mesa_loge("WaitForBuffersAllocated failed: %d %d", result.status(),
                      GET_STATUS_SAFE(result, status));
            _RETURN_FAILURE_WITH_DEVICE_MEMORY_REPORT(VK_ERROR_INITIALIZATION_FAILED);
        }
        fuchsia_sysmem::wire::BufferCollectionInfo2& info = result->buffer_collection_info;
        uint32_t index = importBufferCollectionInfoPtr->index;
        if (info.buffer_count < index) {
            mesa_loge("Invalid buffer index: %d", index);
            _RETURN_FAILURE_WITH_DEVICE_MEMORY_REPORT(VK_ERROR_INITIALIZATION_FAILED);
        }
        vmo_handle = info.buffers[index].vmo.release();
    }

    if (importVmo) {
        vmo_handle = importVmoInfoPtr->handle;
    }

    if (exportVmo) {
        hasDedicatedImage =
            dedicatedAllocInfoPtr && (dedicatedAllocInfoPtr->image != VK_NULL_HANDLE);
        hasDedicatedBuffer =
            dedicatedAllocInfoPtr && (dedicatedAllocInfoPtr->buffer != VK_NULL_HANDLE);

        if (hasDedicatedImage && hasDedicatedBuffer) {
            mesa_loge(
                "Invalid VkMemoryDedicatedAllocationInfo: At least one "
                "of image and buffer must be VK_NULL_HANDLE.");
            return VK_ERROR_OUT_OF_DEVICE_MEMORY;
        }

        const VkImageCreateInfo* pImageCreateInfo = nullptr;

        VkBufferConstraintsInfoFUCHSIA bufferConstraintsInfo = {
            .sType = VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CREATE_INFO_FUCHSIA,
            .pNext = nullptr,
            .createInfo = {},
            .requiredFormatFeatures = 0,
            .bufferCollectionConstraints =
                VkBufferCollectionConstraintsInfoFUCHSIA{
                    .sType = VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CONSTRAINTS_INFO_FUCHSIA,
                    .pNext = nullptr,
                    .minBufferCount = 1,
                    .maxBufferCount = 0,
                    .minBufferCountForCamping = 0,
                    .minBufferCountForDedicatedSlack = 0,
                    .minBufferCountForSharedSlack = 0,
                },
        };
        const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo = nullptr;

        if (hasDedicatedImage) {
            std::lock_guard<std::recursive_mutex> lock(mLock);

            auto it = info_VkImage.find(dedicatedAllocInfoPtr->image);
            if (it == info_VkImage.end()) return VK_ERROR_INITIALIZATION_FAILED;
            const auto& imageInfo = it->second;

            pImageCreateInfo = &imageInfo.createInfo;
        }

        if (hasDedicatedBuffer) {
            std::lock_guard<std::recursive_mutex> lock(mLock);

            auto it = info_VkBuffer.find(dedicatedAllocInfoPtr->buffer);
            if (it == info_VkBuffer.end()) return VK_ERROR_INITIALIZATION_FAILED;
            const auto& bufferInfo = it->second;

            bufferConstraintsInfo.createInfo = bufferInfo.createInfo;
            pBufferConstraintsInfo = &bufferConstraintsInfo;
        }

        hasDedicatedImage =
            hasDedicatedImage && getBufferCollectionConstraintsVulkanImageUsage(pImageCreateInfo);
        hasDedicatedBuffer = hasDedicatedBuffer && getBufferCollectionConstraintsVulkanBufferUsage(
                                                       pBufferConstraintsInfo);

        if (hasDedicatedImage || hasDedicatedBuffer) {
            auto token_ends = fidl::CreateEndpoints<::fuchsia_sysmem::BufferCollectionToken>();
            if (!token_ends.is_ok()) {
                mesa_loge("zx_channel_create failed: %d", token_ends.status_value());
                abort();
            }

            {
                auto result =
                    mSysmemAllocator->AllocateSharedCollection(std::move(token_ends->server));
                if (!result.ok()) {
                    mesa_loge("AllocateSharedCollection failed: %d", result.status());
                    abort();
                }
            }

            auto collection_ends = fidl::CreateEndpoints<::fuchsia_sysmem::BufferCollection>();
            if (!collection_ends.is_ok()) {
                mesa_loge("zx_channel_create failed: %d", collection_ends.status_value());
                abort();
            }

            {
                auto result = mSysmemAllocator->BindSharedCollection(
                    std::move(token_ends->client), std::move(collection_ends->server));
                if (!result.ok()) {
                    mesa_loge("BindSharedCollection failed: %d", result.status());
                    abort();
                }
            }

            fidl::WireSyncClient<fuchsia_sysmem::BufferCollection> collection(
                std::move(collection_ends->client));
            if (hasDedicatedImage) {
                // TODO(fxbug.dev/42172354): Use setBufferCollectionImageConstraintsFUCHSIA.
                VkResult res = setBufferCollectionConstraintsFUCHSIA(enc, device, &collection,
                                                                     pImageCreateInfo);
                if (res == VK_ERROR_FORMAT_NOT_SUPPORTED) {
                    mesa_loge("setBufferCollectionConstraints failed: format %u is not supported",
                              pImageCreateInfo->format);
                    return VK_ERROR_OUT_OF_DEVICE_MEMORY;
                }
                if (res != VK_SUCCESS) {
                    mesa_loge("setBufferCollectionConstraints failed: %d", res);
                    abort();
                }
            }

            if (hasDedicatedBuffer) {
                VkResult res = setBufferCollectionBufferConstraintsFUCHSIA(&collection,
                                                                           pBufferConstraintsInfo);
                if (res != VK_SUCCESS) {
                    mesa_loge("setBufferCollectionBufferConstraints failed: %d", res);
                    abort();
                }
            }

            {
                auto result = collection->WaitForBuffersAllocated();
                if (result.ok() && result->status == ZX_OK) {
                    fuchsia_sysmem::wire::BufferCollectionInfo2& info =
                        result->buffer_collection_info;
                    if (!info.buffer_count) {
                        mesa_loge(
                            "WaitForBuffersAllocated returned "
                            "invalid count: %d",
                            info.buffer_count);
                        abort();
                    }
                    vmo_handle = info.buffers[0].vmo.release();
                } else {
                    mesa_loge("WaitForBuffersAllocated failed: %d %d", result.status(),
                              GET_STATUS_SAFE(result, status));
                    abort();
                }
            }

            collection->Close();

            zx::vmo vmo_copy;
            zx_status_t status = zx_handle_duplicate(vmo_handle, ZX_RIGHT_SAME_RIGHTS,
                                                     vmo_copy.reset_and_get_address());
            if (status != ZX_OK) {
                mesa_loge("Failed to duplicate VMO: %d", status);
                abort();
            }

            if (pImageCreateInfo) {
                // Only device-local images need to create color buffer; for
                // host-visible images, the color buffer is already created
                // when sysmem allocates memory. Here we use the |tiling|
                // field of image creation info to determine if it uses
                // host-visible memory.
                bool isLinear = pImageCreateInfo->tiling == VK_IMAGE_TILING_LINEAR;
                if (!isLinear) {
                    fuchsia_hardware_goldfish::wire::ColorBufferFormatType format;
                    switch (pImageCreateInfo->format) {
                        case VK_FORMAT_B8G8R8A8_SINT:
                        case VK_FORMAT_B8G8R8A8_UNORM:
                        case VK_FORMAT_B8G8R8A8_SRGB:
                        case VK_FORMAT_B8G8R8A8_SNORM:
                        case VK_FORMAT_B8G8R8A8_SSCALED:
                        case VK_FORMAT_B8G8R8A8_USCALED:
                            format = fuchsia_hardware_goldfish::wire::ColorBufferFormatType::kBgra;
                            break;
                        case VK_FORMAT_R8G8B8A8_SINT:
                        case VK_FORMAT_R8G8B8A8_UNORM:
                        case VK_FORMAT_R8G8B8A8_SRGB:
                        case VK_FORMAT_R8G8B8A8_SNORM:
                        case VK_FORMAT_R8G8B8A8_SSCALED:
                        case VK_FORMAT_R8G8B8A8_USCALED:
                            format = fuchsia_hardware_goldfish::wire::ColorBufferFormatType::kRgba;
                            break;
                        case VK_FORMAT_R8_UNORM:
                        case VK_FORMAT_R8_UINT:
                        case VK_FORMAT_R8_USCALED:
                        case VK_FORMAT_R8_SNORM:
                        case VK_FORMAT_R8_SINT:
                        case VK_FORMAT_R8_SSCALED:
                        case VK_FORMAT_R8_SRGB:
                            format =
                                fuchsia_hardware_goldfish::wire::ColorBufferFormatType::kLuminance;
                            break;
                        case VK_FORMAT_R8G8_UNORM:
                        case VK_FORMAT_R8G8_UINT:
                        case VK_FORMAT_R8G8_USCALED:
                        case VK_FORMAT_R8G8_SNORM:
                        case VK_FORMAT_R8G8_SINT:
                        case VK_FORMAT_R8G8_SSCALED:
                        case VK_FORMAT_R8G8_SRGB:
                            format = fuchsia_hardware_goldfish::wire::ColorBufferFormatType::kRg;
                            break;
                        default:
                            mesa_loge("Unsupported format: %d", pImageCreateInfo->format);
                            abort();
                    }

                    fidl::Arena arena;
                    fuchsia_hardware_goldfish::wire::CreateColorBuffer2Params createParams(arena);
                    createParams.set_width(pImageCreateInfo->extent.width)
                        .set_height(pImageCreateInfo->extent.height)
                        .set_format(format)
                        .set_memory_property(
                            fuchsia_hardware_goldfish::wire::kMemoryPropertyDeviceLocal);

                    auto result = mControlDevice->CreateColorBuffer2(std::move(vmo_copy),
                                                                     std::move(createParams));
                    if (!result.ok() || result->res != ZX_OK) {
                        if (result.ok() && result->res == ZX_ERR_ALREADY_EXISTS) {
                            mesa_logd(
                                "CreateColorBuffer: color buffer already "
                                "exists\n");
                        } else {
                            mesa_loge("CreateColorBuffer failed: %d:%d", result.status(),
                                      GET_STATUS_SAFE(result, res));
                            abort();
                        }
                    }
                }
            }

            if (pBufferConstraintsInfo) {
                fidl::Arena arena;
                fuchsia_hardware_goldfish::wire::CreateBuffer2Params createParams(arena);
                createParams.set_size(arena, pBufferConstraintsInfo->createInfo.size)
                    .set_memory_property(
                        fuchsia_hardware_goldfish::wire::kMemoryPropertyDeviceLocal);

                auto result =
                    mControlDevice->CreateBuffer2(std::move(vmo_copy), std::move(createParams));
                if (!result.ok() || result->is_error()) {
                    mesa_loge("CreateBuffer2 failed: %d:%d", result.status(),
                              GET_STATUS_SAFE(result, error_value()));
                    abort();
                }
            }
        } else {
            mesa_logw(
                "Dedicated image / buffer not available. Cannot create "
                "BufferCollection to export VMOs.");
            return VK_ERROR_OUT_OF_DEVICE_MEMORY;
        }
    }

    if (vmo_handle != ZX_HANDLE_INVALID) {
        zx::vmo vmo_copy;
        zx_status_t status =
            zx_handle_duplicate(vmo_handle, ZX_RIGHT_SAME_RIGHTS, vmo_copy.reset_and_get_address());
        if (status != ZX_OK) {
            mesa_loge("Failed to duplicate VMO: %d", status);
            abort();
        }
        zx_status_t status2 = ZX_OK;

        auto result = mControlDevice->GetBufferHandle(std::move(vmo_copy));
        if (!result.ok() || result->res != ZX_OK) {
            mesa_loge("GetBufferHandle failed: %d:%d", result.status(),
                      GET_STATUS_SAFE(result, res));
        } else {
            fuchsia_hardware_goldfish::wire::BufferHandleType handle_type = result->type;
            uint32_t buffer_handle = result->id;

            if (handle_type == fuchsia_hardware_goldfish::wire::BufferHandleType::kBuffer) {
                importBufferInfo.buffer = buffer_handle;
                vk_append_struct(&structChainIter, &importBufferInfo);
            } else {
                importCbInfo.colorBuffer = buffer_handle;
                vk_append_struct(&structChainIter, &importCbInfo);
            }
        }
    }
#endif

    VirtGpuResourcePtr bufferBlob = nullptr;
#if defined(LINUX_GUEST_BUILD)
    if (exportDmabuf) {
        VirtGpuDevice* instance = VirtGpuDevice::getInstance();
        hasDedicatedImage =
            dedicatedAllocInfoPtr && (dedicatedAllocInfoPtr->image != VK_NULL_HANDLE);
        hasDedicatedBuffer =
            dedicatedAllocInfoPtr && (dedicatedAllocInfoPtr->buffer != VK_NULL_HANDLE);

        if (hasDedicatedImage) {
            VkImageCreateInfo imageCreateInfo;
            bool isDmaBufImage = false;
            {
                std::lock_guard<std::recursive_mutex> lock(mLock);

                auto it = info_VkImage.find(dedicatedAllocInfoPtr->image);
                if (it == info_VkImage.end()) return VK_ERROR_INITIALIZATION_FAILED;
                const auto& imageInfo = it->second;

                imageCreateInfo = imageInfo.createInfo;
                isDmaBufImage = imageInfo.isDmaBufImage;
            }

            // TODO (b/326956485): Support DRM format modifiers for dmabuf memory
            // For now, can only externalize memory for linear images
            if (isDmaBufImage) {
                const VkImageSubresource imageSubresource = {
                    .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
                    .mipLevel = 0,
                    .arrayLayer = 0,
                };
                VkSubresourceLayout subResourceLayout;
                on_vkGetImageSubresourceLayout(context, device, dedicatedAllocInfoPtr->image,
                                               &imageSubresource, &subResourceLayout);
                if (!subResourceLayout.rowPitch) {
                    mesa_loge("Failed to query stride for VirtGpu resource creation.");
                    return VK_ERROR_INITIALIZATION_FAILED;
                }

                uint32_t virglFormat = gfxstream::vk::getVirglFormat(imageCreateInfo.format);
                if (!virglFormat) {
                    mesa_loge("Unsupported VK format for VirtGpu resource, vkFormat: 0x%x",
                              imageCreateInfo.format);
                    return VK_ERROR_FORMAT_NOT_SUPPORTED;
                }
                const uint32_t target = PIPE_TEXTURE_2D;
                uint32_t bind = VIRGL_BIND_RENDER_TARGET;
                if (VK_IMAGE_TILING_LINEAR == imageCreateInfo.tiling) {
                    bind |= VIRGL_BIND_LINEAR;
                }

                if (mCaps.vulkanCapset.alwaysBlob) {
                    struct gfxstreamResourceCreate3d create3d = {};
                    struct VirtGpuExecBuffer exec = {};
                    struct gfxstreamPlaceholderCommandVk placeholderCmd = {};
                    struct VirtGpuCreateBlob createBlob = {};

                    create3d.hdr.opCode = GFXSTREAM_RESOURCE_CREATE_3D;
                    create3d.bind = bind;
                    create3d.target = target;
                    create3d.format = virglFormat;
                    create3d.width = imageCreateInfo.extent.width;
                    create3d.height = imageCreateInfo.extent.height;
                    create3d.blobId = ++mAtomicId;

                    createBlob.blobCmd = reinterpret_cast<uint8_t*>(&create3d);
                    createBlob.blobCmdSize = sizeof(create3d);
                    createBlob.blobMem = kBlobMemHost3d;
                    createBlob.flags = kBlobFlagShareable | kBlobFlagCrossDevice;
                    createBlob.blobId = create3d.blobId;
                    createBlob.size = finalAllocInfo.allocationSize;

                    bufferBlob = instance->createBlob(createBlob);
                    if (!bufferBlob) return VK_ERROR_OUT_OF_DEVICE_MEMORY;

                    placeholderCmd.hdr.opCode = GFXSTREAM_PLACEHOLDER_COMMAND_VK;
                    exec.command = static_cast<void*>(&placeholderCmd);
                    exec.command_size = sizeof(placeholderCmd);
                    exec.flags = kRingIdx;
                    exec.ring_idx = 1;
                    if (instance->execBuffer(exec, bufferBlob.get())) {
                        mesa_loge("Failed to execbuffer placeholder command.");
                        return VK_ERROR_OUT_OF_HOST_MEMORY;
                    }

                    if (bufferBlob->wait()) {
                        mesa_loge("Failed to wait for blob.");
                        return VK_ERROR_OUT_OF_HOST_MEMORY;
                    }
                } else {
                    bufferBlob = instance->createResource(
                        imageCreateInfo.extent.width, imageCreateInfo.extent.height,
                        subResourceLayout.rowPitch,
                        subResourceLayout.rowPitch * imageCreateInfo.extent.height, virglFormat,
                        target, bind);
                    if (!bufferBlob) {
                        mesa_loge("Failed to create colorBuffer resource for Image memory");
                        return VK_ERROR_OUT_OF_DEVICE_MEMORY;
                    }
                    if (bufferBlob->wait()) {
                        mesa_loge("Failed to wait for colorBuffer resource for Image memory");
                        return VK_ERROR_OUT_OF_DEVICE_MEMORY;
                    }
                }
            } else {
                mesa_logw(
                    "The VkMemoryDedicatedAllocateInfo::image associated with VkDeviceMemory "
                    "allocation cannot be used to create exportable resource "
                    "(VkExportMemoryAllocateInfo).\n");
            }
        } else if (hasDedicatedBuffer) {
            uint32_t virglFormat = VIRGL_FORMAT_R8_UNORM;
            const uint32_t target = PIPE_BUFFER;
            uint32_t bind = VIRGL_BIND_LINEAR;
            uint32_t width = finalAllocInfo.allocationSize;
            uint32_t height = 1;

            if (mCaps.vulkanCapset.alwaysBlob) {
                struct gfxstreamResourceCreate3d create3d = {};
                struct VirtGpuExecBuffer exec = {};
                struct gfxstreamPlaceholderCommandVk placeholderCmd = {};
                struct VirtGpuCreateBlob createBlob = {};

                create3d.hdr.opCode = GFXSTREAM_RESOURCE_CREATE_3D;
                create3d.bind = bind;
                create3d.target = target;
                create3d.format = virglFormat;
                create3d.width = width;
                create3d.height = height;
                create3d.blobId = ++mAtomicId;

                createBlob.blobCmd = reinterpret_cast<uint8_t*>(&create3d);
                createBlob.blobCmdSize = sizeof(create3d);
                createBlob.blobMem = kBlobMemHost3d;
                createBlob.flags = kBlobFlagShareable | kBlobFlagCrossDevice;
                createBlob.blobId = create3d.blobId;
                createBlob.size = width;

                bufferBlob = instance->createBlob(createBlob);
                if (!bufferBlob) return VK_ERROR_OUT_OF_DEVICE_MEMORY;

                placeholderCmd.hdr.opCode = GFXSTREAM_PLACEHOLDER_COMMAND_VK;
                exec.command = static_cast<void*>(&placeholderCmd);
                exec.command_size = sizeof(placeholderCmd);
                exec.flags = kRingIdx;
                exec.ring_idx = 1;
                if (instance->execBuffer(exec, bufferBlob.get())) {
                    mesa_loge("Failed to allocate coherent memory: failed to execbuffer for wait.");
                    return VK_ERROR_OUT_OF_HOST_MEMORY;
                }

                bufferBlob->wait();
            } else {
                bufferBlob = instance->createResource(width, height, width, width * height,
                                                      virglFormat, target, bind);
                if (!bufferBlob) {
                    mesa_loge("Failed to create colorBuffer resource for Image memory");
                    return VK_ERROR_OUT_OF_DEVICE_MEMORY;
                }
                if (bufferBlob->wait()) {
                    mesa_loge("Failed to wait for colorBuffer resource for Image memory");
                    return VK_ERROR_OUT_OF_DEVICE_MEMORY;
                }
            }
        } else {
            mesa_logw(
                "VkDeviceMemory is not exportable (VkExportMemoryAllocateInfo). Requires "
                "VkMemoryDedicatedAllocateInfo::image to create external resource.");
        }
    }

    if (importDmabuf) {
        VirtGpuExternalHandle importHandle = {};
        importHandle.osHandle = importFdInfoPtr->fd;
        importHandle.type = kMemHandleDmabuf;

        auto instance = VirtGpuDevice::getInstance();
        bufferBlob = instance->importBlob(importHandle);
        if (!bufferBlob) {
            mesa_loge("%s: Failed to import colorBuffer resource\n", __func__);
            return VK_ERROR_OUT_OF_DEVICE_MEMORY;
        }
    }

    if (bufferBlob) {
        if (hasDedicatedBuffer) {
            importBufferInfo.buffer = bufferBlob->getResourceHandle();
            vk_append_struct(&structChainIter, &importBufferInfo);
        } else {
            importCbInfo.colorBuffer = bufferBlob->getResourceHandle();
            vk_append_struct(&structChainIter, &importCbInfo);
        }
    }
#endif

    if (ahw || bufferBlob || !requestedMemoryIsHostVisible) {
        input_result =
            enc->vkAllocateMemory(device, &finalAllocInfo, pAllocator, pMemory, true /* do lock */);

        if (input_result != VK_SUCCESS) _RETURN_FAILURE_WITH_DEVICE_MEMORY_REPORT(input_result);

        VkDeviceSize allocationSize = finalAllocInfo.allocationSize;
        setDeviceMemoryInfo(device, *pMemory, 0, nullptr, finalAllocInfo.memoryTypeIndex, ahw,
                            isImport, vmo_handle, bufferBlob);

        _RETURN_SCUCCESS_WITH_DEVICE_MEMORY_REPORT;
    }

#ifdef VK_USE_PLATFORM_FUCHSIA
    if (vmo_handle != ZX_HANDLE_INVALID) {
        input_result =
            enc->vkAllocateMemory(device, &finalAllocInfo, pAllocator, pMemory, true /* do lock */);

        // Get VMO handle rights, and only use allowed rights to map the
        // host memory.
        zx_info_handle_basic handle_info;
        zx_status_t status = zx_object_get_info(vmo_handle, ZX_INFO_HANDLE_BASIC, &handle_info,
                                                sizeof(handle_info), nullptr, nullptr);
        if (status != ZX_OK) {
            mesa_loge("%s: cannot get vmo object info: vmo = %u status: %d.", __func__, vmo_handle,
                      status);
            return VK_ERROR_OUT_OF_HOST_MEMORY;
        }

        zx_vm_option_t vm_permission = 0u;
        vm_permission |= (handle_info.rights & ZX_RIGHT_READ) ? ZX_VM_PERM_READ : 0;
        vm_permission |= (handle_info.rights & ZX_RIGHT_WRITE) ? ZX_VM_PERM_WRITE : 0;

        zx_paddr_t addr;
        status = zx_vmar_map(zx_vmar_root_self(), vm_permission, 0, vmo_handle, 0,
                             finalAllocInfo.allocationSize, &addr);
        if (status != ZX_OK) {
            mesa_loge("%s: cannot map vmar: status %d.", __func__, status);
            return VK_ERROR_OUT_OF_HOST_MEMORY;
        }

        setDeviceMemoryInfo(device, *pMemory, finalAllocInfo.allocationSize,
                            reinterpret_cast<uint8_t*>(addr), finalAllocInfo.memoryTypeIndex,
                            /*ahw=*/nullptr, isImport, vmo_handle, /*blobPtr=*/nullptr);
        return VK_SUCCESS;
    }
#endif

    // Host visible memory with direct mapping
    VkResult result = getCoherentMemory(&finalAllocInfo, enc, device, pMemory);
    if (result != VK_SUCCESS) return result;

    _RETURN_SCUCCESS_WITH_DEVICE_MEMORY_REPORT;
}

void ResourceTracker::on_vkFreeMemory(void* context, VkDevice device, VkDeviceMemory memory,
                                      const VkAllocationCallbacks* pAllocateInfo) {
    std::unique_lock<std::recursive_mutex> lock(mLock);

    auto it = info_VkDeviceMemory.find(memory);
    if (it == info_VkDeviceMemory.end()) return;
    auto& info = it->second;
    uint64_t memoryObjectId = (uint64_t)(void*)memory;
#ifdef VK_USE_PLATFORM_ANDROID_KHR
    if (info.ahw) {
        memoryObjectId = getAHardwareBufferId(info.ahw);
    }
#endif

    emitDeviceMemoryReport(info_VkDevice[device],
                           info.imported ? VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_UNIMPORT_EXT
                                         : VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_FREE_EXT,
                           memoryObjectId, 0 /* size */, VK_OBJECT_TYPE_DEVICE_MEMORY,
                           (uint64_t)(void*)memory);

#ifdef VK_USE_PLATFORM_FUCHSIA
    if (info.vmoHandle && info.ptr) {
        zx_status_t status = zx_vmar_unmap(
            zx_vmar_root_self(), reinterpret_cast<zx_paddr_t>(info.ptr), info.allocationSize);
        if (status != ZX_OK) {
            mesa_loge("%s: Cannot unmap ptr: status %d", __func__, status);
        }
        info.ptr = nullptr;
    }
#endif

    if (!info.coherentMemory) {
        lock.unlock();
        VkEncoder* enc = (VkEncoder*)context;
        enc->vkFreeMemory(device, memory, pAllocateInfo, true /* do lock */);
        return;
    }

    auto coherentMemory = freeCoherentMemoryLocked(memory, info);

    // We have to release the lock before we could possibly free a
    // CoherentMemory, because that will call into VkEncoder, which
    // shouldn't be called when the lock is held.
    lock.unlock();
    coherentMemory = nullptr;
}

VkResult ResourceTracker::on_vkMapMemory(void* context, VkResult host_result, VkDevice device,
                                         VkDeviceMemory memory, VkDeviceSize offset,
                                         VkDeviceSize size, VkMemoryMapFlags, void** ppData) {
    if (host_result != VK_SUCCESS) {
        mesa_loge("%s: Host failed to map", __func__);
        return host_result;
    }

    std::unique_lock<std::recursive_mutex> lock(mLock);

    auto deviceMemoryInfoIt = info_VkDeviceMemory.find(memory);
    if (deviceMemoryInfoIt == info_VkDeviceMemory.end()) {
        mesa_loge("%s: Failed to find VkDeviceMemory.", __func__);
        return VK_ERROR_MEMORY_MAP_FAILED;
    }
    auto& deviceMemoryInfo = deviceMemoryInfoIt->second;

    if (deviceMemoryInfo.blobId && !deviceMemoryInfo.coherentMemory &&
        !mCaps.params[kParamCreateGuestHandle]) {
        // NOTE: must not hold lock while calling into the encoder.
        lock.unlock();
        VkEncoder* enc = (VkEncoder*)context;
        VkResult vkResult = enc->vkGetBlobGOOGLE(device, memory, /*doLock*/ false);
        if (vkResult != VK_SUCCESS) {
            mesa_loge("%s: Failed to vkGetBlobGOOGLE().", __func__);
            return vkResult;
        }
        lock.lock();

        // NOTE: deviceMemoryInfoIt potentially invalidated but deviceMemoryInfo still okay.

        struct VirtGpuCreateBlob createBlob = {};
        createBlob.blobMem = kBlobMemHost3d;
        createBlob.flags = kBlobFlagMappable;
        createBlob.blobId = deviceMemoryInfo.blobId;
        createBlob.size = deviceMemoryInfo.coherentMemorySize;

        auto blob = VirtGpuDevice::getInstance()->createBlob(createBlob);
        if (!blob) return VK_ERROR_OUT_OF_DEVICE_MEMORY;

        VirtGpuResourceMappingPtr mapping = blob->createMapping();
        if (!mapping) return VK_ERROR_OUT_OF_DEVICE_MEMORY;

        auto coherentMemory =
            std::make_shared<CoherentMemory>(mapping, createBlob.size, device, memory);

        uint8_t* ptr;
        uint64_t offset;
        coherentMemory->subAllocate(deviceMemoryInfo.allocationSize, &ptr, offset);

        deviceMemoryInfo.coherentMemoryOffset = offset;
        deviceMemoryInfo.coherentMemory = coherentMemory;
        deviceMemoryInfo.ptr = ptr;
    }

    if (!deviceMemoryInfo.ptr) {
        mesa_loge("%s: VkDeviceMemory has nullptr.", __func__);
        return VK_ERROR_MEMORY_MAP_FAILED;
    }

    if (size != VK_WHOLE_SIZE && (deviceMemoryInfo.ptr + offset + size >
                                  deviceMemoryInfo.ptr + deviceMemoryInfo.allocationSize)) {
        mesa_loge(
            "%s: size is too big. alloc size 0x%llx while we wanted offset 0x%llx size 0x%llx "
            "total 0x%llx",
            __func__, (unsigned long long)deviceMemoryInfo.allocationSize,
            (unsigned long long)offset, (unsigned long long)size, (unsigned long long)offset);
        return VK_ERROR_MEMORY_MAP_FAILED;
    }

    *ppData = deviceMemoryInfo.ptr + offset;

    return host_result;
}

void ResourceTracker::on_vkUnmapMemory(void*, VkDevice, VkDeviceMemory) {
    // no-op
}

void ResourceTracker::transformImageMemoryRequirements2ForGuest(VkImage image,
                                                                VkMemoryRequirements2* reqs2) {
    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto it = info_VkImage.find(image);
    if (it == info_VkImage.end()) return;

    auto& info = it->second;

    if (!info.external || !info.externalCreateInfo.handleTypes) {
        transformImageMemoryRequirementsForGuestLocked(image, &reqs2->memoryRequirements);
        return;
    }

    transformImageMemoryRequirementsForGuestLocked(image, &reqs2->memoryRequirements);

    VkMemoryDedicatedRequirements* dedicatedReqs =
        vk_find_struct<VkMemoryDedicatedRequirements>(reqs2);

    if (!dedicatedReqs) return;

    transformExternalResourceMemoryDedicatedRequirementsForGuest(dedicatedReqs);
}

void ResourceTracker::transformBufferMemoryRequirements2ForGuest(VkBuffer buffer,
                                                                 VkMemoryRequirements2* reqs2) {
    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto it = info_VkBuffer.find(buffer);
    if (it == info_VkBuffer.end()) return;

    auto& info = it->second;

    if (!info.external || !info.externalCreateInfo.handleTypes) {
        return;
    }

    VkMemoryDedicatedRequirements* dedicatedReqs =
        vk_find_struct<VkMemoryDedicatedRequirements>(reqs2);

    if (!dedicatedReqs) return;

    transformExternalResourceMemoryDedicatedRequirementsForGuest(dedicatedReqs);
}

VkResult ResourceTracker::on_vkCreateImage(void* context, VkResult, VkDevice device,
                                           const VkImageCreateInfo* pCreateInfo,
                                           const VkAllocationCallbacks* pAllocator,
                                           VkImage* pImage) {
    VkEncoder* enc = (VkEncoder*)context;

    VkImageCreateInfo localCreateInfo = vk_make_orphan_copy(*pCreateInfo);
    if (localCreateInfo.sharingMode != VK_SHARING_MODE_CONCURRENT) {
        localCreateInfo.queueFamilyIndexCount = 0;
        localCreateInfo.pQueueFamilyIndices = nullptr;
    }

    vk_struct_chain_iterator structChainIter = vk_make_chain_iterator(&localCreateInfo);
    VkExternalMemoryImageCreateInfo localExtImgCi;

    const VkExternalMemoryImageCreateInfo* extImgCiPtr =
        vk_find_struct<VkExternalMemoryImageCreateInfo>(pCreateInfo);

    if (extImgCiPtr) {
        localExtImgCi = vk_make_orphan_copy(*extImgCiPtr);
        vk_append_struct(&structChainIter, &localExtImgCi);
    }

#if defined(LINUX_GUEST_BUILD)
    bool isDmaBufImage = false;
    if (extImgCiPtr &&
        (extImgCiPtr->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT)) {
        const wsi_image_create_info* wsiImageCi =
            vk_find_struct<wsi_image_create_info>(pCreateInfo);
        if (wsiImageCi) {
            if (!wsiImageCi->scanout) {
                mesa_logd(
                    "gfxstream only supports native DRM image scanout path for Linux WSI "
                    "(wsi_image_create_info::scanout)");
                return VK_ERROR_INITIALIZATION_FAILED;
            }
            // Linux WSI creates swapchain images with VK_IMAGE_CREATE_ALIAS_BIT. Vulkan spec
            // states: "If the pNext chain includes a VkExternalMemoryImageCreateInfo or
            // VkExternalMemoryImageCreateInfoNV structure whose handleTypes member is not 0, it is
            // as if VK_IMAGE_CREATE_ALIAS_BIT is set." To avoid flag mismatches on host driver,
            // remove the VK_IMAGE_CREATE_ALIAS_BIT here.
            localCreateInfo.flags &= ~VK_IMAGE_CREATE_ALIAS_BIT;
            // TODO (b/326956485): DRM format modifiers to support client/compositor awareness
            // For now, override WSI images to use linear tiling, as compositor will default to
            // DRM_FORMAT_MOD_LINEAR.
            localCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;
        }
        isDmaBufImage = true;
    }
#endif

#ifdef VK_USE_PLATFORM_ANDROID_KHR
    VkNativeBufferANDROID localAnb;
    const VkNativeBufferANDROID* anbInfoPtr = vk_find_struct<VkNativeBufferANDROID>(pCreateInfo);
    if (anbInfoPtr) {
        localAnb = vk_make_orphan_copy(*anbInfoPtr);
        vk_append_struct(&structChainIter, &localAnb);
    }

    VkExternalFormatANDROID localExtFormatAndroid;
    const VkExternalFormatANDROID* extFormatAndroidPtr =
        vk_find_struct<VkExternalFormatANDROID>(pCreateInfo);
    if (extFormatAndroidPtr) {
        localExtFormatAndroid = vk_make_orphan_copy(*extFormatAndroidPtr);

        // Do not append external format android;
        // instead, replace the local image localCreateInfo format
        // with the corresponding Vulkan format
        if (extFormatAndroidPtr->externalFormat) {
            localCreateInfo.format = vk_format_from_fourcc(extFormatAndroidPtr->externalFormat);
            if (localCreateInfo.format == VK_FORMAT_UNDEFINED)
                return VK_ERROR_VALIDATION_FAILED_EXT;
        }
    }
#endif

#ifdef VK_USE_PLATFORM_FUCHSIA
    const VkBufferCollectionImageCreateInfoFUCHSIA* extBufferCollectionPtr =
        vk_find_struct<VkBufferCollectionImageCreateInfoFUCHSIA>(pCreateInfo);

    bool isSysmemBackedMemory = false;

    if (extImgCiPtr &&
        (extImgCiPtr->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA)) {
        isSysmemBackedMemory = true;
    }

    if (extBufferCollectionPtr) {
        const auto& collection =
            *reinterpret_cast<fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>*>(
                extBufferCollectionPtr->collection);
        uint32_t index = extBufferCollectionPtr->index;
        zx::vmo vmo;

        fuchsia_sysmem::wire::BufferCollectionInfo2 info;

        auto result = collection->WaitForBuffersAllocated();
        if (result.ok() && result->status == ZX_OK) {
            info = std::move(result->buffer_collection_info);
            if (index < info.buffer_count && info.settings.has_image_format_constraints) {
                vmo = std::move(info.buffers[index].vmo);
            }
        } else {
            mesa_loge("WaitForBuffersAllocated failed: %d %d", result.status(),
                      GET_STATUS_SAFE(result, status));
        }

        if (vmo.is_valid()) {
            zx::vmo vmo_dup;
            if (zx_status_t status = vmo.duplicate(ZX_RIGHT_SAME_RIGHTS, &vmo_dup);
                status != ZX_OK) {
                mesa_loge("%s: zx_vmo_duplicate failed: %d", __func__, status);
                abort();
            }

            auto buffer_handle_result = mControlDevice->GetBufferHandle(std::move(vmo_dup));
            if (!buffer_handle_result.ok()) {
                mesa_loge("%s: GetBufferHandle FIDL error: %d", __func__,
                          buffer_handle_result.status());
                abort();
            }
            if (buffer_handle_result.value().res == ZX_OK) {
                // Buffer handle already exists.
                // If it is a ColorBuffer, no-op; Otherwise return error.
                if (buffer_handle_result.value().type !=
                    fuchsia_hardware_goldfish::wire::BufferHandleType::kColorBuffer) {
                    mesa_loge("%s: BufferHandle %u is not a ColorBuffer", __func__,
                              buffer_handle_result.value().id);
                    return VK_ERROR_OUT_OF_HOST_MEMORY;
                }
            } else if (buffer_handle_result.value().res == ZX_ERR_NOT_FOUND) {
                // Buffer handle not found. Create ColorBuffer based on buffer settings.
                auto format = info.settings.image_format_constraints.pixel_format.type ==
                                      fuchsia_sysmem::wire::PixelFormatType::kR8G8B8A8
                                  ? fuchsia_hardware_goldfish::wire::ColorBufferFormatType::kRgba
                                  : fuchsia_hardware_goldfish::wire::ColorBufferFormatType::kBgra;

                uint32_t memory_property =
                    info.settings.buffer_settings.heap ==
                            fuchsia_sysmem::wire::HeapType::kGoldfishDeviceLocal
                        ? fuchsia_hardware_goldfish::wire::kMemoryPropertyDeviceLocal
                        : fuchsia_hardware_goldfish::wire::kMemoryPropertyHostVisible;

                fidl::Arena arena;
                fuchsia_hardware_goldfish::wire::CreateColorBuffer2Params createParams(arena);
                createParams.set_width(info.settings.image_format_constraints.min_coded_width)
                    .set_height(info.settings.image_format_constraints.min_coded_height)
                    .set_format(format)
                    .set_memory_property(memory_property);

                auto result =
                    mControlDevice->CreateColorBuffer2(std::move(vmo), std::move(createParams));
                if (result.ok() && result->res == ZX_ERR_ALREADY_EXISTS) {
                    mesa_logd("CreateColorBuffer: color buffer already exists\n");
                } else if (!result.ok() || result->res != ZX_OK) {
                    mesa_loge("CreateColorBuffer failed: %d:%d", result.status(),
                              GET_STATUS_SAFE(result, res));
                }
            }

            if (info.settings.buffer_settings.heap ==
                fuchsia_sysmem::wire::HeapType::kGoldfishHostVisible) {
                mesa_logd(
                    "%s: Image uses host visible memory heap; set tiling "
                    "to linear to match host ImageCreateInfo",
                    __func__);
                localCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;
            }
        }
        isSysmemBackedMemory = true;
    }

    if (isSysmemBackedMemory) {
        localCreateInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
    }
#endif

    VkResult res;
    VkMemoryRequirements memReqs;

    if (supportsCreateResourcesWithRequirements()) {
        res = enc->vkCreateImageWithRequirementsGOOGLE(device, &localCreateInfo, pAllocator, pImage,
                                                       &memReqs, true /* do lock */);
    } else {
        res = enc->vkCreateImage(device, &localCreateInfo, pAllocator, pImage, true /* do lock */);
    }

    if (res != VK_SUCCESS) return res;

    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto it = info_VkImage.find(*pImage);
    if (it == info_VkImage.end()) return VK_ERROR_INITIALIZATION_FAILED;

    auto& info = it->second;

    info.device = device;
    info.createInfo = *pCreateInfo;
    info.createInfo.pNext = nullptr;

#ifdef VK_USE_PLATFORM_ANDROID_KHR
    if (extFormatAndroidPtr && extFormatAndroidPtr->externalFormat) {
        info.hasExternalFormat = true;
        info.externalFourccFormat = extFormatAndroidPtr->externalFormat;
    }
#endif  // VK_USE_PLATFORM_ANDROID_KHR

    if (supportsCreateResourcesWithRequirements()) {
        info.baseRequirementsKnown = true;
    }

    if (extImgCiPtr) {
        info.external = true;
        info.externalCreateInfo = *extImgCiPtr;
    }

#ifdef VK_USE_PLATFORM_FUCHSIA
    if (isSysmemBackedMemory) {
        info.isSysmemBackedMemory = true;
    }
#endif

// Delete `protocolVersion` check goldfish drivers are gone.
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
    if (mCaps.vulkanCapset.colorBufferMemoryIndex == 0xFFFFFFFF) {
        mCaps.vulkanCapset.colorBufferMemoryIndex = getColorBufferMemoryIndex(context, device);
    }
    if ((extImgCiPtr && (extImgCiPtr->handleTypes &
                         VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID))) {
        updateMemoryTypeBits(&memReqs.memoryTypeBits, mCaps.vulkanCapset.colorBufferMemoryIndex);
    }
#endif
#if defined(LINUX_GUEST_BUILD)
    if (mCaps.vulkanCapset.colorBufferMemoryIndex == 0xFFFFFFFF) {
        mCaps.vulkanCapset.colorBufferMemoryIndex = getColorBufferMemoryIndex(context, device);
    }
    info.isDmaBufImage = isDmaBufImage;
    if (info.isDmaBufImage) {
        updateMemoryTypeBits(&memReqs.memoryTypeBits, mCaps.vulkanCapset.colorBufferMemoryIndex);
        if (localCreateInfo.tiling == VK_IMAGE_TILING_OPTIMAL) {
            // Linux WSI calls vkGetImageSubresourceLayout() to query the stride for swapchain
            // support. Similarly, stride is also queried from vkGetImageSubresourceLayout() to
            // determine the stride for colorBuffer resource creation (guest-side dmabuf resource).
            // To satisfy valid usage of this API, must call on the linearPeerImage for the VkImage
            // in question. As long as these two use cases match, the rowPitch won't actually be
            // used by WSI.
            VkImageCreateInfo linearPeerImageCreateInfo = {
                .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
                .pNext = nullptr,
                .flags = {},
                .imageType = VK_IMAGE_TYPE_2D,
                .format = localCreateInfo.format,
                .extent = localCreateInfo.extent,
                .mipLevels = 1,
                .arrayLayers = 1,
                .samples = VK_SAMPLE_COUNT_1_BIT,
                .tiling = VK_IMAGE_TILING_LINEAR,
                .usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
                .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
                .queueFamilyIndexCount = 0,
                .pQueueFamilyIndices = nullptr,
                .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
            };
            res = enc->vkCreateImage(device, &linearPeerImageCreateInfo, pAllocator,
                                     &info.linearPeerImage, true /* do lock */);
            if (res != VK_SUCCESS) return res;
        }
    }
#endif

    if (info.baseRequirementsKnown) {
        transformImageMemoryRequirementsForGuestLocked(*pImage, &memReqs);
        info.baseRequirements = memReqs;
    }
    return res;
}

VkResult ResourceTracker::on_vkCreateSamplerYcbcrConversion(
    void* context, VkResult, VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
    const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion) {
    VkSamplerYcbcrConversionCreateInfo localCreateInfo = vk_make_orphan_copy(*pCreateInfo);

#ifdef VK_USE_PLATFORM_ANDROID_KHR
    const VkExternalFormatANDROID* extFormatAndroidPtr =
        vk_find_struct<VkExternalFormatANDROID>(pCreateInfo);
    if (extFormatAndroidPtr) {
        if (extFormatAndroidPtr->externalFormat == DRM_FORMAT_RGB565) {
            // We don't support external formats on host and it causes RGB565
            // to fail in CtsGraphicsTestCases android.graphics.cts.BasicVulkanGpuTest
            // when passed as an external format.
            // We may consider doing this for all external formats.
            // See b/134771579.
            *pYcbcrConversion = VK_YCBCR_CONVERSION_DO_NOTHING;
            return VK_SUCCESS;
        } else if (extFormatAndroidPtr->externalFormat) {
            localCreateInfo.format = vk_format_from_fourcc(extFormatAndroidPtr->externalFormat);
        }
    }
#endif

    VkEncoder* enc = (VkEncoder*)context;
    VkResult res = enc->vkCreateSamplerYcbcrConversion(device, &localCreateInfo, pAllocator,
                                                       pYcbcrConversion, true /* do lock */);

    if (*pYcbcrConversion == VK_YCBCR_CONVERSION_DO_NOTHING) {
        mesa_loge(
            "FATAL: vkCreateSamplerYcbcrConversion returned a reserved value "
            "(VK_YCBCR_CONVERSION_DO_NOTHING)");
        abort();
    }
    return res;
}

void ResourceTracker::on_vkDestroySamplerYcbcrConversion(void* context, VkDevice device,
                                                         VkSamplerYcbcrConversion ycbcrConversion,
                                                         const VkAllocationCallbacks* pAllocator) {
    VkEncoder* enc = (VkEncoder*)context;
    if (ycbcrConversion != VK_YCBCR_CONVERSION_DO_NOTHING) {
        enc->vkDestroySamplerYcbcrConversion(device, ycbcrConversion, pAllocator,
                                             true /* do lock */);
    }
}

VkResult ResourceTracker::on_vkCreateSamplerYcbcrConversionKHR(
    void* context, VkResult, VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
    const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion) {
    VkSamplerYcbcrConversionCreateInfo localCreateInfo = vk_make_orphan_copy(*pCreateInfo);

#if defined(VK_USE_PLATFORM_ANDROID_KHR)
    const VkExternalFormatANDROID* extFormatAndroidPtr =
        vk_find_struct<VkExternalFormatANDROID>(pCreateInfo);
    if (extFormatAndroidPtr) {
        if (extFormatAndroidPtr->externalFormat == DRM_FORMAT_RGB565) {
            // We don't support external formats on host and it causes RGB565
            // to fail in CtsGraphicsTestCases android.graphics.cts.BasicVulkanGpuTest
            // when passed as an external format.
            // We may consider doing this for all external formats.
            // See b/134771579.
            *pYcbcrConversion = VK_YCBCR_CONVERSION_DO_NOTHING;
            return VK_SUCCESS;
        } else if (extFormatAndroidPtr->externalFormat) {
            localCreateInfo.format = vk_format_from_fourcc(extFormatAndroidPtr->externalFormat);
        }
    }
#endif

    VkEncoder* enc = (VkEncoder*)context;
    VkResult res = enc->vkCreateSamplerYcbcrConversionKHR(device, &localCreateInfo, pAllocator,
                                                          pYcbcrConversion, true /* do lock */);

    if (*pYcbcrConversion == VK_YCBCR_CONVERSION_DO_NOTHING) {
        mesa_loge(
            "FATAL: vkCreateSamplerYcbcrConversionKHR returned a reserved value "
            "(VK_YCBCR_CONVERSION_DO_NOTHING)");
        abort();
    }
    return res;
}

void ResourceTracker::on_vkDestroySamplerYcbcrConversionKHR(
    void* context, VkDevice device, VkSamplerYcbcrConversion ycbcrConversion,
    const VkAllocationCallbacks* pAllocator) {
    VkEncoder* enc = (VkEncoder*)context;
    if (ycbcrConversion != VK_YCBCR_CONVERSION_DO_NOTHING) {
        enc->vkDestroySamplerYcbcrConversionKHR(device, ycbcrConversion, pAllocator,
                                                true /* do lock */);
    }
}

VkResult ResourceTracker::on_vkCreateSampler(void* context, VkResult, VkDevice device,
                                             const VkSamplerCreateInfo* pCreateInfo,
                                             const VkAllocationCallbacks* pAllocator,
                                             VkSampler* pSampler) {
    VkSamplerCreateInfo localCreateInfo = vk_make_orphan_copy(*pCreateInfo);
    vk_struct_chain_iterator structChainIter = vk_make_chain_iterator(&localCreateInfo);

#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(VK_USE_PLATFORM_FUCHSIA)
    VkSamplerYcbcrConversionInfo localVkSamplerYcbcrConversionInfo;
    const VkSamplerYcbcrConversionInfo* samplerYcbcrConversionInfo =
        vk_find_struct<VkSamplerYcbcrConversionInfo>(pCreateInfo);
    if (samplerYcbcrConversionInfo) {
        if (samplerYcbcrConversionInfo->conversion != VK_YCBCR_CONVERSION_DO_NOTHING) {
            localVkSamplerYcbcrConversionInfo = vk_make_orphan_copy(*samplerYcbcrConversionInfo);
            vk_append_struct(&structChainIter, &localVkSamplerYcbcrConversionInfo);
        }
    }

    VkSamplerCustomBorderColorCreateInfoEXT localVkSamplerCustomBorderColorCreateInfo;
    const VkSamplerCustomBorderColorCreateInfoEXT* samplerCustomBorderColorCreateInfo =
        vk_find_struct<VkSamplerCustomBorderColorCreateInfoEXT>(pCreateInfo);
    if (samplerCustomBorderColorCreateInfo) {
        localVkSamplerCustomBorderColorCreateInfo =
            vk_make_orphan_copy(*samplerCustomBorderColorCreateInfo);
        vk_append_struct(&structChainIter, &localVkSamplerCustomBorderColorCreateInfo);
    }
#endif

    VkEncoder* enc = (VkEncoder*)context;
    return enc->vkCreateSampler(device, &localCreateInfo, pAllocator, pSampler, true /* do lock */);
}

void ResourceTracker::on_vkGetPhysicalDeviceExternalFenceProperties(
    void* context, VkPhysicalDevice physicalDevice,
    const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo,
    VkExternalFenceProperties* pExternalFenceProperties) {
    (void)context;
    (void)physicalDevice;

    pExternalFenceProperties->exportFromImportedHandleTypes = 0;
    pExternalFenceProperties->compatibleHandleTypes = 0;
    pExternalFenceProperties->externalFenceFeatures = 0;

    bool syncFd = pExternalFenceInfo->handleType & VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;

    if (!syncFd) {
        return;
    }

#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
    pExternalFenceProperties->exportFromImportedHandleTypes =
        VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
    pExternalFenceProperties->compatibleHandleTypes = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
    pExternalFenceProperties->externalFenceFeatures =
        VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT;
#endif
}

void ResourceTracker::on_vkGetPhysicalDeviceExternalFencePropertiesKHR(
    void* context, VkPhysicalDevice physicalDevice,
    const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo,
    VkExternalFenceProperties* pExternalFenceProperties) {
    on_vkGetPhysicalDeviceExternalFenceProperties(context, physicalDevice, pExternalFenceInfo,
                                                  pExternalFenceProperties);
}

VkResult ResourceTracker::on_vkCreateFence(void* context, VkResult input_result, VkDevice device,
                                           const VkFenceCreateInfo* pCreateInfo,
                                           const VkAllocationCallbacks* pAllocator,
                                           VkFence* pFence) {
    VkEncoder* enc = (VkEncoder*)context;
    VkFenceCreateInfo finalCreateInfo = *pCreateInfo;

    const VkExportFenceCreateInfo* exportFenceInfoPtr =
        vk_find_struct<VkExportFenceCreateInfo>(pCreateInfo);

#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
    bool exportSyncFd = exportFenceInfoPtr && (exportFenceInfoPtr->handleTypes &
                                               VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT);
#endif

    input_result =
        enc->vkCreateFence(device, &finalCreateInfo, pAllocator, pFence, true /* do lock */);

    if (input_result != VK_SUCCESS) return input_result;

#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
    if (exportSyncFd) {
        if (!mFeatureInfo->hasVirtioGpuNativeSync) {
            mesa_logd("%s: ensure sync device\n", __func__);
            ensureSyncDeviceFd();
        }

        mesa_logd("%s: getting fence info\n", __func__);
        std::lock_guard<std::recursive_mutex> lock(mLock);
        auto it = info_VkFence.find(*pFence);

        if (it == info_VkFence.end()) return VK_ERROR_INITIALIZATION_FAILED;

        auto& info = it->second;

        info.external = true;
        info.exportFenceCreateInfo = *exportFenceInfoPtr;
        mesa_logd("%s: info set (fence still -1). fence: %p\n", __func__, (void*)(*pFence));
        // syncFd is still -1 because we expect user to explicitly
        // export it via vkGetFenceFdKHR
    }
#endif

    return input_result;
}

void ResourceTracker::on_vkDestroyFence(void* context, VkDevice device, VkFence fence,
                                        const VkAllocationCallbacks* pAllocator) {
    VkEncoder* enc = (VkEncoder*)context;
    enc->vkDestroyFence(device, fence, pAllocator, true /* do lock */);
}

VkResult ResourceTracker::on_vkResetFences(void* context, VkResult, VkDevice device,
                                           uint32_t fenceCount, const VkFence* pFences) {
    VkEncoder* enc = (VkEncoder*)context;
    VkResult res = enc->vkResetFences(device, fenceCount, pFences, true /* do lock */);

    if (res != VK_SUCCESS) return res;

    if (!fenceCount) return res;

    // Permanence: temporary
    // on fence reset, close the fence fd
    // and act like we need to GetFenceFdKHR/ImportFenceFdKHR again
    std::lock_guard<std::recursive_mutex> lock(mLock);
    for (uint32_t i = 0; i < fenceCount; ++i) {
        VkFence fence = pFences[i];
        auto it = info_VkFence.find(fence);
        auto& info = it->second;
        if (!info.external) continue;

#if GFXSTREAM_ENABLE_GUEST_GOLDFISH
        if (info.syncFd >= 0) {
            mesa_logd("%s: resetting fence. make fd -1\n", __func__);
            goldfish_sync_signal(info.syncFd);
            auto* syncHelper =
                ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->syncHelper();
            syncHelper->close(info.syncFd);
            info.syncFd = -1;
        }
#endif
    }

    return res;
}

VkResult ResourceTracker::on_vkImportFenceFdKHR(void* context, VkResult, VkDevice device,
                                                const VkImportFenceFdInfoKHR* pImportFenceFdInfo) {
    (void)context;
    (void)device;
    (void)pImportFenceFdInfo;

    // Transference: copy
    // meaning dup() the incoming fd

    VkEncoder* enc = (VkEncoder*)context;

    bool hasFence = pImportFenceFdInfo->fence != VK_NULL_HANDLE;

    if (!hasFence) return VK_ERROR_OUT_OF_HOST_MEMORY;

#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)

    bool syncFdImport = pImportFenceFdInfo->handleType & VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;

    if (!syncFdImport) {
        mesa_loge("%s: VK_ERROR_OUT_OF_HOST_MEMORY: no sync fd import\n", __func__);
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }

    std::lock_guard<std::recursive_mutex> lock(mLock);
    auto it = info_VkFence.find(pImportFenceFdInfo->fence);
    if (it == info_VkFence.end()) {
        mesa_loge("%s: VK_ERROR_OUT_OF_HOST_MEMORY: no fence info\n", __func__);
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }

    auto& info = it->second;

    auto* syncHelper = ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->syncHelper();
#if GFXSTREAM_ENABLE_GUEST_GOLDFISH
    if (info.syncFd >= 0) {
        mesa_logd("%s: previous sync fd exists, close it\n", __func__);
        goldfish_sync_signal(info.syncFd);
        syncHelper->close(info.syncFd);
    }
#endif

    if (pImportFenceFdInfo->fd < 0) {
        mesa_logd("%s: import -1, set to -1 and exit\n", __func__);
        info.syncFd = -1;
    } else {
        mesa_logd("%s: import actual fd, dup and close()\n", __func__);
        info.syncFd = syncHelper->dup(pImportFenceFdInfo->fd);
        syncHelper->close(pImportFenceFdInfo->fd);
    }
    return VK_SUCCESS;
#else
    return VK_ERROR_OUT_OF_HOST_MEMORY;
#endif
}

VkResult ResourceTracker::on_vkGetFenceFdKHR(void* context, VkResult, VkDevice device,
                                             const VkFenceGetFdInfoKHR* pGetFdInfo, int* pFd) {
    // export operation.
    // first check if fence is signaled
    // then if so, return -1
    // else, queue work

    VkEncoder* enc = (VkEncoder*)context;

    bool hasFence = pGetFdInfo->fence != VK_NULL_HANDLE;

    if (!hasFence) {
        mesa_loge("%s: VK_ERROR_OUT_OF_HOST_MEMORY: no fence\n", __func__);
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }

#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
    bool syncFdExport = pGetFdInfo->handleType & VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;

    if (!syncFdExport) {
        mesa_loge("%s: VK_ERROR_OUT_OF_HOST_MEMORY: no sync fd fence\n", __func__);
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }

    VkResult currentFenceStatus =
        enc->vkGetFenceStatus(device, pGetFdInfo->fence, true /* do lock */);

    if (VK_ERROR_DEVICE_LOST == currentFenceStatus) {  // Other error
        mesa_loge("%s: VK_ERROR_DEVICE_LOST: Other error\n", __func__);
        *pFd = -1;
        return VK_ERROR_DEVICE_LOST;
    }

    if (VK_NOT_READY == currentFenceStatus || VK_SUCCESS == currentFenceStatus) {
        // Fence is valid. We also create a new sync fd for a signaled
        // fence, because ANGLE will use the returned fd directly to
        // implement eglDupNativeFenceFDANDROID, where -1 is only returned
        // when error occurs.
        std::lock_guard<std::recursive_mutex> lock(mLock);

        auto it = info_VkFence.find(pGetFdInfo->fence);
        if (it == info_VkFence.end()) {
            mesa_loge("%s: VK_ERROR_OUT_OF_HOST_MEMORY: no fence info\n", __func__);
            return VK_ERROR_OUT_OF_HOST_MEMORY;
        }

        auto& info = it->second;

        bool syncFdCreated = info.external && (info.exportFenceCreateInfo.handleTypes &
                                               VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT);

        if (!syncFdCreated) {
            mesa_loge("%s: VK_ERROR_OUT_OF_HOST_MEMORY: no sync fd created\n", __func__);
            return VK_ERROR_OUT_OF_HOST_MEMORY;
        }

        if (mFeatureInfo->hasVirtioGpuNativeSync) {
            VkResult result;
            int64_t osHandle;
            uint64_t hostFenceHandle = get_host_u64_VkFence(pGetFdInfo->fence);

            result = createFence(device, hostFenceHandle, osHandle);
            if (result != VK_SUCCESS) return result;

            *pFd = osHandle;
        } else {
#if GFXSTREAM_ENABLE_GUEST_GOLDFISH
            goldfish_sync_queue_work(
                mSyncDeviceFd, get_host_u64_VkFence(pGetFdInfo->fence) /* the handle */,
                GOLDFISH_SYNC_VULKAN_SEMAPHORE_SYNC /* thread handle (doubling as type field) */,
                pFd);
#endif
        }

        // relinquish ownership
        info.syncFd = -1;
        mesa_logd("%s: got fd: %d\n", __func__, *pFd);
        return VK_SUCCESS;
    }
    return VK_ERROR_DEVICE_LOST;
#else
    return VK_ERROR_OUT_OF_HOST_MEMORY;
#endif
}

VkResult ResourceTracker::on_vkWaitForFences(void* context, VkResult, VkDevice device,
                                             uint32_t fenceCount, const VkFence* pFences,
                                             VkBool32 waitAll, uint64_t timeout) {
    VkEncoder* enc = (VkEncoder*)context;

#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
    std::vector<VkFence> fencesExternal;
    std::vector<int> fencesExternalWaitFds;
    std::vector<VkFence> fencesNonExternal;

    std::unique_lock<std::recursive_mutex> lock(mLock);

    for (uint32_t i = 0; i < fenceCount; ++i) {
        auto it = info_VkFence.find(pFences[i]);
        if (it == info_VkFence.end()) continue;
        const auto& info = it->second;
        if (info.syncFd >= 0) {
            fencesExternal.push_back(pFences[i]);
            fencesExternalWaitFds.push_back(info.syncFd);
        } else {
            fencesNonExternal.push_back(pFences[i]);
        }
    }

    lock.unlock();

    if (fencesExternal.empty()) {
        // No need for work pool, just wait with host driver.
        return enc->vkWaitForFences(device, fenceCount, pFences, waitAll, timeout,
                                    true /* do lock */);
    } else {
        // Depending on wait any or wait all,
        // schedule a wait group with waitAny/waitAll
        std::vector<WorkPool::Task> tasks;

        mesa_logd("%s: scheduling ext waits\n", __func__);

        for (auto fd : fencesExternalWaitFds) {
            mesa_logd("%s: wait on %d\n", __func__, fd);
            tasks.push_back([fd] {
                auto* syncHelper =
                    ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->syncHelper();
                syncHelper->wait(fd, 3000);
                mesa_logd("done waiting on fd %d\n", fd);
            });
        }

        if (!fencesNonExternal.empty()) {
            tasks.push_back(
                [this, fencesNonExternal /* copy of vector */, device, waitAll, timeout] {
                    auto hostConn = ResourceTracker::threadingCallbacks.hostConnectionGetFunc();
                    auto vkEncoder = ResourceTracker::threadingCallbacks.vkEncoderGetFunc(hostConn);
                    mesa_logd("%s: vkWaitForFences to host\n", __func__);
                    vkEncoder->vkWaitForFences(device, fencesNonExternal.size(),
                                               fencesNonExternal.data(), waitAll, timeout,
                                               true /* do lock */);
                });
        }

        auto waitGroupHandle = mWorkPool.schedule(tasks);

        // Convert timeout to microseconds from nanoseconds
        bool waitRes = false;
        if (waitAll) {
            waitRes = mWorkPool.waitAll(waitGroupHandle, timeout / 1000);
        } else {
            waitRes = mWorkPool.waitAny(waitGroupHandle, timeout / 1000);
        }

        if (waitRes) {
            mesa_logd("%s: VK_SUCCESS\n", __func__);
            return VK_SUCCESS;
        } else {
            mesa_loge("%s: VK_TIMEOUT\n", __func__);
            return VK_TIMEOUT;
        }
    }
#else
    return enc->vkWaitForFences(device, fenceCount, pFences, waitAll, timeout, true /* do lock */);
#endif
}

VkResult ResourceTracker::on_vkCreateDescriptorPool(void* context, VkResult, VkDevice device,
                                                    const VkDescriptorPoolCreateInfo* pCreateInfo,
                                                    const VkAllocationCallbacks* pAllocator,
                                                    VkDescriptorPool* pDescriptorPool) {
    VkEncoder* enc = (VkEncoder*)context;

    VkResult res = enc->vkCreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool,
                                               true /* do lock */);

    if (res != VK_SUCCESS) return res;

    VkDescriptorPool pool = *pDescriptorPool;

    struct goldfish_VkDescriptorPool* dp = as_goldfish_VkDescriptorPool(pool);
    dp->allocInfo = new DescriptorPoolAllocationInfo;
    dp->allocInfo->device = device;
    dp->allocInfo->createFlags = pCreateInfo->flags;
    dp->allocInfo->maxSets = pCreateInfo->maxSets;
    dp->allocInfo->usedSets = 0;

    for (uint32_t i = 0; i < pCreateInfo->poolSizeCount; ++i) {
        dp->allocInfo->descriptorCountInfo.push_back({
            pCreateInfo->pPoolSizes[i].type, pCreateInfo->pPoolSizes[i].descriptorCount,
            0, /* used */
        });
    }

    if (mFeatureInfo->hasVulkanBatchedDescriptorSetUpdate) {
        std::vector<uint64_t> poolIds(pCreateInfo->maxSets);

        uint32_t count = pCreateInfo->maxSets;
        enc->vkCollectDescriptorPoolIdsGOOGLE(device, pool, &count, poolIds.data(),
                                              true /* do lock */);

        dp->allocInfo->freePoolIds = poolIds;
    }

    return res;
}

void ResourceTracker::on_vkDestroyDescriptorPool(void* context, VkDevice device,
                                                 VkDescriptorPool descriptorPool,
                                                 const VkAllocationCallbacks* pAllocator) {
    if (!descriptorPool) return;

    VkEncoder* enc = (VkEncoder*)context;

    clearDescriptorPoolAndUnregisterDescriptorSets(context, device, descriptorPool);

    enc->vkDestroyDescriptorPool(device, descriptorPool, pAllocator, true /* do lock */);
}

VkResult ResourceTracker::on_vkResetDescriptorPool(void* context, VkResult, VkDevice device,
                                                   VkDescriptorPool descriptorPool,
                                                   VkDescriptorPoolResetFlags flags) {
    if (!descriptorPool) return VK_ERROR_INITIALIZATION_FAILED;

    VkEncoder* enc = (VkEncoder*)context;

    VkResult res = enc->vkResetDescriptorPool(device, descriptorPool, flags, true /* do lock */);

    if (res != VK_SUCCESS) return res;

    clearDescriptorPoolAndUnregisterDescriptorSets(context, device, descriptorPool);
    return res;
}

VkResult ResourceTracker::on_vkAllocateDescriptorSets(
    void* context, VkResult, VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo,
    VkDescriptorSet* pDescriptorSets) {
    VkEncoder* enc = (VkEncoder*)context;
    auto ci = pAllocateInfo;
    auto sets = pDescriptorSets;
    if (mFeatureInfo->hasVulkanBatchedDescriptorSetUpdate) {
        // Using the pool ID's we collected earlier from the host
        VkResult poolAllocResult = validateAndApplyVirtualDescriptorSetAllocation(ci, sets);

        if (poolAllocResult != VK_SUCCESS) return poolAllocResult;

        for (uint32_t i = 0; i < ci->descriptorSetCount; ++i) {
            register_VkDescriptorSet(sets[i]);
            VkDescriptorSetLayout setLayout =
                as_goldfish_VkDescriptorSet(sets[i])->reified->setLayout;

            // Need to add ref to the set layout in the virtual case
            // because the set itself might not be realized on host at the
            // same time
            struct goldfish_VkDescriptorSetLayout* dsl =
                as_goldfish_VkDescriptorSetLayout(setLayout);
            ++dsl->layoutInfo->refcount;
        }
    } else {
        VkResult allocRes = enc->vkAllocateDescriptorSets(device, ci, sets, true /* do lock */);

        if (allocRes != VK_SUCCESS) return allocRes;

        for (uint32_t i = 0; i < ci->descriptorSetCount; ++i) {
            applyDescriptorSetAllocation(ci->descriptorPool, ci->pSetLayouts[i]);
            fillDescriptorSetInfoForPool(ci->descriptorPool, ci->pSetLayouts[i], sets[i]);
        }
    }

    return VK_SUCCESS;
}

VkResult ResourceTracker::on_vkFreeDescriptorSets(void* context, VkResult, VkDevice device,
                                                  VkDescriptorPool descriptorPool,
                                                  uint32_t descriptorSetCount,
                                                  const VkDescriptorSet* pDescriptorSets) {
    VkEncoder* enc = (VkEncoder*)context;

    // Bit of robustness so that we can double free descriptor sets
    // and do other invalid usages
    // https://github.com/KhronosGroup/Vulkan-Docs/issues/1070
    // (people expect VK_SUCCESS to always be returned by vkFreeDescriptorSets)
    std::vector<VkDescriptorSet> toActuallyFree;
    {
        std::lock_guard<std::recursive_mutex> lock(mLock);

        // Pool was destroyed
        if (info_VkDescriptorPool.find(descriptorPool) == info_VkDescriptorPool.end()) {
            return VK_SUCCESS;
        }

        if (!descriptorPoolSupportsIndividualFreeLocked(descriptorPool)) return VK_SUCCESS;

        std::vector<VkDescriptorSet> existingDescriptorSets;
        ;

        // Check if this descriptor set was in the pool's set of allocated descriptor sets,
        // to guard against double free (Double free is allowed by the client)
        {
            auto allocedSets = as_goldfish_VkDescriptorPool(descriptorPool)->allocInfo->allocedSets;

            for (uint32_t i = 0; i < descriptorSetCount; ++i) {
                if (allocedSets.end() == allocedSets.find(pDescriptorSets[i])) {
                    mesa_loge(
                        "%s: Warning: descriptor set %p not found in pool. Was this "
                        "double-freed?\n",
                        __func__, (void*)pDescriptorSets[i]);
                    continue;
                }

                auto it = info_VkDescriptorSet.find(pDescriptorSets[i]);
                if (it == info_VkDescriptorSet.end()) continue;

                existingDescriptorSets.push_back(pDescriptorSets[i]);
            }
        }

        for (auto set : existingDescriptorSets) {
            if (removeDescriptorSetFromPool(set,
                                            mFeatureInfo->hasVulkanBatchedDescriptorSetUpdate)) {
                toActuallyFree.push_back(set);
            }
        }

        if (toActuallyFree.empty()) return VK_SUCCESS;
    }

    if (mFeatureInfo->hasVulkanBatchedDescriptorSetUpdate) {
        // In the batched set update case, decrement refcount on the set layout
        // and only free on host if we satisfied a pending allocation on the
        // host.
        for (uint32_t i = 0; i < toActuallyFree.size(); ++i) {
            VkDescriptorSetLayout setLayout =
                as_goldfish_VkDescriptorSet(toActuallyFree[i])->reified->setLayout;
            decDescriptorSetLayoutRef(context, device, setLayout, nullptr);
        }
        freeDescriptorSetsIfHostAllocated(enc, device, (uint32_t)toActuallyFree.size(),
                                          toActuallyFree.data());
    } else {
        // In the non-batched set update case, just free them directly.
        enc->vkFreeDescriptorSets(device, descriptorPool, (uint32_t)toActuallyFree.size(),
                                  toActuallyFree.data(), true /* do lock */);
    }
    return VK_SUCCESS;
}

VkResult ResourceTracker::on_vkCreateDescriptorSetLayout(
    void* context, VkResult, VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
    const VkAllocationCallbacks* pAllocator, VkDescriptorSetLayout* pSetLayout) {
    VkEncoder* enc = (VkEncoder*)context;

    VkResult res = enc->vkCreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout,
                                                    true /* do lock */);

    if (res != VK_SUCCESS) return res;

    struct goldfish_VkDescriptorSetLayout* dsl = as_goldfish_VkDescriptorSetLayout(*pSetLayout);
    dsl->layoutInfo = new DescriptorSetLayoutInfo;
    for (uint32_t i = 0; i < pCreateInfo->bindingCount; ++i) {
        dsl->layoutInfo->bindings.push_back(pCreateInfo->pBindings[i]);
    }
    dsl->layoutInfo->refcount = 1;

    return res;
}

void ResourceTracker::on_vkUpdateDescriptorSets(void* context, VkDevice device,
                                                uint32_t descriptorWriteCount,
                                                const VkWriteDescriptorSet* pDescriptorWrites,
                                                uint32_t descriptorCopyCount,
                                                const VkCopyDescriptorSet* pDescriptorCopies) {
    VkEncoder* enc = (VkEncoder*)context;

    std::vector<VkDescriptorImageInfo> transformedImageInfos;
    std::vector<VkWriteDescriptorSet> transformedWrites(descriptorWriteCount);

    memcpy(transformedWrites.data(), pDescriptorWrites,
           sizeof(VkWriteDescriptorSet) * descriptorWriteCount);

    size_t imageInfosNeeded = 0;
    for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
        if (!isDescriptorTypeImageInfo(transformedWrites[i].descriptorType)) continue;
        if (!transformedWrites[i].pImageInfo) continue;

        imageInfosNeeded += transformedWrites[i].descriptorCount;
    }

    transformedImageInfos.resize(imageInfosNeeded);

    size_t imageInfoIndex = 0;
    for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
        if (!isDescriptorTypeImageInfo(transformedWrites[i].descriptorType)) continue;
        if (!transformedWrites[i].pImageInfo) continue;

        for (uint32_t j = 0; j < transformedWrites[i].descriptorCount; ++j) {
            transformedImageInfos[imageInfoIndex] = transformedWrites[i].pImageInfo[j];
            ++imageInfoIndex;
        }
        transformedWrites[i].pImageInfo =
            &transformedImageInfos[imageInfoIndex - transformedWrites[i].descriptorCount];
    }

    {
        // Validate and filter samplers
        std::lock_guard<std::recursive_mutex> lock(mLock);
        size_t imageInfoIndex = 0;
        for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
            if (!isDescriptorTypeImageInfo(transformedWrites[i].descriptorType)) continue;
            if (!transformedWrites[i].pImageInfo) continue;

            bool isImmutableSampler = descriptorBindingIsImmutableSampler(
                transformedWrites[i].dstSet, transformedWrites[i].dstBinding);

            for (uint32_t j = 0; j < transformedWrites[i].descriptorCount; ++j) {
                if (isImmutableSampler) {
                    transformedImageInfos[imageInfoIndex].sampler = 0;
                }
                transformedImageInfos[imageInfoIndex] =
                    filterNonexistentSampler(transformedImageInfos[imageInfoIndex]);
                ++imageInfoIndex;
            }
        }
    }

    if (mFeatureInfo->hasVulkanBatchedDescriptorSetUpdate) {
        for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
            VkDescriptorSet set = transformedWrites[i].dstSet;
            doEmulatedDescriptorWrite(&transformedWrites[i],
                                      as_goldfish_VkDescriptorSet(set)->reified);
        }

        for (uint32_t i = 0; i < descriptorCopyCount; ++i) {
            doEmulatedDescriptorCopy(
                &pDescriptorCopies[i],
                as_goldfish_VkDescriptorSet(pDescriptorCopies[i].srcSet)->reified,
                as_goldfish_VkDescriptorSet(pDescriptorCopies[i].dstSet)->reified);
        }
    } else {
        enc->vkUpdateDescriptorSets(device, descriptorWriteCount, transformedWrites.data(),
                                    descriptorCopyCount, pDescriptorCopies, true /* do lock */);
    }
}

void ResourceTracker::on_vkDestroyImage(void* context, VkDevice device, VkImage image,
                                        const VkAllocationCallbacks* pAllocator) {
#ifdef VK_USE_PLATFORM_ANDROID_KHR
    auto* syncHelper = ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->syncHelper();
    {
        std::lock_guard<std::recursive_mutex> lock(mLock);  // do not guard encoder may cause
                                                            // deadlock b/243339973

        // Wait for any pending QSRIs to prevent a race between the Gfxstream host
        // potentially processing the below `vkDestroyImage()` from the VK encoder
        // command stream before processing a previously submitted
        // `VIRTIO_GPU_NATIVE_SYNC_VULKAN_QSRI_EXPORT` from the virtio-gpu command
        // stream which relies on the image existing.
        auto imageInfoIt = info_VkImage.find(image);
        if (imageInfoIt != info_VkImage.end()) {
            auto& imageInfo = imageInfoIt->second;
            for (int syncFd : imageInfo.pendingQsriSyncFds) {
                int syncWaitRet = syncHelper->wait(syncFd, 3000);
                if (syncWaitRet < 0) {
                    mesa_loge("%s: Failed to wait for pending QSRI sync: sterror: %s errno: %d",
                              __func__, strerror(errno), errno);
                }
                syncHelper->close(syncFd);
            }
            imageInfo.pendingQsriSyncFds.clear();
        }
    }
#endif
    VkEncoder* enc = (VkEncoder*)context;
#if defined(LINUX_GUEST_BUILD)
    auto imageInfoIt = info_VkImage.find(image);
    if (imageInfoIt != info_VkImage.end()) {
        auto& imageInfo = imageInfoIt->second;
        if (imageInfo.linearPeerImage) {
            enc->vkDestroyImage(device, imageInfo.linearPeerImage, pAllocator, true /* do lock */);
        }
    }
#endif
    enc->vkDestroyImage(device, image, pAllocator, true /* do lock */);
}

void ResourceTracker::on_vkGetImageMemoryRequirements(void* context, VkDevice device, VkImage image,
                                                      VkMemoryRequirements* pMemoryRequirements) {
    std::unique_lock<std::recursive_mutex> lock(mLock);

    auto it = info_VkImage.find(image);
    if (it == info_VkImage.end()) return;

    auto& info = it->second;

    if (info.baseRequirementsKnown) {
        *pMemoryRequirements = info.baseRequirements;
        return;
    }

    lock.unlock();

    VkEncoder* enc = (VkEncoder*)context;

    enc->vkGetImageMemoryRequirements(device, image, pMemoryRequirements, true /* do lock */);

    lock.lock();

    transformImageMemoryRequirementsForGuestLocked(image, pMemoryRequirements);

    info.baseRequirementsKnown = true;
    info.baseRequirements = *pMemoryRequirements;
}

void ResourceTracker::on_vkGetImageMemoryRequirements2(void* context, VkDevice device,
                                                       const VkImageMemoryRequirementsInfo2* pInfo,
                                                       VkMemoryRequirements2* pMemoryRequirements) {
    VkEncoder* enc = (VkEncoder*)context;
    enc->vkGetImageMemoryRequirements2(device, pInfo, pMemoryRequirements, true /* do lock */);
    transformImageMemoryRequirements2ForGuest(pInfo->image, pMemoryRequirements);
}

void ResourceTracker::on_vkGetImageMemoryRequirements2KHR(
    void* context, VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo,
    VkMemoryRequirements2* pMemoryRequirements) {
    VkEncoder* enc = (VkEncoder*)context;
    enc->vkGetImageMemoryRequirements2KHR(device, pInfo, pMemoryRequirements, true /* do lock */);
    transformImageMemoryRequirements2ForGuest(pInfo->image, pMemoryRequirements);
}

void ResourceTracker::on_vkGetImageSubresourceLayout(void* context, VkDevice device, VkImage image,
                                                     const VkImageSubresource* pSubresource,
                                                     VkSubresourceLayout* pLayout) {
    VkEncoder* enc = (VkEncoder*)context;
    VkImage targetImage = image;
#if defined(LINUX_GUEST_BUILD)
    auto it = info_VkImage.find(image);
    if (it == info_VkImage.end()) return;
    const auto& info = it->second;
    if (info.linearPeerImage) {
        targetImage = info.linearPeerImage;
    }
#endif
    enc->vkGetImageSubresourceLayout(device, targetImage, pSubresource, pLayout,
                                     true /* do lock */);
}

VkResult ResourceTracker::on_vkBindImageMemory(void* context, VkResult, VkDevice device,
                                               VkImage image, VkDeviceMemory memory,
                                               VkDeviceSize memoryOffset) {
    VkEncoder* enc = (VkEncoder*)context;
    // Do not forward calls with invalid handles to host.
    if (info_VkDeviceMemory.find(memory) == info_VkDeviceMemory.end() ||
        info_VkImage.find(image) == info_VkImage.end()) {
        return VK_ERROR_OUT_OF_DEVICE_MEMORY;
    }
    return enc->vkBindImageMemory(device, image, memory, memoryOffset, true /* do lock */);
}

VkResult ResourceTracker::on_vkBindImageMemory2(void* context, VkResult, VkDevice device,
                                                uint32_t bindingCount,
                                                const VkBindImageMemoryInfo* pBindInfos) {
    VkEncoder* enc = (VkEncoder*)context;

    if (bindingCount < 1 || !pBindInfos) {
        return VK_ERROR_OUT_OF_DEVICE_MEMORY;
    }

    for (uint32_t i = 0; i < bindingCount; i++) {
        const VkBindImageMemoryInfo& bimi = pBindInfos[i];

        auto imageIt = info_VkImage.find(bimi.image);
        if (imageIt == info_VkImage.end()) {
            return VK_ERROR_OUT_OF_DEVICE_MEMORY;
        }

        if (bimi.memory != VK_NULL_HANDLE) {
            auto memoryIt = info_VkDeviceMemory.find(bimi.memory);
            if (memoryIt == info_VkDeviceMemory.end()) {
                return VK_ERROR_OUT_OF_DEVICE_MEMORY;
            }
        }
    }

    return enc->vkBindImageMemory2(device, bindingCount, pBindInfos, true /* do lock */);
}

VkResult ResourceTracker::on_vkBindImageMemory2KHR(void* context, VkResult result, VkDevice device,
                                                   uint32_t bindingCount,
                                                   const VkBindImageMemoryInfo* pBindInfos) {
    return on_vkBindImageMemory2(context, result, device, bindingCount, pBindInfos);
}

VkResult ResourceTracker::on_vkCreateBuffer(void* context, VkResult, VkDevice device,
                                            const VkBufferCreateInfo* pCreateInfo,
                                            const VkAllocationCallbacks* pAllocator,
                                            VkBuffer* pBuffer) {
    VkEncoder* enc = (VkEncoder*)context;

    VkBufferCreateInfo localCreateInfo = vk_make_orphan_copy(*pCreateInfo);
    vk_struct_chain_iterator structChainIter = vk_make_chain_iterator(&localCreateInfo);
    VkExternalMemoryBufferCreateInfo localExtBufCi;

    const VkExternalMemoryBufferCreateInfo* extBufCiPtr =
        vk_find_struct<VkExternalMemoryBufferCreateInfo>(pCreateInfo);
    if (extBufCiPtr) {
        localExtBufCi = vk_make_orphan_copy(*extBufCiPtr);
        vk_append_struct(&structChainIter, &localExtBufCi);
    }

    VkBufferOpaqueCaptureAddressCreateInfo localCapAddrCi;
    const VkBufferOpaqueCaptureAddressCreateInfo* pCapAddrCi =
        vk_find_struct<VkBufferOpaqueCaptureAddressCreateInfo>(pCreateInfo);
    if (pCapAddrCi) {
        localCapAddrCi = vk_make_orphan_copy(*pCapAddrCi);
        vk_append_struct(&structChainIter, &localCapAddrCi);
    }

    VkBufferDeviceAddressCreateInfoEXT localDevAddrCi;
    const VkBufferDeviceAddressCreateInfoEXT* pDevAddrCi =
        vk_find_struct<VkBufferDeviceAddressCreateInfoEXT>(pCreateInfo);
    if (pDevAddrCi) {
        localDevAddrCi = vk_make_orphan_copy(*pDevAddrCi);
        vk_append_struct(&structChainIter, &localDevAddrCi);
    }

#ifdef VK_USE_PLATFORM_FUCHSIA
    std::optional<zx::vmo> vmo;
    bool isSysmemBackedMemory = false;

    if (extBufCiPtr &&
        (extBufCiPtr->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA)) {
        isSysmemBackedMemory = true;
    }

    const auto* extBufferCollectionPtr =
        vk_find_struct<VkBufferCollectionBufferCreateInfoFUCHSIA>(pCreateInfo);

    if (extBufferCollectionPtr) {
        const auto& collection =
            *reinterpret_cast<fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>*>(
                extBufferCollectionPtr->collection);
        uint32_t index = extBufferCollectionPtr->index;

        auto result = collection->WaitForBuffersAllocated();
        if (result.ok() && result->status == ZX_OK) {
            auto& info = result->buffer_collection_info;
            if (index < info.buffer_count) {
                vmo = std::make_optional<zx::vmo>(std::move(info.buffers[index].vmo));
            }
        } else {
            mesa_loge("WaitForBuffersAllocated failed: %d %d", result.status(),
                      GET_STATUS_SAFE(result, status));
        }

        if (vmo && vmo->is_valid()) {
            fidl::Arena arena;
            fuchsia_hardware_goldfish::wire::CreateBuffer2Params createParams(arena);
            createParams.set_size(arena, pCreateInfo->size)
                .set_memory_property(fuchsia_hardware_goldfish::wire::kMemoryPropertyDeviceLocal);

            auto result = mControlDevice->CreateBuffer2(std::move(*vmo), createParams);
            if (!result.ok() ||
                (result->is_error() != ZX_OK && result->error_value() != ZX_ERR_ALREADY_EXISTS)) {
                mesa_loge("CreateBuffer2 failed: %d:%d", result.status(),
                          GET_STATUS_SAFE(result, error_value()));
            }
            isSysmemBackedMemory = true;
        }
    }
#endif  // VK_USE_PLATFORM_FUCHSIA

    VkResult res;
    VkMemoryRequirements memReqs;

    if (supportsCreateResourcesWithRequirements()) {
        res = enc->vkCreateBufferWithRequirementsGOOGLE(device, &localCreateInfo, pAllocator,
                                                        pBuffer, &memReqs, true /* do lock */);
    } else {
        res =
            enc->vkCreateBuffer(device, &localCreateInfo, pAllocator, pBuffer, true /* do lock */);
    }

    if (res != VK_SUCCESS) return res;

#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
    if (mCaps.vulkanCapset.colorBufferMemoryIndex == 0xFFFFFFFF) {
        mCaps.vulkanCapset.colorBufferMemoryIndex = getColorBufferMemoryIndex(context, device);
    }
    if (extBufCiPtr &&
        ((extBufCiPtr->handleTypes &
          VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) ||
         (extBufCiPtr->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT))) {
        updateMemoryTypeBits(&memReqs.memoryTypeBits, mCaps.vulkanCapset.colorBufferMemoryIndex);
    }
#endif

    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto it = info_VkBuffer.find(*pBuffer);
    if (it == info_VkBuffer.end()) return VK_ERROR_INITIALIZATION_FAILED;

    auto& info = it->second;

    info.createInfo = localCreateInfo;
    info.createInfo.pNext = nullptr;

    if (supportsCreateResourcesWithRequirements()) {
        info.baseRequirementsKnown = true;
        info.baseRequirements = memReqs;
    }

    if (extBufCiPtr) {
        info.external = true;
        info.externalCreateInfo = *extBufCiPtr;
    }

#ifdef VK_USE_PLATFORM_FUCHSIA
    if (isSysmemBackedMemory) {
        info.isSysmemBackedMemory = true;
    }
#endif

    return res;
}

void ResourceTracker::on_vkDestroyBuffer(void* context, VkDevice device, VkBuffer buffer,
                                         const VkAllocationCallbacks* pAllocator) {
    VkEncoder* enc = (VkEncoder*)context;
    enc->vkDestroyBuffer(device, buffer, pAllocator, true /* do lock */);
}

void ResourceTracker::on_vkGetBufferMemoryRequirements(void* context, VkDevice device,
                                                       VkBuffer buffer,
                                                       VkMemoryRequirements* pMemoryRequirements) {
    std::unique_lock<std::recursive_mutex> lock(mLock);

    auto it = info_VkBuffer.find(buffer);
    if (it == info_VkBuffer.end()) return;

    auto& info = it->second;

    if (info.baseRequirementsKnown) {
        *pMemoryRequirements = info.baseRequirements;
        return;
    }

    lock.unlock();

    VkEncoder* enc = (VkEncoder*)context;
    enc->vkGetBufferMemoryRequirements(device, buffer, pMemoryRequirements, true /* do lock */);

    lock.lock();

    info.baseRequirementsKnown = true;
    info.baseRequirements = *pMemoryRequirements;
}

void ResourceTracker::on_vkGetBufferMemoryRequirements2(
    void* context, VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo,
    VkMemoryRequirements2* pMemoryRequirements) {
    VkEncoder* enc = (VkEncoder*)context;
    enc->vkGetBufferMemoryRequirements2(device, pInfo, pMemoryRequirements, true /* do lock */);
    transformBufferMemoryRequirements2ForGuest(pInfo->buffer, pMemoryRequirements);
}

void ResourceTracker::on_vkGetBufferMemoryRequirements2KHR(
    void* context, VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo,
    VkMemoryRequirements2* pMemoryRequirements) {
    VkEncoder* enc = (VkEncoder*)context;
    enc->vkGetBufferMemoryRequirements2KHR(device, pInfo, pMemoryRequirements, true /* do lock */);
    transformBufferMemoryRequirements2ForGuest(pInfo->buffer, pMemoryRequirements);
}

VkResult ResourceTracker::on_vkBindBufferMemory(void* context, VkResult, VkDevice device,
                                                VkBuffer buffer, VkDeviceMemory memory,
                                                VkDeviceSize memoryOffset) {
    VkEncoder* enc = (VkEncoder*)context;
    return enc->vkBindBufferMemory(device, buffer, memory, memoryOffset, true /* do lock */);
}

VkResult ResourceTracker::on_vkBindBufferMemory2(void* context, VkResult, VkDevice device,
                                                 uint32_t bindInfoCount,
                                                 const VkBindBufferMemoryInfo* pBindInfos) {
    VkEncoder* enc = (VkEncoder*)context;
    return enc->vkBindBufferMemory2(device, bindInfoCount, pBindInfos, true /* do lock */);
}

VkResult ResourceTracker::on_vkBindBufferMemory2KHR(void* context, VkResult, VkDevice device,
                                                    uint32_t bindInfoCount,
                                                    const VkBindBufferMemoryInfo* pBindInfos) {
    VkEncoder* enc = (VkEncoder*)context;
    return enc->vkBindBufferMemory2KHR(device, bindInfoCount, pBindInfos, true /* do lock */);
}

VkResult ResourceTracker::on_vkCreateSemaphore(void* context, VkResult input_result,
                                               VkDevice device,
                                               const VkSemaphoreCreateInfo* pCreateInfo,
                                               const VkAllocationCallbacks* pAllocator,
                                               VkSemaphore* pSemaphore) {
    (void)input_result;
    VkEncoder* enc = (VkEncoder*)context;

    VkSemaphoreCreateInfo finalCreateInfo = *pCreateInfo;

    const VkExportSemaphoreCreateInfoKHR* exportSemaphoreInfoPtr =
        vk_find_struct<VkExportSemaphoreCreateInfoKHR>(pCreateInfo);

#ifdef VK_USE_PLATFORM_FUCHSIA
    bool exportEvent =
        exportSemaphoreInfoPtr && (exportSemaphoreInfoPtr->handleTypes &
                                   VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA);

    if (exportEvent) {
        finalCreateInfo.pNext = nullptr;
        // If we have timeline semaphores externally, leave it there.
        const VkSemaphoreTypeCreateInfo* typeCi =
            vk_find_struct<VkSemaphoreTypeCreateInfo>(pCreateInfo);
        if (typeCi) finalCreateInfo.pNext = typeCi;
    }
#endif

#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
    bool exportSyncFd = exportSemaphoreInfoPtr && (exportSemaphoreInfoPtr->handleTypes &
                                                   VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT);

    if (exportSyncFd) {
        finalCreateInfo.pNext = nullptr;
        // If we have timeline semaphores externally, leave it there.
        const VkSemaphoreTypeCreateInfo* typeCi =
            vk_find_struct<VkSemaphoreTypeCreateInfo>(pCreateInfo);
        if (typeCi) finalCreateInfo.pNext = typeCi;
    }
#endif
    input_result = enc->vkCreateSemaphore(device, &finalCreateInfo, pAllocator, pSemaphore,
                                          true /* do lock */);

    zx_handle_t event_handle = ZX_HANDLE_INVALID;

#ifdef VK_USE_PLATFORM_FUCHSIA
    if (exportEvent) {
        zx_event_create(0, &event_handle);
    }
#endif

    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto it = info_VkSemaphore.find(*pSemaphore);
    if (it == info_VkSemaphore.end()) return VK_ERROR_INITIALIZATION_FAILED;

    auto& info = it->second;

    info.device = device;
    info.eventHandle = event_handle;
#ifdef VK_USE_PLATFORM_FUCHSIA
    info.eventKoid = getEventKoid(info.eventHandle);
#endif

#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
    if (exportSyncFd) {
        if (mFeatureInfo->hasVirtioGpuNativeSync &&
            !(mCaps.params[kParamFencePassing] && mCaps.vulkanCapset.externalSync)) {
            VkResult result;
            int64_t osHandle;
            uint64_t hostFenceHandle = get_host_u64_VkSemaphore(*pSemaphore);

            result = createFence(device, hostFenceHandle, osHandle);
            if (result != VK_SUCCESS) return result;

            info.syncFd.emplace(osHandle);
        } else {
#if GFXSTREAM_ENABLE_GUEST_GOLDFISH
            ensureSyncDeviceFd();

            if (exportSyncFd) {
                int syncFd = -1;
                goldfish_sync_queue_work(
                    mSyncDeviceFd, get_host_u64_VkSemaphore(*pSemaphore) /* the handle */,
                    GOLDFISH_SYNC_VULKAN_SEMAPHORE_SYNC /* thread handle (doubling as type field) */
                    ,
                    &syncFd);
                info.syncFd.emplace(syncFd);
            }
#endif
        }
    }
#endif

    return VK_SUCCESS;
}

void ResourceTracker::on_vkDestroySemaphore(void* context, VkDevice device, VkSemaphore semaphore,
                                            const VkAllocationCallbacks* pAllocator) {
    VkEncoder* enc = (VkEncoder*)context;
    enc->vkDestroySemaphore(device, semaphore, pAllocator, true /* do lock */);
}

// https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetSemaphoreFdKHR
// Each call to vkGetSemaphoreFdKHR must create a new file descriptor and transfer ownership
// of it to the application. To avoid leaking resources, the application must release ownership
// of the file descriptor when it is no longer needed.
VkResult ResourceTracker::on_vkGetSemaphoreFdKHR(void* context, VkResult, VkDevice device,
                                                 const VkSemaphoreGetFdInfoKHR* pGetFdInfo,
                                                 int* pFd) {
#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
    VkEncoder* enc = (VkEncoder*)context;
    bool getSyncFd = pGetFdInfo->handleType & VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;

    if (getSyncFd) {
        if (mCaps.params[kParamFencePassing] && mCaps.vulkanCapset.externalSync) {
            uint64_t syncId = ++mAtomicId;
            int64_t osHandle = -1;

            VkResult result = enc->vkGetSemaphoreGOOGLE(device, pGetFdInfo->semaphore, syncId,
                                                        true /* do lock */);
            if (result != VK_SUCCESS) {
                ALOGE("unable to get the semaphore");
                return result;
            }

            result = acquireSync(syncId, osHandle);
            if (result != VK_SUCCESS) {
                ALOGE("unable to create host sync object");
                return result;
            }

            *pFd = (int)osHandle;
            return VK_SUCCESS;
        } else {
            // Doesn't this assume that sync file descriptor generated via the non-fence
            // passing path during "on_vkCreateSemaphore" is the same one that would be
            // generated via guest's "okGetSemaphoreFdKHR" call?
            std::lock_guard<std::recursive_mutex> lock(mLock);
            auto it = info_VkSemaphore.find(pGetFdInfo->semaphore);
            if (it == info_VkSemaphore.end()) return VK_ERROR_OUT_OF_HOST_MEMORY;
            auto& semInfo = it->second;
            // syncFd is supposed to have value.
            auto* syncHelper =
                ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->syncHelper();
            *pFd = syncHelper->dup(semInfo.syncFd.value_or(-1));
            return VK_SUCCESS;
        }
    } else {
        // opaque fd
        int hostFd = 0;
        VkResult result = enc->vkGetSemaphoreFdKHR(device, pGetFdInfo, &hostFd, true /* do lock */);
        if (result != VK_SUCCESS) {
            return result;
        }
        *pFd = memfd_create("vk_opaque_fd", 0);
        write(*pFd, &hostFd, sizeof(hostFd));
        return VK_SUCCESS;
    }
#else
    (void)context;
    (void)device;
    (void)pGetFdInfo;
    (void)pFd;
    return VK_ERROR_INCOMPATIBLE_DRIVER;
#endif
}

VkResult ResourceTracker::on_vkImportSemaphoreFdKHR(
    void* context, VkResult input_result, VkDevice device,
    const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo) {
#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
    VkEncoder* enc = (VkEncoder*)context;
    if (input_result != VK_SUCCESS) {
        return input_result;
    }

    auto* syncHelper = ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->syncHelper();

    if (pImportSemaphoreFdInfo->handleType & VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) {
        VkImportSemaphoreFdInfoKHR tmpInfo = *pImportSemaphoreFdInfo;

        std::lock_guard<std::recursive_mutex> lock(mLock);

        auto semaphoreIt = info_VkSemaphore.find(pImportSemaphoreFdInfo->semaphore);
        auto& info = semaphoreIt->second;

        if (info.syncFd.value_or(-1) >= 0) {
            syncHelper->close(info.syncFd.value());
        }

        info.syncFd.emplace(pImportSemaphoreFdInfo->fd);

        return VK_SUCCESS;
    } else {
        int fd = pImportSemaphoreFdInfo->fd;
        int err = lseek(fd, 0, SEEK_SET);
        if (err == -1) {
            mesa_loge("lseek fail on import semaphore");
        }
        int hostFd = 0;
        read(fd, &hostFd, sizeof(hostFd));
        VkImportSemaphoreFdInfoKHR tmpInfo = *pImportSemaphoreFdInfo;
        tmpInfo.fd = hostFd;
        VkResult result = enc->vkImportSemaphoreFdKHR(device, &tmpInfo, true /* do lock */);
        syncHelper->close(fd);
        return result;
    }
#else
    (void)context;
    (void)input_result;
    (void)device;
    (void)pImportSemaphoreFdInfo;
    return VK_ERROR_INCOMPATIBLE_DRIVER;
#endif
}

VkResult ResourceTracker::on_vkGetMemoryFdPropertiesKHR(
    void* context, VkResult, VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, int fd,
    VkMemoryFdPropertiesKHR* pMemoryFdProperties) {
#if defined(__linux__) && !defined(VK_USE_PLATFORM_ANDROID_KHR)
    if (!(handleType & VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT)) {
        mesa_loge("%s: VK_KHR_external_memory_fd behavior not defined for handleType: 0x%x\n",
                  __func__, handleType);
        return VK_ERROR_INVALID_EXTERNAL_HANDLE;
    }
    // Sanity-check device
    std::lock_guard<std::recursive_mutex> lock(mLock);
    auto deviceIt = info_VkDevice.find(device);
    if (deviceIt == info_VkDevice.end()) {
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }
    // TODO: Verify FD valid ?
    (void)fd;

    if (mCaps.vulkanCapset.colorBufferMemoryIndex == 0xFFFFFFFF) {
        mCaps.vulkanCapset.colorBufferMemoryIndex = getColorBufferMemoryIndex(context, device);
    }

    updateMemoryTypeBits(&pMemoryFdProperties->memoryTypeBits,
                         mCaps.vulkanCapset.colorBufferMemoryIndex);

    return VK_SUCCESS;
#else
    (void)context;
    (void)device;
    (void)handleType;
    (void)fd;
    (void)pMemoryFdProperties;
    return VK_ERROR_INCOMPATIBLE_DRIVER;
#endif
}

VkResult ResourceTracker::on_vkGetMemoryFdKHR(void* context, VkResult, VkDevice device,
                                              const VkMemoryGetFdInfoKHR* pGetFdInfo, int* pFd) {
#if defined(__linux__) && !defined(VK_USE_PLATFORM_ANDROID_KHR)
    if (!pGetFdInfo) return VK_ERROR_OUT_OF_HOST_MEMORY;
    if (!pGetFdInfo->memory) return VK_ERROR_OUT_OF_HOST_MEMORY;

    if (!(pGetFdInfo->handleType & (VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
                                    VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT))) {
        mesa_loge("%s: Export operation not defined for handleType: 0x%x\n", __func__,
                  pGetFdInfo->handleType);
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }
    // Sanity-check device
    std::lock_guard<std::recursive_mutex> lock(mLock);
    auto deviceIt = info_VkDevice.find(device);
    if (deviceIt == info_VkDevice.end()) {
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }

    auto deviceMemIt = info_VkDeviceMemory.find(pGetFdInfo->memory);
    if (deviceMemIt == info_VkDeviceMemory.end()) {
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }
    auto& info = deviceMemIt->second;

    if (!info.blobPtr) {
        mesa_loge("%s: VkDeviceMemory does not have a resource available for export.\n", __func__);
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }

    VirtGpuExternalHandle handle{};
    int ret = info.blobPtr->exportBlob(handle);
    if (ret != 0 || handle.osHandle < 0) {
        mesa_loge("%s: Failed to export host resource to FD.\n", __func__);
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }
    *pFd = handle.osHandle;
    return VK_SUCCESS;
#else
    (void)context;
    (void)device;
    (void)pGetFdInfo;
    (void)pFd;
    return VK_ERROR_INCOMPATIBLE_DRIVER;
#endif
}

void ResourceTracker::flushCommandBufferPendingCommandsBottomUp(
    void* context, VkQueue queue, const std::vector<VkCommandBuffer>& workingSet) {
    if (workingSet.empty()) return;

    std::vector<VkCommandBuffer> nextLevel;
    for (auto commandBuffer : workingSet) {
        struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(commandBuffer);
        forAllObjects(cb->subObjects, [&nextLevel](void* secondary) {
            nextLevel.push_back((VkCommandBuffer)secondary);
        });
    }

    flushCommandBufferPendingCommandsBottomUp(context, queue, nextLevel);

    // After this point, everyone at the previous level has been flushed
    for (auto cmdbuf : workingSet) {
        struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(cmdbuf);

        // There's no pending commands here, skip. (case 1)
        if (!cb->privateStream) continue;

        unsigned char* writtenPtr = 0;
        size_t written = 0;
        CommandBufferStagingStream* cmdBufStream =
            static_cast<CommandBufferStagingStream*>(cb->privateStream);
        cmdBufStream->getWritten(&writtenPtr, &written);

        // There's no pending commands here, skip. (case 2, stream created but no new recordings)
        if (!written) continue;

        // There are pending commands to flush.
        VkEncoder* enc = (VkEncoder*)context;
        VkDeviceMemory deviceMemory = cmdBufStream->getDeviceMemory();
        VkDeviceSize dataOffset = 0;
        if (mFeatureInfo->hasVulkanAuxCommandMemory) {
            // for suballocations, deviceMemory is an alias VkDeviceMemory
            // get underling VkDeviceMemory for given alias
            deviceMemoryTransform_tohost(&deviceMemory, 1 /*memoryCount*/, &dataOffset,
                                         1 /*offsetCount*/, nullptr /*size*/, 0 /*sizeCount*/,
                                         nullptr /*typeIndex*/, 0 /*typeIndexCount*/,
                                         nullptr /*typeBits*/, 0 /*typeBitCounts*/);

            // mark stream as flushing before flushing commands
            cmdBufStream->markFlushing();
            enc->vkQueueFlushCommandsFromAuxMemoryGOOGLE(queue, cmdbuf, deviceMemory, dataOffset,
                                                         written, true /*do lock*/);
        } else {
            enc->vkQueueFlushCommandsGOOGLE(queue, cmdbuf, written, (const void*)writtenPtr,
                                            true /* do lock */);
        }
        // Reset this stream.
        // flushing happens on vkQueueSubmit
        // vulkan api states that on queue submit,
        // applications MUST not attempt to modify the command buffer in any way
        // -as the device may be processing the commands recorded to it.
        // It is safe to call reset() here for this reason.
        // Command Buffer associated with this stream will only leave pending state
        // after queue submit is complete and host has read the data
        cmdBufStream->reset();
    }
}

uint32_t ResourceTracker::syncEncodersForQueue(VkQueue queue, VkEncoder* currentEncoder) {
    if (!supportsAsyncQueueSubmit()) {
        return 0;
    }

    struct goldfish_VkQueue* q = as_goldfish_VkQueue(queue);
    if (!q) return 0;

    auto lastEncoder = q->lastUsedEncoder;

    if (lastEncoder == currentEncoder) return 0;

    currentEncoder->incRef();

    q->lastUsedEncoder = currentEncoder;

    if (!lastEncoder) return 0;

    auto oldSeq = q->sequenceNumber;
    q->sequenceNumber += 2;
    lastEncoder->vkQueueHostSyncGOOGLE(queue, false, oldSeq + 1, true /* do lock */);
    lastEncoder->flush();
    currentEncoder->vkQueueHostSyncGOOGLE(queue, true, oldSeq + 2, true /* do lock */);

    if (lastEncoder->decRef()) {
        q->lastUsedEncoder = nullptr;
    }

    return 0;
}

template <class VkSubmitInfoType>
void ResourceTracker::flushStagingStreams(void* context, VkQueue queue, uint32_t submitCount,
                                          const VkSubmitInfoType* pSubmits) {
    std::vector<VkCommandBuffer> toFlush;
    for (uint32_t i = 0; i < submitCount; ++i) {
        for (uint32_t j = 0; j < getCommandBufferCount(pSubmits[i]); ++j) {
            toFlush.push_back(getCommandBuffer(pSubmits[i], j));
        }
    }

    std::unordered_set<VkDescriptorSet> pendingSets;
    collectAllPendingDescriptorSetsBottomUp(toFlush, pendingSets);
    commitDescriptorSetUpdates(context, queue, pendingSets);

    flushCommandBufferPendingCommandsBottomUp(context, queue, toFlush);

    for (auto cb : toFlush) {
        resetCommandBufferPendingTopology(cb);
    }
}

VkResult ResourceTracker::on_vkQueueSubmit(void* context, VkResult input_result, VkQueue queue,
                                           uint32_t submitCount, const VkSubmitInfo* pSubmits,
                                           VkFence fence) {
    MESA_TRACE_SCOPE("on_vkQueueSubmit");

    /* From the Vulkan 1.3.204 spec:
     *
     *    VUID-VkSubmitInfo-pNext-03240
     *
     *    "If the pNext chain of this structure includes a VkTimelineSemaphoreSubmitInfo structure
     *    and any element of pSignalSemaphores was created with a VkSemaphoreType of
     *    VK_SEMAPHORE_TYPE_TIMELINE, then its signalSemaphoreValueCount member must equal
     *    signalSemaphoreCount"
     *
     * Internally, Mesa WSI creates placeholder semaphores/fences (see transformVkSemaphore functions
     * in in gfxstream_vk_private.cpp).  We don't want to forward that to the host, since there is
     * no host side Vulkan object associated with the placeholder sync objects.
     *
     * The way to test this behavior is Zink + glxgears, on Linux hosts.  It should fail without
     * this check.
     */
    for (uint32_t i = 0; i < submitCount; i++) {
        VkTimelineSemaphoreSubmitInfo* tssi = const_cast<VkTimelineSemaphoreSubmitInfo*>(
            vk_find_struct<VkTimelineSemaphoreSubmitInfo>(&pSubmits[i]));

        if (tssi) {
            uint32_t count = getSignalSemaphoreCount(pSubmits[i]);
            if (count != tssi->signalSemaphoreValueCount) {
                tssi->signalSemaphoreValueCount = count;
            }
        }
    }

    return on_vkQueueSubmitTemplate<VkSubmitInfo>(context, input_result, queue, submitCount,
                                                  pSubmits, fence);
}

VkResult ResourceTracker::on_vkQueueSubmit2(void* context, VkResult input_result, VkQueue queue,
                                            uint32_t submitCount, const VkSubmitInfo2* pSubmits,
                                            VkFence fence) {
    MESA_TRACE_SCOPE("on_vkQueueSubmit2");
    return on_vkQueueSubmitTemplate<VkSubmitInfo2>(context, input_result, queue, submitCount,
                                                   pSubmits, fence);
}

VkResult ResourceTracker::vkQueueSubmitEnc(VkEncoder* enc, VkQueue queue, uint32_t submitCount,
                                           const VkSubmitInfo* pSubmits, VkFence fence) {
    if (supportsAsyncQueueSubmit()) {
        enc->vkQueueSubmitAsyncGOOGLE(queue, submitCount, pSubmits, fence, true /* do lock */);
        return VK_SUCCESS;
    } else {
        return enc->vkQueueSubmit(queue, submitCount, pSubmits, fence, true /* do lock */);
    }
}

VkResult ResourceTracker::vkQueueSubmitEnc(VkEncoder* enc, VkQueue queue, uint32_t submitCount,
                                           const VkSubmitInfo2* pSubmits, VkFence fence) {
    if (supportsAsyncQueueSubmit()) {
        enc->vkQueueSubmitAsync2GOOGLE(queue, submitCount, pSubmits, fence, true /* do lock */);
        return VK_SUCCESS;
    } else {
        return enc->vkQueueSubmit2(queue, submitCount, pSubmits, fence, true /* do lock */);
    }
}

template <typename VkSubmitInfoType>
VkResult ResourceTracker::on_vkQueueSubmitTemplate(void* context, VkResult input_result,
                                                   VkQueue queue, uint32_t submitCount,
                                                   const VkSubmitInfoType* pSubmits,
                                                   VkFence fence) {
    flushStagingStreams(context, queue, submitCount, pSubmits);

    std::vector<VkSemaphore> pre_signal_semaphores;
    std::vector<zx_handle_t> pre_signal_events;
    std::vector<int> pre_signal_sync_fds;
    std::vector<std::pair<zx_handle_t, zx_koid_t>> post_wait_events;
    std::vector<int> post_wait_sync_fds;

    VkEncoder* enc = (VkEncoder*)context;

    std::unique_lock<std::recursive_mutex> lock(mLock);

    for (uint32_t i = 0; i < submitCount; ++i) {
        for (uint32_t j = 0; j < getWaitSemaphoreCount(pSubmits[i]); ++j) {
            VkSemaphore semaphore = getWaitSemaphore(pSubmits[i], j);
            auto it = info_VkSemaphore.find(semaphore);
            if (it != info_VkSemaphore.end()) {
                auto& semInfo = it->second;
#ifdef VK_USE_PLATFORM_FUCHSIA
                if (semInfo.eventHandle) {
                    pre_signal_events.push_back(semInfo.eventHandle);
                    pre_signal_semaphores.push_back(semaphore);
                }
#endif
#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
                if (semInfo.syncFd.has_value()) {
                    pre_signal_sync_fds.push_back(semInfo.syncFd.value());
                    pre_signal_semaphores.push_back(semaphore);
                }
#endif
            }
        }
        for (uint32_t j = 0; j < getSignalSemaphoreCount(pSubmits[i]); ++j) {
            auto it = info_VkSemaphore.find(getSignalSemaphore(pSubmits[i], j));
            if (it != info_VkSemaphore.end()) {
                auto& semInfo = it->second;
#ifdef VK_USE_PLATFORM_FUCHSIA
                if (semInfo.eventHandle) {
                    post_wait_events.push_back({semInfo.eventHandle, semInfo.eventKoid});
#ifndef FUCHSIA_NO_TRACE
                    if (semInfo.eventKoid != ZX_KOID_INVALID) {
                        // TODO(fxbug.dev/42144867): Remove the "semaphore"
                        // FLOW_END events once it is removed from clients
                        // (for example, gfx Engine).
                        TRACE_FLOW_END("gfx", "semaphore", semInfo.eventKoid);
                        TRACE_FLOW_BEGIN("gfx", "goldfish_post_wait_event", semInfo.eventKoid);
                    }
#endif
                }
#endif
#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
                if (semInfo.syncFd.value_or(-1) >= 0) {
                    post_wait_sync_fds.push_back(semInfo.syncFd.value());
                }
#endif
            }
        }
    }
    lock.unlock();

    if (pre_signal_semaphores.empty()) {
        input_result = vkQueueSubmitEnc(enc, queue, submitCount, pSubmits, fence);
        if (input_result != VK_SUCCESS) return input_result;
    } else {
        // Schedule waits on the OS external objects and
        // signal the wait semaphores
        // in a separate thread.
        std::vector<WorkPool::Task> preSignalTasks;
        std::vector<WorkPool::Task> preSignalQueueSubmitTasks;
        ;
#ifdef VK_USE_PLATFORM_FUCHSIA
        for (auto event : pre_signal_events) {
            preSignalTasks.push_back([event] {
                zx_object_wait_one(event, ZX_EVENT_SIGNALED, ZX_TIME_INFINITE, nullptr);
            });
        }
#endif
#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
        for (auto fd : pre_signal_sync_fds) {
            // https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkImportSemaphoreFdInfoKHR.html
            // fd == -1 is treated as already signaled
            if (fd != -1) {
                preSignalTasks.push_back([fd] {
                    auto* syncHelper =
                        ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->syncHelper();
                    syncHelper->wait(fd, 3000);
                });
            }
        }
#endif
        if (!preSignalTasks.empty()) {
            auto waitGroupHandle = mWorkPool.schedule(preSignalTasks);
            mWorkPool.waitAll(waitGroupHandle);
        }

        // Use the old version of VkSubmitInfo
        VkSubmitInfo submit_info = {
            .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
            .waitSemaphoreCount = 0,
            .pWaitSemaphores = nullptr,
            .pWaitDstStageMask = nullptr,
            .signalSemaphoreCount = static_cast<uint32_t>(pre_signal_semaphores.size()),
            .pSignalSemaphores = pre_signal_semaphores.data()};
        vkQueueSubmitEnc(enc, queue, 1, &submit_info, VK_NULL_HANDLE);
        input_result = vkQueueSubmitEnc(enc, queue, submitCount, pSubmits, fence);
        if (input_result != VK_SUCCESS) return input_result;
    }
    lock.lock();
    int externalFenceFdToSignal = -1;

#if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
    if (fence != VK_NULL_HANDLE) {
        auto it = info_VkFence.find(fence);
        if (it != info_VkFence.end()) {
            const auto& info = it->second;
            if (info.syncFd >= 0) {
                externalFenceFdToSignal = info.syncFd;
            }
        }
    }
#endif
    if (externalFenceFdToSignal >= 0 || !post_wait_events.empty() || !post_wait_sync_fds.empty()) {
        std::vector<WorkPool::Task> tasks;

        tasks.push_back([queue, externalFenceFdToSignal, post_wait_events /* copy of zx handles */,
                         post_wait_sync_fds /* copy of sync fds */] {
            auto hostConn = ResourceTracker::threadingCallbacks.hostConnectionGetFunc();
            auto vkEncoder = ResourceTracker::threadingCallbacks.vkEncoderGetFunc(hostConn);
            auto waitIdleRes = vkEncoder->vkQueueWaitIdle(queue, true /* do lock */);
#ifdef VK_USE_PLATFORM_FUCHSIA
            MESA_TRACE_SCOPE("on_vkQueueSubmit::SignalSemaphores");
            (void)externalFenceFdToSignal;
            for (auto& [event, koid] : post_wait_events) {
#ifndef FUCHSIA_NO_TRACE
                if (koid != ZX_KOID_INVALID) {
                    TRACE_FLOW_END("gfx", "goldfish_post_wait_event", koid);
                    TRACE_FLOW_BEGIN("gfx", "event_signal", koid);
                }
#endif
                zx_object_signal(event, 0, ZX_EVENT_SIGNALED);
            }
#endif
#if GFXSTREAM_ENABLE_GUEST_GOLDFISH
            for (auto& fd : post_wait_sync_fds) {
                goldfish_sync_signal(fd);
            }

            if (externalFenceFdToSignal >= 0) {
                mesa_logd("%s: external fence real signal: %d\n", __func__,
                          externalFenceFdToSignal);
                goldfish_sync_signal(externalFenceFdToSignal);
            }
#endif
        });
        auto queueAsyncWaitHandle = mWorkPool.schedule(tasks);
        auto& queueWorkItems = mQueueSensitiveWorkPoolItems[queue];
        queueWorkItems.push_back(queueAsyncWaitHandle);
    }
    return VK_SUCCESS;
}

VkResult ResourceTracker::on_vkQueueWaitIdle(void* context, VkResult, VkQueue queue) {
    VkEncoder* enc = (VkEncoder*)context;

    std::unique_lock<std::recursive_mutex> lock(mLock);
    std::vector<WorkPool::WaitGroupHandle> toWait = mQueueSensitiveWorkPoolItems[queue];
    mQueueSensitiveWorkPoolItems[queue].clear();
    lock.unlock();

    if (toWait.empty()) {
        mesa_logd("%s: No queue-specific work pool items\n", __func__);
        return enc->vkQueueWaitIdle(queue, true /* do lock */);
    }

    for (auto handle : toWait) {
        mesa_logd("%s: waiting on work group item: %llu\n", __func__, (unsigned long long)handle);
        mWorkPool.waitAll(handle);
    }

    // now done waiting, get the host's opinion
    return enc->vkQueueWaitIdle(queue, true /* do lock */);
}

#ifdef VK_USE_PLATFORM_ANDROID_KHR
void ResourceTracker::unwrap_VkNativeBufferANDROID(const VkNativeBufferANDROID* inputNativeInfo,
                                                   VkNativeBufferANDROID* outputNativeInfo) {
    if (!inputNativeInfo || !inputNativeInfo->handle) {
        return;
    }

    if (!outputNativeInfo || !outputNativeInfo) {
        mesa_loge("FATAL: Local native buffer info not properly allocated!");
        abort();
    }

    auto* gralloc = ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->grallocHelper();
    const native_handle_t* nativeHandle = (const native_handle_t*)inputNativeInfo->handle;
    *(uint32_t*)(outputNativeInfo->handle) = gralloc->getHostHandle(nativeHandle);
}

void ResourceTracker::unwrap_VkBindImageMemorySwapchainInfoKHR(
    const VkBindImageMemorySwapchainInfoKHR* inputBimsi,
    VkBindImageMemorySwapchainInfoKHR* outputBimsi) {
    if (!inputBimsi || !inputBimsi->swapchain) {
        return;
    }

    if (!outputBimsi || !outputBimsi->swapchain) {
        return;
    }

    // Android based swapchains are implemented by the Android framework's
    // libvulkan. The only exist within the guest and should not be sent to
    // the host.
    outputBimsi->swapchain = VK_NULL_HANDLE;
}
#endif

void ResourceTracker::unwrap_vkCreateImage_pCreateInfo(const VkImageCreateInfo* pCreateInfo,
                                                       VkImageCreateInfo* local_pCreateInfo) {
#ifdef VK_USE_PLATFORM_ANDROID_KHR
    const VkNativeBufferANDROID* inputNativeInfo =
        vk_find_struct<VkNativeBufferANDROID>(pCreateInfo);

    VkNativeBufferANDROID* outputNativeInfo = const_cast<VkNativeBufferANDROID*>(
        vk_find_struct<VkNativeBufferANDROID>(local_pCreateInfo));

    unwrap_VkNativeBufferANDROID(inputNativeInfo, outputNativeInfo);
#endif
}

void ResourceTracker::unwrap_vkAcquireImageANDROID_nativeFenceFd(int fd, int* fd_out) {
#ifdef VK_USE_PLATFORM_ANDROID_KHR
    (void)fd_out;
    if (fd != -1) {
        MESA_TRACE_SCOPE("waitNativeFenceInAcquire");
        // Implicit Synchronization
        auto* syncHelper =
            ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->syncHelper();
        syncHelper->wait(fd, 3000);
        // From libvulkan's swapchain.cpp:
        // """
        // NOTE: we're relying on AcquireImageANDROID to close fence_clone,
        // even if the call fails. We could close it ourselves on failure, but
        // that would create a race condition if the driver closes it on a
        // failure path: some other thread might create an fd with the same
        // number between the time the driver closes it and the time we close
        // it. We must assume one of: the driver *always* closes it even on
        // failure, or *never* closes it on failure.
        // """
        // Therefore, assume contract where we need to close fd in this driver
        syncHelper->close(fd);
    }
#endif
}

void ResourceTracker::unwrap_VkBindImageMemory2_pBindInfos(
    uint32_t bindInfoCount, const VkBindImageMemoryInfo* inputBindInfos,
    VkBindImageMemoryInfo* outputBindInfos) {
#ifdef VK_USE_PLATFORM_ANDROID_KHR
    for (uint32_t i = 0; i < bindInfoCount; ++i) {
        const VkBindImageMemoryInfo* inputBindInfo = &inputBindInfos[i];
        VkBindImageMemoryInfo* outputBindInfo = &outputBindInfos[i];

        const VkNativeBufferANDROID* inputNativeInfo =
            vk_find_struct<VkNativeBufferANDROID>(inputBindInfo);

        VkNativeBufferANDROID* outputNativeInfo = const_cast<VkNativeBufferANDROID*>(
            vk_find_struct<VkNativeBufferANDROID>(outputBindInfo));

        unwrap_VkNativeBufferANDROID(inputNativeInfo, outputNativeInfo);

        const VkBindImageMemorySwapchainInfoKHR* inputBimsi =
            vk_find_struct<VkBindImageMemorySwapchainInfoKHR>(inputBindInfo);

        VkBindImageMemorySwapchainInfoKHR* outputBimsi =
            const_cast<VkBindImageMemorySwapchainInfoKHR*>(
                vk_find_struct<VkBindImageMemorySwapchainInfoKHR>(outputBindInfo));

        unwrap_VkBindImageMemorySwapchainInfoKHR(inputBimsi, outputBimsi);
    }
#endif
}

// Action of vkMapMemoryIntoAddressSpaceGOOGLE:
// 1. preprocess (on_vkMapMemoryIntoAddressSpaceGOOGLE_pre):
//    uses address space device to reserve the right size of
//    memory.
// 2. the reservation results in a physical address. the physical
//    address is set as |*pAddress|.
// 3. after pre, the API call is encoded to the host, where the
//    value of pAddress is also sent (the physical address).
// 4. the host will obtain the actual gpu pointer and send it
//    back out in |*pAddress|.
// 5. postprocess (on_vkMapMemoryIntoAddressSpaceGOOGLE) will run,
//    using the mmap() method of GoldfishAddressSpaceBlock to obtain
//    a pointer in guest userspace corresponding to the host pointer.
VkResult ResourceTracker::on_vkMapMemoryIntoAddressSpaceGOOGLE_pre(void*, VkResult, VkDevice,
                                                                   VkDeviceMemory memory,
                                                                   uint64_t* pAddress) {
    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto it = info_VkDeviceMemory.find(memory);
    if (it == info_VkDeviceMemory.end()) {
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }

#if defined(__ANDROID__)
    auto& memInfo = it->second;

    GoldfishAddressSpaceBlockPtr block = std::make_shared<GoldfishAddressSpaceBlock>();
    block->allocate(mGoldfishAddressSpaceBlockProvider.get(), memInfo.coherentMemorySize);

    memInfo.goldfishBlock = block;
    *pAddress = block->physAddr();

    return VK_SUCCESS;
#else
    (void)pAddress;
    return VK_ERROR_MEMORY_MAP_FAILED;
#endif
}

VkResult ResourceTracker::on_vkMapMemoryIntoAddressSpaceGOOGLE(void*, VkResult input_result,
                                                               VkDevice, VkDeviceMemory memory,
                                                               uint64_t* pAddress) {
    (void)memory;
    (void)pAddress;

    if (input_result != VK_SUCCESS) {
        return input_result;
    }

    return input_result;
}

VkResult ResourceTracker::initDescriptorUpdateTemplateBuffers(
    const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
    VkDescriptorUpdateTemplate descriptorUpdateTemplate) {
    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto it = info_VkDescriptorUpdateTemplate.find(descriptorUpdateTemplate);
    if (it == info_VkDescriptorUpdateTemplate.end()) {
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    auto& info = it->second;
    uint32_t inlineUniformBlockBufferSize = 0;

    for (uint32_t i = 0; i < pCreateInfo->descriptorUpdateEntryCount; ++i) {
        const auto& entry = pCreateInfo->pDescriptorUpdateEntries[i];
        uint32_t descCount = entry.descriptorCount;
        VkDescriptorType descType = entry.descriptorType;
        ++info.templateEntryCount;
        if (isDescriptorTypeInlineUniformBlock(descType)) {
            inlineUniformBlockBufferSize += descCount;
            ++info.inlineUniformBlockCount;
        } else {
            for (uint32_t j = 0; j < descCount; ++j) {
                if (isDescriptorTypeImageInfo(descType)) {
                    ++info.imageInfoCount;
                } else if (isDescriptorTypeBufferInfo(descType)) {
                    ++info.bufferInfoCount;
                } else if (isDescriptorTypeBufferView(descType)) {
                    ++info.bufferViewCount;
                } else {
                    mesa_loge("%s: FATAL: Unknown descriptor type %d\n", __func__, descType);
                    // abort();
                }
            }
        }
    }

    if (info.templateEntryCount)
        info.templateEntries = new VkDescriptorUpdateTemplateEntry[info.templateEntryCount];

    if (info.imageInfoCount) {
        info.imageInfoIndices = new uint32_t[info.imageInfoCount];
        info.imageInfos = new VkDescriptorImageInfo[info.imageInfoCount];
    }

    if (info.bufferInfoCount) {
        info.bufferInfoIndices = new uint32_t[info.bufferInfoCount];
        info.bufferInfos = new VkDescriptorBufferInfo[info.bufferInfoCount];
    }

    if (info.bufferViewCount) {
        info.bufferViewIndices = new uint32_t[info.bufferViewCount];
        info.bufferViews = new VkBufferView[info.bufferViewCount];
    }

    if (info.inlineUniformBlockCount) {
        info.inlineUniformBlockBuffer.resize(inlineUniformBlockBufferSize);
        info.inlineUniformBlockBytesPerBlocks.resize(info.inlineUniformBlockCount);
    }

    uint32_t imageInfoIndex = 0;
    uint32_t bufferInfoIndex = 0;
    uint32_t bufferViewIndex = 0;
    uint32_t inlineUniformBlockIndex = 0;

    for (uint32_t i = 0; i < pCreateInfo->descriptorUpdateEntryCount; ++i) {
        const auto& entry = pCreateInfo->pDescriptorUpdateEntries[i];
        uint32_t descCount = entry.descriptorCount;
        VkDescriptorType descType = entry.descriptorType;

        info.templateEntries[i] = entry;

        if (isDescriptorTypeInlineUniformBlock(descType)) {
            info.inlineUniformBlockBytesPerBlocks[inlineUniformBlockIndex] = descCount;
            ++inlineUniformBlockIndex;
        } else {
            for (uint32_t j = 0; j < descCount; ++j) {
                if (isDescriptorTypeImageInfo(descType)) {
                    info.imageInfoIndices[imageInfoIndex] = i;
                    ++imageInfoIndex;
                } else if (isDescriptorTypeBufferInfo(descType)) {
                    info.bufferInfoIndices[bufferInfoIndex] = i;
                    ++bufferInfoIndex;
                } else if (isDescriptorTypeBufferView(descType)) {
                    info.bufferViewIndices[bufferViewIndex] = i;
                    ++bufferViewIndex;
                } else {
                    mesa_loge("%s: FATAL: Unknown descriptor type %d\n", __func__, descType);
                    // abort();
                }
            }
        }
    }

    return VK_SUCCESS;
}

VkResult ResourceTracker::on_vkCreateDescriptorUpdateTemplate(
    void* context, VkResult input_result, VkDevice device,
    const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
    const VkAllocationCallbacks* pAllocator,
    VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) {
    (void)context;
    (void)device;
    (void)pAllocator;

    if (input_result != VK_SUCCESS) return input_result;

    return initDescriptorUpdateTemplateBuffers(pCreateInfo, *pDescriptorUpdateTemplate);
}

VkResult ResourceTracker::on_vkCreateDescriptorUpdateTemplateKHR(
    void* context, VkResult input_result, VkDevice device,
    const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
    const VkAllocationCallbacks* pAllocator,
    VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) {
    (void)context;
    (void)device;
    (void)pAllocator;

    if (input_result != VK_SUCCESS) return input_result;

    return initDescriptorUpdateTemplateBuffers(pCreateInfo, *pDescriptorUpdateTemplate);
}

void ResourceTracker::on_vkUpdateDescriptorSetWithTemplate(
    void* context, VkDevice device, VkDescriptorSet descriptorSet,
    VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData) {
    VkEncoder* enc = (VkEncoder*)context;

    uint8_t* userBuffer = (uint8_t*)pData;
    if (!userBuffer) return;

    // TODO: Make this thread safe
    std::unique_lock<std::recursive_mutex> lock(mLock);

    auto it = info_VkDescriptorUpdateTemplate.find(descriptorUpdateTemplate);
    if (it == info_VkDescriptorUpdateTemplate.end()) {
        return;
    }

    auto& info = it->second;

    uint32_t templateEntryCount = info.templateEntryCount;
    VkDescriptorUpdateTemplateEntry* templateEntries = info.templateEntries;

    uint32_t imageInfoCount = info.imageInfoCount;
    uint32_t bufferInfoCount = info.bufferInfoCount;
    uint32_t bufferViewCount = info.bufferViewCount;
    uint32_t inlineUniformBlockCount = info.inlineUniformBlockCount;
    uint32_t* imageInfoIndices = info.imageInfoIndices;
    uint32_t* bufferInfoIndices = info.bufferInfoIndices;
    uint32_t* bufferViewIndices = info.bufferViewIndices;
    VkDescriptorImageInfo* imageInfos = info.imageInfos;
    VkDescriptorBufferInfo* bufferInfos = info.bufferInfos;
    VkBufferView* bufferViews = info.bufferViews;
    uint8_t* inlineUniformBlockBuffer = info.inlineUniformBlockBuffer.data();
    uint32_t* inlineUniformBlockBytesPerBlocks = info.inlineUniformBlockBytesPerBlocks.data();

    lock.unlock();

    size_t currImageInfoOffset = 0;
    size_t currBufferInfoOffset = 0;
    size_t currBufferViewOffset = 0;
    size_t inlineUniformBlockOffset = 0;
    size_t inlineUniformBlockIdx = 0;

    struct goldfish_VkDescriptorSet* ds = as_goldfish_VkDescriptorSet(descriptorSet);
    ReifiedDescriptorSet* reified = ds->reified;

    bool batched = mFeatureInfo->hasVulkanBatchedDescriptorSetUpdate;

    for (uint32_t i = 0; i < templateEntryCount; ++i) {
        const auto& entry = templateEntries[i];
        VkDescriptorType descType = entry.descriptorType;
        uint32_t dstBinding = entry.dstBinding;

        auto offset = entry.offset;
        auto stride = entry.stride;
        auto dstArrayElement = entry.dstArrayElement;

        uint32_t descCount = entry.descriptorCount;

        if (isDescriptorTypeImageInfo(descType)) {
            if (!stride) stride = sizeof(VkDescriptorImageInfo);

            const VkDescriptorImageInfo* currImageInfoBegin =
                (const VkDescriptorImageInfo*)((uint8_t*)imageInfos + currImageInfoOffset);

            for (uint32_t j = 0; j < descCount; ++j) {
                const VkDescriptorImageInfo* user =
                    (const VkDescriptorImageInfo*)(userBuffer + offset + j * stride);

                memcpy(((uint8_t*)imageInfos) + currImageInfoOffset, user,
                       sizeof(VkDescriptorImageInfo));
                currImageInfoOffset += sizeof(VkDescriptorImageInfo);
            }

            if (batched) {
                doEmulatedDescriptorImageInfoWriteFromTemplate(
                    descType, dstBinding, dstArrayElement, descCount, currImageInfoBegin, reified);
            }
        } else if (isDescriptorTypeBufferInfo(descType)) {
            if (!stride) stride = sizeof(VkDescriptorBufferInfo);

            const VkDescriptorBufferInfo* currBufferInfoBegin =
                (const VkDescriptorBufferInfo*)((uint8_t*)bufferInfos + currBufferInfoOffset);

            for (uint32_t j = 0; j < descCount; ++j) {
                const VkDescriptorBufferInfo* user =
                    (const VkDescriptorBufferInfo*)(userBuffer + offset + j * stride);

                memcpy(((uint8_t*)bufferInfos) + currBufferInfoOffset, user,
                       sizeof(VkDescriptorBufferInfo));

                // TODO(b/355497683): move this into gfxstream_vk_UpdateDescriptorSetWithTemplate().
#if defined(__linux__) || defined(VK_USE_PLATFORM_ANDROID_KHR)
                // Convert mesa to internal for objects in the user buffer
                VkDescriptorBufferInfo* internalBufferInfo =
                    (VkDescriptorBufferInfo*)(((uint8_t*)bufferInfos) + currBufferInfoOffset);
                VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_buffer, internalBufferInfo->buffer);
                internalBufferInfo->buffer = gfxstream_buffer->internal_object;
#endif
                currBufferInfoOffset += sizeof(VkDescriptorBufferInfo);
            }

            if (batched) {
                doEmulatedDescriptorBufferInfoWriteFromTemplate(
                    descType, dstBinding, dstArrayElement, descCount, currBufferInfoBegin, reified);
            }

        } else if (isDescriptorTypeBufferView(descType)) {
            if (!stride) stride = sizeof(VkBufferView);

            const VkBufferView* currBufferViewBegin =
                (const VkBufferView*)((uint8_t*)bufferViews + currBufferViewOffset);

            for (uint32_t j = 0; j < descCount; ++j) {
                const VkBufferView* user = (const VkBufferView*)(userBuffer + offset + j * stride);

                memcpy(((uint8_t*)bufferViews) + currBufferViewOffset, user, sizeof(VkBufferView));
                currBufferViewOffset += sizeof(VkBufferView);
            }

            if (batched) {
                doEmulatedDescriptorBufferViewWriteFromTemplate(
                    descType, dstBinding, dstArrayElement, descCount, currBufferViewBegin, reified);
            }
        } else if (isDescriptorTypeInlineUniformBlock(descType)) {
            uint32_t inlineUniformBlockBytesPerBlock =
                inlineUniformBlockBytesPerBlocks[inlineUniformBlockIdx];
            uint8_t* currInlineUniformBlockBufferBegin =
                inlineUniformBlockBuffer + inlineUniformBlockOffset;
            memcpy(currInlineUniformBlockBufferBegin, userBuffer + offset,
                   inlineUniformBlockBytesPerBlock);
            inlineUniformBlockIdx++;
            inlineUniformBlockOffset += inlineUniformBlockBytesPerBlock;

            if (batched) {
                doEmulatedDescriptorInlineUniformBlockFromTemplate(
                    descType, dstBinding, dstArrayElement, descCount,
                    currInlineUniformBlockBufferBegin, reified);
            }
        } else {
            mesa_loge("%s: FATAL: Unknown descriptor type %d\n", __func__, descType);
            abort();
        }
    }

    if (batched) return;

    enc->vkUpdateDescriptorSetWithTemplateSized2GOOGLE(
        device, descriptorSet, descriptorUpdateTemplate, imageInfoCount, bufferInfoCount,
        bufferViewCount, static_cast<uint32_t>(info.inlineUniformBlockBuffer.size()),
        imageInfoIndices, bufferInfoIndices, bufferViewIndices, imageInfos, bufferInfos,
        bufferViews, inlineUniformBlockBuffer, true /* do lock */);
}

void ResourceTracker::on_vkUpdateDescriptorSetWithTemplateKHR(
    void* context, VkDevice device, VkDescriptorSet descriptorSet,
    VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData) {
    on_vkUpdateDescriptorSetWithTemplate(context, device, descriptorSet, descriptorUpdateTemplate,
                                         pData);
}

VkResult ResourceTracker::on_vkGetPhysicalDeviceImageFormatProperties2_common(
    bool isKhr, void* context, VkResult input_result, VkPhysicalDevice physicalDevice,
    const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
    VkImageFormatProperties2* pImageFormatProperties) {
    VkEncoder* enc = (VkEncoder*)context;
    (void)input_result;

    uint32_t supportedHandleType = 0;
    VkExternalImageFormatProperties* ext_img_properties =
        vk_find_struct<VkExternalImageFormatProperties>(pImageFormatProperties);

#ifdef VK_USE_PLATFORM_FUCHSIA

    constexpr VkFormat kExternalImageSupportedFormats[] = {
        VK_FORMAT_B8G8R8A8_SINT,  VK_FORMAT_B8G8R8A8_UNORM,   VK_FORMAT_B8G8R8A8_SRGB,
        VK_FORMAT_B8G8R8A8_SNORM, VK_FORMAT_B8G8R8A8_SSCALED, VK_FORMAT_B8G8R8A8_USCALED,
        VK_FORMAT_R8G8B8A8_SINT,  VK_FORMAT_R8G8B8A8_UNORM,   VK_FORMAT_R8G8B8A8_SRGB,
        VK_FORMAT_R8G8B8A8_SNORM, VK_FORMAT_R8G8B8A8_SSCALED, VK_FORMAT_R8G8B8A8_USCALED,
        VK_FORMAT_R8_UNORM,       VK_FORMAT_R8_UINT,          VK_FORMAT_R8_USCALED,
        VK_FORMAT_R8_SNORM,       VK_FORMAT_R8_SINT,          VK_FORMAT_R8_SSCALED,
        VK_FORMAT_R8_SRGB,        VK_FORMAT_R8G8_UNORM,       VK_FORMAT_R8G8_UINT,
        VK_FORMAT_R8G8_USCALED,   VK_FORMAT_R8G8_SNORM,       VK_FORMAT_R8G8_SINT,
        VK_FORMAT_R8G8_SSCALED,   VK_FORMAT_R8G8_SRGB,
    };

    if (ext_img_properties) {
        if (std::find(std::begin(kExternalImageSupportedFormats),
                      std::end(kExternalImageSupportedFormats),
                      pImageFormatInfo->format) == std::end(kExternalImageSupportedFormats)) {
            return VK_ERROR_FORMAT_NOT_SUPPORTED;
        }
    }
    supportedHandleType |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA;
#endif

#ifdef VK_USE_PLATFORM_ANDROID_KHR
    VkAndroidHardwareBufferUsageANDROID* output_ahw_usage =
        vk_find_struct<VkAndroidHardwareBufferUsageANDROID>(pImageFormatProperties);
    supportedHandleType |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
                           VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
#endif
    const VkPhysicalDeviceExternalImageFormatInfo* ext_img_info =
        vk_find_struct<VkPhysicalDeviceExternalImageFormatInfo>(pImageFormatInfo);
    if (supportedHandleType && ext_img_info) {
        // 0 is a valid handleType so we don't check against 0
        if (ext_img_info->handleType != (ext_img_info->handleType & supportedHandleType)) {
            return VK_ERROR_FORMAT_NOT_SUPPORTED;
        }
    }

    VkResult hostRes;

    if (isKhr) {
        hostRes = enc->vkGetPhysicalDeviceImageFormatProperties2KHR(
            physicalDevice, pImageFormatInfo, pImageFormatProperties, true /* do lock */);
    } else {
        hostRes = enc->vkGetPhysicalDeviceImageFormatProperties2(
            physicalDevice, pImageFormatInfo, pImageFormatProperties, true /* do lock */);
    }

    if (hostRes != VK_SUCCESS) return hostRes;

#ifdef VK_USE_PLATFORM_FUCHSIA
    if (ext_img_properties) {
        if (ext_img_info) {
            if (static_cast<uint32_t>(ext_img_info->handleType) ==
                VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA) {
                ext_img_properties->externalMemoryProperties = {
                    .externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
                                              VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT,
                    .exportFromImportedHandleTypes =
                        VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA,
                    .compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA,
                };
            }
        }
    }
#endif

#ifdef VK_USE_PLATFORM_ANDROID_KHR
    if (output_ahw_usage) {
        output_ahw_usage->androidHardwareBufferUsage = getAndroidHardwareBufferUsageFromVkUsage(
            pImageFormatInfo->flags, pImageFormatInfo->usage);
    }
#endif
    if (ext_img_properties) {
        transformImpl_VkExternalMemoryProperties_fromhost(
            &ext_img_properties->externalMemoryProperties, 0);
    }
    return hostRes;
}

VkResult ResourceTracker::on_vkGetPhysicalDeviceImageFormatProperties2(
    void* context, VkResult input_result, VkPhysicalDevice physicalDevice,
    const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
    VkImageFormatProperties2* pImageFormatProperties) {
    return on_vkGetPhysicalDeviceImageFormatProperties2_common(
        false /* not KHR */, context, input_result, physicalDevice, pImageFormatInfo,
        pImageFormatProperties);
}

VkResult ResourceTracker::on_vkGetPhysicalDeviceImageFormatProperties2KHR(
    void* context, VkResult input_result, VkPhysicalDevice physicalDevice,
    const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
    VkImageFormatProperties2* pImageFormatProperties) {
    return on_vkGetPhysicalDeviceImageFormatProperties2_common(
        true /* is KHR */, context, input_result, physicalDevice, pImageFormatInfo,
        pImageFormatProperties);
}

void ResourceTracker::on_vkGetPhysicalDeviceExternalBufferProperties_common(
    bool isKhr, void* context, VkPhysicalDevice physicalDevice,
    const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
    VkExternalBufferProperties* pExternalBufferProperties) {
    VkEncoder* enc = (VkEncoder*)context;

#if defined(ANDROID)
    // Older versions of Goldfish's Gralloc did not support allocating AHARDWAREBUFFER_FORMAT_BLOB
    // with GPU usage (b/299520213).
    if (ResourceTracker::threadingCallbacks.hostConnectionGetFunc()
            ->grallocHelper()
            ->treatBlobAsImage() &&
        pExternalBufferInfo->handleType ==
            VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) {
        pExternalBufferProperties->externalMemoryProperties.externalMemoryFeatures = 0;
        pExternalBufferProperties->externalMemoryProperties.exportFromImportedHandleTypes = 0;
        pExternalBufferProperties->externalMemoryProperties.compatibleHandleTypes = 0;
        return;
    }
#endif

    uint32_t supportedHandleType = 0;
#ifdef VK_USE_PLATFORM_FUCHSIA
    supportedHandleType |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA;
#endif
#ifdef VK_USE_PLATFORM_ANDROID_KHR
    supportedHandleType |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
                           VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
#endif
    if (supportedHandleType) {
        // 0 is a valid handleType so we can't check against 0
        if (pExternalBufferInfo->handleType !=
            (pExternalBufferInfo->handleType & supportedHandleType)) {
            return;
        }
    }

    if (isKhr) {
        enc->vkGetPhysicalDeviceExternalBufferPropertiesKHR(
            physicalDevice, pExternalBufferInfo, pExternalBufferProperties, true /* do lock */);
    } else {
        enc->vkGetPhysicalDeviceExternalBufferProperties(
            physicalDevice, pExternalBufferInfo, pExternalBufferProperties, true /* do lock */);
    }
    transformImpl_VkExternalMemoryProperties_fromhost(
        &pExternalBufferProperties->externalMemoryProperties, 0);
}

void ResourceTracker::on_vkGetPhysicalDeviceExternalBufferProperties(
    void* context, VkPhysicalDevice physicalDevice,
    const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
    VkExternalBufferProperties* pExternalBufferProperties) {
    return on_vkGetPhysicalDeviceExternalBufferProperties_common(
        false /* not KHR */, context, physicalDevice, pExternalBufferInfo,
        pExternalBufferProperties);
}

void ResourceTracker::on_vkGetPhysicalDeviceExternalBufferPropertiesKHR(
    void* context, VkPhysicalDevice physicalDevice,
    const VkPhysicalDeviceExternalBufferInfoKHR* pExternalBufferInfo,
    VkExternalBufferPropertiesKHR* pExternalBufferProperties) {
    return on_vkGetPhysicalDeviceExternalBufferProperties_common(
        true /* is KHR */, context, physicalDevice, pExternalBufferInfo, pExternalBufferProperties);
}

void ResourceTracker::on_vkGetPhysicalDeviceExternalSemaphoreProperties(
    void*, VkPhysicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
    VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
    (void)pExternalSemaphoreInfo;
    (void)pExternalSemaphoreProperties;
#ifdef VK_USE_PLATFORM_FUCHSIA
    if (pExternalSemaphoreInfo->handleType ==
        static_cast<uint32_t>(VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA)) {
        pExternalSemaphoreProperties->compatibleHandleTypes |=
            VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA;
        pExternalSemaphoreProperties->exportFromImportedHandleTypes |=
            VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA;
        pExternalSemaphoreProperties->externalSemaphoreFeatures |=
            VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT |
            VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
    }
#else
    const VkSemaphoreTypeCreateInfo* semaphoreTypeCi =
        vk_find_struct<VkSemaphoreTypeCreateInfo>(pExternalSemaphoreInfo);
    bool isSemaphoreTimeline =
        semaphoreTypeCi != nullptr && semaphoreTypeCi->semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE;
    if (isSemaphoreTimeline) {
        // b/304373623
        // dEQP-VK.api.external.semaphore.sync_fd#info_timeline
        pExternalSemaphoreProperties->compatibleHandleTypes = 0;
        pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
        pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
    } else if (pExternalSemaphoreInfo->handleType ==
               VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) {
        pExternalSemaphoreProperties->compatibleHandleTypes |=
            VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
        pExternalSemaphoreProperties->exportFromImportedHandleTypes |=
            VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
        pExternalSemaphoreProperties->externalSemaphoreFeatures |=
            VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT |
            VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
    }
#endif  // VK_USE_PLATFORM_FUCHSIA
}

void ResourceTracker::on_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(
    void* context, VkPhysicalDevice physicalDevice,
    const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
    VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
    on_vkGetPhysicalDeviceExternalSemaphoreProperties(
        context, physicalDevice, pExternalSemaphoreInfo, pExternalSemaphoreProperties);
}

void ResourceTracker::registerEncoderCleanupCallback(const VkEncoder* encoder, void* object,
                                                     CleanupCallback callback) {
    std::lock_guard<std::recursive_mutex> lock(mLock);
    auto& callbacks = mEncoderCleanupCallbacks[encoder];
    callbacks[object] = callback;
}

void ResourceTracker::unregisterEncoderCleanupCallback(const VkEncoder* encoder, void* object) {
    std::lock_guard<std::recursive_mutex> lock(mLock);
    mEncoderCleanupCallbacks[encoder].erase(object);
}

void ResourceTracker::onEncoderDeleted(const VkEncoder* encoder) {
    std::unique_lock<std::recursive_mutex> lock(mLock);
    if (mEncoderCleanupCallbacks.find(encoder) == mEncoderCleanupCallbacks.end()) return;

    std::unordered_map<void*, CleanupCallback> callbackCopies = mEncoderCleanupCallbacks[encoder];

    mEncoderCleanupCallbacks.erase(encoder);
    lock.unlock();

    for (auto it : callbackCopies) {
        it.second();
    }
}

CommandBufferStagingStream::Alloc ResourceTracker::getAlloc() {
    if (mFeatureInfo->hasVulkanAuxCommandMemory) {
        return [this](size_t size) -> CommandBufferStagingStream::Memory {
            VkMemoryAllocateInfo info{
                .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
                .pNext = nullptr,
                .allocationSize = size,
                .memoryTypeIndex = VK_MAX_MEMORY_TYPES  // indicates auxiliary memory
            };

            auto enc = ResourceTracker::getThreadLocalEncoder();
            VkDevice device = VK_NULL_HANDLE;
            VkDeviceMemory vkDeviceMem = VK_NULL_HANDLE;
            VkResult result = getCoherentMemory(&info, enc, device, &vkDeviceMem);
            if (result != VK_SUCCESS) {
                mesa_loge("Failed to get coherent memory %u", result);
                return {.deviceMemory = VK_NULL_HANDLE, .ptr = nullptr};
            }

            // getCoherentMemory() uses suballocations.
            // To retrieve the suballocated memory address, look up
            // VkDeviceMemory filled in by getCoherentMemory()
            // scope of mLock
            {
                std::lock_guard<std::recursive_mutex> lock(mLock);
                const auto it = info_VkDeviceMemory.find(vkDeviceMem);
                if (it == info_VkDeviceMemory.end()) {
                    mesa_loge("Coherent memory allocated %u not found", result);
                    return {.deviceMemory = VK_NULL_HANDLE, .ptr = nullptr};
                };

                const auto& info = it->second;
                return {.deviceMemory = vkDeviceMem, .ptr = info.ptr};
            }
        };
    }
    return nullptr;
}

CommandBufferStagingStream::Free ResourceTracker::getFree() {
    if (mFeatureInfo->hasVulkanAuxCommandMemory) {
        return [this](const CommandBufferStagingStream::Memory& memory) {
            // deviceMemory may not be the actual backing auxiliary VkDeviceMemory
            // for suballocations, deviceMemory is a alias VkDeviceMemory hand;
            // freeCoherentMemoryLocked maps the alias to the backing VkDeviceMemory
            VkDeviceMemory deviceMemory = memory.deviceMemory;
            std::unique_lock<std::recursive_mutex> lock(mLock);
            auto it = info_VkDeviceMemory.find(deviceMemory);
            if (it == info_VkDeviceMemory.end()) {
                mesa_loge("Device memory to free not found");
                return;
            }
            auto coherentMemory = freeCoherentMemoryLocked(deviceMemory, it->second);
            // We have to release the lock before we could possibly free a
            // CoherentMemory, because that will call into VkEncoder, which
            // shouldn't be called when the lock is held.
            lock.unlock();
            coherentMemory = nullptr;
        };
    }
    return nullptr;
}

VkResult ResourceTracker::on_vkBeginCommandBuffer(void* context, VkResult input_result,
                                                  VkCommandBuffer commandBuffer,
                                                  const VkCommandBufferBeginInfo* pBeginInfo) {
    (void)context;

    resetCommandBufferStagingInfo(commandBuffer, true /* also reset primaries */,
                                  true /* also clear pending descriptor sets */);

    VkEncoder* enc = ResourceTracker::getCommandBufferEncoder(commandBuffer);
    (void)input_result;

    struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(commandBuffer);
    cb->flags = pBeginInfo->flags;

    VkCommandBufferBeginInfo modifiedBeginInfo;

    if (pBeginInfo->pInheritanceInfo && !cb->isSecondary) {
        modifiedBeginInfo = *pBeginInfo;
        modifiedBeginInfo.pInheritanceInfo = nullptr;
        pBeginInfo = &modifiedBeginInfo;
    }

    if (!supportsDeferredCommands()) {
        return enc->vkBeginCommandBuffer(commandBuffer, pBeginInfo, true /* do lock */);
    }

    enc->vkBeginCommandBufferAsyncGOOGLE(commandBuffer, pBeginInfo, true /* do lock */);

    return VK_SUCCESS;
}

VkResult ResourceTracker::on_vkEndCommandBuffer(void* context, VkResult input_result,
                                                VkCommandBuffer commandBuffer) {
    VkEncoder* enc = (VkEncoder*)context;
    (void)input_result;

    if (!supportsDeferredCommands()) {
        return enc->vkEndCommandBuffer(commandBuffer, true /* do lock */);
    }

    enc->vkEndCommandBufferAsyncGOOGLE(commandBuffer, true /* do lock */);

    return VK_SUCCESS;
}

VkResult ResourceTracker::on_vkResetCommandBuffer(void* context, VkResult input_result,
                                                  VkCommandBuffer commandBuffer,
                                                  VkCommandBufferResetFlags flags) {
    VkEncoder* enc = (VkEncoder*)context;
    (void)input_result;

    if (!supportsDeferredCommands()) {
        VkResult res = enc->vkResetCommandBuffer(commandBuffer, flags, true /* do lock */);
        resetCommandBufferStagingInfo(commandBuffer, true /* also reset primaries */,
                                    true /* also clear pending descriptor sets */);
        return res;
    }

    enc->vkResetCommandBufferAsyncGOOGLE(commandBuffer, flags, true /* do lock */);
    resetCommandBufferStagingInfo(commandBuffer, true /* also reset primaries */,
                                  true /* also clear pending descriptor sets */);
    return VK_SUCCESS;
}

VkResult ResourceTracker::on_vkCreateImageView(void* context, VkResult input_result,
                                               VkDevice device,
                                               const VkImageViewCreateInfo* pCreateInfo,
                                               const VkAllocationCallbacks* pAllocator,
                                               VkImageView* pView) {
    VkEncoder* enc = (VkEncoder*)context;
    (void)input_result;

    VkImageViewCreateInfo localCreateInfo = vk_make_orphan_copy(*pCreateInfo);
    vk_struct_chain_iterator structChainIter = vk_make_chain_iterator(&localCreateInfo);

#if defined(VK_USE_PLATFORM_ANDROID_KHR)
    if (pCreateInfo->format == VK_FORMAT_UNDEFINED) {
        std::lock_guard<std::recursive_mutex> lock(mLock);

        auto it = info_VkImage.find(pCreateInfo->image);
        if (it != info_VkImage.end() && it->second.hasExternalFormat) {
            localCreateInfo.format = vk_format_from_fourcc(it->second.externalFourccFormat);
        }
    }
    VkSamplerYcbcrConversionInfo localVkSamplerYcbcrConversionInfo;
    const VkSamplerYcbcrConversionInfo* samplerYcbcrConversionInfo =
        vk_find_struct<VkSamplerYcbcrConversionInfo>(pCreateInfo);
    if (samplerYcbcrConversionInfo) {
        if (samplerYcbcrConversionInfo->conversion != VK_YCBCR_CONVERSION_DO_NOTHING) {
            localVkSamplerYcbcrConversionInfo = vk_make_orphan_copy(*samplerYcbcrConversionInfo);
            vk_append_struct(&structChainIter, &localVkSamplerYcbcrConversionInfo);
        }
    }
#endif

    return enc->vkCreateImageView(device, &localCreateInfo, pAllocator, pView, true /* do lock */);
}

void ResourceTracker::on_vkCmdExecuteCommands(void* context, VkCommandBuffer commandBuffer,
                                              uint32_t commandBufferCount,
                                              const VkCommandBuffer* pCommandBuffers) {
    VkEncoder* enc = (VkEncoder*)context;

    if (!mFeatureInfo->hasVulkanQueueSubmitWithCommands) {
        enc->vkCmdExecuteCommands(commandBuffer, commandBufferCount, pCommandBuffers,
                                  true /* do lock */);
        return;
    }

    struct goldfish_VkCommandBuffer* primary = as_goldfish_VkCommandBuffer(commandBuffer);
    for (uint32_t i = 0; i < commandBufferCount; ++i) {
        struct goldfish_VkCommandBuffer* secondary =
            as_goldfish_VkCommandBuffer(pCommandBuffers[i]);
        appendObject(&secondary->superObjects, primary);
        appendObject(&primary->subObjects, secondary);
    }

    enc->vkCmdExecuteCommands(commandBuffer, commandBufferCount, pCommandBuffers,
                              true /* do lock */);
}

void ResourceTracker::on_vkCmdBindDescriptorSets(void* context, VkCommandBuffer commandBuffer,
                                                 VkPipelineBindPoint pipelineBindPoint,
                                                 VkPipelineLayout layout, uint32_t firstSet,
                                                 uint32_t descriptorSetCount,
                                                 const VkDescriptorSet* pDescriptorSets,
                                                 uint32_t dynamicOffsetCount,
                                                 const uint32_t* pDynamicOffsets) {
    VkEncoder* enc = (VkEncoder*)context;

    if (mFeatureInfo->hasVulkanBatchedDescriptorSetUpdate)
        addPendingDescriptorSets(commandBuffer, descriptorSetCount, pDescriptorSets);

    enc->vkCmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet,
                                 descriptorSetCount, pDescriptorSets, dynamicOffsetCount,
                                 pDynamicOffsets, true /* do lock */);
}

void ResourceTracker::on_vkCmdPipelineBarrier(
    void* context, VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask,
    VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags,
    uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers,
    uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
    uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers) {
    VkEncoder* enc = (VkEncoder*)context;

    std::vector<VkImageMemoryBarrier> updatedImageMemoryBarriers;
    updatedImageMemoryBarriers.reserve(imageMemoryBarrierCount);
    for (uint32_t i = 0; i < imageMemoryBarrierCount; i++) {
        VkImageMemoryBarrier barrier = pImageMemoryBarriers[i];

#ifdef VK_USE_PLATFORM_ANDROID_KHR
        // Unfortunetly, Android does not yet have a mechanism for sharing the expected
        // VkImageLayout when passing around AHardwareBuffer-s so many existing users
        // that import AHardwareBuffer-s into VkImage-s/VkDeviceMemory-s simply use
        // VK_IMAGE_LAYOUT_UNDEFINED. 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 AHardwareBuffer-s being unintentionally
        // cleared. See go/ahb-vkimagelayout for more information.
        if (barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex &&
            (barrier.srcQueueFamilyIndex == VK_QUEUE_FAMILY_EXTERNAL ||
             barrier.srcQueueFamilyIndex == VK_QUEUE_FAMILY_FOREIGN_EXT) &&
            barrier.oldLayout == VK_IMAGE_LAYOUT_UNDEFINED) {
            // This is not a complete solution as the Vulkan spec does not require that
            // Vulkan drivers perform a no-op in the case when oldLayout equals newLayout
            // but this has been observed to be enough to work for now to avoid clearing
            // out images.
            // TODO(b/236179843): figure out long term solution.
            barrier.oldLayout = barrier.newLayout;
        }
#endif

        updatedImageMemoryBarriers.push_back(barrier);
    }

    enc->vkCmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
                              memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
                              pBufferMemoryBarriers, updatedImageMemoryBarriers.size(),
                              updatedImageMemoryBarriers.data(), true /* do lock */);
}

void ResourceTracker::on_vkDestroyDescriptorSetLayout(void* context, VkDevice device,
                                                      VkDescriptorSetLayout descriptorSetLayout,
                                                      const VkAllocationCallbacks* pAllocator) {
    decDescriptorSetLayoutRef(context, device, descriptorSetLayout, pAllocator);
}

VkResult ResourceTracker::on_vkAllocateCommandBuffers(
    void* context, VkResult input_result, VkDevice device,
    const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers) {
    (void)input_result;

    VkEncoder* enc = (VkEncoder*)context;
    VkResult res =
        enc->vkAllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers, true /* do lock */);
    if (VK_SUCCESS != res) return res;

    for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; ++i) {
        struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(pCommandBuffers[i]);
        cb->isSecondary = pAllocateInfo->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY;
        cb->device = device;
    }

    return res;
}

#if defined(VK_USE_PLATFORM_ANDROID_KHR)
VkResult ResourceTracker::exportSyncFdForQSRILocked(VkImage image, int* fd) {
    mesa_logd("%s: call for image %p hos timage handle 0x%llx\n", __func__, (void*)image,
              (unsigned long long)get_host_u64_VkImage(image));

    if (mFeatureInfo->hasVirtioGpuNativeSync) {
        struct VirtGpuExecBuffer exec = {};
        struct gfxstreamCreateQSRIExportVK exportQSRI = {};
        VirtGpuDevice* instance = VirtGpuDevice::getInstance();

        uint64_t hostImageHandle = get_host_u64_VkImage(image);

        exportQSRI.hdr.opCode = GFXSTREAM_CREATE_QSRI_EXPORT_VK;
        exportQSRI.imageHandleLo = (uint32_t)hostImageHandle;
        exportQSRI.imageHandleHi = (uint32_t)(hostImageHandle >> 32);

        exec.command = static_cast<void*>(&exportQSRI);
        exec.command_size = sizeof(exportQSRI);
        exec.flags = kFenceOut | kRingIdx;
        if (instance->execBuffer(exec, nullptr)) return VK_ERROR_OUT_OF_HOST_MEMORY;

        *fd = exec.handle.osHandle;
    } else {
#if GFXSTREAM_ENABLE_GUEST_GOLDFISH
        ensureSyncDeviceFd();
        goldfish_sync_queue_work(
            mSyncDeviceFd, get_host_u64_VkImage(image) /* the handle */,
            GOLDFISH_SYNC_VULKAN_QSRI /* thread handle (doubling as type field) */, fd);
#endif
    }

    mesa_logd("%s: got fd: %d\n", __func__, *fd);
    auto imageInfoIt = info_VkImage.find(image);
    if (imageInfoIt != info_VkImage.end()) {
        auto& imageInfo = imageInfoIt->second;

        auto* syncHelper =
            ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->syncHelper();

        // Remove any pending QSRI sync fds that are already signaled.
        auto syncFdIt = imageInfo.pendingQsriSyncFds.begin();
        while (syncFdIt != imageInfo.pendingQsriSyncFds.end()) {
            int syncFd = *syncFdIt;
            int syncWaitRet = syncHelper->wait(syncFd, /*timeout msecs*/ 0);
            if (syncWaitRet == 0) {
                // Sync fd is signaled.
                syncFdIt = imageInfo.pendingQsriSyncFds.erase(syncFdIt);
                syncHelper->close(syncFd);
            } else {
                if (errno != ETIME) {
                    mesa_loge("%s: Failed to wait for pending QSRI sync: sterror: %s errno: %d",
                              __func__, strerror(errno), errno);
                }
                break;
            }
        }

        int syncFdDup = syncHelper->dup(*fd);
        if (syncFdDup < 0) {
            mesa_loge("%s: Failed to dup() QSRI sync fd : sterror: %s errno: %d", __func__,
                      strerror(errno), errno);
        } else {
            imageInfo.pendingQsriSyncFds.push_back(syncFdDup);
        }
    }

    return VK_SUCCESS;
}

VkResult ResourceTracker::on_vkQueueSignalReleaseImageANDROID(void* context, VkResult input_result,
                                                              VkQueue queue,
                                                              uint32_t waitSemaphoreCount,
                                                              const VkSemaphore* pWaitSemaphores,
                                                              VkImage image, int* pNativeFenceFd) {
    (void)input_result;

    VkEncoder* enc = (VkEncoder*)context;

    if (!mFeatureInfo->hasVulkanAsyncQsri) {
        return enc->vkQueueSignalReleaseImageANDROID(queue, waitSemaphoreCount, pWaitSemaphores,
                                                     image, pNativeFenceFd, true /* lock */);
    }

    {
        std::lock_guard<std::recursive_mutex> lock(mLock);
        auto it = info_VkImage.find(image);
        if (it == info_VkImage.end()) {
            if (pNativeFenceFd) *pNativeFenceFd = -1;
            return VK_ERROR_INITIALIZATION_FAILED;
        }
    }

    enc->vkQueueSignalReleaseImageANDROIDAsyncGOOGLE(queue, waitSemaphoreCount, pWaitSemaphores,
                                                     image, true /* lock */);

    std::lock_guard<std::recursive_mutex> lock(mLock);
    VkResult result;
    if (pNativeFenceFd) {
        result = exportSyncFdForQSRILocked(image, pNativeFenceFd);
    } else {
        int syncFd;
        result = exportSyncFdForQSRILocked(image, &syncFd);

        if (syncFd >= 0) {
            auto* syncHelper =
                ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->syncHelper();
            syncHelper->close(syncFd);
        }
    }

    return result;
}
#endif

VkResult ResourceTracker::on_vkCreateGraphicsPipelines(
    void* context, VkResult input_result, VkDevice device, VkPipelineCache pipelineCache,
    uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos,
    const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines) {
    (void)input_result;
    VkEncoder* enc = (VkEncoder*)context;
    std::vector<VkGraphicsPipelineCreateInfo> localCreateInfos(pCreateInfos,
                                                               pCreateInfos + createInfoCount);
    for (VkGraphicsPipelineCreateInfo& graphicsPipelineCreateInfo : localCreateInfos) {
        // dEQP-VK.api.pipeline.pipeline_invalid_pointers_unused_structs#graphics
        bool requireViewportState = false;
        // VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00750
        requireViewportState |=
            graphicsPipelineCreateInfo.pRasterizationState != nullptr &&
            graphicsPipelineCreateInfo.pRasterizationState->rasterizerDiscardEnable == VK_FALSE;
        // VUID-VkGraphicsPipelineCreateInfo-pViewportState-04892
#ifdef VK_EXT_extended_dynamic_state2
        if (!requireViewportState && graphicsPipelineCreateInfo.pDynamicState) {
            for (uint32_t i = 0; i < graphicsPipelineCreateInfo.pDynamicState->dynamicStateCount;
                 i++) {
                if (VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT ==
                    graphicsPipelineCreateInfo.pDynamicState->pDynamicStates[i]) {
                    requireViewportState = true;
                    break;
                }
            }
        }
#endif  // VK_EXT_extended_dynamic_state2
        if (!requireViewportState) {
            graphicsPipelineCreateInfo.pViewportState = nullptr;
        }

        // It has the same requirement as for pViewportState.
        bool shouldIncludeFragmentShaderState = requireViewportState;

        // VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00751
        if (!shouldIncludeFragmentShaderState) {
            graphicsPipelineCreateInfo.pMultisampleState = nullptr;
        }

        bool forceDepthStencilState = false;
        bool forceColorBlendState = false;

        const VkPipelineRenderingCreateInfo* pipelineRenderingInfo =
            vk_find_struct<VkPipelineRenderingCreateInfo>(&graphicsPipelineCreateInfo);

        if (pipelineRenderingInfo) {
            forceDepthStencilState |=
                pipelineRenderingInfo->depthAttachmentFormat != VK_FORMAT_UNDEFINED;
            forceDepthStencilState |=
                pipelineRenderingInfo->stencilAttachmentFormat != VK_FORMAT_UNDEFINED;
            forceColorBlendState |= pipelineRenderingInfo->colorAttachmentCount != 0;
        }

        // VUID-VkGraphicsPipelineCreateInfo-renderPass-06043
        // VUID-VkGraphicsPipelineCreateInfo-renderPass-06044
        if (graphicsPipelineCreateInfo.renderPass == VK_NULL_HANDLE ||
            !shouldIncludeFragmentShaderState) {
            // VUID-VkGraphicsPipelineCreateInfo-renderPass-06053
            if (!forceDepthStencilState) {
                graphicsPipelineCreateInfo.pDepthStencilState = nullptr;
            }
            if (!forceColorBlendState) {
                graphicsPipelineCreateInfo.pColorBlendState = nullptr;
            }
        }
    }
    return enc->vkCreateGraphicsPipelines(device, pipelineCache, localCreateInfos.size(),
                                          localCreateInfos.data(), pAllocator, pPipelines,
                                          true /* do lock */);
}

uint32_t ResourceTracker::getApiVersionFromInstance(VkInstance instance) {
    std::lock_guard<std::recursive_mutex> lock(mLock);
    uint32_t api = kDefaultApiVersion;

    auto it = info_VkInstance.find(instance);
    if (it == info_VkInstance.end()) return api;

    api = it->second.highestApiVersion;

    return api;
}

uint32_t ResourceTracker::getApiVersionFromDevice(VkDevice device) {
    std::lock_guard<std::recursive_mutex> lock(mLock);

    uint32_t api = kDefaultApiVersion;

    auto it = info_VkDevice.find(device);
    if (it == info_VkDevice.end()) return api;

    api = it->second.apiVersion;

    return api;
}

bool ResourceTracker::hasInstanceExtension(VkInstance instance, const std::string& name) {
    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto it = info_VkInstance.find(instance);
    if (it == info_VkInstance.end()) return false;

    return it->second.enabledExtensions.find(name) != it->second.enabledExtensions.end();
}

bool ResourceTracker::hasDeviceExtension(VkDevice device, const std::string& name) {
    std::lock_guard<std::recursive_mutex> lock(mLock);

    auto it = info_VkDevice.find(device);
    if (it == info_VkDevice.end()) return false;

    return it->second.enabledExtensions.find(name) != it->second.enabledExtensions.end();
}

VkDevice ResourceTracker::getDevice(VkCommandBuffer commandBuffer) const {
    struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(commandBuffer);
    if (!cb) {
        return nullptr;
    }
    return cb->device;
}

// Resets staging stream for this command buffer and primary command buffers
// where this command buffer has been recorded. If requested, also clears the pending
// descriptor sets.
void ResourceTracker::resetCommandBufferStagingInfo(VkCommandBuffer commandBuffer,
                                                    bool alsoResetPrimaries,
                                                    bool alsoClearPendingDescriptorSets) {
    struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(commandBuffer);
    if (!cb) {
        return;
    }
    if (cb->privateEncoder) {
        sStaging.pushStaging((CommandBufferStagingStream*)cb->privateStream, cb->privateEncoder);
        cb->privateEncoder = nullptr;
        cb->privateStream = nullptr;
    }

    if (alsoClearPendingDescriptorSets && cb->userPtr) {
        CommandBufferPendingDescriptorSets* pendingSets =
            (CommandBufferPendingDescriptorSets*)cb->userPtr;
        pendingSets->sets.clear();
    }

    if (alsoResetPrimaries) {
        forAllObjects(cb->superObjects, [this, alsoResetPrimaries,
                                         alsoClearPendingDescriptorSets](void* obj) {
            VkCommandBuffer superCommandBuffer = (VkCommandBuffer)obj;
            struct goldfish_VkCommandBuffer* superCb =
                as_goldfish_VkCommandBuffer(superCommandBuffer);
            this->resetCommandBufferStagingInfo(superCommandBuffer, alsoResetPrimaries,
                                                alsoClearPendingDescriptorSets);
        });
        eraseObjects(&cb->superObjects);
    }

    forAllObjects(cb->subObjects, [cb](void* obj) {
        VkCommandBuffer subCommandBuffer = (VkCommandBuffer)obj;
        struct goldfish_VkCommandBuffer* subCb = as_goldfish_VkCommandBuffer(subCommandBuffer);
        // We don't do resetCommandBufferStagingInfo(subCommandBuffer)
        // since the user still might have submittable stuff pending there.
        eraseObject(&subCb->superObjects, (void*)cb);
    });

    eraseObjects(&cb->subObjects);
}

// Unlike resetCommandBufferStagingInfo, this does not always erase its
// superObjects pointers because the command buffer has merely been
// submitted, not reset.  However, if the command buffer was recorded with
// ONE_TIME_SUBMIT_BIT, then it will also reset its primaries.
//
// Also, we save the set of descriptor sets referenced by this command
// buffer because we only submitted the command buffer and it's possible to
// update the descriptor set again and re-submit the same command without
// recording it (Update-after-bind descriptor sets)
void ResourceTracker::resetCommandBufferPendingTopology(VkCommandBuffer commandBuffer) {
    struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(commandBuffer);
    if (cb->flags & VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT) {
        resetCommandBufferStagingInfo(commandBuffer, true /* reset primaries */,
                                      true /* clear pending descriptor sets */);
    } else {
        resetCommandBufferStagingInfo(commandBuffer, false /* Don't reset primaries */,
                                      false /* Don't clear pending descriptor sets */);
    }
}

void ResourceTracker::resetCommandPoolStagingInfo(VkCommandPool commandPool) {
    struct goldfish_VkCommandPool* p = as_goldfish_VkCommandPool(commandPool);

    if (!p) return;

    forAllObjects(p->subObjects, [this](void* commandBuffer) {
        this->resetCommandBufferStagingInfo((VkCommandBuffer)commandBuffer,
                                            true /* also reset primaries */,
                                            true /* also clear pending descriptor sets */);
    });
}

void ResourceTracker::addToCommandPool(VkCommandPool commandPool, uint32_t commandBufferCount,
                                       VkCommandBuffer* pCommandBuffers) {
    for (uint32_t i = 0; i < commandBufferCount; ++i) {
        struct goldfish_VkCommandPool* p = as_goldfish_VkCommandPool(commandPool);
        struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(pCommandBuffers[i]);
        appendObject(&p->subObjects, (void*)(pCommandBuffers[i]));
        appendObject(&cb->poolObjects, (void*)commandPool);
    }
}

void ResourceTracker::clearCommandPool(VkCommandPool commandPool) {
    resetCommandPoolStagingInfo(commandPool);
    struct goldfish_VkCommandPool* p = as_goldfish_VkCommandPool(commandPool);
    forAllObjects(p->subObjects, [this](void* commandBuffer) {
        this->unregister_VkCommandBuffer((VkCommandBuffer)commandBuffer);
    });
    eraseObjects(&p->subObjects);
}

const VkPhysicalDeviceMemoryProperties& ResourceTracker::getPhysicalDeviceMemoryProperties(
    void* context, VkDevice device, VkPhysicalDevice physicalDevice) {
    if (!mCachedPhysicalDeviceMemoryProps) {
        if (physicalDevice == VK_NULL_HANDLE) {
            std::lock_guard<std::recursive_mutex> lock(mLock);

            auto deviceInfoIt = info_VkDevice.find(device);
            if (deviceInfoIt == info_VkDevice.end()) {
                mesa_loge("Failed to pass device or physical device.");
                abort();
            }
            const auto& deviceInfo = deviceInfoIt->second;
            physicalDevice = deviceInfo.physdev;
        }

        VkEncoder* enc = (VkEncoder*)context;

        VkPhysicalDeviceMemoryProperties properties;
        enc->vkGetPhysicalDeviceMemoryProperties(physicalDevice, &properties, true /* no lock */);

        mCachedPhysicalDeviceMemoryProps.emplace(std::move(properties));
    }
    return *mCachedPhysicalDeviceMemoryProps;
}

static ResourceTracker* sTracker = nullptr;

ResourceTracker::ResourceTracker() {
    mCreateMapping = new CreateMapping();
    mDestroyMapping = new DestroyMapping();
    // nothing to do
}

ResourceTracker::~ResourceTracker() {
    delete mCreateMapping;
    delete mDestroyMapping;
}

VulkanHandleMapping* ResourceTracker::createMapping() { return mCreateMapping; }

VulkanHandleMapping* ResourceTracker::destroyMapping() { return mDestroyMapping; }

// static
ResourceTracker* ResourceTracker::get() {
    if (!sTracker) {
        // To be initialized once on vulkan device open.
        sTracker = new ResourceTracker;
    }
    return sTracker;
}

// static
ALWAYS_INLINE_GFXSTREAM VkEncoder* ResourceTracker::getCommandBufferEncoder(
    VkCommandBuffer commandBuffer) {
    if (!(ResourceTracker::streamFeatureBits &
          VULKAN_STREAM_FEATURE_QUEUE_SUBMIT_WITH_COMMANDS_BIT)) {
        auto enc = ResourceTracker::getThreadLocalEncoder();
        ResourceTracker::get()->syncEncodersForCommandBuffer(commandBuffer, enc);
        return enc;
    }

    struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(commandBuffer);
    if (!cb->privateEncoder) {
        sStaging.setAllocFree(ResourceTracker::get()->getAlloc(),
                              ResourceTracker::get()->getFree());
        sStaging.popStaging((CommandBufferStagingStream**)&cb->privateStream, &cb->privateEncoder);
    }
    uint8_t* writtenPtr;
    size_t written;
    ((CommandBufferStagingStream*)cb->privateStream)->getWritten(&writtenPtr, &written);
    return cb->privateEncoder;
}

// static
ALWAYS_INLINE_GFXSTREAM VkEncoder* ResourceTracker::getQueueEncoder(VkQueue queue) {
    auto enc = ResourceTracker::getThreadLocalEncoder();
    if (!(ResourceTracker::streamFeatureBits &
          VULKAN_STREAM_FEATURE_QUEUE_SUBMIT_WITH_COMMANDS_BIT)) {
        ResourceTracker::get()->syncEncodersForQueue(queue, enc);
    }
    return enc;
}

// static
ALWAYS_INLINE_GFXSTREAM VkEncoder* ResourceTracker::getThreadLocalEncoder() {
    auto hostConn = ResourceTracker::threadingCallbacks.hostConnectionGetFunc();
    auto vkEncoder = ResourceTracker::threadingCallbacks.vkEncoderGetFunc(hostConn);
    return vkEncoder;
}

// static
void ResourceTracker::setSeqnoPtr(uint32_t* seqnoptr) { sSeqnoPtr = seqnoptr; }

// static
ALWAYS_INLINE_GFXSTREAM uint32_t ResourceTracker::nextSeqno() {
    uint32_t res = __atomic_add_fetch(sSeqnoPtr, 1, __ATOMIC_SEQ_CST);
    return res;
}

// static
ALWAYS_INLINE_GFXSTREAM uint32_t ResourceTracker::getSeqno() {
    uint32_t res = __atomic_load_n(sSeqnoPtr, __ATOMIC_SEQ_CST);
    return res;
}

void ResourceTracker::transformImpl_VkExternalMemoryProperties_tohost(VkExternalMemoryProperties*,
                                                                      uint32_t) {}

void ResourceTracker::transformImpl_VkImageCreateInfo_fromhost(const VkImageCreateInfo*, uint32_t) {
}
void ResourceTracker::transformImpl_VkImageCreateInfo_tohost(const VkImageCreateInfo*, uint32_t) {}

#define DEFINE_TRANSFORMED_TYPE_IMPL(type)                                  \
    void ResourceTracker::transformImpl_##type##_tohost(type*, uint32_t) {} \
    void ResourceTracker::transformImpl_##type##_fromhost(type*, uint32_t) {}

LIST_TRIVIAL_TRANSFORMED_TYPES(DEFINE_TRANSFORMED_TYPE_IMPL)

}  // namespace vk
}  // namespace gfxstream
