// 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 {
    Lock 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) {
        AutoLock<Lock> lock(mLock);
        stream->reset();
        streams.push_back(stream);
        encoders.push_back(encoder);
    }

    void popStaging(CommandBufferStagingStream** streamOut, VkEncoder** encoderOut) {
        AutoLock<Lock> 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) { \
        AutoLock<RecursiveLock> lock(mLock);          \
        info_##type[obj] = type##_Info();             \
    }

#define HANDLE_UNREGISTER_IMPL_IMPL(type)               \
    void ResourceTracker::unregister_##type(type obj) { \
        AutoLock<RecursiveLock> 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 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) {
    AutoLock<RecursiveLock> lock(mLock);

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

void ResourceTracker::unregister_VkDevice(VkDevice device) {
    AutoLock<RecursiveLock> lock(mLock);

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

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

    clearCommandPool(pool);

    AutoLock<RecursiveLock> lock(mLock);
    info_VkCommandPool.erase(pool);
}

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

    AutoLock<RecursiveLock> 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;
    }

    AutoLock<RecursiveLock> 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();
    }

    AutoLock<RecursiveLock> lock(mLock);
    info_VkQueue.erase(queue);
}

void ResourceTracker::unregister_VkDeviceMemory(VkDeviceMemory mem) {
    AutoLock<RecursiveLock> 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) {
    AutoLock<RecursiveLock> 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) {
    AutoLock<RecursiveLock> lock(mLock);

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

    info_VkBuffer.erase(buf);
}

void ResourceTracker::unregister_VkSemaphore(VkSemaphore sem) {
    AutoLock<RecursiveLock> 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) {
    AutoLock<RecursiveLock> 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) {
    AutoLock<RecursiveLock> 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) {
    AutoLock<RecursiveLock> 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;

    AutoLock<RecursiveLock> lock(mLock);
    unregister_VkDescriptorSet_locked(set);
}

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

    AutoLock<RecursiveLock> 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;

    AutoLock<RecursiveLock> 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) {
    AutoLock<RecursiveLock> 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) {
    AutoLock<RecursiveLock> 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) {
    AutoLock<RecursiveLock> 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) {
    AutoLock<RecursiveLock> lock(mLock);
    auto& info = info_VkImage[image];

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

uint8_t* ResourceTracker::getMappedPointer(VkDeviceMemory memory) {
    AutoLock<RecursiveLock> 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) {
    AutoLock<RecursiveLock> 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) const {
    AutoLock<RecursiveLock> 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) {
        AutoLock<RecursiveLock> 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;

    AutoLock<RecursiveLock> 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) {
    AutoLock<RecursiveLock> lock(mLock);
    info_VkQueue[*pQueue].device = device;
}

void ResourceTracker::on_vkGetDeviceQueue2(void*, VkDevice device, const VkDeviceQueueInfo2*,
                                           VkQueue* pQueue) {
    AutoLock<RecursiveLock> 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;
    AutoLock<RecursiveLock> 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;

    AutoLock<RecursiveLock> 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;

    AutoLock<RecursiveLock> 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;
    }

    AutoLock<RecursiveLock> 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;

    AutoLock<RecursiveLock> 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;

    AutoLock<RecursiveLock> 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;
    {
        AutoLock<RecursiveLock> 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.
    AutoLock<RecursiveLock> lock(mLock);
    VkBufferCollectionFUCHSIA buffer_collection =
        reinterpret_cast<VkBufferCollectionFUCHSIA>(pCollection);
    if (info_VkBufferCollectionFUCHSIA.find(buffer_collection) !=
        info_VkBufferCollectionFUCHSIA.end()) {
        info_VkBufferCollectionFUCHSIA[buffer_collection].constraints =
            gfxstream::guest::makeOptional(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.
    AutoLock<RecursiveLock> lock(mLock);
    VkBufferCollectionFUCHSIA buffer_collection =
        reinterpret_cast<VkBufferCollectionFUCHSIA>(pCollection);
    if (info_VkBufferCollectionFUCHSIA.find(buffer_collection) !=
        info_VkBufferCollectionFUCHSIA.end()) {
        info_VkBufferCollectionFUCHSIA[buffer_collection].constraints =
            gfxstream::guest::makeOptional(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.hasValue()) {
        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
    // ====================================================================
    {
        AutoLock<RecursiveLock> 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
        AutoLock<RecursiveLock> lock(mLock);
        if (info_VkBufferCollectionFUCHSIA.find(collection) ==
            info_VkBufferCollectionFUCHSIA.end()) {
            return VK_ERROR_OUT_OF_DEVICE_MEMORY;
        }

        info_VkBufferCollectionFUCHSIA[collection].properties =
            gfxstream::guest::makeOptional(*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
    // ====================================================================
    {
        AutoLock<RecursiveLock> lock(mLock);
        auto getIndexResult = getBufferCollectionImageCreateInfoIndexLocked(
            collection, info, &pProperties->createInfoIndex);
        if (getIndexResult != VK_SUCCESS) {
            return getIndexResult;
        }
    }

    // formatFeatures
    // ====================================================================
    VkPhysicalDevice physicalDevice;
    {
        AutoLock<RecursiveLock> 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;
        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;
        }
        {
            AutoLock<RecursiveLock> 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;
            }
            {
                AutoLock<RecursiveLock> 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_logi("%s: has alloc flags\n", __func__);
            allocFlagsInfo = *allocFlagsInfoPtr;
            vk_append_struct(&structChainIter, &allocFlagsInfo);
        }

        if (opaqueCaptureAddressAllocInfoPtr) {
            mesa_logi("%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 = ++mBlobId;
        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 = ++mBlobId;
        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.
        AutoLock<RecursiveLock> 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) {
        AutoLock<RecursiveLock> 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);
        AutoLock<RecursiveLock> 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;
    {
        AutoLock<RecursiveLock> 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;

    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_logi("%s: has alloc flags\n", __func__);
        allocFlagsInfo = *allocFlagsInfoPtr;
        vk_append_struct(&structChainIter, &allocFlagsInfo);
    }

    if (opaqueCaptureAddressAllocInfoPtr) {
        mesa_logi("%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) {
        bool hasDedicatedImage =
            dedicatedAllocInfoPtr && (dedicatedAllocInfoPtr->image != VK_NULL_HANDLE);
        bool 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) {
            AutoLock<RecursiveLock> 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) {
            AutoLock<RecursiveLock> 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 %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) {
        bool hasDedicatedImage =
            dedicatedAllocInfoPtr && (dedicatedAllocInfoPtr->image != VK_NULL_HANDLE);
        bool 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) {
            AutoLock<RecursiveLock> 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) {
            AutoLock<RecursiveLock> 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 colorBufferBlob = nullptr;
#if defined(LINUX_GUEST_BUILD)
    if (exportDmabuf) {
        VirtGpuDevice* instance = VirtGpuDevice::getInstance();
        bool hasDedicatedImage =
            dedicatedAllocInfoPtr && (dedicatedAllocInfoPtr->image != VK_NULL_HANDLE);
        bool hasDedicatedBuffer =
            dedicatedAllocInfoPtr && (dedicatedAllocInfoPtr->buffer != VK_NULL_HANDLE);

        if (hasDedicatedImage) {
            VkImageCreateInfo imageCreateInfo;
            bool isDmaBufImage = false;
            {
                AutoLock<RecursiveLock> 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;
                }
                colorBufferBlob = instance->createResource(
                    imageCreateInfo.extent.width, imageCreateInfo.extent.height,
                    subResourceLayout.rowPitch, virglFormat, target, bind);
                if (!colorBufferBlob) {
                    mesa_loge("Failed to create colorBuffer resource for Image memory");
                    return VK_ERROR_OUT_OF_DEVICE_MEMORY;
                }
                if (!colorBufferBlob->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) {
            mesa_logw(
                "VkDeviceMemory allocated with VkMemoryDedicatedAllocateInfo::buffer cannot be "
                "exported (VkExportMemoryAllocateInfo)");
        } 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();
        colorBufferBlob = instance->importBlob(importHandle);
        if (!colorBufferBlob) {
            mesa_loge("%s: Failed to import colorBuffer resource\n", __func__);
            return VK_ERROR_OUT_OF_DEVICE_MEMORY;
        }
    }

    if (colorBufferBlob) {
        importCbInfo.colorBuffer = colorBufferBlob->getResourceHandle();
        vk_append_struct(&structChainIter, &importCbInfo);
    }
#endif

    if (ahw || colorBufferBlob || !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, colorBufferBlob);

        _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) {
    AutoLock<RecursiveLock> 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", 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;
    }

    AutoLock<RecursiveLock> 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) {
    AutoLock<RecursiveLock> 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) {
    AutoLock<RecursiveLock> 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;

    AutoLock<RecursiveLock> 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_logi("%s: ensure sync device\n", __func__);
            ensureSyncDeviceFd();
        }

        mesa_logi("%s: getting fence info\n", __func__);
        AutoLock<RecursiveLock> 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_logi("%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
    AutoLock<RecursiveLock> 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_logi("%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_logi("%s: VK_ERROR_OUT_OF_HOST_MEMORY: no sync fd import\n", __func__);
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }

    AutoLock<RecursiveLock> lock(mLock);
    auto it = info_VkFence.find(pImportFenceFdInfo->fence);
    if (it == info_VkFence.end()) {
        mesa_logi("%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_logi("%s: previous sync fd exists, close it\n", __func__);
        goldfish_sync_signal(info.syncFd);
        syncHelper->close(info.syncFd);
    }
#endif

    if (pImportFenceFdInfo->fd < 0) {
        mesa_logi("%s: import -1, set to -1 and exit\n", __func__);
        info.syncFd = -1;
    } else {
        mesa_logi("%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_logi("%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_logi("%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_logi("%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.
        AutoLock<RecursiveLock> lock(mLock);

        auto it = info_VkFence.find(pGetFdInfo->fence);
        if (it == info_VkFence.end()) {
            mesa_logi("%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_logi("%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_logi("%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;

    AutoLock<RecursiveLock> 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_logi("%s: scheduling ext waits\n", __func__);

        for (auto fd : fencesExternalWaitFds) {
            mesa_logi("%s: wait on %d\n", __func__, fd);
            tasks.push_back([fd] {
                auto* syncHelper =
                    ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->syncHelper();
                syncHelper->wait(fd, 3000);
                mesa_logi("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_logi("%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_logi("%s: VK_SUCCESS\n", __func__);
            return VK_SUCCESS;
        } else {
            mesa_logi("%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;
    {
        AutoLock<RecursiveLock> 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_logi(
                        "%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
        AutoLock<RecursiveLock> 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();
    {
        AutoLock<RecursiveLock> 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) {
    AutoLock<RecursiveLock> 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
    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 = gfxstream::guest::makeOptional(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

    AutoLock<RecursiveLock> 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) {
    AutoLock<RecursiveLock> 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

    AutoLock<RecursiveLock> 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) {
            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) {
        AutoLock<RecursiveLock> 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;

        AutoLock<RecursiveLock> 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
    AutoLock<RecursiveLock> 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
    AutoLock<RecursiveLock> 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) {
    AEMU_SCOPED_TRACE("on_vkQueueSubmit");
    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) {
    AEMU_SCOPED_TRACE("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;

    AutoLock<RecursiveLock> 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
            AEMU_SCOPED_TRACE("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_logi("%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;

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

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

    for (auto handle : toWait) {
        mesa_logi("%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) {
        AEMU_SCOPED_TRACE("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) {
    AutoLock<RecursiveLock> 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) {
    AutoLock<RecursiveLock> 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
    AutoLock<RecursiveLock> 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));
#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) {
    AutoLock<RecursiveLock> lock(mLock);
    auto& callbacks = mEncoderCleanupCallbacks[encoder];
    callbacks[object] = callback;
}

void ResourceTracker::unregisterEncoderCleanupCallback(const VkEncoder* encoder, void* object) {
    AutoLock<RecursiveLock> lock(mLock);
    mEncoderCleanupCallbacks[encoder].erase(object);
}

void ResourceTracker::onEncoderDeleted(const VkEncoder* encoder) {
    AutoLock<RecursiveLock> 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
            {
                AutoLock<RecursiveLock> 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;
            AutoLock<RecursiveLock> 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) {
        AutoLock<RecursiveLock> 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_logi("%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_logi("%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 */);
    }

    {
        AutoLock<RecursiveLock> 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 */);

    AutoLock<RecursiveLock> 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) const {
    AutoLock<RecursiveLock> 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) const {
    AutoLock<RecursiveLock> 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) const {
    AutoLock<RecursiveLock> 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) const {
    AutoLock<RecursiveLock> 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) {
            AutoLock<RecursiveLock> 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
