/*
 * Copyright (c) 2021-2023 The Khronos Group Inc.
 * Copyright (c) 2021-2023 Valve Corporation
 * Copyright (c) 2021-2023 LunarG, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and/or associated documentation files (the "Materials"), to
 * deal in the Materials without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Materials, and to permit persons to whom the Materials are
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice(s) and this permission notice shall be included in
 * all copies or substantial portions of the Materials.
 *
 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
 * USE OR OTHER DEALINGS IN THE MATERIALS.
 *
 * Author: Charles Giessen <charles@lunarg.com>
 */

#include "test_icd.h"

// export vk_icdGetInstanceProcAddr
#if !defined(TEST_ICD_EXPORT_ICD_GIPA)
#define TEST_ICD_EXPORT_ICD_GIPA 0
#endif

// export vk_icdNegotiateLoaderICDInterfaceVersion
#if !defined(TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION)
#define TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION 0
#endif

// export vk_icdGetPhysicalDeviceProcAddr
#if !defined(TEST_ICD_EXPORT_ICD_GPDPA)
#define TEST_ICD_EXPORT_ICD_GPDPA 0
#endif

// export vk_icdEnumerateAdapterPhysicalDevices
#if !defined(TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES)
#define TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES 0
#endif

// expose vk_icdNegotiateLoaderICDInterfaceVersion, vk_icdEnumerateAdapterPhysicalDevices, and vk_icdGetPhysicalDeviceProcAddr
// through vk_icdGetInstanceProcAddr or vkGetInstanceProcAddr
#if !defined(TEST_ICD_EXPOSE_VERSION_7)
#define TEST_ICD_EXPOSE_VERSION_7 0
#endif

TestICD icd;
extern "C" {
FRAMEWORK_EXPORT TestICD* get_test_icd_func() { return &icd; }
FRAMEWORK_EXPORT TestICD* reset_icd_func() {
    icd.~TestICD();
    return new (&icd) TestICD();
}
}

LayerDefinition& FindLayer(std::vector<LayerDefinition>& layers, std::string layerName) {
    for (auto& layer : layers) {
        if (layer.layerName == layerName) return layer;
    }
    assert(false && "Layer name not found!");
    return layers[0];
}
bool CheckLayer(std::vector<LayerDefinition>& layers, std::string layerName) {
    for (auto& layer : layers) {
        if (layer.layerName == layerName) return true;
    }
    return false;
}

bool IsInstanceExtensionSupported(const char* extension_name) {
    return icd.instance_extensions.end() !=
           std::find_if(icd.instance_extensions.begin(), icd.instance_extensions.end(),
                        [extension_name](Extension const& ext) { return string_eq(&ext.extensionName[0], extension_name); });
}

bool IsInstanceExtensionEnabled(const char* extension_name) {
    return icd.enabled_instance_extensions.end() !=
           std::find_if(icd.enabled_instance_extensions.begin(), icd.enabled_instance_extensions.end(),
                        [extension_name](Extension const& ext) { return string_eq(&ext.extensionName[0], extension_name); });
}

bool IsPhysicalDeviceExtensionAvailable(const char* extension_name) {
    for (auto& phys_dev : icd.physical_devices) {
        if (phys_dev.extensions.end() !=
            std::find_if(phys_dev.extensions.begin(), phys_dev.extensions.end(),
                         [extension_name](Extension const& ext) { return ext.extensionName == extension_name; })) {
            return true;
        }
    }
    return false;
}

// typename T must have '.get()' function that returns a type U
template <typename T, typename U>
VkResult FillCountPtr(std::vector<T> const& data_vec, uint32_t* pCount, U* pData) {
    if (pCount == nullptr) {
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }
    if (pData == nullptr) {
        *pCount = static_cast<uint32_t>(data_vec.size());
        return VK_SUCCESS;
    }
    uint32_t amount_written = 0;
    uint32_t amount_to_write = static_cast<uint32_t>(data_vec.size());
    if (*pCount < data_vec.size()) {
        amount_to_write = *pCount;
    }
    for (size_t i = 0; i < amount_to_write; i++) {
        pData[i] = data_vec[i].get();
        amount_written++;
    }
    if (*pCount < data_vec.size()) {
        *pCount = amount_written;
        return VK_INCOMPLETE;
    }
    *pCount = amount_written;
    return VK_SUCCESS;
}

template <typename T>
VkResult FillCountPtr(std::vector<T> const& data_vec, uint32_t* pCount, T* pData) {
    if (pCount == nullptr) {
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }
    if (pData == nullptr) {
        *pCount = static_cast<uint32_t>(data_vec.size());
        return VK_SUCCESS;
    }
    uint32_t amount_written = 0;
    uint32_t amount_to_write = static_cast<uint32_t>(data_vec.size());
    if (*pCount < data_vec.size()) {
        amount_to_write = *pCount;
    }
    for (size_t i = 0; i < amount_to_write; i++) {
        pData[i] = data_vec[i];
        amount_written++;
    }
    if (*pCount < data_vec.size()) {
        *pCount = amount_written;
        return VK_INCOMPLETE;
    }
    *pCount = amount_written;
    return VK_SUCCESS;
}

//// Instance Functions ////

// VK_SUCCESS,VK_INCOMPLETE
VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceExtensionProperties(const char* pLayerName, uint32_t* pPropertyCount,
                                                                           VkExtensionProperties* pProperties) {
    if (pLayerName != nullptr) {
        auto& layer = FindLayer(icd.instance_layers, std::string(pLayerName));
        return FillCountPtr(layer.extensions, pPropertyCount, pProperties);
    } else {  // instance extensions
        FillCountPtr(icd.instance_extensions, pPropertyCount, pProperties);
    }

    return VK_SUCCESS;
}

VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceLayerProperties(uint32_t* pPropertyCount, VkLayerProperties* pProperties) {
    return FillCountPtr(icd.instance_layers, pPropertyCount, pProperties);
}

VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceVersion(uint32_t* pApiVersion) {
    if (pApiVersion != nullptr) {
        *pApiVersion = icd.icd_api_version;
    }
    return VK_SUCCESS;
}

VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
                                                     [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
                                                     VkInstance* pInstance) {
    if (pCreateInfo == nullptr || pCreateInfo->pApplicationInfo == nullptr) {
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }

    if (icd.icd_api_version < VK_API_VERSION_1_1) {
        if (pCreateInfo->pApplicationInfo->apiVersion > VK_API_VERSION_1_0) {
            return VK_ERROR_INCOMPATIBLE_DRIVER;
        }
    }

    // Add to the list of enabled extensions only those that the ICD actively supports
    for (uint32_t iii = 0; iii < pCreateInfo->enabledExtensionCount; ++iii) {
        if (IsInstanceExtensionSupported(pCreateInfo->ppEnabledExtensionNames[iii])) {
            icd.add_enabled_instance_extension({pCreateInfo->ppEnabledExtensionNames[iii]});
        }
    }

    // VK_SUCCESS
    *pInstance = icd.instance_handle.handle;

    icd.passed_in_instance_create_flags = pCreateInfo->flags;

    return VK_SUCCESS;
}

VKAPI_ATTR void VKAPI_CALL test_vkDestroyInstance([[maybe_unused]] VkInstance instance,
                                                  [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {}

// VK_SUCCESS,VK_INCOMPLETE
VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDevices([[maybe_unused]] VkInstance instance, uint32_t* pPhysicalDeviceCount,
                                                               VkPhysicalDevice* pPhysicalDevices) {
    if (pPhysicalDevices == nullptr) {
        *pPhysicalDeviceCount = static_cast<uint32_t>(icd.physical_devices.size());
    } else {
        uint32_t handles_written = 0;
        for (size_t i = 0; i < icd.physical_devices.size(); i++) {
            if (i < *pPhysicalDeviceCount) {
                handles_written++;
                pPhysicalDevices[i] = icd.physical_devices[i].vk_physical_device.handle;
            } else {
                *pPhysicalDeviceCount = handles_written;
                return VK_INCOMPLETE;
            }
        }
        *pPhysicalDeviceCount = handles_written;
    }
    return VK_SUCCESS;
}

// VK_SUCCESS,VK_INCOMPLETE, VK_ERROR_INITIALIZATION_FAILED
VKAPI_ATTR VkResult VKAPI_CALL
test_vkEnumeratePhysicalDeviceGroups([[maybe_unused]] VkInstance instance, uint32_t* pPhysicalDeviceGroupCount,
                                     VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
    VkResult result = VK_SUCCESS;

    if (pPhysicalDeviceGroupProperties == nullptr) {
        if (0 == icd.physical_device_groups.size()) {
            *pPhysicalDeviceGroupCount = static_cast<uint32_t>(icd.physical_devices.size());
        } else {
            *pPhysicalDeviceGroupCount = static_cast<uint32_t>(icd.physical_device_groups.size());
        }
    } else {
        // NOTE: This is a fake struct to make sure the pNext chain is properly passed down to the ICD
        //       vkEnumeratePhysicalDeviceGroups.
        //       The two versions must match:
        //           "FakePNext" test in loader_regresion_tests.cpp
        //           "test_vkEnumeratePhysicalDeviceGroups" in test_icd.cpp
        struct FakePnextSharedWithICD {
            VkStructureType sType;
            void* pNext;
            uint32_t value;
        };

        uint32_t group_count = 0;
        if (0 == icd.physical_device_groups.size()) {
            group_count = static_cast<uint32_t>(icd.physical_devices.size());
            for (size_t device_group = 0; device_group < icd.physical_devices.size(); device_group++) {
                if (device_group >= *pPhysicalDeviceGroupCount) {
                    group_count = *pPhysicalDeviceGroupCount;
                    result = VK_INCOMPLETE;
                    break;
                }
                pPhysicalDeviceGroupProperties[device_group].subsetAllocation = false;
                pPhysicalDeviceGroupProperties[device_group].physicalDeviceCount = 1;
                pPhysicalDeviceGroupProperties[device_group].physicalDevices[0] =
                    icd.physical_devices[device_group].vk_physical_device.handle;
                for (size_t i = 1; i < VK_MAX_DEVICE_GROUP_SIZE; i++) {
                    pPhysicalDeviceGroupProperties[device_group].physicalDevices[i] = {};
                }
            }
        } else {
            group_count = static_cast<uint32_t>(icd.physical_device_groups.size());
            for (size_t device_group = 0; device_group < icd.physical_device_groups.size(); device_group++) {
                if (device_group >= *pPhysicalDeviceGroupCount) {
                    group_count = *pPhysicalDeviceGroupCount;
                    result = VK_INCOMPLETE;
                    break;
                }
                pPhysicalDeviceGroupProperties[device_group].subsetAllocation =
                    icd.physical_device_groups[device_group].subset_allocation;
                uint32_t handles_written = 0;
                for (size_t i = 0; i < icd.physical_device_groups[device_group].physical_device_handles.size(); i++) {
                    handles_written++;
                    pPhysicalDeviceGroupProperties[device_group].physicalDevices[i] =
                        icd.physical_device_groups[device_group].physical_device_handles[i]->vk_physical_device.handle;
                }
                for (size_t i = handles_written; i < VK_MAX_DEVICE_GROUP_SIZE; i++) {
                    pPhysicalDeviceGroupProperties[device_group].physicalDevices[i] = {};
                }
                pPhysicalDeviceGroupProperties[device_group].physicalDeviceCount = handles_written;
            }
        }
        // NOTE: The following code is purely to test pNext passing in vkEnumeratePhysicalDevice groups
        //       and includes normally invalid information.
        for (size_t device_group = 0; device_group < group_count; device_group++) {
            if (nullptr != pPhysicalDeviceGroupProperties[device_group].pNext) {
                VkBaseInStructure* base = reinterpret_cast<VkBaseInStructure*>(pPhysicalDeviceGroupProperties[device_group].pNext);
                if (base->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT) {
                    FakePnextSharedWithICD* fake = reinterpret_cast<FakePnextSharedWithICD*>(base);
                    fake->value = 0xDECAFBAD;
                }
            }
        }
        *pPhysicalDeviceGroupCount = static_cast<uint32_t>(group_count);
    }
    return result;
}

VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDebugUtilsMessengerEXT(
    [[maybe_unused]] VkInstance instance, [[maybe_unused]] const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
    [[maybe_unused]] const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pMessenger) {
    if (nullptr != pMessenger) {
        uint64_t fake_msgr_handle = reinterpret_cast<uint64_t>(new uint8_t);
        icd.messenger_handles.push_back(fake_msgr_handle);
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || \
    defined(_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
        *pMessenger = reinterpret_cast<VkDebugUtilsMessengerEXT>(fake_msgr_handle);
#else
        *pMessenger = fake_msgr_handle;
#endif
    }
    return VK_SUCCESS;
}

VKAPI_ATTR void VKAPI_CALL test_vkDestroyDebugUtilsMessengerEXT([[maybe_unused]] VkInstance instance,
                                                                VkDebugUtilsMessengerEXT messenger,
                                                                [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {
    if (messenger != VK_NULL_HANDLE) {
        uint64_t fake_msgr_handle = (uint64_t)(messenger);
        auto found_iter = std::find(icd.messenger_handles.begin(), icd.messenger_handles.end(), fake_msgr_handle);
        if (found_iter != icd.messenger_handles.end()) {
            // Remove it from the list
            icd.messenger_handles.erase(found_iter);
            // Delete the handle
            delete (uint8_t*)fake_msgr_handle;
        } else {
            assert(false && "Messenger not found during destroy!");
        }
    }
}

// Debug utils & debug marker ext stubs
VKAPI_ATTR VkResult VKAPI_CALL test_vkDebugMarkerSetObjectTagEXT(VkDevice dev, const VkDebugMarkerObjectTagInfoEXT* pTagInfo) {
    if (pTagInfo && pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {
        VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pTagInfo->object);
        if (pd != icd.physical_devices.at(icd.lookup_device(dev).phys_dev_index).vk_physical_device.handle)
            return VK_ERROR_DEVICE_LOST;
    }
    if (pTagInfo && pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {
        if (pTagInfo->object != icd.surface_handles.at(0)) return VK_ERROR_DEVICE_LOST;
    }
    if (pTagInfo && pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT) {
        if (pTagInfo->object != (uint64_t)(uintptr_t)icd.instance_handle.handle) return VK_ERROR_DEVICE_LOST;
    }
    return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL test_vkDebugMarkerSetObjectNameEXT(VkDevice dev, const VkDebugMarkerObjectNameInfoEXT* pNameInfo) {
    if (pNameInfo && pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {
        VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pNameInfo->object);
        if (pd != icd.physical_devices.at(icd.lookup_device(dev).phys_dev_index).vk_physical_device.handle)
            return VK_ERROR_DEVICE_LOST;
    }
    if (pNameInfo && pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {
        if (pNameInfo->object != icd.surface_handles.at(0)) return VK_ERROR_DEVICE_LOST;
    }
    if (pNameInfo && pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT) {
        if (pNameInfo->object != (uint64_t)(uintptr_t)icd.instance_handle.handle) return VK_ERROR_DEVICE_LOST;
    }
    return VK_SUCCESS;
}
VKAPI_ATTR void VKAPI_CALL test_vkCmdDebugMarkerBeginEXT(VkCommandBuffer, const VkDebugMarkerMarkerInfoEXT*) {}
VKAPI_ATTR void VKAPI_CALL test_vkCmdDebugMarkerEndEXT(VkCommandBuffer) {}
VKAPI_ATTR void VKAPI_CALL test_vkCmdDebugMarkerInsertEXT(VkCommandBuffer, const VkDebugMarkerMarkerInfoEXT*) {}

VKAPI_ATTR VkResult VKAPI_CALL test_vkSetDebugUtilsObjectNameEXT(VkDevice dev, const VkDebugUtilsObjectNameInfoEXT* pNameInfo) {
    if (pNameInfo && pNameInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {
        VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pNameInfo->objectHandle);
        if (pd != icd.physical_devices.at(icd.lookup_device(dev).phys_dev_index).vk_physical_device.handle)
            return VK_ERROR_DEVICE_LOST;
    }
    if (pNameInfo && pNameInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) {
        if (pNameInfo->objectHandle != icd.surface_handles.at(0)) return VK_ERROR_DEVICE_LOST;
    }
    if (pNameInfo && pNameInfo->objectType == VK_OBJECT_TYPE_INSTANCE) {
        if (pNameInfo->objectHandle != (uint64_t)(uintptr_t)icd.instance_handle.handle) return VK_ERROR_DEVICE_LOST;
    }
    return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL test_vkSetDebugUtilsObjectTagEXT(VkDevice dev, const VkDebugUtilsObjectTagInfoEXT* pTagInfo) {
    if (pTagInfo && pTagInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {
        VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pTagInfo->objectHandle);
        if (pd != icd.physical_devices.at(icd.lookup_device(dev).phys_dev_index).vk_physical_device.handle)
            return VK_ERROR_DEVICE_LOST;
    }
    if (pTagInfo && pTagInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) {
        if (pTagInfo->objectHandle != icd.surface_handles.at(0)) return VK_ERROR_DEVICE_LOST;
    }
    if (pTagInfo && pTagInfo->objectType == VK_OBJECT_TYPE_INSTANCE) {
        if (pTagInfo->objectHandle != (uint64_t)(uintptr_t)icd.instance_handle.handle) return VK_ERROR_DEVICE_LOST;
    }
    return VK_SUCCESS;
}
VKAPI_ATTR void VKAPI_CALL test_vkQueueBeginDebugUtilsLabelEXT(VkQueue, const VkDebugUtilsLabelEXT*) {}
VKAPI_ATTR void VKAPI_CALL test_vkQueueEndDebugUtilsLabelEXT(VkQueue) {}
VKAPI_ATTR void VKAPI_CALL test_vkQueueInsertDebugUtilsLabelEXT(VkQueue, const VkDebugUtilsLabelEXT*) {}
VKAPI_ATTR void VKAPI_CALL test_vkCmdBeginDebugUtilsLabelEXT(VkCommandBuffer, const VkDebugUtilsLabelEXT*) {}
VKAPI_ATTR void VKAPI_CALL test_vkCmdEndDebugUtilsLabelEXT(VkCommandBuffer) {}
VKAPI_ATTR void VKAPI_CALL test_vkCmdInsertDebugUtilsLabelEXT(VkCommandBuffer, const VkDebugUtilsLabelEXT*) {}

//// Physical Device functions ////

// VK_SUCCESS,VK_INCOMPLETE
VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceLayerProperties(VkPhysicalDevice, uint32_t*, VkLayerProperties*) {
    assert(false && "ICD's don't contain layers???");
    return VK_SUCCESS;
}

// VK_SUCCESS, VK_INCOMPLETE, VK_ERROR_LAYER_NOT_PRESENT
VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char* pLayerName,
                                                                         uint32_t* pPropertyCount,
                                                                         VkExtensionProperties* pProperties) {
    auto& phys_dev = icd.GetPhysDevice(physicalDevice);
    if (pLayerName != nullptr) {
        assert(false && "Drivers don't contain layers???");
        return VK_SUCCESS;
    } else {  // instance extensions
        return FillCountPtr(phys_dev.extensions, pPropertyCount, pProperties);
    }
}

VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
                                                                         uint32_t* pQueueFamilyPropertyCount,
                                                                         VkQueueFamilyProperties* pQueueFamilyProperties) {
    auto& phys_dev = icd.GetPhysDevice(physicalDevice);
    FillCountPtr(phys_dev.queue_family_properties, pQueueFamilyPropertyCount, pQueueFamilyProperties);
}

VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo,
                                                   [[maybe_unused]] const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) {
    // VK_SUCCESS
    auto found = std::find_if(icd.physical_devices.begin(), icd.physical_devices.end(), [physicalDevice](PhysicalDevice& phys_dev) {
        return phys_dev.vk_physical_device.handle == physicalDevice;
    });
    if (found == icd.physical_devices.end()) return VK_ERROR_INITIALIZATION_FAILED;
    auto device_handle = DispatchableHandle<VkDevice>();
    *pDevice = device_handle.handle;
    found->device_handles.push_back(device_handle.handle);
    found->device_create_infos.push_back(DeviceCreateInfo{pCreateInfo});
    for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
        found->queue_handles.emplace_back();
    }
    icd.device_handles.emplace_back(std::move(device_handle));

    return VK_SUCCESS;
}

VKAPI_ATTR void VKAPI_CALL test_vkDestroyDevice(VkDevice device, [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {
    auto found = std::find(icd.device_handles.begin(), icd.device_handles.end(), device);
    if (found != icd.device_handles.end()) icd.device_handles.erase(found);
    auto fd = icd.lookup_device(device);
    if (!fd.found) return;
    auto& phys_dev = icd.physical_devices.at(fd.phys_dev_index);
    phys_dev.device_handles.erase(phys_dev.device_handles.begin() + fd.dev_index);
    phys_dev.device_create_infos.erase(phys_dev.device_create_infos.begin() + fd.dev_index);
}

VKAPI_ATTR VkResult VKAPI_CALL generic_tool_props_function([[maybe_unused]] VkPhysicalDevice physicalDevice, uint32_t* pToolCount,
                                                           VkPhysicalDeviceToolPropertiesEXT* pToolProperties) {
    if (icd.tooling_properties.size() == 0) {
        return VK_SUCCESS;
    }
    if (pToolProperties == nullptr && pToolCount != nullptr) {
        *pToolCount = static_cast<uint32_t>(icd.tooling_properties.size());
    } else if (pToolCount != nullptr) {
        for (size_t i = 0; i < *pToolCount; i++) {
            if (i >= icd.tooling_properties.size()) {
                return VK_INCOMPLETE;
            }
            pToolProperties[i] = icd.tooling_properties[i];
        }
    }
    return VK_SUCCESS;
}

VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceToolPropertiesEXT(VkPhysicalDevice physicalDevice, uint32_t* pToolCount,
                                                                         VkPhysicalDeviceToolPropertiesEXT* pToolProperties) {
    return generic_tool_props_function(physicalDevice, pToolCount, pToolProperties);
}

VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceToolProperties(VkPhysicalDevice physicalDevice, uint32_t* pToolCount,
                                                                      VkPhysicalDeviceToolPropertiesEXT* pToolProperties) {
    return generic_tool_props_function(physicalDevice, pToolCount, pToolProperties);
}

template <typename T>
T to_nondispatch_handle(uint64_t handle) {
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || \
    defined(_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
    return reinterpret_cast<T>(handle);
#else
    return handle;
#endif
}

template <typename T>
uint64_t from_nondispatch_handle(T handle) {
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || \
    defined(_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
    return reinterpret_cast<uint64_t>(handle);
#else
    return handle;
#endif
}

//// WSI ////
template <typename HandleType>
void common_nondispatch_handle_creation(std::vector<uint64_t>& handles, HandleType* pHandle) {
    if (nullptr != pHandle) {
        if (handles.size() == 0)
            handles.push_back(800851234);
        else
            handles.push_back(handles.back() + 102030);
        *pHandle = to_nondispatch_handle<HandleType>(handles.back());
    }
}
#if defined(VK_USE_PLATFORM_ANDROID_KHR)

VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo,
                                                              const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
    return VK_SUCCESS;
}
#endif

#if defined(VK_USE_PLATFORM_WIN32_KHR)
VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateWin32SurfaceKHR([[maybe_unused]] VkInstance instance,
                                                            [[maybe_unused]] const VkWin32SurfaceCreateInfoKHR* pCreateInfo,
                                                            [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
                                                            VkSurfaceKHR* pSurface) {
    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
    return VK_SUCCESS;
}

VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice, uint32_t) { return VK_TRUE; }
#endif  // VK_USE_PLATFORM_WIN32_KHR

#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateWaylandSurfaceKHR([[maybe_unused]] VkInstance instance,
                                                              [[maybe_unused]] const VkWaylandSurfaceCreateInfoKHR* pCreateInfo,
                                                              [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
                                                              VkSurfaceKHR* pSurface) {
    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
    return VK_SUCCESS;
}

VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice, uint32_t,
                                                                                     struct wl_display*) {
    return VK_TRUE;
}
#endif  // VK_USE_PLATFORM_WAYLAND_KHR
#if defined(VK_USE_PLATFORM_XCB_KHR)
VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateXcbSurfaceKHR([[maybe_unused]] VkInstance instance,
                                                          [[maybe_unused]] const VkXcbSurfaceCreateInfoKHR* pCreateInfo,
                                                          [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
                                                          VkSurfaceKHR* pSurface) {
    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
    return VK_SUCCESS;
}

VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice, uint32_t, xcb_connection_t*,
                                                                                 xcb_visualid_t) {
    return VK_TRUE;
}
#endif  // VK_USE_PLATFORM_XCB_KHR

#if defined(VK_USE_PLATFORM_XLIB_KHR)
VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateXlibSurfaceKHR([[maybe_unused]] VkInstance instance,
                                                           [[maybe_unused]] const VkXlibSurfaceCreateInfoKHR* pCreateInfo,
                                                           [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
                                                           VkSurfaceKHR* pSurface) {
    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
    return VK_SUCCESS;
}

VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice, uint32_t, Display*, VisualID) {
    return VK_TRUE;
}
#endif  // VK_USE_PLATFORM_XLIB_KHR

#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDirectFBSurfaceEXT(VkInstance instance,
                                                               const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo,
                                                               const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
    return VK_SUCCESS;
}

VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceDirectFBPresentationSupportEXT(VkPhysicalDevice physicalDevice,
                                                                                      uint32_t queueFamilyIndex, IDirectFB* dfb) {
    return VK_TRUE;
}

#endif  // VK_USE_PLATFORM_DIRECTFB_EXT

#if defined(VK_USE_PLATFORM_MACOS_MVK)
VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateMacOSSurfaceMVK([[maybe_unused]] VkInstance instance,
                                                            [[maybe_unused]] const VkMacOSSurfaceCreateInfoMVK* pCreateInfo,
                                                            [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
                                                            VkSurfaceKHR* pSurface) {
    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
    return VK_SUCCESS;
}
#endif  // VK_USE_PLATFORM_MACOS_MVK

#if defined(VK_USE_PLATFORM_IOS_MVK)
VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateIOSSurfaceMVK([[maybe_unused]] VkInstance instance,
                                                          [[maybe_unused]] const VkIOSSurfaceCreateInfoMVK* pCreateInfo,
                                                          [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
                                                          VkSurfaceKHR* pSurface) {
    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
    return VK_SUCCESS;
}
#endif  // VK_USE_PLATFORM_IOS_MVK

#if defined(VK_USE_PLATFORM_GGP)
VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateStreamDescriptorSurfaceGGP(VkInstance instance,
                                                                       const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo,
                                                                       const VkAllocationCallbacks* pAllocator,
                                                                       VkSurfaceKHR* pSurface) {
    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
    return VK_SUCCESS;
}
#endif  // VK_USE_PLATFORM_GGP

#if defined(VK_USE_PLATFORM_METAL_EXT)
VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateMetalSurfaceEXT([[maybe_unused]] VkInstance instance,
                                                            [[maybe_unused]] const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
                                                            [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
                                                            VkSurfaceKHR* pSurface) {
    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
    return VK_SUCCESS;
}
#endif  // VK_USE_PLATFORM_METAL_EXT

#if defined(VK_USE_PLATFORM_SCREEN_QNX)
VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateScreenSurfaceQNX(VkInstance instance, const VkScreenSurfaceCreateInfoQNX* pCreateInfo,
                                                             const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
    return VK_SUCCESS;
}

VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice,
                                                                                    uint32_t queueFamilyIndex,
                                                                                    struct _screen_window* window) {
    return VK_TRUE;
}
#endif  // VK_USE_PLATFORM_SCREEN_QNX

VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateHeadlessSurfaceEXT([[maybe_unused]] VkInstance instance,
                                                               [[maybe_unused]] const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo,
                                                               [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
                                                               VkSurfaceKHR* pSurface) {
    common_nondispatch_handle_creation(icd.surface_handles, pSurface);
    return VK_SUCCESS;
}

VKAPI_ATTR void VKAPI_CALL test_vkDestroySurfaceKHR([[maybe_unused]] VkInstance instance, VkSurfaceKHR surface,
                                                    [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {
    if (surface != VK_NULL_HANDLE) {
        uint64_t fake_surf_handle = from_nondispatch_handle(surface);
        auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
        if (found_iter != icd.surface_handles.end()) {
            // Remove it from the list
            icd.surface_handles.erase(found_iter);
        } else {
            assert(false && "Surface not found during destroy!");
        }
    }
}
// VK_KHR_swapchain
VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateSwapchainKHR([[maybe_unused]] VkDevice device,
                                                         [[maybe_unused]] const VkSwapchainCreateInfoKHR* pCreateInfo,
                                                         [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
                                                         VkSwapchainKHR* pSwapchain) {
    common_nondispatch_handle_creation(icd.swapchain_handles, pSwapchain);
    return VK_SUCCESS;
}

VKAPI_ATTR VkResult VKAPI_CALL test_vkGetSwapchainImagesKHR([[maybe_unused]] VkDevice device,
                                                            [[maybe_unused]] VkSwapchainKHR swapchain,
                                                            uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages) {
    std::vector<uint64_t> handles{123, 234, 345, 345, 456};
    if (pSwapchainImages == nullptr) {
        if (pSwapchainImageCount) *pSwapchainImageCount = static_cast<uint32_t>(handles.size());
    } else if (pSwapchainImageCount) {
        for (uint32_t i = 0; i < *pSwapchainImageCount && i < handles.size(); i++) {
            pSwapchainImages[i] = to_nondispatch_handle<VkImage>(handles.back());
        }
        if (*pSwapchainImageCount < handles.size()) return VK_INCOMPLETE;
    }
    return VK_SUCCESS;
}

VKAPI_ATTR void VKAPI_CALL test_vkDestroySwapchainKHR([[maybe_unused]] VkDevice device, VkSwapchainKHR swapchain,
                                                      [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {
    if (swapchain != VK_NULL_HANDLE) {
        uint64_t fake_swapchain_handle = from_nondispatch_handle(swapchain);
        auto found_iter = icd.swapchain_handles.erase(
            std::remove(icd.swapchain_handles.begin(), icd.swapchain_handles.end(), fake_swapchain_handle),
            icd.swapchain_handles.end());
        if (!icd.swapchain_handles.empty() && found_iter == icd.swapchain_handles.end()) {
            assert(false && "Swapchain not found during destroy!");
        }
    }
}
// VK_KHR_swapchain with 1.1
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDeviceGroupSurfacePresentModesKHR([[maybe_unused]] VkDevice device,
                                                                           [[maybe_unused]] VkSurfaceKHR surface,
                                                                           VkDeviceGroupPresentModeFlagsKHR* pModes) {
    if (!pModes) return VK_ERROR_INITIALIZATION_FAILED;
    *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR;
    return VK_SUCCESS;
}

// VK_KHR_surface
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
                                                                         VkSurfaceKHR surface, VkBool32* pSupported) {
    if (surface != VK_NULL_HANDLE) {
        uint64_t fake_surf_handle = (uint64_t)(surface);
        auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
        if (found_iter == icd.surface_handles.end()) {
            assert(false && "Surface not found during GetPhysicalDeviceSurfaceSupportKHR query!");
            return VK_ERROR_UNKNOWN;
        }
    }
    if (nullptr != pSupported) {
        *pSupported = icd.GetPhysDevice(physicalDevice).queue_family_properties.at(queueFamilyIndex).support_present;
    }
    return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
                                                                              VkSurfaceCapabilitiesKHR* pSurfaceCapabilities) {
    if (surface != VK_NULL_HANDLE) {
        uint64_t fake_surf_handle = (uint64_t)(surface);
        auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
        if (found_iter == icd.surface_handles.end()) {
            assert(false && "Surface not found during GetPhysicalDeviceSurfaceCapabilitiesKHR query!");
            return VK_ERROR_UNKNOWN;
        }
    }
    if (nullptr != pSurfaceCapabilities) {
        *pSurfaceCapabilities = icd.GetPhysDevice(physicalDevice).surface_capabilities;
    }
    return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
                                                                         uint32_t* pSurfaceFormatCount,
                                                                         VkSurfaceFormatKHR* pSurfaceFormats) {
    if (surface != VK_NULL_HANDLE) {
        uint64_t fake_surf_handle = (uint64_t)(surface);
        auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
        if (found_iter == icd.surface_handles.end()) {
            assert(false && "Surface not found during GetPhysicalDeviceSurfaceFormatsKHR query!");
            return VK_ERROR_UNKNOWN;
        }
    }
    FillCountPtr(icd.GetPhysDevice(physicalDevice).surface_formats, pSurfaceFormatCount, pSurfaceFormats);
    return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
                                                                              uint32_t* pPresentModeCount,
                                                                              VkPresentModeKHR* pPresentModes) {
    if (surface != VK_NULL_HANDLE) {
        uint64_t fake_surf_handle = (uint64_t)(surface);
        auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
        if (found_iter == icd.surface_handles.end()) {
            assert(false && "Surface not found during GetPhysicalDeviceSurfacePresentModesKHR query!");
            return VK_ERROR_UNKNOWN;
        }
    }
    FillCountPtr(icd.GetPhysDevice(physicalDevice).surface_present_modes, pPresentModeCount, pPresentModes);
    return VK_SUCCESS;
}

// VK_KHR_display
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
                                                                            uint32_t* pPropertyCount,
                                                                            VkDisplayPropertiesKHR* pProperties) {
    FillCountPtr(icd.GetPhysDevice(physicalDevice).display_properties, pPropertyCount, pProperties);
    return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,
                                                                                 uint32_t* pPropertyCount,
                                                                                 VkDisplayPlanePropertiesKHR* pProperties) {
    FillCountPtr(icd.GetPhysDevice(physicalDevice).display_plane_properties, pPropertyCount, pProperties);
    return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice,
                                                                          [[maybe_unused]] uint32_t planeIndex,
                                                                          uint32_t* pDisplayCount, VkDisplayKHR* pDisplays) {
    FillCountPtr(icd.GetPhysDevice(physicalDevice).displays, pDisplayCount, pDisplays);
    return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice,
                                                                  [[maybe_unused]] VkDisplayKHR display, uint32_t* pPropertyCount,
                                                                  VkDisplayModePropertiesKHR* pProperties) {
    FillCountPtr(icd.GetPhysDevice(physicalDevice).display_mode_properties, pPropertyCount, pProperties);
    return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, [[maybe_unused]] VkDisplayKHR display,
                                                           [[maybe_unused]] const VkDisplayModeCreateInfoKHR* pCreateInfo,
                                                           [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
                                                           VkDisplayModeKHR* pMode) {
    if (nullptr != pMode) {
        *pMode = icd.GetPhysDevice(physicalDevice).display_mode;
    }
    return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice,
                                                                     [[maybe_unused]] VkDisplayModeKHR mode,
                                                                     [[maybe_unused]] uint32_t planeIndex,
                                                                     VkDisplayPlaneCapabilitiesKHR* pCapabilities) {
    if (nullptr != pCapabilities) {
        *pCapabilities = icd.GetPhysDevice(physicalDevice).display_plane_capabilities;
    }
    return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDisplayPlaneSurfaceKHR(
    [[maybe_unused]] VkInstance instance, [[maybe_unused]] const VkDisplaySurfaceCreateInfoKHR* pCreateInfo,
    [[maybe_unused]] const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
    if (nullptr != pSurface) {
        uint64_t fake_surf_handle = reinterpret_cast<uint64_t>(new uint8_t);
        icd.surface_handles.push_back(fake_surf_handle);
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || \
    defined(_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
        *pSurface = reinterpret_cast<VkSurfaceKHR>(fake_surf_handle);
#else
        *pSurface = fake_surf_handle;
#endif
    }
    return VK_SUCCESS;
}

// VK_KHR_get_surface_capabilities2
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,
                                                                               const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
                                                                               VkSurfaceCapabilities2KHR* pSurfaceCapabilities) {
    if (nullptr != pSurfaceInfo && nullptr != pSurfaceCapabilities) {
        return test_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, pSurfaceInfo->surface,
                                                              &pSurfaceCapabilities->surfaceCapabilities);
    }
    return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
                                                                          const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
                                                                          uint32_t* pSurfaceFormatCount,
                                                                          VkSurfaceFormat2KHR* pSurfaceFormats) {
    if (nullptr != pSurfaceFormatCount) {
        test_vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, pSurfaceInfo->surface, pSurfaceFormatCount, nullptr);
        if (nullptr != pSurfaceFormats) {
            auto& phys_dev = icd.GetPhysDevice(physicalDevice);
            // Since the structures are different, we have to copy each item over seperately.  Since we have multiple, we
            // have to manually copy the data here instead of calling the next function
            for (uint32_t cnt = 0; cnt < *pSurfaceFormatCount; ++cnt) {
                memcpy(&pSurfaceFormats[cnt].surfaceFormat, &phys_dev.surface_formats[cnt], sizeof(VkSurfaceFormatKHR));
            }
        }
    }
    return VK_SUCCESS;
}
// VK_KHR_display_swapchain
VkResult test_vkCreateSharedSwapchainsKHR([[maybe_unused]] VkDevice device, uint32_t swapchainCount,
                                          [[maybe_unused]] const VkSwapchainCreateInfoKHR* pCreateInfos,
                                          [[maybe_unused]] const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains) {
    for (uint32_t i = 0; i < swapchainCount; i++) {
        common_nondispatch_handle_creation(icd.swapchain_handles, &pSwapchains[i]);
    }
    return VK_SUCCESS;
}

//// misc
VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateCommandPool([[maybe_unused]] VkDevice device,
                                                        [[maybe_unused]] const VkCommandPoolCreateInfo* pCreateInfo,
                                                        [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
                                                        VkCommandPool* pCommandPool) {
    if (pCommandPool != nullptr) {
        pCommandPool = reinterpret_cast<VkCommandPool*>(0xdeadbeefdeadbeef);
    }
    return VK_SUCCESS;
}

VKAPI_ATTR void VKAPI_CALL test_vkDestroyCommandPool(VkDevice, VkCommandPool, const VkAllocationCallbacks*) {
    // do nothing, leak memory for now
}
VKAPI_ATTR VkResult VKAPI_CALL test_vkAllocateCommandBuffers([[maybe_unused]] VkDevice device,
                                                             const VkCommandBufferAllocateInfo* pAllocateInfo,
                                                             VkCommandBuffer* pCommandBuffers) {
    if (pAllocateInfo != nullptr && pCommandBuffers != nullptr) {
        for (size_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
            icd.allocated_command_buffers.push_back({});
            pCommandBuffers[i] = icd.allocated_command_buffers.back().handle;
        }
    }
    return VK_SUCCESS;
}

VKAPI_ATTR void VKAPI_CALL test_vkGetDeviceQueue([[maybe_unused]] VkDevice device, [[maybe_unused]] uint32_t queueFamilyIndex,
                                                 uint32_t queueIndex, VkQueue* pQueue) {
    auto fd = icd.lookup_device(device);
    if (fd.found) {
        *pQueue = icd.physical_devices.at(fd.phys_dev_index).queue_handles[queueIndex].handle;
    }
}

// VK_EXT_acquire_drm_display
VKAPI_ATTR VkResult VKAPI_CALL test_vkAcquireDrmDisplayEXT(VkPhysicalDevice, int32_t, VkDisplayKHR) { return VK_SUCCESS; }

VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDrmDisplayEXT(VkPhysicalDevice physicalDevice, [[maybe_unused]] int32_t drmFd,
                                                       [[maybe_unused]] uint32_t connectorId, VkDisplayKHR* display) {
    if (nullptr != display && icd.GetPhysDevice(physicalDevice).displays.size() > 0) {
        *display = icd.GetPhysDevice(physicalDevice).displays[0];
    }
    return VK_SUCCESS;
}

//// stubs
// 1.0
VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures) {
    if (nullptr != pFeatures) {
        memcpy(pFeatures, &icd.GetPhysDevice(physicalDevice).features, sizeof(VkPhysicalDeviceFeatures));
    }
}
VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
                                                              VkPhysicalDeviceProperties* pProperties) {
    if (nullptr != pProperties) {
        auto& phys_dev = icd.GetPhysDevice(physicalDevice);
        memcpy(pProperties, &phys_dev.properties, sizeof(VkPhysicalDeviceProperties));
        size_t max_len = (phys_dev.deviceName.length() > VK_MAX_PHYSICAL_DEVICE_NAME_SIZE) ? VK_MAX_PHYSICAL_DEVICE_NAME_SIZE
                                                                                           : phys_dev.deviceName.length();
        std::copy(phys_dev.deviceName.c_str(), phys_dev.deviceName.c_str() + max_len, pProperties->deviceName);
        pProperties->deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE - 1] = '\0';
    }
}
VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,
                                                                    VkPhysicalDeviceMemoryProperties* pMemoryProperties) {
    if (nullptr != pMemoryProperties) {
        memcpy(pMemoryProperties, &icd.GetPhysDevice(physicalDevice).memory_properties, sizeof(VkPhysicalDeviceMemoryProperties));
    }
}
VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceSparseImageFormatProperties(
    VkPhysicalDevice physicalDevice, [[maybe_unused]] VkFormat format, [[maybe_unused]] VkImageType type,
    [[maybe_unused]] VkSampleCountFlagBits samples, [[maybe_unused]] VkImageUsageFlags usage, [[maybe_unused]] VkImageTiling tiling,
    uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties) {
    FillCountPtr(icd.GetPhysDevice(physicalDevice).sparse_image_format_properties, pPropertyCount, pProperties);
}
VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
                                                                    VkFormatProperties* pFormatProperties) {
    if (nullptr != pFormatProperties) {
        memcpy(pFormatProperties, &icd.GetPhysDevice(physicalDevice).format_properties[static_cast<uint32_t>(format)],
               sizeof(VkFormatProperties));
    }
}
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceImageFormatProperties(
    VkPhysicalDevice physicalDevice, [[maybe_unused]] VkFormat format, [[maybe_unused]] VkImageType type,
    [[maybe_unused]] VkImageTiling tiling, [[maybe_unused]] VkImageUsageFlags usage, [[maybe_unused]] VkImageCreateFlags flags,
    VkImageFormatProperties* pImageFormatProperties) {
    if (nullptr != pImageFormatProperties) {
        memcpy(pImageFormatProperties, &icd.GetPhysDevice(physicalDevice).image_format_properties, sizeof(VkImageFormatProperties));
    }
    return VK_SUCCESS;
}

// 1.1
VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
                                                             VkPhysicalDeviceFeatures2* pFeatures) {
    if (nullptr != pFeatures) {
        test_vkGetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
    }
}
VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
                                                               VkPhysicalDeviceProperties2* pProperties) {
    if (nullptr != pProperties) {
        auto& phys_dev = icd.GetPhysDevice(physicalDevice);
        test_vkGetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
        VkBaseInStructure* pNext = reinterpret_cast<VkBaseInStructure*>(pProperties->pNext);
        while (pNext) {
            if (pNext->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT) {
                VkPhysicalDevicePCIBusInfoPropertiesEXT* bus_info =
                    reinterpret_cast<VkPhysicalDevicePCIBusInfoPropertiesEXT*>(pNext);
                bus_info->pciBus = phys_dev.pci_bus;
            }
            pNext = reinterpret_cast<VkBaseInStructure*>(const_cast<VkBaseInStructure*>(pNext->pNext));
        }
    }
}
VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice,
                                                                     VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
    if (nullptr != pMemoryProperties) {
        test_vkGetPhysicalDeviceMemoryProperties(physicalDevice, &pMemoryProperties->memoryProperties);
    }
}
VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
                                                                          uint32_t* pQueueFamilyPropertyCount,
                                                                          VkQueueFamilyProperties2* pQueueFamilyProperties) {
    if (nullptr != pQueueFamilyPropertyCount) {
        test_vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, nullptr);
        if (nullptr != pQueueFamilyProperties) {
            auto& phys_dev = icd.GetPhysDevice(physicalDevice);
            // Since the structures are different, we have to copy each item over seperately.  Since we have multiple, we
            // have to manually copy the data here instead of calling the next function
            for (uint32_t queue = 0; queue < *pQueueFamilyPropertyCount; ++queue) {
                memcpy(&pQueueFamilyProperties[queue].queueFamilyProperties, &phys_dev.queue_family_properties[queue].properties,
                       sizeof(VkQueueFamilyProperties));
            }
        }
    }
}
VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceSparseImageFormatProperties2(
    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount,
    VkSparseImageFormatProperties2* pProperties) {
    if (nullptr != pPropertyCount) {
        test_vkGetPhysicalDeviceSparseImageFormatProperties(physicalDevice, pFormatInfo->format, pFormatInfo->type,
                                                            pFormatInfo->samples, pFormatInfo->usage, pFormatInfo->tiling,
                                                            pPropertyCount, nullptr);
        if (nullptr != pProperties) {
            auto& phys_dev = icd.GetPhysDevice(physicalDevice);
            // Since the structures are different, we have to copy each item over seperately.  Since we have multiple, we
            // have to manually copy the data here instead of calling the next function
            for (uint32_t cnt = 0; cnt < *pPropertyCount; ++cnt) {
                memcpy(&pProperties[cnt].properties, &phys_dev.sparse_image_format_properties[cnt],
                       sizeof(VkSparseImageFormatProperties));
            }
        }
    }
}
VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
                                                                     VkFormatProperties2* pFormatProperties) {
    if (nullptr != pFormatProperties) {
        test_vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &pFormatProperties->formatProperties);
    }
}
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceImageFormatProperties2(
    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
    VkImageFormatProperties2* pImageFormatProperties) {
    if (nullptr != pImageFormatInfo) {
        VkImageFormatProperties* ptr = nullptr;
        if (pImageFormatProperties) {
            ptr = &pImageFormatProperties->imageFormatProperties;
        }
        test_vkGetPhysicalDeviceImageFormatProperties(physicalDevice, pImageFormatInfo->format, pImageFormatInfo->type,
                                                      pImageFormatInfo->tiling, pImageFormatInfo->usage, pImageFormatInfo->flags,
                                                      ptr);
    }
    return VK_SUCCESS;
}
VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceExternalBufferProperties(
    VkPhysicalDevice physicalDevice, [[maybe_unused]] const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
    VkExternalBufferProperties* pExternalBufferProperties) {
    if (nullptr != pExternalBufferProperties) {
        auto& phys_dev = icd.GetPhysDevice(physicalDevice);
        memcpy(&pExternalBufferProperties->externalMemoryProperties, &phys_dev.external_memory_properties,
               sizeof(VkExternalMemoryProperties));
    }
}
VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceExternalSemaphoreProperties(
    VkPhysicalDevice physicalDevice, [[maybe_unused]] const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
    VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
    if (nullptr != pExternalSemaphoreProperties) {
        auto& phys_dev = icd.GetPhysDevice(physicalDevice);
        memcpy(pExternalSemaphoreProperties, &phys_dev.external_semaphore_properties, sizeof(VkExternalSemaphoreProperties));
    }
}
VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceExternalFenceProperties(
    VkPhysicalDevice physicalDevice, [[maybe_unused]] const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo,
    VkExternalFenceProperties* pExternalFenceProperties) {
    if (nullptr != pExternalFenceProperties) {
        auto& phys_dev = icd.GetPhysDevice(physicalDevice);
        memcpy(pExternalFenceProperties, &phys_dev.external_fence_properties, sizeof(VkExternalFenceProperties));
    }
}
// Entry-points associated with the VK_KHR_performance_query extension
VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
    VkPhysicalDevice, uint32_t, uint32_t*, VkPerformanceCounterKHR*, VkPerformanceCounterDescriptionKHR*) {
    return VK_SUCCESS;
}
VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(VkPhysicalDevice,
                                                                                        const VkQueryPoolPerformanceCreateInfoKHR*,
                                                                                        uint32_t*) {}
VKAPI_ATTR VkResult VKAPI_CALL test_vkAcquireProfilingLockKHR(VkDevice, const VkAcquireProfilingLockInfoKHR*) { return VK_SUCCESS; }
VKAPI_ATTR void VKAPI_CALL test_vkReleaseProfilingLockKHR(VkDevice) {}
// Entry-points associated with the VK_EXT_sample_locations extension
VKAPI_ATTR void VKAPI_CALL test_vkCmdSetSampleLocationsEXT(VkCommandBuffer, const VkSampleLocationsInfoEXT*) {}
VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceMultisamplePropertiesEXT(VkPhysicalDevice, VkSampleCountFlagBits,
                                                                            VkMultisamplePropertiesEXT*) {}
// Entry-points associated with the VK_EXT_calibrated_timestamps extension
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT(VkPhysicalDevice, uint32_t*, VkTimeDomainEXT*) {
    return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetCalibratedTimestampsEXT(VkDevice, uint32_t, const VkCalibratedTimestampInfoEXT*, uint64_t*,
                                                                 uint64_t*) {
    return VK_SUCCESS;
}

#if defined(WIN32)
VKAPI_ATTR VkResult VKAPI_CALL test_vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID,
                                                                          uint32_t* pPhysicalDeviceCount,
                                                                          VkPhysicalDevice* pPhysicalDevices) {
    if (adapterLUID.LowPart != icd.adapterLUID.LowPart || adapterLUID.HighPart != icd.adapterLUID.HighPart) {
        *pPhysicalDeviceCount = 0;
        return VK_SUCCESS;
    }
    icd.called_enumerate_adapter_physical_devices = true;
    VkResult res = test_vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
    // For this testing, flip order intentionally
    if (nullptr != pPhysicalDevices) {
        std::reverse(pPhysicalDevices, pPhysicalDevices + *pPhysicalDeviceCount);
    }
    return res;
}
#endif  // defined(WIN32)

VkResult test_vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) {
    if (icd.called_vk_icd_gipa == CalledICDGIPA::not_called &&
        icd.called_negotiate_interface == CalledNegotiateInterface::not_called)
        icd.called_negotiate_interface = CalledNegotiateInterface::vk_icd_negotiate;
    else if (icd.called_vk_icd_gipa != CalledICDGIPA::not_called)
        icd.called_negotiate_interface = CalledNegotiateInterface::vk_icd_gipa_first;

    // loader puts the minimum it supports in pSupportedVersion, if that is lower than our minimum
    // If the ICD doesn't supports the interface version provided by the loader, report VK_ERROR_INCOMPATIBLE_DRIVER
    if (icd.min_icd_interface_version > *pSupportedVersion) {
        icd.interface_version_check = InterfaceVersionCheck::loader_version_too_old;
        *pSupportedVersion = icd.min_icd_interface_version;
        return VK_ERROR_INCOMPATIBLE_DRIVER;
    }

    // the loader-provided interface version is newer than that supported by the ICD
    if (icd.max_icd_interface_version < *pSupportedVersion) {
        icd.interface_version_check = InterfaceVersionCheck::loader_version_too_new;
        *pSupportedVersion = icd.max_icd_interface_version;
    }
    // ICD interface version is greater than the loader's,  return the loader's version
    else if (icd.max_icd_interface_version > *pSupportedVersion) {
        icd.interface_version_check = InterfaceVersionCheck::icd_version_too_new;
        // don't change *pSupportedVersion
    } else {
        icd.interface_version_check = InterfaceVersionCheck::version_is_supported;
        *pSupportedVersion = icd.max_icd_interface_version;
    }

    return VK_SUCCESS;
}

// Forward declarations for trampolines
extern "C" {
#if TEST_ICD_EXPOSE_VERSION_7
FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion);
#if TEST_ICD_EXPORT_ICD_GPDPA
FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName);
#endif
#if defined(WIN32) && TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES
FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID,
                                                                                      uint32_t* pPhysicalDeviceCount,
                                                                                      VkPhysicalDevice* pPhysicalDevices);
#endif
#endif
}

//// trampolines

PFN_vkVoidFunction get_instance_func_ver_1_1([[maybe_unused]] VkInstance instance, const char* pName) {
    if (icd.icd_api_version >= VK_API_VERSION_1_1) {
        if (string_eq(pName, "test_vkEnumerateInstanceVersion")) {
            return icd.can_query_vkEnumerateInstanceVersion ? to_vkVoidFunction(test_vkEnumerateInstanceVersion) : nullptr;
        }
        if (string_eq(pName, "vkEnumeratePhysicalDeviceGroups")) {
            return to_vkVoidFunction(test_vkEnumeratePhysicalDeviceGroups);
        }
    }
    return nullptr;
}

PFN_vkVoidFunction get_physical_device_func_wsi([[maybe_unused]] VkInstance instance, const char* pName) {
    if (IsInstanceExtensionEnabled("VK_KHR_surface")) {
        if (string_eq(pName, "vkGetPhysicalDeviceSurfaceSupportKHR"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfaceSupportKHR);
        if (string_eq(pName, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
        if (string_eq(pName, "vkGetPhysicalDeviceSurfaceFormatsKHR"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfaceFormatsKHR);
        if (string_eq(pName, "vkGetPhysicalDeviceSurfacePresentModesKHR"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfacePresentModesKHR);
    }
    if (IsInstanceExtensionEnabled("VK_KHR_get_surface_capabilities2")) {
        if (string_eq(pName, "vkGetPhysicalDeviceSurfaceCapabilities2KHR"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfaceCapabilities2KHR);
        if (string_eq(pName, "vkGetPhysicalDeviceSurfaceFormats2KHR"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfaceFormats2KHR);
    }
    if (IsInstanceExtensionEnabled("VK_KHR_display")) {
        if (string_eq(pName, "vkGetPhysicalDeviceDisplayPropertiesKHR"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceDisplayPropertiesKHR);
        if (string_eq(pName, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceDisplayPlanePropertiesKHR);
        if (string_eq(pName, "vkGetDisplayPlaneSupportedDisplaysKHR"))
            return to_vkVoidFunction(test_vkGetDisplayPlaneSupportedDisplaysKHR);
        if (string_eq(pName, "vkGetDisplayModePropertiesKHR")) return to_vkVoidFunction(test_vkGetDisplayModePropertiesKHR);
        if (string_eq(pName, "vkCreateDisplayModeKHR")) return to_vkVoidFunction(test_vkCreateDisplayModeKHR);
        if (string_eq(pName, "vkGetDisplayPlaneCapabilitiesKHR")) return to_vkVoidFunction(test_vkGetDisplayPlaneCapabilitiesKHR);
        if (string_eq(pName, "vkCreateDisplayPlaneSurfaceKHR")) return to_vkVoidFunction(test_vkCreateDisplayPlaneSurfaceKHR);
    }
    if (IsInstanceExtensionEnabled("VK_EXT_acquire_drm_display")) {
        if (string_eq(pName, "vkAcquireDrmDisplayEXT")) return to_vkVoidFunction(test_vkAcquireDrmDisplayEXT);
        if (string_eq(pName, "vkGetDrmDisplayEXT")) return to_vkVoidFunction(test_vkGetDrmDisplayEXT);
    }
    return nullptr;
}

PFN_vkVoidFunction get_instance_func_wsi(VkInstance instance, const char* pName) {
    if (icd.min_icd_interface_version >= 3 && icd.enable_icd_wsi == true) {
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
        if (string_eq(pName, "vkCreateAndroidSurfaceKHR")) {
            icd.is_using_icd_wsi = true;
            return to_vkVoidFunction(test_vkCreateAndroidSurfaceKHR);
        }
#endif
#if defined(VK_USE_PLATFORM_METAL_EXT)
        if (string_eq(pName, "vkCreateMetalSurfaceEXT")) {
            return to_vkVoidFunction(test_vkCreateMetalSurfaceEXT);
        }
#endif
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
        if (string_eq(pName, "vkCreateWaylandSurfaceKHR")) {
            return to_vkVoidFunction(test_vkCreateWaylandSurfaceKHR);
        }
        if (string_eq(pName, "vkGetPhysicalDeviceWaylandPresentationSupportKHR")) {
            return to_vkVoidFunction(test_vkGetPhysicalDeviceWaylandPresentationSupportKHR);
        }
#endif
#if defined(VK_USE_PLATFORM_XCB_KHR)
        if (string_eq(pName, "vkCreateXcbSurfaceKHR")) {
            return to_vkVoidFunction(test_vkCreateXcbSurfaceKHR);
        }
        if (string_eq(pName, "vkGetPhysicalDeviceXcbPresentationSupportKHR")) {
            return to_vkVoidFunction(test_vkGetPhysicalDeviceXcbPresentationSupportKHR);
        }
#endif
#if defined(VK_USE_PLATFORM_XLIB_KHR)
        if (string_eq(pName, "vkCreateXlibSurfaceKHR")) {
            return to_vkVoidFunction(test_vkCreateXlibSurfaceKHR);
        }
        if (string_eq(pName, "vkGetPhysicalDeviceXlibPresentationSupportKHR")) {
            return to_vkVoidFunction(test_vkGetPhysicalDeviceXlibPresentationSupportKHR);
        }
#endif
#if defined(VK_USE_PLATFORM_WIN32_KHR)
        if (string_eq(pName, "vkCreateWin32SurfaceKHR")) {
            return to_vkVoidFunction(test_vkCreateWin32SurfaceKHR);
        }
        if (string_eq(pName, "vkGetPhysicalDeviceWin32PresentationSupportKHR")) {
            return to_vkVoidFunction(test_vkGetPhysicalDeviceWin32PresentationSupportKHR);
        }
#endif
#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
        if (string_eq(pName, "vkCreateDirectFBSurfaceEXT")) {
            return to_vkVoidFunction(test_vkCreateDirectFBSurfaceEXT);
        }
        if (string_eq(pName, "vkGetPhysicalDeviceDirectFBPresentationSupportEXT")) {
            return to_vkVoidFunction(test_vkGetPhysicalDeviceDirectFBPresentationSupportEXT);
        }
#endif  // VK_USE_PLATFORM_DIRECTFB_EXT

#if defined(VK_USE_PLATFORM_MACOS_MVK)
        if (string_eq(pName, "vkCreateMacOSSurfaceMVK")) {
            return to_vkVoidFunction(test_vkCreateMacOSSurfaceMVK);
        }
#endif  // VK_USE_PLATFORM_MACOS_MVK

#if defined(VK_USE_PLATFORM_IOS_MVK)
        if (string_eq(pName, "vkCreateIOSSurfaceMVK")) {
            return to_vkVoidFunction(test_vkCreateIOSSurfaceMVK);
        }
#endif  // VK_USE_PLATFORM_IOS_MVK

#if defined(VK_USE_PLATFORM_GGP)
        if (string_eq(pName, "vkCreateStreamDescriptorSurfaceGGP")) {
            return to_vkVoidFunction(test_vkCreateStreamDescriptorSurfaceGGP);
        }
#endif  // VK_USE_PLATFORM_GGP

#if defined(VK_USE_PLATFORM_SCREEN_QNX)
        if (string_eq(pName, "vkCreateScreenSurfaceQNX")) {
            return to_vkVoidFunction(test_vkCreateScreenSurfaceQNX);
        }
        if (string_eq(pName, "vkGetPhysicalDeviceScreenPresentationSupportQNX")) {
            return to_vkVoidFunction(test_vkGetPhysicalDeviceScreenPresentationSupportQNX);
        }
#endif  // VK_USE_PLATFORM_SCREEN_QNX

        if (string_eq(pName, "vkCreateHeadlessSurfaceEXT")) {
            return to_vkVoidFunction(test_vkCreateHeadlessSurfaceEXT);
        }

        if (string_eq(pName, "vkDestroySurfaceKHR")) {
            icd.is_using_icd_wsi = true;
            return to_vkVoidFunction(test_vkDestroySurfaceKHR);
        }
    }
    if (IsInstanceExtensionEnabled(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
        if (string_eq(pName, "vkCreateDebugUtilsMessengerEXT")) {
            return to_vkVoidFunction(test_vkCreateDebugUtilsMessengerEXT);
        }
        if (string_eq(pName, "vkDestroyDebugUtilsMessengerEXT")) {
            return to_vkVoidFunction(test_vkDestroyDebugUtilsMessengerEXT);
        }
    }

    PFN_vkVoidFunction ret_phys_dev_wsi = get_physical_device_func_wsi(instance, pName);
    if (ret_phys_dev_wsi != nullptr) return ret_phys_dev_wsi;
    return nullptr;
}
PFN_vkVoidFunction get_physical_device_func([[maybe_unused]] VkInstance instance, const char* pName) {
    if (string_eq(pName, "vkEnumerateDeviceLayerProperties")) return to_vkVoidFunction(test_vkEnumerateDeviceLayerProperties);
    if (string_eq(pName, "vkEnumerateDeviceExtensionProperties"))
        return to_vkVoidFunction(test_vkEnumerateDeviceExtensionProperties);
    if (string_eq(pName, "vkGetPhysicalDeviceQueueFamilyProperties"))
        return to_vkVoidFunction(test_vkGetPhysicalDeviceQueueFamilyProperties);
    if (string_eq(pName, "vkCreateDevice")) return to_vkVoidFunction(test_vkCreateDevice);

    if (string_eq(pName, "vkGetPhysicalDeviceFeatures")) return to_vkVoidFunction(test_vkGetPhysicalDeviceFeatures);
    if (string_eq(pName, "vkGetPhysicalDeviceProperties")) return to_vkVoidFunction(test_vkGetPhysicalDeviceProperties);
    if (string_eq(pName, "vkGetPhysicalDeviceMemoryProperties")) return to_vkVoidFunction(test_vkGetPhysicalDeviceMemoryProperties);
    if (string_eq(pName, "vkGetPhysicalDeviceSparseImageFormatProperties"))
        return to_vkVoidFunction(test_vkGetPhysicalDeviceSparseImageFormatProperties);
    if (string_eq(pName, "vkGetPhysicalDeviceFormatProperties")) return to_vkVoidFunction(test_vkGetPhysicalDeviceFormatProperties);
    if (string_eq(pName, "vkGetPhysicalDeviceImageFormatProperties"))
        return to_vkVoidFunction(test_vkGetPhysicalDeviceImageFormatProperties);

    if (IsInstanceExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
        if (string_eq(pName, "vkGetPhysicalDeviceFeatures2KHR")) return to_vkVoidFunction(test_vkGetPhysicalDeviceFeatures2);
        if (string_eq(pName, "vkGetPhysicalDeviceProperties2KHR")) return to_vkVoidFunction(test_vkGetPhysicalDeviceProperties2);
        if (string_eq(pName, "vkGetPhysicalDeviceFormatProperties2KHR"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceFormatProperties2);
        if (string_eq(pName, "vkGetPhysicalDeviceMemoryProperties2KHR"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceMemoryProperties2);

        if (string_eq(pName, "vkGetPhysicalDeviceQueueFamilyProperties2KHR"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceQueueFamilyProperties2);

        if (string_eq(pName, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceSparseImageFormatProperties2);

        if (string_eq(pName, "vkGetPhysicalDeviceImageFormatProperties2KHR")) {
            return to_vkVoidFunction(test_vkGetPhysicalDeviceImageFormatProperties2);
        }
    }
    if (IsInstanceExtensionEnabled(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) {
        if (string_eq(pName, "vkGetPhysicalDeviceExternalBufferPropertiesKHR"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalBufferProperties);
    }
    if (IsInstanceExtensionEnabled(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) {
        if (string_eq(pName, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalSemaphoreProperties);
    }
    if (IsInstanceExtensionEnabled(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME)) {
        if (string_eq(pName, "vkGetPhysicalDeviceExternalFencePropertiesKHR"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalFenceProperties);
    }

    // The following physical device extensions only need 1 device to support them for the ICD to export
    // them
    if (IsPhysicalDeviceExtensionAvailable(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME)) {
        if (string_eq(pName, "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR"))
            return to_vkVoidFunction(test_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR);
        if (string_eq(pName, "vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR);
        if (string_eq(pName, "vkAcquireProfilingLockKHR")) return to_vkVoidFunction(test_vkAcquireProfilingLockKHR);
        if (string_eq(pName, "vkReleaseProfilingLockKHR")) return to_vkVoidFunction(test_vkReleaseProfilingLockKHR);
    }
    if (IsPhysicalDeviceExtensionAvailable(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME)) {
        if (string_eq(pName, "vkCmdSetSampleLocationsEXT")) return to_vkVoidFunction(test_vkCmdSetSampleLocationsEXT);
        if (string_eq(pName, "vkGetPhysicalDeviceMultisamplePropertiesEXT"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceMultisamplePropertiesEXT);
    }
    if (IsPhysicalDeviceExtensionAvailable(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME)) {
        if (string_eq(pName, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT);
        if (string_eq(pName, "vkGetCalibratedTimestampsEXT")) return to_vkVoidFunction(test_vkGetCalibratedTimestampsEXT);
    }

    if (icd.icd_api_version >= VK_MAKE_API_VERSION(0, 1, 1, 0)) {
        if (string_eq(pName, "vkGetPhysicalDeviceFeatures2")) return to_vkVoidFunction(test_vkGetPhysicalDeviceFeatures2);
        if (string_eq(pName, "vkGetPhysicalDeviceProperties2")) return to_vkVoidFunction(test_vkGetPhysicalDeviceProperties2);
        if (string_eq(pName, "vkGetPhysicalDeviceFormatProperties2"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceFormatProperties2);
        if (string_eq(pName, "vkGetPhysicalDeviceMemoryProperties2"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceMemoryProperties2);

        if (string_eq(pName, "vkGetPhysicalDeviceQueueFamilyProperties2"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceQueueFamilyProperties2);

        if (string_eq(pName, "vkGetPhysicalDeviceSparseImageFormatProperties2"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceSparseImageFormatProperties2);

        if (string_eq(pName, "vkGetPhysicalDeviceImageFormatProperties2")) {
            return to_vkVoidFunction(test_vkGetPhysicalDeviceImageFormatProperties2);
        }

        if (string_eq(pName, "vkGetPhysicalDeviceExternalBufferProperties"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalBufferProperties);
        if (string_eq(pName, "vkGetPhysicalDeviceExternalSemaphoreProperties"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalSemaphoreProperties);
        if (string_eq(pName, "vkGetPhysicalDeviceExternalFenceProperties"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalFenceProperties);
    }

    if (icd.supports_tooling_info_core) {
        if (string_eq(pName, "vkGetPhysicalDeviceToolProperties")) return to_vkVoidFunction(test_vkGetPhysicalDeviceToolProperties);
    }
    if (icd.supports_tooling_info_ext) {
        if (string_eq(pName, "vkGetPhysicalDeviceToolPropertiesEXT"))
            return to_vkVoidFunction(test_vkGetPhysicalDeviceToolPropertiesEXT);
    }

    for (auto& phys_dev : icd.physical_devices) {
        for (auto& func : phys_dev.custom_physical_device_functions) {
            if (func.name == pName) {
                return to_vkVoidFunction(func.function);
            }
        }
    }
    return nullptr;
}

PFN_vkVoidFunction get_instance_func(VkInstance instance, const char* pName) {
    if (string_eq(pName, "vkDestroyInstance")) return to_vkVoidFunction(test_vkDestroyInstance);
    if (string_eq(pName, "vkEnumeratePhysicalDevices")) return to_vkVoidFunction(test_vkEnumeratePhysicalDevices);

    if (IsInstanceExtensionEnabled(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME)) {
        if (string_eq(pName, "vkEnumeratePhysicalDeviceGroupsKHR")) return to_vkVoidFunction(test_vkEnumeratePhysicalDeviceGroups);
    }

    PFN_vkVoidFunction ret_phys_dev = get_physical_device_func(instance, pName);
    if (ret_phys_dev != nullptr) return ret_phys_dev;

    PFN_vkVoidFunction ret_1_1 = get_instance_func_ver_1_1(instance, pName);
    if (ret_1_1 != nullptr) return ret_1_1;

    PFN_vkVoidFunction ret_wsi = get_instance_func_wsi(instance, pName);
    if (ret_wsi != nullptr) return ret_wsi;

    for (auto& func : icd.custom_instance_functions) {
        if (func.name == pName) {
            return to_vkVoidFunction(func.function);
        }
    }

    return nullptr;
}

bool should_check(std::vector<const char*> const& exts, VkDevice device, const char* ext_name) {
    if (device == NULL) return true;  // always look if device is NULL
    for (auto const& ext : exts) {
        if (string_eq(ext, ext_name)) {
            return true;
        }
    }
    return false;
}

PFN_vkVoidFunction get_device_func(VkDevice device, const char* pName) {
    TestICD::FindDevice fd{};
    DeviceCreateInfo create_info{};
    if (device != nullptr) {
        fd = icd.lookup_device(device);
        if (!fd.found) return NULL;
        create_info = icd.physical_devices.at(fd.phys_dev_index).device_create_infos.at(fd.dev_index);
    }
    if (string_eq(pName, "vkCreateCommandPool")) return to_vkVoidFunction(test_vkCreateCommandPool);
    if (string_eq(pName, "vkAllocateCommandBuffers")) return to_vkVoidFunction(test_vkAllocateCommandBuffers);
    if (string_eq(pName, "vkDestroyCommandPool")) return to_vkVoidFunction(test_vkDestroyCommandPool);
    if (string_eq(pName, "vkGetDeviceQueue")) return to_vkVoidFunction(test_vkGetDeviceQueue);
    if (string_eq(pName, "vkDestroyDevice")) return to_vkVoidFunction(test_vkDestroyDevice);
    if (should_check(create_info.enabled_extensions, device, "VK_KHR_swapchain")) {
        if (string_eq(pName, "vkCreateSwapchainKHR")) return to_vkVoidFunction(test_vkCreateSwapchainKHR);
        if (string_eq(pName, "vkGetSwapchainImagesKHR")) return to_vkVoidFunction(test_vkGetSwapchainImagesKHR);
        if (string_eq(pName, "vkDestroySwapchainKHR")) return to_vkVoidFunction(test_vkDestroySwapchainKHR);

        if (icd.icd_api_version >= VK_API_VERSION_1_1 && string_eq(pName, "vkGetDeviceGroupSurfacePresentModesKHR"))
            return to_vkVoidFunction(test_vkGetDeviceGroupSurfacePresentModesKHR);
    }
    if (should_check(create_info.enabled_extensions, device, "VK_KHR_display_swapchain")) {
        if (string_eq(pName, "vkCreateSharedSwapchainsKHR")) return to_vkVoidFunction(test_vkCreateSharedSwapchainsKHR);
    }
    if (should_check(create_info.enabled_extensions, device, "VK_KHR_device_group")) {
        if (string_eq(pName, "vkGetDeviceGroupSurfacePresentModesKHR"))
            return to_vkVoidFunction(test_vkGetDeviceGroupSurfacePresentModesKHR);
    }
    if (should_check(create_info.enabled_extensions, device, "VK_EXT_debug_marker")) {
        if (string_eq(pName, "vkDebugMarkerSetObjectTagEXT")) return to_vkVoidFunction(test_vkDebugMarkerSetObjectTagEXT);
        if (string_eq(pName, "vkDebugMarkerSetObjectNameEXT")) return to_vkVoidFunction(test_vkDebugMarkerSetObjectNameEXT);
        if (string_eq(pName, "vkCmdDebugMarkerBeginEXT")) return to_vkVoidFunction(test_vkCmdDebugMarkerBeginEXT);
        if (string_eq(pName, "vkCmdDebugMarkerEndEXT")) return to_vkVoidFunction(test_vkCmdDebugMarkerEndEXT);
        if (string_eq(pName, "vkCmdDebugMarkerInsertEXT")) return to_vkVoidFunction(test_vkCmdDebugMarkerInsertEXT);
    }
    if (IsInstanceExtensionEnabled("VK_EXT_debug_utils")) {
        if (string_eq(pName, "vkSetDebugUtilsObjectNameEXT")) return to_vkVoidFunction(test_vkSetDebugUtilsObjectNameEXT);
        if (string_eq(pName, "vkSetDebugUtilsObjectTagEXT")) return to_vkVoidFunction(test_vkSetDebugUtilsObjectTagEXT);
        if (string_eq(pName, "vkQueueBeginDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueBeginDebugUtilsLabelEXT);
        if (string_eq(pName, "vkQueueEndDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueEndDebugUtilsLabelEXT);
        if (string_eq(pName, "vkQueueInsertDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueInsertDebugUtilsLabelEXT);
        if (string_eq(pName, "vkCmdBeginDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdBeginDebugUtilsLabelEXT);
        if (string_eq(pName, "vkCmdEndDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdEndDebugUtilsLabelEXT);
        if (string_eq(pName, "vkCmdInsertDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdInsertDebugUtilsLabelEXT);
    }
    // look for device functions setup from a test
    for (const auto& phys_dev : icd.physical_devices) {
        for (const auto& function : phys_dev.known_device_functions) {
            if (function.name == pName) {
                return to_vkVoidFunction(function.function);
            }
        }
    }
    return nullptr;
}

VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_vkGetInstanceProcAddr(VkInstance instance, const char* pName) {
    return get_instance_func(instance, pName);
}

VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_vkGetDeviceProcAddr(VkDevice device, const char* pName) {
    return get_device_func(device, pName);
}

PFN_vkVoidFunction base_get_instance_proc_addr(VkInstance instance, const char* pName) {
    if (pName == nullptr) return nullptr;
    if (instance == NULL) {
#if TEST_ICD_EXPOSE_VERSION_7
        if (string_eq(pName, "vk_icdNegotiateLoaderICDInterfaceVersion"))
            return icd.exposes_vk_icdNegotiateLoaderICDInterfaceVersion
                       ? to_vkVoidFunction(vk_icdNegotiateLoaderICDInterfaceVersion)
                       : NULL;
#if TEST_ICD_EXPORT_ICD_GPDPA
        if (string_eq(pName, "vk_icdGetPhysicalDeviceProcAddr"))
            return icd.exposes_vk_icdGetPhysicalDeviceProcAddr ? to_vkVoidFunction(vk_icdGetPhysicalDeviceProcAddr) : NULL;
#endif
#if defined(WIN32) && TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES
        if (string_eq(pName, "vk_icdEnumerateAdapterPhysicalDevices"))
            return icd.exposes_vk_icdEnumerateAdapterPhysicalDevices ? to_vkVoidFunction(vk_icdEnumerateAdapterPhysicalDevices)
                                                                     : NULL;
#endif  // defined(WIN32)
#endif  // TEST_ICD_EXPOSE_VERSION_7

        if (string_eq(pName, "vkGetInstanceProcAddr")) return to_vkVoidFunction(test_vkGetInstanceProcAddr);
        if (string_eq(pName, "vkEnumerateInstanceExtensionProperties"))
            return icd.exposes_vkEnumerateInstanceExtensionProperties
                       ? to_vkVoidFunction(test_vkEnumerateInstanceExtensionProperties)
                       : NULL;
        if (string_eq(pName, "vkEnumerateInstanceLayerProperties"))
            return to_vkVoidFunction(test_vkEnumerateInstanceLayerProperties);
        if (string_eq(pName, "vkEnumerateInstanceVersion"))
            return icd.can_query_vkEnumerateInstanceVersion ? to_vkVoidFunction(test_vkEnumerateInstanceVersion) : nullptr;
        if (string_eq(pName, "vkCreateInstance")) return to_vkVoidFunction(test_vkCreateInstance);
    }
    if (string_eq(pName, "vkGetDeviceProcAddr")) return to_vkVoidFunction(test_vkGetDeviceProcAddr);

    auto instance_func_return = get_instance_func(instance, pName);
    if (instance_func_return != nullptr) return instance_func_return;

    // Need to return function pointers for device extensions
    auto device_func_return = get_device_func(nullptr, pName);
    if (device_func_return != nullptr) return device_func_return;
    return nullptr;
}

// Exported functions
extern "C" {
#if TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION
FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) {
    return test_vk_icdNegotiateLoaderICDInterfaceVersion(pSupportedVersion);
}
#endif  // TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION

#if TEST_ICD_EXPORT_ICD_GPDPA
FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName) {
    return get_physical_device_func(instance, pName);
}
#endif  // TEST_ICD_EXPORT_ICD_GPDPA

#if TEST_ICD_EXPORT_ICD_GIPA
FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName) {
    if (icd.called_vk_icd_gipa == CalledICDGIPA::not_called) icd.called_vk_icd_gipa = CalledICDGIPA::vk_icd_gipa;
    return base_get_instance_proc_addr(instance, pName);
}
#else   // !TEST_ICD_EXPORT_ICD_GIPA
FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* pName) {
    if (icd.called_vk_icd_gipa == CalledICDGIPA::not_called) icd.called_vk_icd_gipa = CalledICDGIPA::vk_gipa;
    return base_get_instance_proc_addr(instance, pName);
}
FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
                                                                 const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) {
    return test_vkCreateInstance(pCreateInfo, pAllocator, pInstance);
}
FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char* pLayerName,
                                                                                       uint32_t* pPropertyCount,
                                                                                       VkExtensionProperties* pProperties) {
    return test_vkEnumerateInstanceExtensionProperties(pLayerName, pPropertyCount, pProperties);
}
#endif  // TEST_ICD_EXPORT_ICD_GIPA

#if TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES
#if defined(WIN32)
FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID,
                                                                                      uint32_t* pPhysicalDeviceCount,
                                                                                      VkPhysicalDevice* pPhysicalDevices) {
    return test_vk_icdEnumerateAdapterPhysicalDevices(instance, adapterLUID, pPhysicalDeviceCount, pPhysicalDevices);
}
#endif  // defined(WIN32)
#endif  // TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES

}  // extern "C"
