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