15db71995Sopenharmony_ci/*
25db71995Sopenharmony_ci * Copyright (c) 2021-2022 The Khronos Group Inc.
35db71995Sopenharmony_ci * Copyright (c) 2021-2022 Valve Corporation
45db71995Sopenharmony_ci * Copyright (c) 2021-2022 LunarG, Inc.
55db71995Sopenharmony_ci *
65db71995Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy
75db71995Sopenharmony_ci * of this software and/or associated documentation files (the "Materials"), to
85db71995Sopenharmony_ci * deal in the Materials without restriction, including without limitation the
95db71995Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
105db71995Sopenharmony_ci * sell copies of the Materials, and to permit persons to whom the Materials are
115db71995Sopenharmony_ci * furnished to do so, subject to the following conditions:
125db71995Sopenharmony_ci *
135db71995Sopenharmony_ci * The above copyright notice(s) and this permission notice shall be included in
145db71995Sopenharmony_ci * all copies or substantial portions of the Materials.
155db71995Sopenharmony_ci *
165db71995Sopenharmony_ci * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
175db71995Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
185db71995Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
195db71995Sopenharmony_ci *
205db71995Sopenharmony_ci * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
215db71995Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
225db71995Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
235db71995Sopenharmony_ci * USE OR OTHER DEALINGS IN THE MATERIALS.
245db71995Sopenharmony_ci *
255db71995Sopenharmony_ci * Author: Charles Giessen <charles@lunarg.com>
265db71995Sopenharmony_ci */
275db71995Sopenharmony_ci
285db71995Sopenharmony_ci#include "test_layer.h"
295db71995Sopenharmony_ci
305db71995Sopenharmony_ci#include "vk_dispatch_table_helper.h"
315db71995Sopenharmony_ci
325db71995Sopenharmony_ci// export the enumeration functions instance|device+layer|extension
335db71995Sopenharmony_ci#if !defined(TEST_LAYER_EXPORT_ENUMERATE_FUNCTIONS)
345db71995Sopenharmony_ci#define TEST_LAYER_EXPORT_ENUMERATE_FUNCTIONS 0
355db71995Sopenharmony_ci#endif
365db71995Sopenharmony_ci
375db71995Sopenharmony_ci// export test_layer_GetInstanceProcAddr
385db71995Sopenharmony_ci#if !defined(TEST_LAYER_EXPORT_LAYER_NAMED_GIPA)
395db71995Sopenharmony_ci#define TEST_LAYER_EXPORT_LAYER_NAMED_GIPA 0
405db71995Sopenharmony_ci#endif
415db71995Sopenharmony_ci
425db71995Sopenharmony_ci// export test_override_GetInstanceProcAddr
435db71995Sopenharmony_ci#if !defined(TEST_LAYER_EXPORT_OVERRIDE_GIPA)
445db71995Sopenharmony_ci#define TEST_LAYER_EXPORT_OVERRIDE_GIPA 0
455db71995Sopenharmony_ci#endif
465db71995Sopenharmony_ci
475db71995Sopenharmony_ci// export vkGetInstanceProcAddr
485db71995Sopenharmony_ci#if !defined(TEST_LAYER_EXPORT_LAYER_VK_GIPA)
495db71995Sopenharmony_ci#define TEST_LAYER_EXPORT_LAYER_VK_GIPA 0
505db71995Sopenharmony_ci#endif
515db71995Sopenharmony_ci
525db71995Sopenharmony_ci// export test_layer_GetDeviceProcAddr
535db71995Sopenharmony_ci#if !defined(TEST_LAYER_EXPORT_LAYER_NAMED_GDPA)
545db71995Sopenharmony_ci#define TEST_LAYER_EXPORT_LAYER_NAMED_GDPA 0
555db71995Sopenharmony_ci#endif
565db71995Sopenharmony_ci
575db71995Sopenharmony_ci// export test_override_GetDeviceProcAddr
585db71995Sopenharmony_ci#if !defined(TEST_LAYER_EXPORT_OVERRIDE_GDPA)
595db71995Sopenharmony_ci#define TEST_LAYER_EXPORT_OVERRIDE_GDPA 0
605db71995Sopenharmony_ci#endif
615db71995Sopenharmony_ci
625db71995Sopenharmony_ci// export vkGetDeviceProcAddr
635db71995Sopenharmony_ci#if !defined(TEST_LAYER_EXPORT_LAYER_VK_GDPA)
645db71995Sopenharmony_ci#define TEST_LAYER_EXPORT_LAYER_VK_GDPA 0
655db71995Sopenharmony_ci#endif
665db71995Sopenharmony_ci
675db71995Sopenharmony_ci// export vk_layerGetPhysicalDeviceProcAddr
685db71995Sopenharmony_ci#if !defined(TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR)
695db71995Sopenharmony_ci#define TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR 0
705db71995Sopenharmony_ci#endif
715db71995Sopenharmony_ci
725db71995Sopenharmony_ci// export vkNegotiateLoaderLayerInterfaceVersion
735db71995Sopenharmony_ci#if !defined(LAYER_EXPORT_NEGOTIATE_LOADER_LAYER_INTERFACE_VERSION)
745db71995Sopenharmony_ci#define LAYER_EXPORT_NEGOTIATE_LOADER_LAYER_INTERFACE_VERSION 0
755db71995Sopenharmony_ci#endif
765db71995Sopenharmony_ci
775db71995Sopenharmony_ci#if !defined(TEST_LAYER_NAME)
785db71995Sopenharmony_ci#define TEST_LAYER_NAME "VK_LAYER_LunarG_test_layer"
795db71995Sopenharmony_ci#endif
805db71995Sopenharmony_ci
815db71995Sopenharmony_ciTestLayer layer;
825db71995Sopenharmony_ciextern "C" {
835db71995Sopenharmony_ciFRAMEWORK_EXPORT TestLayer* get_test_layer_func() { return &layer; }
845db71995Sopenharmony_ciFRAMEWORK_EXPORT TestLayer* reset_layer_func() {
855db71995Sopenharmony_ci    layer.~TestLayer();
865db71995Sopenharmony_ci    return new (&layer) TestLayer();
875db71995Sopenharmony_ci}
885db71995Sopenharmony_ci}
895db71995Sopenharmony_ci
905db71995Sopenharmony_cibool IsInstanceExtensionSupported(const char* extension_name) {
915db71995Sopenharmony_ci    return layer.instance_extensions.end() !=
925db71995Sopenharmony_ci           std::find_if(layer.instance_extensions.begin(), layer.instance_extensions.end(),
935db71995Sopenharmony_ci                        [extension_name](Extension const& ext) { return string_eq(&ext.extensionName[0], extension_name); });
945db71995Sopenharmony_ci}
955db71995Sopenharmony_ci
965db71995Sopenharmony_cibool IsInstanceExtensionEnabled(const char* extension_name) {
975db71995Sopenharmony_ci    return layer.enabled_instance_extensions.end() !=
985db71995Sopenharmony_ci           std::find_if(layer.enabled_instance_extensions.begin(), layer.enabled_instance_extensions.end(),
995db71995Sopenharmony_ci                        [extension_name](Extension const& ext) { return string_eq(&ext.extensionName[0], extension_name); });
1005db71995Sopenharmony_ci}
1015db71995Sopenharmony_ci
1025db71995Sopenharmony_cibool IsDeviceExtensionAvailable(VkDevice dev, const char* extension_name) {
1035db71995Sopenharmony_ci    for (auto& device : layer.created_devices) {
1045db71995Sopenharmony_ci        if ((dev == VK_NULL_HANDLE || device.device_handle == dev) &&
1055db71995Sopenharmony_ci            device.enabled_extensions.end() !=
1065db71995Sopenharmony_ci                std::find_if(device.enabled_extensions.begin(), device.enabled_extensions.end(),
1075db71995Sopenharmony_ci                             [extension_name](Extension const& ext) { return ext.extensionName == extension_name; })) {
1085db71995Sopenharmony_ci            return true;
1095db71995Sopenharmony_ci        }
1105db71995Sopenharmony_ci    }
1115db71995Sopenharmony_ci    return false;
1125db71995Sopenharmony_ci}
1135db71995Sopenharmony_ci
1145db71995Sopenharmony_ciVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_instance_func(VkInstance instance, const char* pName);
1155db71995Sopenharmony_ci
1165db71995Sopenharmony_ciVkLayerInstanceCreateInfo* get_chain_info(const VkInstanceCreateInfo* pCreateInfo, VkLayerFunction func) {
1175db71995Sopenharmony_ci    VkLayerInstanceCreateInfo* chain_info = (VkLayerInstanceCreateInfo*)pCreateInfo->pNext;
1185db71995Sopenharmony_ci    while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO && chain_info->function == func)) {
1195db71995Sopenharmony_ci        chain_info = (VkLayerInstanceCreateInfo*)chain_info->pNext;
1205db71995Sopenharmony_ci    }
1215db71995Sopenharmony_ci    assert(chain_info != NULL);
1225db71995Sopenharmony_ci    return chain_info;
1235db71995Sopenharmony_ci}
1245db71995Sopenharmony_ci
1255db71995Sopenharmony_ciVkLayerDeviceCreateInfo* get_chain_info(const VkDeviceCreateInfo* pCreateInfo, VkLayerFunction func) {
1265db71995Sopenharmony_ci    VkLayerDeviceCreateInfo* chain_info = (VkLayerDeviceCreateInfo*)pCreateInfo->pNext;
1275db71995Sopenharmony_ci    while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO && chain_info->function == func)) {
1285db71995Sopenharmony_ci        chain_info = (VkLayerDeviceCreateInfo*)chain_info->pNext;
1295db71995Sopenharmony_ci    }
1305db71995Sopenharmony_ci    assert(chain_info != NULL);
1315db71995Sopenharmony_ci    return chain_info;
1325db71995Sopenharmony_ci}
1335db71995Sopenharmony_ci
1345db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceLayerProperties(uint32_t*, VkLayerProperties*) { return VK_SUCCESS; }
1355db71995Sopenharmony_ci
1365db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceExtensionProperties(const char* pLayerName, uint32_t* pPropertyCount,
1375db71995Sopenharmony_ci                                                                           VkExtensionProperties* pProperties) {
1385db71995Sopenharmony_ci    if (pPropertyCount == nullptr) {
1395db71995Sopenharmony_ci        return VK_INCOMPLETE;
1405db71995Sopenharmony_ci    }
1415db71995Sopenharmony_ci    if (pLayerName && string_eq(pLayerName, TEST_LAYER_NAME)) {
1425db71995Sopenharmony_ci        if (pProperties) {
1435db71995Sopenharmony_ci            if (*pPropertyCount < layer.injected_instance_extensions.size()) {
1445db71995Sopenharmony_ci                return VK_INCOMPLETE;
1455db71995Sopenharmony_ci            }
1465db71995Sopenharmony_ci            for (size_t i = 0; i < layer.injected_instance_extensions.size(); i++) {
1475db71995Sopenharmony_ci                pProperties[i] = layer.injected_instance_extensions.at(i).get();
1485db71995Sopenharmony_ci            }
1495db71995Sopenharmony_ci            *pPropertyCount = static_cast<uint32_t>(layer.injected_instance_extensions.size());
1505db71995Sopenharmony_ci        } else {
1515db71995Sopenharmony_ci            *pPropertyCount = static_cast<uint32_t>(layer.injected_instance_extensions.size());
1525db71995Sopenharmony_ci        }
1535db71995Sopenharmony_ci        return VK_SUCCESS;
1545db71995Sopenharmony_ci    }
1555db71995Sopenharmony_ci
1565db71995Sopenharmony_ci    uint32_t hardware_prop_count = 0;
1575db71995Sopenharmony_ci    if (pProperties) {
1585db71995Sopenharmony_ci        hardware_prop_count = *pPropertyCount - static_cast<uint32_t>(layer.injected_instance_extensions.size());
1595db71995Sopenharmony_ci    }
1605db71995Sopenharmony_ci
1615db71995Sopenharmony_ci    VkResult res =
1625db71995Sopenharmony_ci        layer.instance_dispatch_table.EnumerateInstanceExtensionProperties(pLayerName, &hardware_prop_count, pProperties);
1635db71995Sopenharmony_ci    if (res < 0) {
1645db71995Sopenharmony_ci        return res;
1655db71995Sopenharmony_ci    }
1665db71995Sopenharmony_ci
1675db71995Sopenharmony_ci    if (pProperties == nullptr) {
1685db71995Sopenharmony_ci        *pPropertyCount = hardware_prop_count + static_cast<uint32_t>(layer.injected_instance_extensions.size());
1695db71995Sopenharmony_ci    } else {
1705db71995Sopenharmony_ci        if (hardware_prop_count + layer.injected_instance_extensions.size() > *pPropertyCount) {
1715db71995Sopenharmony_ci            *pPropertyCount = hardware_prop_count;
1725db71995Sopenharmony_ci            return VK_INCOMPLETE;
1735db71995Sopenharmony_ci        }
1745db71995Sopenharmony_ci        for (size_t i = 0; i < layer.injected_instance_extensions.size(); i++) {
1755db71995Sopenharmony_ci            pProperties[hardware_prop_count + i] = layer.injected_instance_extensions.at(i).get();
1765db71995Sopenharmony_ci        }
1775db71995Sopenharmony_ci        *pPropertyCount = hardware_prop_count + static_cast<uint32_t>(layer.injected_instance_extensions.size());
1785db71995Sopenharmony_ci    }
1795db71995Sopenharmony_ci    return res;
1805db71995Sopenharmony_ci}
1815db71995Sopenharmony_ci
1825db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceLayerProperties(VkPhysicalDevice, uint32_t*, VkLayerProperties*) {
1835db71995Sopenharmony_ci    return VK_SUCCESS;
1845db71995Sopenharmony_ci}
1855db71995Sopenharmony_ci
1865db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char* pLayerName,
1875db71995Sopenharmony_ci                                                                         uint32_t* pPropertyCount,
1885db71995Sopenharmony_ci                                                                         VkExtensionProperties* pProperties) {
1895db71995Sopenharmony_ci    if (pPropertyCount == nullptr) {
1905db71995Sopenharmony_ci        return VK_INCOMPLETE;
1915db71995Sopenharmony_ci    }
1925db71995Sopenharmony_ci
1935db71995Sopenharmony_ci    if (pLayerName && string_eq(pLayerName, TEST_LAYER_NAME)) {
1945db71995Sopenharmony_ci        if (pProperties) {
1955db71995Sopenharmony_ci            if (*pPropertyCount < static_cast<uint32_t>(layer.injected_device_extensions.size())) {
1965db71995Sopenharmony_ci                return VK_INCOMPLETE;
1975db71995Sopenharmony_ci            }
1985db71995Sopenharmony_ci            for (size_t i = 0; i < layer.injected_device_extensions.size(); i++) {
1995db71995Sopenharmony_ci                pProperties[i] = layer.injected_device_extensions.at(i).get();
2005db71995Sopenharmony_ci            }
2015db71995Sopenharmony_ci            *pPropertyCount = static_cast<uint32_t>(layer.injected_device_extensions.size());
2025db71995Sopenharmony_ci        } else {
2035db71995Sopenharmony_ci            *pPropertyCount = static_cast<uint32_t>(layer.injected_device_extensions.size());
2045db71995Sopenharmony_ci        }
2055db71995Sopenharmony_ci        return VK_SUCCESS;
2065db71995Sopenharmony_ci    }
2075db71995Sopenharmony_ci
2085db71995Sopenharmony_ci    uint32_t hardware_prop_count = 0;
2095db71995Sopenharmony_ci    if (pProperties) {
2105db71995Sopenharmony_ci        hardware_prop_count = *pPropertyCount - static_cast<uint32_t>(layer.injected_device_extensions.size());
2115db71995Sopenharmony_ci    }
2125db71995Sopenharmony_ci
2135db71995Sopenharmony_ci    VkResult res = layer.instance_dispatch_table.EnumerateDeviceExtensionProperties(physicalDevice, pLayerName,
2145db71995Sopenharmony_ci                                                                                    &hardware_prop_count, pProperties);
2155db71995Sopenharmony_ci    if (res < 0) {
2165db71995Sopenharmony_ci        return res;
2175db71995Sopenharmony_ci    }
2185db71995Sopenharmony_ci
2195db71995Sopenharmony_ci    if (pProperties == nullptr) {
2205db71995Sopenharmony_ci        *pPropertyCount = hardware_prop_count + static_cast<uint32_t>(layer.injected_device_extensions.size());
2215db71995Sopenharmony_ci    } else {
2225db71995Sopenharmony_ci        if (hardware_prop_count + layer.injected_device_extensions.size() > *pPropertyCount) {
2235db71995Sopenharmony_ci            *pPropertyCount = hardware_prop_count;
2245db71995Sopenharmony_ci            return VK_INCOMPLETE;
2255db71995Sopenharmony_ci        }
2265db71995Sopenharmony_ci        for (size_t i = 0; i < layer.injected_device_extensions.size(); i++) {
2275db71995Sopenharmony_ci            pProperties[hardware_prop_count + i] = layer.injected_device_extensions.at(i).get();
2285db71995Sopenharmony_ci        }
2295db71995Sopenharmony_ci        *pPropertyCount = hardware_prop_count + static_cast<uint32_t>(layer.injected_device_extensions.size());
2305db71995Sopenharmony_ci    }
2315db71995Sopenharmony_ci    return res;
2325db71995Sopenharmony_ci}
2335db71995Sopenharmony_ci
2345db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceVersion(uint32_t* pApiVersion) {
2355db71995Sopenharmony_ci    if (pApiVersion != nullptr) {
2365db71995Sopenharmony_ci        *pApiVersion = VK_API_VERSION_1_0;
2375db71995Sopenharmony_ci    }
2385db71995Sopenharmony_ci    return VK_SUCCESS;
2395db71995Sopenharmony_ci}
2405db71995Sopenharmony_ci
2415db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL test_vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
2425db71995Sopenharmony_ci                                                     const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) {
2435db71995Sopenharmony_ci    VkLayerInstanceCreateInfo* chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
2445db71995Sopenharmony_ci
2455db71995Sopenharmony_ci    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
2465db71995Sopenharmony_ci    PFN_vk_icdGetPhysicalDeviceProcAddr fpGetPhysicalDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetPhysicalDeviceProcAddr;
2475db71995Sopenharmony_ci    PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
2485db71995Sopenharmony_ci    if (fpCreateInstance == NULL) {
2495db71995Sopenharmony_ci        return VK_ERROR_INITIALIZATION_FAILED;
2505db71995Sopenharmony_ci    }
2515db71995Sopenharmony_ci
2525db71995Sopenharmony_ci    if (layer.call_create_device_while_create_device_is_called) {
2535db71995Sopenharmony_ci        auto* createDeviceCallback = get_chain_info(pCreateInfo, VK_LOADER_LAYER_CREATE_DEVICE_CALLBACK);
2545db71995Sopenharmony_ci        layer.callback_vkCreateDevice = createDeviceCallback->u.layerDevice.pfnLayerCreateDevice;
2555db71995Sopenharmony_ci        layer.callback_vkDestroyDevice = createDeviceCallback->u.layerDevice.pfnLayerDestroyDevice;
2565db71995Sopenharmony_ci    }
2575db71995Sopenharmony_ci
2585db71995Sopenharmony_ci    // Advance the link info for the next element of the chain
2595db71995Sopenharmony_ci    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
2605db71995Sopenharmony_ci    layer.next_vkGetInstanceProcAddr = fpGetInstanceProcAddr;
2615db71995Sopenharmony_ci
2625db71995Sopenharmony_ci    bool use_modified_create_info = false;
2635db71995Sopenharmony_ci    VkInstanceCreateInfo instance_create_info{};
2645db71995Sopenharmony_ci    VkApplicationInfo application_info{};
2655db71995Sopenharmony_ci    if (pCreateInfo) {
2665db71995Sopenharmony_ci        instance_create_info = *pCreateInfo;
2675db71995Sopenharmony_ci        if (pCreateInfo->pApplicationInfo) {
2685db71995Sopenharmony_ci            application_info = *pCreateInfo->pApplicationInfo;
2695db71995Sopenharmony_ci        }
2705db71995Sopenharmony_ci    }
2715db71995Sopenharmony_ci
2725db71995Sopenharmony_ci    // If the test needs to modify the api version, do it before we call down the chain
2735db71995Sopenharmony_ci    if (layer.alter_api_version != VK_API_VERSION_1_0 && pCreateInfo && pCreateInfo->pApplicationInfo) {
2745db71995Sopenharmony_ci        application_info.apiVersion = layer.alter_api_version;
2755db71995Sopenharmony_ci        instance_create_info.pApplicationInfo = &application_info;
2765db71995Sopenharmony_ci        use_modified_create_info = true;
2775db71995Sopenharmony_ci    }
2785db71995Sopenharmony_ci    const VkInstanceCreateInfo* create_info_pointer = use_modified_create_info ? &instance_create_info : pCreateInfo;
2795db71995Sopenharmony_ci
2805db71995Sopenharmony_ci    if (layer.clobber_pInstance) {
2815db71995Sopenharmony_ci        memset(*pInstance, 0, 128);
2825db71995Sopenharmony_ci    }
2835db71995Sopenharmony_ci
2845db71995Sopenharmony_ci    // Continue call down the chain
2855db71995Sopenharmony_ci    VkResult result = fpCreateInstance(create_info_pointer, pAllocator, pInstance);
2865db71995Sopenharmony_ci    if (result != VK_SUCCESS) {
2875db71995Sopenharmony_ci        return result;
2885db71995Sopenharmony_ci    }
2895db71995Sopenharmony_ci    layer.instance_handle = *pInstance;
2905db71995Sopenharmony_ci    if (layer.use_gipa_GetPhysicalDeviceProcAddr) {
2915db71995Sopenharmony_ci        layer.next_GetPhysicalDeviceProcAddr =
2925db71995Sopenharmony_ci            reinterpret_cast<PFN_GetPhysicalDeviceProcAddr>(fpGetInstanceProcAddr(*pInstance, "vk_layerGetPhysicalDeviceProcAddr"));
2935db71995Sopenharmony_ci    } else {
2945db71995Sopenharmony_ci        layer.next_GetPhysicalDeviceProcAddr = fpGetPhysicalDeviceProcAddr;
2955db71995Sopenharmony_ci    }
2965db71995Sopenharmony_ci    // Init layer's dispatch table using GetInstanceProcAddr of
2975db71995Sopenharmony_ci    // next layer in the chain.
2985db71995Sopenharmony_ci    layer_init_instance_dispatch_table(layer.instance_handle, &layer.instance_dispatch_table, fpGetInstanceProcAddr);
2995db71995Sopenharmony_ci
3005db71995Sopenharmony_ci    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
3015db71995Sopenharmony_ci        layer.enabled_instance_extensions.push_back({pCreateInfo->ppEnabledExtensionNames[i]});
3025db71995Sopenharmony_ci    }
3035db71995Sopenharmony_ci
3045db71995Sopenharmony_ci    if (layer.create_instance_callback) result = layer.create_instance_callback(layer);
3055db71995Sopenharmony_ci
3065db71995Sopenharmony_ci    for (auto& func : layer.custom_physical_device_interception_functions) {
3075db71995Sopenharmony_ci        auto next_func = layer.next_GetPhysicalDeviceProcAddr(*pInstance, func.name.c_str());
3085db71995Sopenharmony_ci        layer.custom_dispatch_functions.at(func.name.c_str()) = next_func;
3095db71995Sopenharmony_ci    }
3105db71995Sopenharmony_ci
3115db71995Sopenharmony_ci    for (auto& func : layer.custom_device_interception_functions) {
3125db71995Sopenharmony_ci        auto next_func = layer.next_vkGetInstanceProcAddr(*pInstance, func.name.c_str());
3135db71995Sopenharmony_ci        layer.custom_dispatch_functions.at(func.name.c_str()) = next_func;
3145db71995Sopenharmony_ci    }
3155db71995Sopenharmony_ci
3165db71995Sopenharmony_ci    if (layer.do_spurious_allocations_in_create_instance && pAllocator && pAllocator->pfnAllocation) {
3175db71995Sopenharmony_ci        layer.spurious_instance_memory_allocation =
3185db71995Sopenharmony_ci            pAllocator->pfnAllocation(pAllocator->pUserData, 100, 8, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
3195db71995Sopenharmony_ci        if (layer.spurious_instance_memory_allocation == nullptr) {
3205db71995Sopenharmony_ci            return VK_ERROR_OUT_OF_HOST_MEMORY;
3215db71995Sopenharmony_ci        }
3225db71995Sopenharmony_ci    }
3235db71995Sopenharmony_ci
3245db71995Sopenharmony_ci    if (!layer.make_spurious_log_in_create_instance.empty()) {
3255db71995Sopenharmony_ci        auto* chain = reinterpret_cast<const VkBaseInStructure*>(pCreateInfo->pNext);
3265db71995Sopenharmony_ci        while (chain) {
3275db71995Sopenharmony_ci            if (chain->sType == VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) {
3285db71995Sopenharmony_ci                auto* debug_messenger = reinterpret_cast<const VkDebugUtilsMessengerCreateInfoEXT*>(chain);
3295db71995Sopenharmony_ci                VkDebugUtilsMessengerCallbackDataEXT data{};
3305db71995Sopenharmony_ci                data.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
3315db71995Sopenharmony_ci                data.pMessage = layer.make_spurious_log_in_create_instance.c_str();
3325db71995Sopenharmony_ci                debug_messenger->pfnUserCallback(VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT,
3335db71995Sopenharmony_ci                                                 VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &data, debug_messenger->pUserData);
3345db71995Sopenharmony_ci            }
3355db71995Sopenharmony_ci
3365db71995Sopenharmony_ci            chain = chain->pNext;
3375db71995Sopenharmony_ci        }
3385db71995Sopenharmony_ci    }
3395db71995Sopenharmony_ci
3405db71995Sopenharmony_ci    if (layer.buggy_query_of_vkCreateDevice) {
3415db71995Sopenharmony_ci        layer.instance_dispatch_table.CreateDevice =
3425db71995Sopenharmony_ci            reinterpret_cast<PFN_vkCreateDevice>(fpGetInstanceProcAddr(nullptr, "vkCreateDevice"));
3435db71995Sopenharmony_ci    }
3445db71995Sopenharmony_ci
3455db71995Sopenharmony_ci    if (layer.call_create_device_while_create_device_is_called) {
3465db71995Sopenharmony_ci        uint32_t phys_dev_count = 0;
3475db71995Sopenharmony_ci        result = layer.instance_dispatch_table.EnumeratePhysicalDevices(layer.instance_handle, &phys_dev_count, nullptr);
3485db71995Sopenharmony_ci        if (result != VK_SUCCESS) {
3495db71995Sopenharmony_ci            return result;
3505db71995Sopenharmony_ci        }
3515db71995Sopenharmony_ci        layer.queried_physical_devices.resize(phys_dev_count);
3525db71995Sopenharmony_ci        result = layer.instance_dispatch_table.EnumeratePhysicalDevices(layer.instance_handle, &phys_dev_count,
3535db71995Sopenharmony_ci                                                                        layer.queried_physical_devices.data());
3545db71995Sopenharmony_ci        if (result != VK_SUCCESS) {
3555db71995Sopenharmony_ci            return result;
3565db71995Sopenharmony_ci        }
3575db71995Sopenharmony_ci    }
3585db71995Sopenharmony_ci
3595db71995Sopenharmony_ci    if (layer.check_if_EnumDevExtProps_is_same_as_queried_function) {
3605db71995Sopenharmony_ci        auto chain_info_EnumDeviceExtProps = reinterpret_cast<PFN_vkEnumerateDeviceExtensionProperties>(
3615db71995Sopenharmony_ci            fpGetInstanceProcAddr(layer.instance_handle, "vkEnumerateDeviceExtensionProperties"));
3625db71995Sopenharmony_ci        if (chain_info_EnumDeviceExtProps != layer.instance_dispatch_table.EnumerateDeviceExtensionProperties) {
3635db71995Sopenharmony_ci            return VK_ERROR_INITIALIZATION_FAILED;
3645db71995Sopenharmony_ci        }
3655db71995Sopenharmony_ci    }
3665db71995Sopenharmony_ci
3675db71995Sopenharmony_ci    return result;
3685db71995Sopenharmony_ci}
3695db71995Sopenharmony_ci
3705db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL test_override_vkCreateInstance(const VkInstanceCreateInfo*, const VkAllocationCallbacks*,
3715db71995Sopenharmony_ci                                                              VkInstance*) {
3725db71995Sopenharmony_ci    return VK_ERROR_INVALID_SHADER_NV;
3735db71995Sopenharmony_ci}
3745db71995Sopenharmony_ci
3755db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator) {
3765db71995Sopenharmony_ci    if (layer.spurious_instance_memory_allocation && pAllocator && pAllocator->pfnFree) {
3775db71995Sopenharmony_ci        pAllocator->pfnFree(pAllocator->pUserData, layer.spurious_instance_memory_allocation);
3785db71995Sopenharmony_ci        layer.spurious_instance_memory_allocation = nullptr;
3795db71995Sopenharmony_ci    }
3805db71995Sopenharmony_ci
3815db71995Sopenharmony_ci    layer.instance_dispatch_table.DestroyInstance(instance, pAllocator);
3825db71995Sopenharmony_ci}
3835db71995Sopenharmony_ci
3845db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo,
3855db71995Sopenharmony_ci                                                   const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) {
3865db71995Sopenharmony_ci    VkLayerDeviceCreateInfo* chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
3875db71995Sopenharmony_ci
3885db71995Sopenharmony_ci    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
3895db71995Sopenharmony_ci    PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
3905db71995Sopenharmony_ci    VkInstance instance_to_use = layer.buggy_query_of_vkCreateDevice ? NULL : layer.instance_handle;
3915db71995Sopenharmony_ci    PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(instance_to_use, "vkCreateDevice");
3925db71995Sopenharmony_ci    if (fpCreateDevice == NULL) {
3935db71995Sopenharmony_ci        return VK_ERROR_INITIALIZATION_FAILED;
3945db71995Sopenharmony_ci    }
3955db71995Sopenharmony_ci
3965db71995Sopenharmony_ci    layer.next_vkGetDeviceProcAddr = fpGetDeviceProcAddr;
3975db71995Sopenharmony_ci
3985db71995Sopenharmony_ci    if (layer.check_if_EnumDevExtProps_is_same_as_queried_function) {
3995db71995Sopenharmony_ci        auto chain_info_EnumDeviceExtProps = reinterpret_cast<PFN_vkEnumerateDeviceExtensionProperties>(
4005db71995Sopenharmony_ci            fpGetInstanceProcAddr(layer.instance_handle, "vkEnumerateDeviceExtensionProperties"));
4015db71995Sopenharmony_ci        if (chain_info_EnumDeviceExtProps != layer.instance_dispatch_table.EnumerateDeviceExtensionProperties) {
4025db71995Sopenharmony_ci            return VK_ERROR_INITIALIZATION_FAILED;
4035db71995Sopenharmony_ci        }
4045db71995Sopenharmony_ci    }
4055db71995Sopenharmony_ci    // Advance the link info for the next element on the chain
4065db71995Sopenharmony_ci    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
4075db71995Sopenharmony_ci
4085db71995Sopenharmony_ci    if (layer.clobber_pDevice) {
4095db71995Sopenharmony_ci        memset(*pDevice, 0, 128);
4105db71995Sopenharmony_ci    }
4115db71995Sopenharmony_ci
4125db71995Sopenharmony_ci    VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
4135db71995Sopenharmony_ci    if (result != VK_SUCCESS) {
4145db71995Sopenharmony_ci        return result;
4155db71995Sopenharmony_ci    }
4165db71995Sopenharmony_ci    TestLayer::Device device{};
4175db71995Sopenharmony_ci    device.device_handle = *pDevice;
4185db71995Sopenharmony_ci
4195db71995Sopenharmony_ci    // initialize layer's dispatch table
4205db71995Sopenharmony_ci    layer_init_device_dispatch_table(device.device_handle, &device.dispatch_table, fpGetDeviceProcAddr);
4215db71995Sopenharmony_ci
4225db71995Sopenharmony_ci    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
4235db71995Sopenharmony_ci        device.enabled_extensions.push_back({pCreateInfo->ppEnabledExtensionNames[i]});
4245db71995Sopenharmony_ci    }
4255db71995Sopenharmony_ci
4265db71995Sopenharmony_ci    for (auto& func : layer.custom_device_interception_functions) {
4275db71995Sopenharmony_ci        auto next_func = layer.next_vkGetDeviceProcAddr(*pDevice, func.name.c_str());
4285db71995Sopenharmony_ci        layer.custom_dispatch_functions.at(func.name.c_str()) = next_func;
4295db71995Sopenharmony_ci    }
4305db71995Sopenharmony_ci
4315db71995Sopenharmony_ci    if (layer.create_device_callback) {
4325db71995Sopenharmony_ci        result = layer.create_device_callback(layer);
4335db71995Sopenharmony_ci    }
4345db71995Sopenharmony_ci
4355db71995Sopenharmony_ci    // Need to add the created devices to the list so it can be freed
4365db71995Sopenharmony_ci    layer.created_devices.push_back(device);
4375db71995Sopenharmony_ci
4385db71995Sopenharmony_ci    if (layer.do_spurious_allocations_in_create_device && pAllocator && pAllocator->pfnAllocation) {
4395db71995Sopenharmony_ci        void* allocation = pAllocator->pfnAllocation(pAllocator->pUserData, 110, 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
4405db71995Sopenharmony_ci        if (allocation == nullptr) {
4415db71995Sopenharmony_ci            return VK_ERROR_OUT_OF_HOST_MEMORY;
4425db71995Sopenharmony_ci        } else {
4435db71995Sopenharmony_ci            layer.spurious_device_memory_allocations.push_back({allocation, device.device_handle});
4445db71995Sopenharmony_ci        }
4455db71995Sopenharmony_ci    }
4465db71995Sopenharmony_ci
4475db71995Sopenharmony_ci    if (layer.call_create_device_while_create_device_is_called) {
4485db71995Sopenharmony_ci        PFN_vkGetDeviceProcAddr next_gdpa = layer.next_vkGetDeviceProcAddr;
4495db71995Sopenharmony_ci        result = layer.callback_vkCreateDevice(
4505db71995Sopenharmony_ci            instance_to_use, layer.queried_physical_devices.at(layer.physical_device_index_to_use_during_create_device),
4515db71995Sopenharmony_ci            pCreateInfo, pAllocator, &layer.second_device_created_during_create_device.device_handle, get_instance_func,
4525db71995Sopenharmony_ci            &next_gdpa);
4535db71995Sopenharmony_ci        if (result != VK_SUCCESS) {
4545db71995Sopenharmony_ci            return result;
4555db71995Sopenharmony_ci        }
4565db71995Sopenharmony_ci        // initialize the other device's dispatch table
4575db71995Sopenharmony_ci        layer_init_device_dispatch_table(layer.second_device_created_during_create_device.device_handle,
4585db71995Sopenharmony_ci                                         &layer.second_device_created_during_create_device.dispatch_table, next_gdpa);
4595db71995Sopenharmony_ci    }
4605db71995Sopenharmony_ci
4615db71995Sopenharmony_ci    return result;
4625db71995Sopenharmony_ci}
4635db71995Sopenharmony_ci
4645db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount,
4655db71995Sopenharmony_ci                                                               VkPhysicalDevice* pPhysicalDevices) {
4665db71995Sopenharmony_ci    if (layer.add_phys_devs || layer.remove_phys_devs || layer.reorder_phys_devs) {
4675db71995Sopenharmony_ci        VkResult res = VK_SUCCESS;
4685db71995Sopenharmony_ci
4695db71995Sopenharmony_ci        if (layer.complete_physical_devices.size() == 0) {
4705db71995Sopenharmony_ci            // Get list of all physical devices from lower down
4715db71995Sopenharmony_ci            // NOTE: This only works if we don't test changing the number of devices
4725db71995Sopenharmony_ci            //       underneath us when using this test.
4735db71995Sopenharmony_ci            uint32_t icd_count = 0;
4745db71995Sopenharmony_ci            layer.instance_dispatch_table.EnumeratePhysicalDevices(instance, &icd_count, nullptr);
4755db71995Sopenharmony_ci            std::vector<VkPhysicalDevice> tmp_vector;
4765db71995Sopenharmony_ci            tmp_vector.resize(icd_count);
4775db71995Sopenharmony_ci            layer.instance_dispatch_table.EnumeratePhysicalDevices(instance, &icd_count, tmp_vector.data());
4785db71995Sopenharmony_ci            layer.complete_physical_devices.clear();
4795db71995Sopenharmony_ci
4805db71995Sopenharmony_ci            if (layer.remove_phys_devs) {
4815db71995Sopenharmony_ci                // Erase the 3rd and 4th items
4825db71995Sopenharmony_ci                layer.removed_physical_devices.push_back(tmp_vector[3]);
4835db71995Sopenharmony_ci                layer.removed_physical_devices.push_back(tmp_vector[4]);
4845db71995Sopenharmony_ci                tmp_vector.erase(tmp_vector.begin() + 3);
4855db71995Sopenharmony_ci                tmp_vector.erase(tmp_vector.begin() + 3);
4865db71995Sopenharmony_ci            }
4875db71995Sopenharmony_ci
4885db71995Sopenharmony_ci            if (layer.add_phys_devs) {
4895db71995Sopenharmony_ci                // Insert a new device in the beginning, middle, and end
4905db71995Sopenharmony_ci                uint32_t middle = static_cast<uint32_t>(tmp_vector.size() / 2);
4915db71995Sopenharmony_ci                VkPhysicalDevice new_phys_dev = reinterpret_cast<VkPhysicalDevice>((size_t)(0xABCD0000));
4925db71995Sopenharmony_ci                layer.added_physical_devices.push_back(new_phys_dev);
4935db71995Sopenharmony_ci                tmp_vector.insert(tmp_vector.begin(), new_phys_dev);
4945db71995Sopenharmony_ci                new_phys_dev = reinterpret_cast<VkPhysicalDevice>((size_t)(0xBADC0000));
4955db71995Sopenharmony_ci                layer.added_physical_devices.push_back(new_phys_dev);
4965db71995Sopenharmony_ci                tmp_vector.insert(tmp_vector.begin() + middle, new_phys_dev);
4975db71995Sopenharmony_ci                new_phys_dev = reinterpret_cast<VkPhysicalDevice>((size_t)(0xDCBA0000));
4985db71995Sopenharmony_ci                layer.added_physical_devices.push_back(new_phys_dev);
4995db71995Sopenharmony_ci                tmp_vector.push_back(new_phys_dev);
5005db71995Sopenharmony_ci            }
5015db71995Sopenharmony_ci
5025db71995Sopenharmony_ci            if (layer.reorder_phys_devs) {
5035db71995Sopenharmony_ci                // Flip the order of items
5045db71995Sopenharmony_ci                for (int32_t dev = static_cast<int32_t>(tmp_vector.size() - 1); dev >= 0; --dev) {
5055db71995Sopenharmony_ci                    layer.complete_physical_devices.push_back(tmp_vector[dev]);
5065db71995Sopenharmony_ci                }
5075db71995Sopenharmony_ci            } else {
5085db71995Sopenharmony_ci                // Otherwise, keep the order the same
5095db71995Sopenharmony_ci                for (uint32_t dev = 0; dev < tmp_vector.size(); ++dev) {
5105db71995Sopenharmony_ci                    layer.complete_physical_devices.push_back(tmp_vector[dev]);
5115db71995Sopenharmony_ci                }
5125db71995Sopenharmony_ci            }
5135db71995Sopenharmony_ci        }
5145db71995Sopenharmony_ci
5155db71995Sopenharmony_ci        if (nullptr == pPhysicalDevices) {
5165db71995Sopenharmony_ci            *pPhysicalDeviceCount = static_cast<uint32_t>(layer.complete_physical_devices.size());
5175db71995Sopenharmony_ci        } else {
5185db71995Sopenharmony_ci            uint32_t adj_count = static_cast<uint32_t>(layer.complete_physical_devices.size());
5195db71995Sopenharmony_ci            if (*pPhysicalDeviceCount < adj_count) {
5205db71995Sopenharmony_ci                adj_count = *pPhysicalDeviceCount;
5215db71995Sopenharmony_ci                res = VK_INCOMPLETE;
5225db71995Sopenharmony_ci            }
5235db71995Sopenharmony_ci            for (uint32_t dev = 0; dev < adj_count; ++dev) {
5245db71995Sopenharmony_ci                pPhysicalDevices[dev] = layer.complete_physical_devices[dev];
5255db71995Sopenharmony_ci            }
5265db71995Sopenharmony_ci            *pPhysicalDeviceCount = adj_count;
5275db71995Sopenharmony_ci        }
5285db71995Sopenharmony_ci
5295db71995Sopenharmony_ci        return res;
5305db71995Sopenharmony_ci    } else {
5315db71995Sopenharmony_ci        return layer.instance_dispatch_table.EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
5325db71995Sopenharmony_ci    }
5335db71995Sopenharmony_ci}
5345db71995Sopenharmony_ci
5355db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
5365db71995Sopenharmony_ci                                                              VkPhysicalDeviceProperties* pProperties) {
5375db71995Sopenharmony_ci    if (std::find(layer.removed_physical_devices.begin(), layer.removed_physical_devices.end(), physicalDevice) !=
5385db71995Sopenharmony_ci        layer.removed_physical_devices.end()) {
5395db71995Sopenharmony_ci        // Should not get here since the application should not know about those devices
5405db71995Sopenharmony_ci        assert(false);
5415db71995Sopenharmony_ci    } else if (std::find(layer.added_physical_devices.begin(), layer.added_physical_devices.end(), physicalDevice) !=
5425db71995Sopenharmony_ci               layer.added_physical_devices.end()) {
5435db71995Sopenharmony_ci        // Added device so put in some placeholder info we can test against
5445db71995Sopenharmony_ci        pProperties->apiVersion = VK_API_VERSION_1_2;
5455db71995Sopenharmony_ci        pProperties->driverVersion = VK_MAKE_API_VERSION(0, 12, 14, 196);
5465db71995Sopenharmony_ci        pProperties->vendorID = 0xDECAFBAD;
5475db71995Sopenharmony_ci        pProperties->deviceID = 0xDEADBADD;
5485db71995Sopenharmony_ci#if defined(_WIN32)
5495db71995Sopenharmony_ci        strncpy_s(pProperties->deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, "physdev_added_xx", 17);
5505db71995Sopenharmony_ci#else
5515db71995Sopenharmony_ci        strncpy(pProperties->deviceName, "physdev_added_xx", VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
5525db71995Sopenharmony_ci#endif
5535db71995Sopenharmony_ci    } else {
5545db71995Sopenharmony_ci        // Not an affected device so just return
5555db71995Sopenharmony_ci        layer.instance_dispatch_table.GetPhysicalDeviceProperties(physicalDevice, pProperties);
5565db71995Sopenharmony_ci    }
5575db71995Sopenharmony_ci}
5585db71995Sopenharmony_ci
5595db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDeviceGroups(
5605db71995Sopenharmony_ci    VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
5615db71995Sopenharmony_ci    if (layer.add_phys_devs || layer.remove_phys_devs || layer.reorder_phys_devs) {
5625db71995Sopenharmony_ci        VkResult res = VK_SUCCESS;
5635db71995Sopenharmony_ci
5645db71995Sopenharmony_ci        if (layer.complete_physical_device_groups.size() == 0) {
5655db71995Sopenharmony_ci            uint32_t fake_count = 1000;
5665db71995Sopenharmony_ci            // Call EnumerateDevices to add remove devices as needed
5675db71995Sopenharmony_ci            test_vkEnumeratePhysicalDevices(instance, &fake_count, nullptr);
5685db71995Sopenharmony_ci
5695db71995Sopenharmony_ci            // Get list of all physical devices from lower down
5705db71995Sopenharmony_ci            // NOTE: This only works if we don't test changing the number of devices
5715db71995Sopenharmony_ci            //       underneath us when using this test.
5725db71995Sopenharmony_ci            uint32_t icd_group_count = 0;
5735db71995Sopenharmony_ci            layer.instance_dispatch_table.EnumeratePhysicalDeviceGroups(instance, &icd_group_count, nullptr);
5745db71995Sopenharmony_ci            std::vector<VkPhysicalDeviceGroupProperties> tmp_vector(icd_group_count,
5755db71995Sopenharmony_ci                                                                    {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES});
5765db71995Sopenharmony_ci            layer.instance_dispatch_table.EnumeratePhysicalDeviceGroups(instance, &icd_group_count, tmp_vector.data());
5775db71995Sopenharmony_ci            layer.complete_physical_device_groups.clear();
5785db71995Sopenharmony_ci
5795db71995Sopenharmony_ci            if (layer.remove_phys_devs) {
5805db71995Sopenharmony_ci                // Now, if a device has been removed, and it was the only group, we need to remove the group as well.
5815db71995Sopenharmony_ci                for (uint32_t rem_dev = 0; rem_dev < layer.removed_physical_devices.size(); ++rem_dev) {
5825db71995Sopenharmony_ci                    for (uint32_t group = 0; group < icd_group_count; ++group) {
5835db71995Sopenharmony_ci                        for (uint32_t grp_dev = 0; grp_dev < tmp_vector[group].physicalDeviceCount; ++grp_dev) {
5845db71995Sopenharmony_ci                            if (tmp_vector[group].physicalDevices[grp_dev] == layer.removed_physical_devices[rem_dev]) {
5855db71995Sopenharmony_ci                                for (uint32_t cp_item = grp_dev + 1; cp_item < tmp_vector[group].physicalDeviceCount; ++cp_item) {
5865db71995Sopenharmony_ci                                    tmp_vector[group].physicalDevices[grp_dev] = tmp_vector[group].physicalDevices[cp_item];
5875db71995Sopenharmony_ci                                }
5885db71995Sopenharmony_ci                                tmp_vector[group].physicalDeviceCount--;
5895db71995Sopenharmony_ci                            }
5905db71995Sopenharmony_ci                        }
5915db71995Sopenharmony_ci                    }
5925db71995Sopenharmony_ci                }
5935db71995Sopenharmony_ci                for (uint32_t group = 0; group < tmp_vector.size(); ++group) {
5945db71995Sopenharmony_ci                    if (tmp_vector[group].physicalDeviceCount == 0) {
5955db71995Sopenharmony_ci                        layer.removed_physical_device_groups.push_back(tmp_vector[group]);
5965db71995Sopenharmony_ci                        tmp_vector.erase(tmp_vector.begin() + group);
5975db71995Sopenharmony_ci                        --group;
5985db71995Sopenharmony_ci                    }
5995db71995Sopenharmony_ci                }
6005db71995Sopenharmony_ci            }
6015db71995Sopenharmony_ci
6025db71995Sopenharmony_ci            if (layer.add_phys_devs) {
6035db71995Sopenharmony_ci                // Add a new group for each physical device not associated with a current group
6045db71995Sopenharmony_ci                for (uint32_t dev = 0; dev < layer.added_physical_devices.size(); ++dev) {
6055db71995Sopenharmony_ci                    VkPhysicalDeviceGroupProperties props{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES};
6065db71995Sopenharmony_ci                    props.physicalDeviceCount = 1;
6075db71995Sopenharmony_ci                    props.physicalDevices[0] = layer.added_physical_devices[dev];
6085db71995Sopenharmony_ci                    tmp_vector.push_back(props);
6095db71995Sopenharmony_ci                    layer.added_physical_device_groups.push_back(props);
6105db71995Sopenharmony_ci                }
6115db71995Sopenharmony_ci            }
6125db71995Sopenharmony_ci
6135db71995Sopenharmony_ci            if (layer.reorder_phys_devs) {
6145db71995Sopenharmony_ci                // Flip the order of items
6155db71995Sopenharmony_ci                for (int32_t dev = static_cast<int32_t>(tmp_vector.size() - 1); dev >= 0; --dev) {
6165db71995Sopenharmony_ci                    layer.complete_physical_device_groups.push_back(tmp_vector[dev]);
6175db71995Sopenharmony_ci                }
6185db71995Sopenharmony_ci            } else {
6195db71995Sopenharmony_ci                // Otherwise, keep the order the same
6205db71995Sopenharmony_ci                for (uint32_t dev = 0; dev < tmp_vector.size(); ++dev) {
6215db71995Sopenharmony_ci                    layer.complete_physical_device_groups.push_back(tmp_vector[dev]);
6225db71995Sopenharmony_ci                }
6235db71995Sopenharmony_ci            }
6245db71995Sopenharmony_ci        }
6255db71995Sopenharmony_ci
6265db71995Sopenharmony_ci        if (nullptr == pPhysicalDeviceGroupProperties) {
6275db71995Sopenharmony_ci            *pPhysicalDeviceGroupCount = static_cast<uint32_t>(layer.complete_physical_device_groups.size());
6285db71995Sopenharmony_ci        } else {
6295db71995Sopenharmony_ci            uint32_t adj_count = static_cast<uint32_t>(layer.complete_physical_device_groups.size());
6305db71995Sopenharmony_ci            if (*pPhysicalDeviceGroupCount < adj_count) {
6315db71995Sopenharmony_ci                adj_count = *pPhysicalDeviceGroupCount;
6325db71995Sopenharmony_ci                res = VK_INCOMPLETE;
6335db71995Sopenharmony_ci            }
6345db71995Sopenharmony_ci            for (uint32_t dev = 0; dev < adj_count; ++dev) {
6355db71995Sopenharmony_ci                pPhysicalDeviceGroupProperties[dev] = layer.complete_physical_device_groups[dev];
6365db71995Sopenharmony_ci            }
6375db71995Sopenharmony_ci            *pPhysicalDeviceGroupCount = adj_count;
6385db71995Sopenharmony_ci        }
6395db71995Sopenharmony_ci
6405db71995Sopenharmony_ci        return res;
6415db71995Sopenharmony_ci    } else {
6425db71995Sopenharmony_ci        return layer.instance_dispatch_table.EnumeratePhysicalDeviceGroups(instance, pPhysicalDeviceGroupCount,
6435db71995Sopenharmony_ci                                                                           pPhysicalDeviceGroupProperties);
6445db71995Sopenharmony_ci    }
6455db71995Sopenharmony_ci}
6465db71995Sopenharmony_ci
6475db71995Sopenharmony_ci// device functions
6485db71995Sopenharmony_ci
6495db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
6505db71995Sopenharmony_ci    for (uint32_t i = 0; i < layer.spurious_device_memory_allocations.size();) {
6515db71995Sopenharmony_ci        auto& allocation = layer.spurious_device_memory_allocations[i];
6525db71995Sopenharmony_ci        if (allocation.device == device && pAllocator && pAllocator->pfnFree) {
6535db71995Sopenharmony_ci            pAllocator->pfnFree(pAllocator->pUserData, allocation.allocation);
6545db71995Sopenharmony_ci            layer.spurious_device_memory_allocations.erase(layer.spurious_device_memory_allocations.begin() + i);
6555db71995Sopenharmony_ci        } else {
6565db71995Sopenharmony_ci            i++;
6575db71995Sopenharmony_ci        }
6585db71995Sopenharmony_ci    }
6595db71995Sopenharmony_ci
6605db71995Sopenharmony_ci    if (layer.call_create_device_while_create_device_is_called) {
6615db71995Sopenharmony_ci        layer.callback_vkDestroyDevice(layer.second_device_created_during_create_device.device_handle, pAllocator,
6625db71995Sopenharmony_ci                                       layer.second_device_created_during_create_device.dispatch_table.DestroyDevice);
6635db71995Sopenharmony_ci    }
6645db71995Sopenharmony_ci
6655db71995Sopenharmony_ci    auto it = std::find_if(std::begin(layer.created_devices), std::end(layer.created_devices),
6665db71995Sopenharmony_ci                           [device](const TestLayer::Device& dev) { return device == dev.device_handle; });
6675db71995Sopenharmony_ci    if (it != std::end(layer.created_devices)) {
6685db71995Sopenharmony_ci        it->dispatch_table.DestroyDevice(device, pAllocator);
6695db71995Sopenharmony_ci        layer.created_devices.erase(it);
6705db71995Sopenharmony_ci    }
6715db71995Sopenharmony_ci}
6725db71995Sopenharmony_ci
6735db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDebugUtilsMessengerEXT(VkInstance instance,
6745db71995Sopenharmony_ci                                                                   const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
6755db71995Sopenharmony_ci                                                                   const VkAllocationCallbacks* pAllocator,
6765db71995Sopenharmony_ci                                                                   VkDebugUtilsMessengerEXT* pMessenger) {
6775db71995Sopenharmony_ci    if (layer.instance_dispatch_table.CreateDebugUtilsMessengerEXT) {
6785db71995Sopenharmony_ci        return layer.instance_dispatch_table.CreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger);
6795db71995Sopenharmony_ci    } else {
6805db71995Sopenharmony_ci        return VK_SUCCESS;
6815db71995Sopenharmony_ci    }
6825db71995Sopenharmony_ci}
6835db71995Sopenharmony_ci
6845db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkDestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
6855db71995Sopenharmony_ci                                                                const VkAllocationCallbacks* pAllocator) {
6865db71995Sopenharmony_ci    if (layer.instance_dispatch_table.DestroyDebugUtilsMessengerEXT)
6875db71995Sopenharmony_ci        return layer.instance_dispatch_table.DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
6885db71995Sopenharmony_ci}
6895db71995Sopenharmony_ci
6905db71995Sopenharmony_ci// Debug utils & debug marker ext stubs
6915db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL test_vkDebugMarkerSetObjectTagEXT(VkDevice dev, const VkDebugMarkerObjectTagInfoEXT* pTagInfo) {
6925db71995Sopenharmony_ci    for (const auto& d : layer.created_devices) {
6935db71995Sopenharmony_ci        if (d.device_handle == dev) {
6945db71995Sopenharmony_ci            if (d.dispatch_table.DebugMarkerSetObjectTagEXT) {
6955db71995Sopenharmony_ci                return d.dispatch_table.DebugMarkerSetObjectTagEXT(dev, pTagInfo);
6965db71995Sopenharmony_ci            } else {
6975db71995Sopenharmony_ci                return VK_SUCCESS;
6985db71995Sopenharmony_ci            }
6995db71995Sopenharmony_ci        }
7005db71995Sopenharmony_ci    }
7015db71995Sopenharmony_ci    return VK_SUCCESS;
7025db71995Sopenharmony_ci}
7035db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL test_vkDebugMarkerSetObjectNameEXT(VkDevice dev, const VkDebugMarkerObjectNameInfoEXT* pNameInfo) {
7045db71995Sopenharmony_ci    for (const auto& d : layer.created_devices) {
7055db71995Sopenharmony_ci        if (d.device_handle == dev) {
7065db71995Sopenharmony_ci            if (d.dispatch_table.DebugMarkerSetObjectNameEXT) {
7075db71995Sopenharmony_ci                return d.dispatch_table.DebugMarkerSetObjectNameEXT(dev, pNameInfo);
7085db71995Sopenharmony_ci            } else {
7095db71995Sopenharmony_ci                return VK_SUCCESS;
7105db71995Sopenharmony_ci            }
7115db71995Sopenharmony_ci        }
7125db71995Sopenharmony_ci    }
7135db71995Sopenharmony_ci    return VK_SUCCESS;
7145db71995Sopenharmony_ci}
7155db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkCmdDebugMarkerBeginEXT(VkCommandBuffer cmd_buf, const VkDebugMarkerMarkerInfoEXT* marker_info) {
7165db71995Sopenharmony_ci    // Just call the first device -
7175db71995Sopenharmony_ci    if (layer.created_devices[0].dispatch_table.CmdDebugMarkerBeginEXT)
7185db71995Sopenharmony_ci        layer.created_devices[0].dispatch_table.CmdDebugMarkerBeginEXT(cmd_buf, marker_info);
7195db71995Sopenharmony_ci}
7205db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkCmdDebugMarkerEndEXT(VkCommandBuffer cmd_buf) {
7215db71995Sopenharmony_ci    // Just call the first device -
7225db71995Sopenharmony_ci    if (layer.created_devices[0].dispatch_table.CmdDebugMarkerEndEXT)
7235db71995Sopenharmony_ci        layer.created_devices[0].dispatch_table.CmdDebugMarkerEndEXT(cmd_buf);
7245db71995Sopenharmony_ci}
7255db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkCmdDebugMarkerInsertEXT(VkCommandBuffer cmd_buf, const VkDebugMarkerMarkerInfoEXT* marker_info) {
7265db71995Sopenharmony_ci    // Just call the first device -
7275db71995Sopenharmony_ci    if (layer.created_devices[0].dispatch_table.CmdDebugMarkerInsertEXT)
7285db71995Sopenharmony_ci        layer.created_devices[0].dispatch_table.CmdDebugMarkerInsertEXT(cmd_buf, marker_info);
7295db71995Sopenharmony_ci}
7305db71995Sopenharmony_ci
7315db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL test_vkSetDebugUtilsObjectNameEXT(VkDevice dev, const VkDebugUtilsObjectNameInfoEXT* pNameInfo) {
7325db71995Sopenharmony_ci    for (const auto& d : layer.created_devices) {
7335db71995Sopenharmony_ci        if (d.device_handle == dev) {
7345db71995Sopenharmony_ci            if (d.dispatch_table.SetDebugUtilsObjectNameEXT) {
7355db71995Sopenharmony_ci                return d.dispatch_table.SetDebugUtilsObjectNameEXT(dev, pNameInfo);
7365db71995Sopenharmony_ci            } else {
7375db71995Sopenharmony_ci                return VK_SUCCESS;
7385db71995Sopenharmony_ci            }
7395db71995Sopenharmony_ci        }
7405db71995Sopenharmony_ci    }
7415db71995Sopenharmony_ci    return VK_SUCCESS;
7425db71995Sopenharmony_ci}
7435db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL test_vkSetDebugUtilsObjectTagEXT(VkDevice dev, const VkDebugUtilsObjectTagInfoEXT* pTagInfo) {
7445db71995Sopenharmony_ci    for (const auto& d : layer.created_devices) {
7455db71995Sopenharmony_ci        if (d.device_handle == dev) {
7465db71995Sopenharmony_ci            if (d.dispatch_table.SetDebugUtilsObjectTagEXT) {
7475db71995Sopenharmony_ci                return d.dispatch_table.SetDebugUtilsObjectTagEXT(dev, pTagInfo);
7485db71995Sopenharmony_ci            } else {
7495db71995Sopenharmony_ci                return VK_SUCCESS;
7505db71995Sopenharmony_ci            }
7515db71995Sopenharmony_ci        }
7525db71995Sopenharmony_ci    }
7535db71995Sopenharmony_ci    return VK_SUCCESS;
7545db71995Sopenharmony_ci}
7555db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkQueueBeginDebugUtilsLabelEXT(VkQueue queue, const VkDebugUtilsLabelEXT* label) {
7565db71995Sopenharmony_ci    // Just call the first device -
7575db71995Sopenharmony_ci    if (layer.created_devices[0].dispatch_table.QueueBeginDebugUtilsLabelEXT)
7585db71995Sopenharmony_ci        layer.created_devices[0].dispatch_table.QueueBeginDebugUtilsLabelEXT(queue, label);
7595db71995Sopenharmony_ci}
7605db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkQueueEndDebugUtilsLabelEXT(VkQueue queue) {
7615db71995Sopenharmony_ci    // Just call the first device -
7625db71995Sopenharmony_ci    if (layer.created_devices[0].dispatch_table.QueueEndDebugUtilsLabelEXT)
7635db71995Sopenharmony_ci        layer.created_devices[0].dispatch_table.QueueEndDebugUtilsLabelEXT(queue);
7645db71995Sopenharmony_ci}
7655db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkQueueInsertDebugUtilsLabelEXT(VkQueue queue, const VkDebugUtilsLabelEXT* label) {
7665db71995Sopenharmony_ci    // Just call the first device -
7675db71995Sopenharmony_ci    if (layer.created_devices[0].dispatch_table.QueueInsertDebugUtilsLabelEXT)
7685db71995Sopenharmony_ci        layer.created_devices[0].dispatch_table.QueueInsertDebugUtilsLabelEXT(queue, label);
7695db71995Sopenharmony_ci}
7705db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkCmdBeginDebugUtilsLabelEXT(VkCommandBuffer cmd_buf, const VkDebugUtilsLabelEXT* label) {
7715db71995Sopenharmony_ci    // Just call the first device -
7725db71995Sopenharmony_ci    if (layer.created_devices[0].dispatch_table.CmdBeginDebugUtilsLabelEXT)
7735db71995Sopenharmony_ci        layer.created_devices[0].dispatch_table.CmdBeginDebugUtilsLabelEXT(cmd_buf, label);
7745db71995Sopenharmony_ci}
7755db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkCmdEndDebugUtilsLabelEXT(VkCommandBuffer cmd_buf) {
7765db71995Sopenharmony_ci    // Just call the first device -
7775db71995Sopenharmony_ci    if (layer.created_devices[0].dispatch_table.CmdEndDebugUtilsLabelEXT)
7785db71995Sopenharmony_ci        layer.created_devices[0].dispatch_table.CmdEndDebugUtilsLabelEXT(cmd_buf);
7795db71995Sopenharmony_ci}
7805db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL test_vkCmdInsertDebugUtilsLabelEXT(VkCommandBuffer cmd_buf, const VkDebugUtilsLabelEXT* label) {
7815db71995Sopenharmony_ci    // Just call the first device -
7825db71995Sopenharmony_ci    if (layer.created_devices[0].dispatch_table.CmdInsertDebugUtilsLabelEXT)
7835db71995Sopenharmony_ci        layer.created_devices[0].dispatch_table.CmdInsertDebugUtilsLabelEXT(cmd_buf, label);
7845db71995Sopenharmony_ci}
7855db71995Sopenharmony_ci
7865db71995Sopenharmony_ci// forward declarations needed for trampolines
7875db71995Sopenharmony_ci#if TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR
7885db71995Sopenharmony_ciextern "C" {
7895db71995Sopenharmony_ciFRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName);
7905db71995Sopenharmony_ci}
7915db71995Sopenharmony_ci#endif
7925db71995Sopenharmony_ci
7935db71995Sopenharmony_ci// trampolines
7945db71995Sopenharmony_ciVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_device_func(VkDevice device, const char* pName);
7955db71995Sopenharmony_ciVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_device_func_impl([[maybe_unused]] VkDevice device, const char* pName) {
7965db71995Sopenharmony_ci    if (string_eq(pName, "vkGetDeviceProcAddr")) return to_vkVoidFunction(get_device_func);
7975db71995Sopenharmony_ci    if (string_eq(pName, "vkDestroyDevice")) return to_vkVoidFunction(test_vkDestroyDevice);
7985db71995Sopenharmony_ci
7995db71995Sopenharmony_ci    if (IsDeviceExtensionAvailable(device, VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) {
8005db71995Sopenharmony_ci        if (string_eq(pName, "vkDebugMarkerSetObjectTagEXT")) return to_vkVoidFunction(test_vkDebugMarkerSetObjectTagEXT);
8015db71995Sopenharmony_ci        if (string_eq(pName, "vkDebugMarkerSetObjectNameEXT")) return to_vkVoidFunction(test_vkDebugMarkerSetObjectNameEXT);
8025db71995Sopenharmony_ci        if (string_eq(pName, "vkCmdDebugMarkerBeginEXT")) return to_vkVoidFunction(test_vkCmdDebugMarkerBeginEXT);
8035db71995Sopenharmony_ci        if (string_eq(pName, "vkCmdDebugMarkerEndEXT")) return to_vkVoidFunction(test_vkCmdDebugMarkerEndEXT);
8045db71995Sopenharmony_ci        if (string_eq(pName, "vkCmdDebugMarkerInsertEXT")) return to_vkVoidFunction(test_vkCmdDebugMarkerInsertEXT);
8055db71995Sopenharmony_ci    }
8065db71995Sopenharmony_ci    if (IsInstanceExtensionEnabled(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
8075db71995Sopenharmony_ci        if (string_eq(pName, "vkSetDebugUtilsObjectNameEXT")) return to_vkVoidFunction(test_vkSetDebugUtilsObjectNameEXT);
8085db71995Sopenharmony_ci        if (string_eq(pName, "vkSetDebugUtilsObjectTagEXT")) return to_vkVoidFunction(test_vkSetDebugUtilsObjectTagEXT);
8095db71995Sopenharmony_ci        if (string_eq(pName, "vkQueueBeginDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueBeginDebugUtilsLabelEXT);
8105db71995Sopenharmony_ci        if (string_eq(pName, "vkQueueEndDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueEndDebugUtilsLabelEXT);
8115db71995Sopenharmony_ci        if (string_eq(pName, "vkQueueInsertDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueInsertDebugUtilsLabelEXT);
8125db71995Sopenharmony_ci        if (string_eq(pName, "vkCmdBeginDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdBeginDebugUtilsLabelEXT);
8135db71995Sopenharmony_ci        if (string_eq(pName, "vkCmdEndDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdEndDebugUtilsLabelEXT);
8145db71995Sopenharmony_ci        if (string_eq(pName, "vkCmdInsertDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdInsertDebugUtilsLabelEXT);
8155db71995Sopenharmony_ci    }
8165db71995Sopenharmony_ci
8175db71995Sopenharmony_ci    for (auto& func : layer.custom_device_interception_functions) {
8185db71995Sopenharmony_ci        if (func.name == pName) {
8195db71995Sopenharmony_ci            return to_vkVoidFunction(func.function);
8205db71995Sopenharmony_ci        }
8215db71995Sopenharmony_ci    }
8225db71995Sopenharmony_ci
8235db71995Sopenharmony_ci    for (auto& func : layer.custom_device_implementation_functions) {
8245db71995Sopenharmony_ci        if (func.name == pName) {
8255db71995Sopenharmony_ci            return to_vkVoidFunction(func.function);
8265db71995Sopenharmony_ci        }
8275db71995Sopenharmony_ci    }
8285db71995Sopenharmony_ci
8295db71995Sopenharmony_ci    return nullptr;
8305db71995Sopenharmony_ci}
8315db71995Sopenharmony_ci
8325db71995Sopenharmony_ciVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_device_func([[maybe_unused]] VkDevice device, const char* pName) {
8335db71995Sopenharmony_ci    PFN_vkVoidFunction ret_dev = get_device_func_impl(device, pName);
8345db71995Sopenharmony_ci    if (ret_dev != nullptr) return ret_dev;
8355db71995Sopenharmony_ci
8365db71995Sopenharmony_ci    return layer.next_vkGetDeviceProcAddr(device, pName);
8375db71995Sopenharmony_ci}
8385db71995Sopenharmony_ci
8395db71995Sopenharmony_ciVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_physical_device_func([[maybe_unused]] VkInstance instance, const char* pName) {
8405db71995Sopenharmony_ci    if (string_eq(pName, "vkEnumerateDeviceLayerProperties")) return to_vkVoidFunction(test_vkEnumerateDeviceLayerProperties);
8415db71995Sopenharmony_ci    if (string_eq(pName, "vkEnumerateDeviceExtensionProperties"))
8425db71995Sopenharmony_ci        return to_vkVoidFunction(test_vkEnumerateDeviceExtensionProperties);
8435db71995Sopenharmony_ci    if (string_eq(pName, "vkEnumeratePhysicalDevices")) return (PFN_vkVoidFunction)test_vkEnumeratePhysicalDevices;
8445db71995Sopenharmony_ci    if (string_eq(pName, "vkEnumeratePhysicalDeviceGroups")) return (PFN_vkVoidFunction)test_vkEnumeratePhysicalDeviceGroups;
8455db71995Sopenharmony_ci    if (string_eq(pName, "vkGetPhysicalDeviceProperties")) return (PFN_vkVoidFunction)test_vkGetPhysicalDeviceProperties;
8465db71995Sopenharmony_ci
8475db71995Sopenharmony_ci    for (auto& func : layer.custom_physical_device_interception_functions) {
8485db71995Sopenharmony_ci        if (func.name == pName) {
8495db71995Sopenharmony_ci            return to_vkVoidFunction(func.function);
8505db71995Sopenharmony_ci        }
8515db71995Sopenharmony_ci    }
8525db71995Sopenharmony_ci
8535db71995Sopenharmony_ci    for (auto& func : layer.custom_physical_device_implementation_functions) {
8545db71995Sopenharmony_ci        if (func.name == pName) {
8555db71995Sopenharmony_ci            return to_vkVoidFunction(func.function);
8565db71995Sopenharmony_ci        }
8575db71995Sopenharmony_ci    }
8585db71995Sopenharmony_ci
8595db71995Sopenharmony_ci#if TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR
8605db71995Sopenharmony_ci    if (string_eq(pName, "vk_layerGetPhysicalDeviceProcAddr")) return to_vkVoidFunction(vk_layerGetPhysicalDeviceProcAddr);
8615db71995Sopenharmony_ci#endif
8625db71995Sopenharmony_ci    return nullptr;
8635db71995Sopenharmony_ci}
8645db71995Sopenharmony_ciVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_instance_func(VkInstance instance, const char* pName);
8655db71995Sopenharmony_ciVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_instance_func_impl(VkInstance instance, const char* pName) {
8665db71995Sopenharmony_ci    if (pName == nullptr) return nullptr;
8675db71995Sopenharmony_ci    if (string_eq(pName, "vkGetInstanceProcAddr")) return to_vkVoidFunction(get_instance_func);
8685db71995Sopenharmony_ci    if (string_eq(pName, "vkEnumerateInstanceLayerProperties")) return to_vkVoidFunction(test_vkEnumerateInstanceLayerProperties);
8695db71995Sopenharmony_ci    if (string_eq(pName, "vkEnumerateInstanceExtensionProperties"))
8705db71995Sopenharmony_ci        return to_vkVoidFunction(test_vkEnumerateInstanceExtensionProperties);
8715db71995Sopenharmony_ci    if (string_eq(pName, "vkEnumerateInstanceVersion")) return to_vkVoidFunction(test_vkEnumerateInstanceVersion);
8725db71995Sopenharmony_ci    if (string_eq(pName, "vkCreateInstance")) return to_vkVoidFunction(test_vkCreateInstance);
8735db71995Sopenharmony_ci    if (string_eq(pName, "vkDestroyInstance")) return to_vkVoidFunction(test_vkDestroyInstance);
8745db71995Sopenharmony_ci    if (string_eq(pName, "vkCreateDevice")) return to_vkVoidFunction(test_vkCreateDevice);
8755db71995Sopenharmony_ci    if (string_eq(pName, "vkGetDeviceProcAddr")) return to_vkVoidFunction(get_device_func);
8765db71995Sopenharmony_ci
8775db71995Sopenharmony_ci    PFN_vkVoidFunction ret_phys_dev = get_physical_device_func(instance, pName);
8785db71995Sopenharmony_ci    if (ret_phys_dev != nullptr) return ret_phys_dev;
8795db71995Sopenharmony_ci
8805db71995Sopenharmony_ci    PFN_vkVoidFunction ret_dev = get_device_func_impl(nullptr, pName);
8815db71995Sopenharmony_ci    if (ret_dev != nullptr) return ret_dev;
8825db71995Sopenharmony_ci
8835db71995Sopenharmony_ci    return nullptr;
8845db71995Sopenharmony_ci}
8855db71995Sopenharmony_ci
8865db71995Sopenharmony_ciVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_instance_func(VkInstance instance, const char* pName) {
8875db71995Sopenharmony_ci    PFN_vkVoidFunction ret_dev = get_instance_func_impl(instance, pName);
8885db71995Sopenharmony_ci    if (ret_dev != nullptr) return ret_dev;
8895db71995Sopenharmony_ci
8905db71995Sopenharmony_ci    return layer.next_vkGetInstanceProcAddr(instance, pName);
8915db71995Sopenharmony_ci}
8925db71995Sopenharmony_ci
8935db71995Sopenharmony_ci// Exported functions
8945db71995Sopenharmony_ciextern "C" {
8955db71995Sopenharmony_ci#if TEST_LAYER_EXPORT_ENUMERATE_FUNCTIONS
8965db71995Sopenharmony_ci
8975db71995Sopenharmony_ci// Pre-instance handling functions
8985db71995Sopenharmony_ci
8995db71995Sopenharmony_ciFRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL test_preinst_vkEnumerateInstanceLayerProperties(
9005db71995Sopenharmony_ci    const VkEnumerateInstanceLayerPropertiesChain* pChain, uint32_t* pPropertyCount, VkLayerProperties* pProperties) {
9015db71995Sopenharmony_ci    VkResult res = pChain->pfnNextLayer(pChain->pNextLink, pPropertyCount, pProperties);
9025db71995Sopenharmony_ci    if (nullptr == pProperties) {
9035db71995Sopenharmony_ci        *pPropertyCount = layer.reported_layer_props;
9045db71995Sopenharmony_ci    } else {
9055db71995Sopenharmony_ci        uint32_t count = layer.reported_layer_props;
9065db71995Sopenharmony_ci        if (*pPropertyCount < layer.reported_layer_props) {
9075db71995Sopenharmony_ci            count = *pPropertyCount;
9085db71995Sopenharmony_ci            res = VK_INCOMPLETE;
9095db71995Sopenharmony_ci        }
9105db71995Sopenharmony_ci        for (uint32_t i = 0; i < count; ++i) {
9115db71995Sopenharmony_ci            snprintf(pProperties[i].layerName, VK_MAX_EXTENSION_NAME_SIZE, "%02d_layer", count);
9125db71995Sopenharmony_ci            pProperties[i].specVersion = count;
9135db71995Sopenharmony_ci            pProperties[i].implementationVersion = 0xABCD0000 + count;
9145db71995Sopenharmony_ci        }
9155db71995Sopenharmony_ci    }
9165db71995Sopenharmony_ci    return res;
9175db71995Sopenharmony_ci}
9185db71995Sopenharmony_ci
9195db71995Sopenharmony_ciFRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL test_preinst_vkEnumerateInstanceExtensionProperties(
9205db71995Sopenharmony_ci    const VkEnumerateInstanceExtensionPropertiesChain* pChain, const char* pLayerName, uint32_t* pPropertyCount,
9215db71995Sopenharmony_ci    VkExtensionProperties* pProperties) {
9225db71995Sopenharmony_ci    VkResult res = pChain->pfnNextLayer(pChain->pNextLink, pLayerName, pPropertyCount, pProperties);
9235db71995Sopenharmony_ci    if (nullptr == pProperties) {
9245db71995Sopenharmony_ci        *pPropertyCount = layer.reported_extension_props;
9255db71995Sopenharmony_ci    } else {
9265db71995Sopenharmony_ci        uint32_t count = layer.reported_extension_props;
9275db71995Sopenharmony_ci        if (*pPropertyCount < layer.reported_extension_props) {
9285db71995Sopenharmony_ci            count = *pPropertyCount;
9295db71995Sopenharmony_ci            res = VK_INCOMPLETE;
9305db71995Sopenharmony_ci        }
9315db71995Sopenharmony_ci        for (uint32_t i = 0; i < count; ++i) {
9325db71995Sopenharmony_ci            snprintf(pProperties[i].extensionName, VK_MAX_EXTENSION_NAME_SIZE, "%02d_ext", count);
9335db71995Sopenharmony_ci            pProperties[i].specVersion = count;
9345db71995Sopenharmony_ci        }
9355db71995Sopenharmony_ci    }
9365db71995Sopenharmony_ci    return res;
9375db71995Sopenharmony_ci}
9385db71995Sopenharmony_ci
9395db71995Sopenharmony_ciFRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
9405db71995Sopenharmony_citest_preinst_vkEnumerateInstanceVersion(const VkEnumerateInstanceVersionChain* pChain, uint32_t* pApiVersion) {
9415db71995Sopenharmony_ci    VkResult res = pChain->pfnNextLayer(pChain->pNextLink, pApiVersion);
9425db71995Sopenharmony_ci    *pApiVersion = layer.reported_instance_version;
9435db71995Sopenharmony_ci    return res;
9445db71995Sopenharmony_ci}
9455db71995Sopenharmony_ci
9465db71995Sopenharmony_ciFRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t* pPropertyCount,
9475db71995Sopenharmony_ci                                                                                   VkLayerProperties* pProperties) {
9485db71995Sopenharmony_ci    return test_vkEnumerateInstanceLayerProperties(pPropertyCount, pProperties);
9495db71995Sopenharmony_ci}
9505db71995Sopenharmony_ciFRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char* pLayerName,
9515db71995Sopenharmony_ci                                                                                       uint32_t* pPropertyCount,
9525db71995Sopenharmony_ci                                                                                       VkExtensionProperties* pProperties) {
9535db71995Sopenharmony_ci    return test_vkEnumerateInstanceExtensionProperties(pLayerName, pPropertyCount, pProperties);
9545db71995Sopenharmony_ci}
9555db71995Sopenharmony_ci
9565db71995Sopenharmony_ciFRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
9575db71995Sopenharmony_ci                                                                                 uint32_t* pPropertyCount,
9585db71995Sopenharmony_ci                                                                                 VkLayerProperties* pProperties) {
9595db71995Sopenharmony_ci    return test_vkEnumerateDeviceLayerProperties(physicalDevice, pPropertyCount, pProperties);
9605db71995Sopenharmony_ci}
9615db71995Sopenharmony_ciFRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
9625db71995Sopenharmony_ci                                                                                     const char* pLayerName,
9635db71995Sopenharmony_ci                                                                                     uint32_t* pPropertyCount,
9645db71995Sopenharmony_ci                                                                                     VkExtensionProperties* pProperties) {
9655db71995Sopenharmony_ci    return test_vkEnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pPropertyCount, pProperties);
9665db71995Sopenharmony_ci}
9675db71995Sopenharmony_ci#endif
9685db71995Sopenharmony_ci
9695db71995Sopenharmony_ci#if TEST_LAYER_EXPORT_LAYER_NAMED_GIPA
9705db71995Sopenharmony_ciFRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_layer_GetInstanceProcAddr(VkInstance instance, const char* pName) {
9715db71995Sopenharmony_ci    return get_instance_func(instance, pName);
9725db71995Sopenharmony_ci}
9735db71995Sopenharmony_ci#endif
9745db71995Sopenharmony_ci
9755db71995Sopenharmony_ci#if TEST_LAYER_EXPORT_OVERRIDE_GIPA
9765db71995Sopenharmony_ciFRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_override_vkGetInstanceProcAddr(VkInstance instance,
9775db71995Sopenharmony_ci                                                                                              const char* pName) {
9785db71995Sopenharmony_ci    if (string_eq(pName, "vkCreateInstance")) return to_vkVoidFunction(test_override_vkCreateInstance);
9795db71995Sopenharmony_ci    return get_instance_func(instance, pName);
9805db71995Sopenharmony_ci}
9815db71995Sopenharmony_ci#endif
9825db71995Sopenharmony_ci
9835db71995Sopenharmony_ci#if TEST_LAYER_EXPORT_LAYER_VK_GIPA
9845db71995Sopenharmony_ciFRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* pName) {
9855db71995Sopenharmony_ci    return get_instance_func(instance, pName);
9865db71995Sopenharmony_ci}
9875db71995Sopenharmony_ci#endif
9885db71995Sopenharmony_ci
9895db71995Sopenharmony_ci#if TEST_LAYER_EXPORT_LAYER_NAMED_GDPA
9905db71995Sopenharmony_ciFRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_layer_GetDeviceProcAddr(VkDevice device, const char* pName) {
9915db71995Sopenharmony_ci    return get_device_func(device, pName);
9925db71995Sopenharmony_ci}
9935db71995Sopenharmony_ci#endif
9945db71995Sopenharmony_ci
9955db71995Sopenharmony_ci#if TEST_LAYER_EXPORT_OVERRIDE_GDPA
9965db71995Sopenharmony_ciFRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_override_GetDeviceProcAddr(VkDevice device, const char* pName) {
9975db71995Sopenharmony_ci    return get_device_func(device, pName);
9985db71995Sopenharmony_ci}
9995db71995Sopenharmony_ci#endif
10005db71995Sopenharmony_ci
10015db71995Sopenharmony_ci#if TEST_LAYER_EXPORT_LAYER_VK_GDPA
10025db71995Sopenharmony_ciFRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* pName) {
10035db71995Sopenharmony_ci    return get_device_func(device, pName);
10045db71995Sopenharmony_ci}
10055db71995Sopenharmony_ci#endif
10065db71995Sopenharmony_ci
10075db71995Sopenharmony_ci#if TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR
10085db71995Sopenharmony_ciFRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance,
10095db71995Sopenharmony_ci                                                                                            const char* pName) {
10105db71995Sopenharmony_ci    auto func = get_physical_device_func(instance, pName);
10115db71995Sopenharmony_ci    if (func != nullptr) return func;
10125db71995Sopenharmony_ci    return layer.next_GetPhysicalDeviceProcAddr(instance, pName);
10135db71995Sopenharmony_ci}
10145db71995Sopenharmony_ci#endif
10155db71995Sopenharmony_ci
10165db71995Sopenharmony_ci#if LAYER_EXPORT_NEGOTIATE_LOADER_LAYER_INTERFACE_VERSION
10175db71995Sopenharmony_ci// vk_layer.h has a forward declaration of vkNegotiateLoaderLayerInterfaceVersion, which doesn't have any attributes
10185db71995Sopenharmony_ci// Since FRAMEWORK_EXPORT adds  __declspec(dllexport), we can't do that here, thus we need our own macro
10195db71995Sopenharmony_ci#if (defined(__GNUC__) && (__GNUC__ >= 4)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
10205db71995Sopenharmony_ci#define EXPORT_NEGOTIATE_FUNCTION __attribute__((visibility("default")))
10215db71995Sopenharmony_ci#else
10225db71995Sopenharmony_ci#define EXPORT_NEGOTIATE_FUNCTION
10235db71995Sopenharmony_ci#endif
10245db71995Sopenharmony_ci
10255db71995Sopenharmony_ciEXPORT_NEGOTIATE_FUNCTION VKAPI_ATTR VkResult VKAPI_CALL
10265db71995Sopenharmony_civkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface* pVersionStruct) {
10275db71995Sopenharmony_ci    if (pVersionStruct) {
10285db71995Sopenharmony_ci        if (pVersionStruct->loaderLayerInterfaceVersion < layer.min_implementation_version) {
10295db71995Sopenharmony_ci            return VK_ERROR_INITIALIZATION_FAILED;
10305db71995Sopenharmony_ci        }
10315db71995Sopenharmony_ci
10325db71995Sopenharmony_ci        pVersionStruct->loaderLayerInterfaceVersion = layer.implementation_version;
10335db71995Sopenharmony_ci        pVersionStruct->pfnGetInstanceProcAddr = get_instance_func;
10345db71995Sopenharmony_ci        pVersionStruct->pfnGetDeviceProcAddr = get_device_func;
10355db71995Sopenharmony_ci#if TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR
10365db71995Sopenharmony_ci        pVersionStruct->pfnGetPhysicalDeviceProcAddr = vk_layerGetPhysicalDeviceProcAddr;
10375db71995Sopenharmony_ci#else
10385db71995Sopenharmony_ci        pVersionStruct->pfnGetPhysicalDeviceProcAddr = nullptr;
10395db71995Sopenharmony_ci#endif
10405db71995Sopenharmony_ci
10415db71995Sopenharmony_ci        return VK_SUCCESS;
10425db71995Sopenharmony_ci    }
10435db71995Sopenharmony_ci    return VK_ERROR_INITIALIZATION_FAILED;
10445db71995Sopenharmony_ci}
10455db71995Sopenharmony_ci#endif
10465db71995Sopenharmony_ci}  // extern "C"
1047