1/* 2 * Copyright (c) 2021-2022 The Khronos Group Inc. 3 * Copyright (c) 2021-2022 Valve Corporation 4 * Copyright (c) 2021-2022 LunarG, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and/or associated documentation files (the "Materials"), to 8 * deal in the Materials without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Materials, and to permit persons to whom the Materials are 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice(s) and this permission notice shall be included in 14 * all copies or substantial portions of the Materials. 15 * 16 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 * 20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE 23 * USE OR OTHER DEALINGS IN THE MATERIALS. 24 * 25 * Author: Charles Giessen <charles@lunarg.com> 26 */ 27 28#include "test_layer.h" 29 30#include "vk_dispatch_table_helper.h" 31 32// export the enumeration functions instance|device+layer|extension 33#if !defined(TEST_LAYER_EXPORT_ENUMERATE_FUNCTIONS) 34#define TEST_LAYER_EXPORT_ENUMERATE_FUNCTIONS 0 35#endif 36 37// export test_layer_GetInstanceProcAddr 38#if !defined(TEST_LAYER_EXPORT_LAYER_NAMED_GIPA) 39#define TEST_LAYER_EXPORT_LAYER_NAMED_GIPA 0 40#endif 41 42// export test_override_GetInstanceProcAddr 43#if !defined(TEST_LAYER_EXPORT_OVERRIDE_GIPA) 44#define TEST_LAYER_EXPORT_OVERRIDE_GIPA 0 45#endif 46 47// export vkGetInstanceProcAddr 48#if !defined(TEST_LAYER_EXPORT_LAYER_VK_GIPA) 49#define TEST_LAYER_EXPORT_LAYER_VK_GIPA 0 50#endif 51 52// export test_layer_GetDeviceProcAddr 53#if !defined(TEST_LAYER_EXPORT_LAYER_NAMED_GDPA) 54#define TEST_LAYER_EXPORT_LAYER_NAMED_GDPA 0 55#endif 56 57// export test_override_GetDeviceProcAddr 58#if !defined(TEST_LAYER_EXPORT_OVERRIDE_GDPA) 59#define TEST_LAYER_EXPORT_OVERRIDE_GDPA 0 60#endif 61 62// export vkGetDeviceProcAddr 63#if !defined(TEST_LAYER_EXPORT_LAYER_VK_GDPA) 64#define TEST_LAYER_EXPORT_LAYER_VK_GDPA 0 65#endif 66 67// export vk_layerGetPhysicalDeviceProcAddr 68#if !defined(TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR) 69#define TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR 0 70#endif 71 72// export vkNegotiateLoaderLayerInterfaceVersion 73#if !defined(LAYER_EXPORT_NEGOTIATE_LOADER_LAYER_INTERFACE_VERSION) 74#define LAYER_EXPORT_NEGOTIATE_LOADER_LAYER_INTERFACE_VERSION 0 75#endif 76 77#if !defined(TEST_LAYER_NAME) 78#define TEST_LAYER_NAME "VK_LAYER_LunarG_test_layer" 79#endif 80 81TestLayer layer; 82extern "C" { 83FRAMEWORK_EXPORT TestLayer* get_test_layer_func() { return &layer; } 84FRAMEWORK_EXPORT TestLayer* reset_layer_func() { 85 layer.~TestLayer(); 86 return new (&layer) TestLayer(); 87} 88} 89 90bool IsInstanceExtensionSupported(const char* extension_name) { 91 return layer.instance_extensions.end() != 92 std::find_if(layer.instance_extensions.begin(), layer.instance_extensions.end(), 93 [extension_name](Extension const& ext) { return string_eq(&ext.extensionName[0], extension_name); }); 94} 95 96bool IsInstanceExtensionEnabled(const char* extension_name) { 97 return layer.enabled_instance_extensions.end() != 98 std::find_if(layer.enabled_instance_extensions.begin(), layer.enabled_instance_extensions.end(), 99 [extension_name](Extension const& ext) { return string_eq(&ext.extensionName[0], extension_name); }); 100} 101 102bool IsDeviceExtensionAvailable(VkDevice dev, const char* extension_name) { 103 for (auto& device : layer.created_devices) { 104 if ((dev == VK_NULL_HANDLE || device.device_handle == dev) && 105 device.enabled_extensions.end() != 106 std::find_if(device.enabled_extensions.begin(), device.enabled_extensions.end(), 107 [extension_name](Extension const& ext) { return ext.extensionName == extension_name; })) { 108 return true; 109 } 110 } 111 return false; 112} 113 114VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_instance_func(VkInstance instance, const char* pName); 115 116VkLayerInstanceCreateInfo* get_chain_info(const VkInstanceCreateInfo* pCreateInfo, VkLayerFunction func) { 117 VkLayerInstanceCreateInfo* chain_info = (VkLayerInstanceCreateInfo*)pCreateInfo->pNext; 118 while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO && chain_info->function == func)) { 119 chain_info = (VkLayerInstanceCreateInfo*)chain_info->pNext; 120 } 121 assert(chain_info != NULL); 122 return chain_info; 123} 124 125VkLayerDeviceCreateInfo* get_chain_info(const VkDeviceCreateInfo* pCreateInfo, VkLayerFunction func) { 126 VkLayerDeviceCreateInfo* chain_info = (VkLayerDeviceCreateInfo*)pCreateInfo->pNext; 127 while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO && chain_info->function == func)) { 128 chain_info = (VkLayerDeviceCreateInfo*)chain_info->pNext; 129 } 130 assert(chain_info != NULL); 131 return chain_info; 132} 133 134VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceLayerProperties(uint32_t*, VkLayerProperties*) { return VK_SUCCESS; } 135 136VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceExtensionProperties(const char* pLayerName, uint32_t* pPropertyCount, 137 VkExtensionProperties* pProperties) { 138 if (pPropertyCount == nullptr) { 139 return VK_INCOMPLETE; 140 } 141 if (pLayerName && string_eq(pLayerName, TEST_LAYER_NAME)) { 142 if (pProperties) { 143 if (*pPropertyCount < layer.injected_instance_extensions.size()) { 144 return VK_INCOMPLETE; 145 } 146 for (size_t i = 0; i < layer.injected_instance_extensions.size(); i++) { 147 pProperties[i] = layer.injected_instance_extensions.at(i).get(); 148 } 149 *pPropertyCount = static_cast<uint32_t>(layer.injected_instance_extensions.size()); 150 } else { 151 *pPropertyCount = static_cast<uint32_t>(layer.injected_instance_extensions.size()); 152 } 153 return VK_SUCCESS; 154 } 155 156 uint32_t hardware_prop_count = 0; 157 if (pProperties) { 158 hardware_prop_count = *pPropertyCount - static_cast<uint32_t>(layer.injected_instance_extensions.size()); 159 } 160 161 VkResult res = 162 layer.instance_dispatch_table.EnumerateInstanceExtensionProperties(pLayerName, &hardware_prop_count, pProperties); 163 if (res < 0) { 164 return res; 165 } 166 167 if (pProperties == nullptr) { 168 *pPropertyCount = hardware_prop_count + static_cast<uint32_t>(layer.injected_instance_extensions.size()); 169 } else { 170 if (hardware_prop_count + layer.injected_instance_extensions.size() > *pPropertyCount) { 171 *pPropertyCount = hardware_prop_count; 172 return VK_INCOMPLETE; 173 } 174 for (size_t i = 0; i < layer.injected_instance_extensions.size(); i++) { 175 pProperties[hardware_prop_count + i] = layer.injected_instance_extensions.at(i).get(); 176 } 177 *pPropertyCount = hardware_prop_count + static_cast<uint32_t>(layer.injected_instance_extensions.size()); 178 } 179 return res; 180} 181 182VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceLayerProperties(VkPhysicalDevice, uint32_t*, VkLayerProperties*) { 183 return VK_SUCCESS; 184} 185 186VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char* pLayerName, 187 uint32_t* pPropertyCount, 188 VkExtensionProperties* pProperties) { 189 if (pPropertyCount == nullptr) { 190 return VK_INCOMPLETE; 191 } 192 193 if (pLayerName && string_eq(pLayerName, TEST_LAYER_NAME)) { 194 if (pProperties) { 195 if (*pPropertyCount < static_cast<uint32_t>(layer.injected_device_extensions.size())) { 196 return VK_INCOMPLETE; 197 } 198 for (size_t i = 0; i < layer.injected_device_extensions.size(); i++) { 199 pProperties[i] = layer.injected_device_extensions.at(i).get(); 200 } 201 *pPropertyCount = static_cast<uint32_t>(layer.injected_device_extensions.size()); 202 } else { 203 *pPropertyCount = static_cast<uint32_t>(layer.injected_device_extensions.size()); 204 } 205 return VK_SUCCESS; 206 } 207 208 uint32_t hardware_prop_count = 0; 209 if (pProperties) { 210 hardware_prop_count = *pPropertyCount - static_cast<uint32_t>(layer.injected_device_extensions.size()); 211 } 212 213 VkResult res = layer.instance_dispatch_table.EnumerateDeviceExtensionProperties(physicalDevice, pLayerName, 214 &hardware_prop_count, pProperties); 215 if (res < 0) { 216 return res; 217 } 218 219 if (pProperties == nullptr) { 220 *pPropertyCount = hardware_prop_count + static_cast<uint32_t>(layer.injected_device_extensions.size()); 221 } else { 222 if (hardware_prop_count + layer.injected_device_extensions.size() > *pPropertyCount) { 223 *pPropertyCount = hardware_prop_count; 224 return VK_INCOMPLETE; 225 } 226 for (size_t i = 0; i < layer.injected_device_extensions.size(); i++) { 227 pProperties[hardware_prop_count + i] = layer.injected_device_extensions.at(i).get(); 228 } 229 *pPropertyCount = hardware_prop_count + static_cast<uint32_t>(layer.injected_device_extensions.size()); 230 } 231 return res; 232} 233 234VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceVersion(uint32_t* pApiVersion) { 235 if (pApiVersion != nullptr) { 236 *pApiVersion = VK_API_VERSION_1_0; 237 } 238 return VK_SUCCESS; 239} 240 241VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, 242 const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) { 243 VkLayerInstanceCreateInfo* chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 244 245 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 246 PFN_vk_icdGetPhysicalDeviceProcAddr fpGetPhysicalDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetPhysicalDeviceProcAddr; 247 PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance"); 248 if (fpCreateInstance == NULL) { 249 return VK_ERROR_INITIALIZATION_FAILED; 250 } 251 252 if (layer.call_create_device_while_create_device_is_called) { 253 auto* createDeviceCallback = get_chain_info(pCreateInfo, VK_LOADER_LAYER_CREATE_DEVICE_CALLBACK); 254 layer.callback_vkCreateDevice = createDeviceCallback->u.layerDevice.pfnLayerCreateDevice; 255 layer.callback_vkDestroyDevice = createDeviceCallback->u.layerDevice.pfnLayerDestroyDevice; 256 } 257 258 // Advance the link info for the next element of the chain 259 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 260 layer.next_vkGetInstanceProcAddr = fpGetInstanceProcAddr; 261 262 bool use_modified_create_info = false; 263 VkInstanceCreateInfo instance_create_info{}; 264 VkApplicationInfo application_info{}; 265 if (pCreateInfo) { 266 instance_create_info = *pCreateInfo; 267 if (pCreateInfo->pApplicationInfo) { 268 application_info = *pCreateInfo->pApplicationInfo; 269 } 270 } 271 272 // If the test needs to modify the api version, do it before we call down the chain 273 if (layer.alter_api_version != VK_API_VERSION_1_0 && pCreateInfo && pCreateInfo->pApplicationInfo) { 274 application_info.apiVersion = layer.alter_api_version; 275 instance_create_info.pApplicationInfo = &application_info; 276 use_modified_create_info = true; 277 } 278 const VkInstanceCreateInfo* create_info_pointer = use_modified_create_info ? &instance_create_info : pCreateInfo; 279 280 if (layer.clobber_pInstance) { 281 memset(*pInstance, 0, 128); 282 } 283 284 // Continue call down the chain 285 VkResult result = fpCreateInstance(create_info_pointer, pAllocator, pInstance); 286 if (result != VK_SUCCESS) { 287 return result; 288 } 289 layer.instance_handle = *pInstance; 290 if (layer.use_gipa_GetPhysicalDeviceProcAddr) { 291 layer.next_GetPhysicalDeviceProcAddr = 292 reinterpret_cast<PFN_GetPhysicalDeviceProcAddr>(fpGetInstanceProcAddr(*pInstance, "vk_layerGetPhysicalDeviceProcAddr")); 293 } else { 294 layer.next_GetPhysicalDeviceProcAddr = fpGetPhysicalDeviceProcAddr; 295 } 296 // Init layer's dispatch table using GetInstanceProcAddr of 297 // next layer in the chain. 298 layer_init_instance_dispatch_table(layer.instance_handle, &layer.instance_dispatch_table, fpGetInstanceProcAddr); 299 300 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) { 301 layer.enabled_instance_extensions.push_back({pCreateInfo->ppEnabledExtensionNames[i]}); 302 } 303 304 if (layer.create_instance_callback) result = layer.create_instance_callback(layer); 305 306 for (auto& func : layer.custom_physical_device_interception_functions) { 307 auto next_func = layer.next_GetPhysicalDeviceProcAddr(*pInstance, func.name.c_str()); 308 layer.custom_dispatch_functions.at(func.name.c_str()) = next_func; 309 } 310 311 for (auto& func : layer.custom_device_interception_functions) { 312 auto next_func = layer.next_vkGetInstanceProcAddr(*pInstance, func.name.c_str()); 313 layer.custom_dispatch_functions.at(func.name.c_str()) = next_func; 314 } 315 316 if (layer.do_spurious_allocations_in_create_instance && pAllocator && pAllocator->pfnAllocation) { 317 layer.spurious_instance_memory_allocation = 318 pAllocator->pfnAllocation(pAllocator->pUserData, 100, 8, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); 319 if (layer.spurious_instance_memory_allocation == nullptr) { 320 return VK_ERROR_OUT_OF_HOST_MEMORY; 321 } 322 } 323 324 if (!layer.make_spurious_log_in_create_instance.empty()) { 325 auto* chain = reinterpret_cast<const VkBaseInStructure*>(pCreateInfo->pNext); 326 while (chain) { 327 if (chain->sType == VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) { 328 auto* debug_messenger = reinterpret_cast<const VkDebugUtilsMessengerCreateInfoEXT*>(chain); 329 VkDebugUtilsMessengerCallbackDataEXT data{}; 330 data.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT; 331 data.pMessage = layer.make_spurious_log_in_create_instance.c_str(); 332 debug_messenger->pfnUserCallback(VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, 333 VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &data, debug_messenger->pUserData); 334 } 335 336 chain = chain->pNext; 337 } 338 } 339 340 if (layer.buggy_query_of_vkCreateDevice) { 341 layer.instance_dispatch_table.CreateDevice = 342 reinterpret_cast<PFN_vkCreateDevice>(fpGetInstanceProcAddr(nullptr, "vkCreateDevice")); 343 } 344 345 if (layer.call_create_device_while_create_device_is_called) { 346 uint32_t phys_dev_count = 0; 347 result = layer.instance_dispatch_table.EnumeratePhysicalDevices(layer.instance_handle, &phys_dev_count, nullptr); 348 if (result != VK_SUCCESS) { 349 return result; 350 } 351 layer.queried_physical_devices.resize(phys_dev_count); 352 result = layer.instance_dispatch_table.EnumeratePhysicalDevices(layer.instance_handle, &phys_dev_count, 353 layer.queried_physical_devices.data()); 354 if (result != VK_SUCCESS) { 355 return result; 356 } 357 } 358 359 if (layer.check_if_EnumDevExtProps_is_same_as_queried_function) { 360 auto chain_info_EnumDeviceExtProps = reinterpret_cast<PFN_vkEnumerateDeviceExtensionProperties>( 361 fpGetInstanceProcAddr(layer.instance_handle, "vkEnumerateDeviceExtensionProperties")); 362 if (chain_info_EnumDeviceExtProps != layer.instance_dispatch_table.EnumerateDeviceExtensionProperties) { 363 return VK_ERROR_INITIALIZATION_FAILED; 364 } 365 } 366 367 return result; 368} 369 370VKAPI_ATTR VkResult VKAPI_CALL test_override_vkCreateInstance(const VkInstanceCreateInfo*, const VkAllocationCallbacks*, 371 VkInstance*) { 372 return VK_ERROR_INVALID_SHADER_NV; 373} 374 375VKAPI_ATTR void VKAPI_CALL test_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator) { 376 if (layer.spurious_instance_memory_allocation && pAllocator && pAllocator->pfnFree) { 377 pAllocator->pfnFree(pAllocator->pUserData, layer.spurious_instance_memory_allocation); 378 layer.spurious_instance_memory_allocation = nullptr; 379 } 380 381 layer.instance_dispatch_table.DestroyInstance(instance, pAllocator); 382} 383 384VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, 385 const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) { 386 VkLayerDeviceCreateInfo* chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 387 388 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 389 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; 390 VkInstance instance_to_use = layer.buggy_query_of_vkCreateDevice ? NULL : layer.instance_handle; 391 PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(instance_to_use, "vkCreateDevice"); 392 if (fpCreateDevice == NULL) { 393 return VK_ERROR_INITIALIZATION_FAILED; 394 } 395 396 layer.next_vkGetDeviceProcAddr = fpGetDeviceProcAddr; 397 398 if (layer.check_if_EnumDevExtProps_is_same_as_queried_function) { 399 auto chain_info_EnumDeviceExtProps = reinterpret_cast<PFN_vkEnumerateDeviceExtensionProperties>( 400 fpGetInstanceProcAddr(layer.instance_handle, "vkEnumerateDeviceExtensionProperties")); 401 if (chain_info_EnumDeviceExtProps != layer.instance_dispatch_table.EnumerateDeviceExtensionProperties) { 402 return VK_ERROR_INITIALIZATION_FAILED; 403 } 404 } 405 // Advance the link info for the next element on the chain 406 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 407 408 if (layer.clobber_pDevice) { 409 memset(*pDevice, 0, 128); 410 } 411 412 VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice); 413 if (result != VK_SUCCESS) { 414 return result; 415 } 416 TestLayer::Device device{}; 417 device.device_handle = *pDevice; 418 419 // initialize layer's dispatch table 420 layer_init_device_dispatch_table(device.device_handle, &device.dispatch_table, fpGetDeviceProcAddr); 421 422 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) { 423 device.enabled_extensions.push_back({pCreateInfo->ppEnabledExtensionNames[i]}); 424 } 425 426 for (auto& func : layer.custom_device_interception_functions) { 427 auto next_func = layer.next_vkGetDeviceProcAddr(*pDevice, func.name.c_str()); 428 layer.custom_dispatch_functions.at(func.name.c_str()) = next_func; 429 } 430 431 if (layer.create_device_callback) { 432 result = layer.create_device_callback(layer); 433 } 434 435 // Need to add the created devices to the list so it can be freed 436 layer.created_devices.push_back(device); 437 438 if (layer.do_spurious_allocations_in_create_device && pAllocator && pAllocator->pfnAllocation) { 439 void* allocation = pAllocator->pfnAllocation(pAllocator->pUserData, 110, 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); 440 if (allocation == nullptr) { 441 return VK_ERROR_OUT_OF_HOST_MEMORY; 442 } else { 443 layer.spurious_device_memory_allocations.push_back({allocation, device.device_handle}); 444 } 445 } 446 447 if (layer.call_create_device_while_create_device_is_called) { 448 PFN_vkGetDeviceProcAddr next_gdpa = layer.next_vkGetDeviceProcAddr; 449 result = layer.callback_vkCreateDevice( 450 instance_to_use, layer.queried_physical_devices.at(layer.physical_device_index_to_use_during_create_device), 451 pCreateInfo, pAllocator, &layer.second_device_created_during_create_device.device_handle, get_instance_func, 452 &next_gdpa); 453 if (result != VK_SUCCESS) { 454 return result; 455 } 456 // initialize the other device's dispatch table 457 layer_init_device_dispatch_table(layer.second_device_created_during_create_device.device_handle, 458 &layer.second_device_created_during_create_device.dispatch_table, next_gdpa); 459 } 460 461 return result; 462} 463 464VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, 465 VkPhysicalDevice* pPhysicalDevices) { 466 if (layer.add_phys_devs || layer.remove_phys_devs || layer.reorder_phys_devs) { 467 VkResult res = VK_SUCCESS; 468 469 if (layer.complete_physical_devices.size() == 0) { 470 // Get list of all physical devices from lower down 471 // NOTE: This only works if we don't test changing the number of devices 472 // underneath us when using this test. 473 uint32_t icd_count = 0; 474 layer.instance_dispatch_table.EnumeratePhysicalDevices(instance, &icd_count, nullptr); 475 std::vector<VkPhysicalDevice> tmp_vector; 476 tmp_vector.resize(icd_count); 477 layer.instance_dispatch_table.EnumeratePhysicalDevices(instance, &icd_count, tmp_vector.data()); 478 layer.complete_physical_devices.clear(); 479 480 if (layer.remove_phys_devs) { 481 // Erase the 3rd and 4th items 482 layer.removed_physical_devices.push_back(tmp_vector[3]); 483 layer.removed_physical_devices.push_back(tmp_vector[4]); 484 tmp_vector.erase(tmp_vector.begin() + 3); 485 tmp_vector.erase(tmp_vector.begin() + 3); 486 } 487 488 if (layer.add_phys_devs) { 489 // Insert a new device in the beginning, middle, and end 490 uint32_t middle = static_cast<uint32_t>(tmp_vector.size() / 2); 491 VkPhysicalDevice new_phys_dev = reinterpret_cast<VkPhysicalDevice>((size_t)(0xABCD0000)); 492 layer.added_physical_devices.push_back(new_phys_dev); 493 tmp_vector.insert(tmp_vector.begin(), new_phys_dev); 494 new_phys_dev = reinterpret_cast<VkPhysicalDevice>((size_t)(0xBADC0000)); 495 layer.added_physical_devices.push_back(new_phys_dev); 496 tmp_vector.insert(tmp_vector.begin() + middle, new_phys_dev); 497 new_phys_dev = reinterpret_cast<VkPhysicalDevice>((size_t)(0xDCBA0000)); 498 layer.added_physical_devices.push_back(new_phys_dev); 499 tmp_vector.push_back(new_phys_dev); 500 } 501 502 if (layer.reorder_phys_devs) { 503 // Flip the order of items 504 for (int32_t dev = static_cast<int32_t>(tmp_vector.size() - 1); dev >= 0; --dev) { 505 layer.complete_physical_devices.push_back(tmp_vector[dev]); 506 } 507 } else { 508 // Otherwise, keep the order the same 509 for (uint32_t dev = 0; dev < tmp_vector.size(); ++dev) { 510 layer.complete_physical_devices.push_back(tmp_vector[dev]); 511 } 512 } 513 } 514 515 if (nullptr == pPhysicalDevices) { 516 *pPhysicalDeviceCount = static_cast<uint32_t>(layer.complete_physical_devices.size()); 517 } else { 518 uint32_t adj_count = static_cast<uint32_t>(layer.complete_physical_devices.size()); 519 if (*pPhysicalDeviceCount < adj_count) { 520 adj_count = *pPhysicalDeviceCount; 521 res = VK_INCOMPLETE; 522 } 523 for (uint32_t dev = 0; dev < adj_count; ++dev) { 524 pPhysicalDevices[dev] = layer.complete_physical_devices[dev]; 525 } 526 *pPhysicalDeviceCount = adj_count; 527 } 528 529 return res; 530 } else { 531 return layer.instance_dispatch_table.EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices); 532 } 533} 534 535VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, 536 VkPhysicalDeviceProperties* pProperties) { 537 if (std::find(layer.removed_physical_devices.begin(), layer.removed_physical_devices.end(), physicalDevice) != 538 layer.removed_physical_devices.end()) { 539 // Should not get here since the application should not know about those devices 540 assert(false); 541 } else if (std::find(layer.added_physical_devices.begin(), layer.added_physical_devices.end(), physicalDevice) != 542 layer.added_physical_devices.end()) { 543 // Added device so put in some placeholder info we can test against 544 pProperties->apiVersion = VK_API_VERSION_1_2; 545 pProperties->driverVersion = VK_MAKE_API_VERSION(0, 12, 14, 196); 546 pProperties->vendorID = 0xDECAFBAD; 547 pProperties->deviceID = 0xDEADBADD; 548#if defined(_WIN32) 549 strncpy_s(pProperties->deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, "physdev_added_xx", 17); 550#else 551 strncpy(pProperties->deviceName, "physdev_added_xx", VK_MAX_PHYSICAL_DEVICE_NAME_SIZE); 552#endif 553 } else { 554 // Not an affected device so just return 555 layer.instance_dispatch_table.GetPhysicalDeviceProperties(physicalDevice, pProperties); 556 } 557} 558 559VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDeviceGroups( 560 VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) { 561 if (layer.add_phys_devs || layer.remove_phys_devs || layer.reorder_phys_devs) { 562 VkResult res = VK_SUCCESS; 563 564 if (layer.complete_physical_device_groups.size() == 0) { 565 uint32_t fake_count = 1000; 566 // Call EnumerateDevices to add remove devices as needed 567 test_vkEnumeratePhysicalDevices(instance, &fake_count, nullptr); 568 569 // Get list of all physical devices from lower down 570 // NOTE: This only works if we don't test changing the number of devices 571 // underneath us when using this test. 572 uint32_t icd_group_count = 0; 573 layer.instance_dispatch_table.EnumeratePhysicalDeviceGroups(instance, &icd_group_count, nullptr); 574 std::vector<VkPhysicalDeviceGroupProperties> tmp_vector(icd_group_count, 575 {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES}); 576 layer.instance_dispatch_table.EnumeratePhysicalDeviceGroups(instance, &icd_group_count, tmp_vector.data()); 577 layer.complete_physical_device_groups.clear(); 578 579 if (layer.remove_phys_devs) { 580 // Now, if a device has been removed, and it was the only group, we need to remove the group as well. 581 for (uint32_t rem_dev = 0; rem_dev < layer.removed_physical_devices.size(); ++rem_dev) { 582 for (uint32_t group = 0; group < icd_group_count; ++group) { 583 for (uint32_t grp_dev = 0; grp_dev < tmp_vector[group].physicalDeviceCount; ++grp_dev) { 584 if (tmp_vector[group].physicalDevices[grp_dev] == layer.removed_physical_devices[rem_dev]) { 585 for (uint32_t cp_item = grp_dev + 1; cp_item < tmp_vector[group].physicalDeviceCount; ++cp_item) { 586 tmp_vector[group].physicalDevices[grp_dev] = tmp_vector[group].physicalDevices[cp_item]; 587 } 588 tmp_vector[group].physicalDeviceCount--; 589 } 590 } 591 } 592 } 593 for (uint32_t group = 0; group < tmp_vector.size(); ++group) { 594 if (tmp_vector[group].physicalDeviceCount == 0) { 595 layer.removed_physical_device_groups.push_back(tmp_vector[group]); 596 tmp_vector.erase(tmp_vector.begin() + group); 597 --group; 598 } 599 } 600 } 601 602 if (layer.add_phys_devs) { 603 // Add a new group for each physical device not associated with a current group 604 for (uint32_t dev = 0; dev < layer.added_physical_devices.size(); ++dev) { 605 VkPhysicalDeviceGroupProperties props{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES}; 606 props.physicalDeviceCount = 1; 607 props.physicalDevices[0] = layer.added_physical_devices[dev]; 608 tmp_vector.push_back(props); 609 layer.added_physical_device_groups.push_back(props); 610 } 611 } 612 613 if (layer.reorder_phys_devs) { 614 // Flip the order of items 615 for (int32_t dev = static_cast<int32_t>(tmp_vector.size() - 1); dev >= 0; --dev) { 616 layer.complete_physical_device_groups.push_back(tmp_vector[dev]); 617 } 618 } else { 619 // Otherwise, keep the order the same 620 for (uint32_t dev = 0; dev < tmp_vector.size(); ++dev) { 621 layer.complete_physical_device_groups.push_back(tmp_vector[dev]); 622 } 623 } 624 } 625 626 if (nullptr == pPhysicalDeviceGroupProperties) { 627 *pPhysicalDeviceGroupCount = static_cast<uint32_t>(layer.complete_physical_device_groups.size()); 628 } else { 629 uint32_t adj_count = static_cast<uint32_t>(layer.complete_physical_device_groups.size()); 630 if (*pPhysicalDeviceGroupCount < adj_count) { 631 adj_count = *pPhysicalDeviceGroupCount; 632 res = VK_INCOMPLETE; 633 } 634 for (uint32_t dev = 0; dev < adj_count; ++dev) { 635 pPhysicalDeviceGroupProperties[dev] = layer.complete_physical_device_groups[dev]; 636 } 637 *pPhysicalDeviceGroupCount = adj_count; 638 } 639 640 return res; 641 } else { 642 return layer.instance_dispatch_table.EnumeratePhysicalDeviceGroups(instance, pPhysicalDeviceGroupCount, 643 pPhysicalDeviceGroupProperties); 644 } 645} 646 647// device functions 648 649VKAPI_ATTR void VKAPI_CALL test_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) { 650 for (uint32_t i = 0; i < layer.spurious_device_memory_allocations.size();) { 651 auto& allocation = layer.spurious_device_memory_allocations[i]; 652 if (allocation.device == device && pAllocator && pAllocator->pfnFree) { 653 pAllocator->pfnFree(pAllocator->pUserData, allocation.allocation); 654 layer.spurious_device_memory_allocations.erase(layer.spurious_device_memory_allocations.begin() + i); 655 } else { 656 i++; 657 } 658 } 659 660 if (layer.call_create_device_while_create_device_is_called) { 661 layer.callback_vkDestroyDevice(layer.second_device_created_during_create_device.device_handle, pAllocator, 662 layer.second_device_created_during_create_device.dispatch_table.DestroyDevice); 663 } 664 665 auto it = std::find_if(std::begin(layer.created_devices), std::end(layer.created_devices), 666 [device](const TestLayer::Device& dev) { return device == dev.device_handle; }); 667 if (it != std::end(layer.created_devices)) { 668 it->dispatch_table.DestroyDevice(device, pAllocator); 669 layer.created_devices.erase(it); 670 } 671} 672 673VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDebugUtilsMessengerEXT(VkInstance instance, 674 const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, 675 const VkAllocationCallbacks* pAllocator, 676 VkDebugUtilsMessengerEXT* pMessenger) { 677 if (layer.instance_dispatch_table.CreateDebugUtilsMessengerEXT) { 678 return layer.instance_dispatch_table.CreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger); 679 } else { 680 return VK_SUCCESS; 681 } 682} 683 684VKAPI_ATTR void VKAPI_CALL test_vkDestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger, 685 const VkAllocationCallbacks* pAllocator) { 686 if (layer.instance_dispatch_table.DestroyDebugUtilsMessengerEXT) 687 return layer.instance_dispatch_table.DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator); 688} 689 690// Debug utils & debug marker ext stubs 691VKAPI_ATTR VkResult VKAPI_CALL test_vkDebugMarkerSetObjectTagEXT(VkDevice dev, const VkDebugMarkerObjectTagInfoEXT* pTagInfo) { 692 for (const auto& d : layer.created_devices) { 693 if (d.device_handle == dev) { 694 if (d.dispatch_table.DebugMarkerSetObjectTagEXT) { 695 return d.dispatch_table.DebugMarkerSetObjectTagEXT(dev, pTagInfo); 696 } else { 697 return VK_SUCCESS; 698 } 699 } 700 } 701 return VK_SUCCESS; 702} 703VKAPI_ATTR VkResult VKAPI_CALL test_vkDebugMarkerSetObjectNameEXT(VkDevice dev, const VkDebugMarkerObjectNameInfoEXT* pNameInfo) { 704 for (const auto& d : layer.created_devices) { 705 if (d.device_handle == dev) { 706 if (d.dispatch_table.DebugMarkerSetObjectNameEXT) { 707 return d.dispatch_table.DebugMarkerSetObjectNameEXT(dev, pNameInfo); 708 } else { 709 return VK_SUCCESS; 710 } 711 } 712 } 713 return VK_SUCCESS; 714} 715VKAPI_ATTR void VKAPI_CALL test_vkCmdDebugMarkerBeginEXT(VkCommandBuffer cmd_buf, const VkDebugMarkerMarkerInfoEXT* marker_info) { 716 // Just call the first device - 717 if (layer.created_devices[0].dispatch_table.CmdDebugMarkerBeginEXT) 718 layer.created_devices[0].dispatch_table.CmdDebugMarkerBeginEXT(cmd_buf, marker_info); 719} 720VKAPI_ATTR void VKAPI_CALL test_vkCmdDebugMarkerEndEXT(VkCommandBuffer cmd_buf) { 721 // Just call the first device - 722 if (layer.created_devices[0].dispatch_table.CmdDebugMarkerEndEXT) 723 layer.created_devices[0].dispatch_table.CmdDebugMarkerEndEXT(cmd_buf); 724} 725VKAPI_ATTR void VKAPI_CALL test_vkCmdDebugMarkerInsertEXT(VkCommandBuffer cmd_buf, const VkDebugMarkerMarkerInfoEXT* marker_info) { 726 // Just call the first device - 727 if (layer.created_devices[0].dispatch_table.CmdDebugMarkerInsertEXT) 728 layer.created_devices[0].dispatch_table.CmdDebugMarkerInsertEXT(cmd_buf, marker_info); 729} 730 731VKAPI_ATTR VkResult VKAPI_CALL test_vkSetDebugUtilsObjectNameEXT(VkDevice dev, const VkDebugUtilsObjectNameInfoEXT* pNameInfo) { 732 for (const auto& d : layer.created_devices) { 733 if (d.device_handle == dev) { 734 if (d.dispatch_table.SetDebugUtilsObjectNameEXT) { 735 return d.dispatch_table.SetDebugUtilsObjectNameEXT(dev, pNameInfo); 736 } else { 737 return VK_SUCCESS; 738 } 739 } 740 } 741 return VK_SUCCESS; 742} 743VKAPI_ATTR VkResult VKAPI_CALL test_vkSetDebugUtilsObjectTagEXT(VkDevice dev, const VkDebugUtilsObjectTagInfoEXT* pTagInfo) { 744 for (const auto& d : layer.created_devices) { 745 if (d.device_handle == dev) { 746 if (d.dispatch_table.SetDebugUtilsObjectTagEXT) { 747 return d.dispatch_table.SetDebugUtilsObjectTagEXT(dev, pTagInfo); 748 } else { 749 return VK_SUCCESS; 750 } 751 } 752 } 753 return VK_SUCCESS; 754} 755VKAPI_ATTR void VKAPI_CALL test_vkQueueBeginDebugUtilsLabelEXT(VkQueue queue, const VkDebugUtilsLabelEXT* label) { 756 // Just call the first device - 757 if (layer.created_devices[0].dispatch_table.QueueBeginDebugUtilsLabelEXT) 758 layer.created_devices[0].dispatch_table.QueueBeginDebugUtilsLabelEXT(queue, label); 759} 760VKAPI_ATTR void VKAPI_CALL test_vkQueueEndDebugUtilsLabelEXT(VkQueue queue) { 761 // Just call the first device - 762 if (layer.created_devices[0].dispatch_table.QueueEndDebugUtilsLabelEXT) 763 layer.created_devices[0].dispatch_table.QueueEndDebugUtilsLabelEXT(queue); 764} 765VKAPI_ATTR void VKAPI_CALL test_vkQueueInsertDebugUtilsLabelEXT(VkQueue queue, const VkDebugUtilsLabelEXT* label) { 766 // Just call the first device - 767 if (layer.created_devices[0].dispatch_table.QueueInsertDebugUtilsLabelEXT) 768 layer.created_devices[0].dispatch_table.QueueInsertDebugUtilsLabelEXT(queue, label); 769} 770VKAPI_ATTR void VKAPI_CALL test_vkCmdBeginDebugUtilsLabelEXT(VkCommandBuffer cmd_buf, const VkDebugUtilsLabelEXT* label) { 771 // Just call the first device - 772 if (layer.created_devices[0].dispatch_table.CmdBeginDebugUtilsLabelEXT) 773 layer.created_devices[0].dispatch_table.CmdBeginDebugUtilsLabelEXT(cmd_buf, label); 774} 775VKAPI_ATTR void VKAPI_CALL test_vkCmdEndDebugUtilsLabelEXT(VkCommandBuffer cmd_buf) { 776 // Just call the first device - 777 if (layer.created_devices[0].dispatch_table.CmdEndDebugUtilsLabelEXT) 778 layer.created_devices[0].dispatch_table.CmdEndDebugUtilsLabelEXT(cmd_buf); 779} 780VKAPI_ATTR void VKAPI_CALL test_vkCmdInsertDebugUtilsLabelEXT(VkCommandBuffer cmd_buf, const VkDebugUtilsLabelEXT* label) { 781 // Just call the first device - 782 if (layer.created_devices[0].dispatch_table.CmdInsertDebugUtilsLabelEXT) 783 layer.created_devices[0].dispatch_table.CmdInsertDebugUtilsLabelEXT(cmd_buf, label); 784} 785 786// forward declarations needed for trampolines 787#if TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR 788extern "C" { 789FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName); 790} 791#endif 792 793// trampolines 794VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_device_func(VkDevice device, const char* pName); 795VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_device_func_impl([[maybe_unused]] VkDevice device, const char* pName) { 796 if (string_eq(pName, "vkGetDeviceProcAddr")) return to_vkVoidFunction(get_device_func); 797 if (string_eq(pName, "vkDestroyDevice")) return to_vkVoidFunction(test_vkDestroyDevice); 798 799 if (IsDeviceExtensionAvailable(device, VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) { 800 if (string_eq(pName, "vkDebugMarkerSetObjectTagEXT")) return to_vkVoidFunction(test_vkDebugMarkerSetObjectTagEXT); 801 if (string_eq(pName, "vkDebugMarkerSetObjectNameEXT")) return to_vkVoidFunction(test_vkDebugMarkerSetObjectNameEXT); 802 if (string_eq(pName, "vkCmdDebugMarkerBeginEXT")) return to_vkVoidFunction(test_vkCmdDebugMarkerBeginEXT); 803 if (string_eq(pName, "vkCmdDebugMarkerEndEXT")) return to_vkVoidFunction(test_vkCmdDebugMarkerEndEXT); 804 if (string_eq(pName, "vkCmdDebugMarkerInsertEXT")) return to_vkVoidFunction(test_vkCmdDebugMarkerInsertEXT); 805 } 806 if (IsInstanceExtensionEnabled(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) { 807 if (string_eq(pName, "vkSetDebugUtilsObjectNameEXT")) return to_vkVoidFunction(test_vkSetDebugUtilsObjectNameEXT); 808 if (string_eq(pName, "vkSetDebugUtilsObjectTagEXT")) return to_vkVoidFunction(test_vkSetDebugUtilsObjectTagEXT); 809 if (string_eq(pName, "vkQueueBeginDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueBeginDebugUtilsLabelEXT); 810 if (string_eq(pName, "vkQueueEndDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueEndDebugUtilsLabelEXT); 811 if (string_eq(pName, "vkQueueInsertDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueInsertDebugUtilsLabelEXT); 812 if (string_eq(pName, "vkCmdBeginDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdBeginDebugUtilsLabelEXT); 813 if (string_eq(pName, "vkCmdEndDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdEndDebugUtilsLabelEXT); 814 if (string_eq(pName, "vkCmdInsertDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdInsertDebugUtilsLabelEXT); 815 } 816 817 for (auto& func : layer.custom_device_interception_functions) { 818 if (func.name == pName) { 819 return to_vkVoidFunction(func.function); 820 } 821 } 822 823 for (auto& func : layer.custom_device_implementation_functions) { 824 if (func.name == pName) { 825 return to_vkVoidFunction(func.function); 826 } 827 } 828 829 return nullptr; 830} 831 832VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_device_func([[maybe_unused]] VkDevice device, const char* pName) { 833 PFN_vkVoidFunction ret_dev = get_device_func_impl(device, pName); 834 if (ret_dev != nullptr) return ret_dev; 835 836 return layer.next_vkGetDeviceProcAddr(device, pName); 837} 838 839VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_physical_device_func([[maybe_unused]] VkInstance instance, const char* pName) { 840 if (string_eq(pName, "vkEnumerateDeviceLayerProperties")) return to_vkVoidFunction(test_vkEnumerateDeviceLayerProperties); 841 if (string_eq(pName, "vkEnumerateDeviceExtensionProperties")) 842 return to_vkVoidFunction(test_vkEnumerateDeviceExtensionProperties); 843 if (string_eq(pName, "vkEnumeratePhysicalDevices")) return (PFN_vkVoidFunction)test_vkEnumeratePhysicalDevices; 844 if (string_eq(pName, "vkEnumeratePhysicalDeviceGroups")) return (PFN_vkVoidFunction)test_vkEnumeratePhysicalDeviceGroups; 845 if (string_eq(pName, "vkGetPhysicalDeviceProperties")) return (PFN_vkVoidFunction)test_vkGetPhysicalDeviceProperties; 846 847 for (auto& func : layer.custom_physical_device_interception_functions) { 848 if (func.name == pName) { 849 return to_vkVoidFunction(func.function); 850 } 851 } 852 853 for (auto& func : layer.custom_physical_device_implementation_functions) { 854 if (func.name == pName) { 855 return to_vkVoidFunction(func.function); 856 } 857 } 858 859#if TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR 860 if (string_eq(pName, "vk_layerGetPhysicalDeviceProcAddr")) return to_vkVoidFunction(vk_layerGetPhysicalDeviceProcAddr); 861#endif 862 return nullptr; 863} 864VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_instance_func(VkInstance instance, const char* pName); 865VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_instance_func_impl(VkInstance instance, const char* pName) { 866 if (pName == nullptr) return nullptr; 867 if (string_eq(pName, "vkGetInstanceProcAddr")) return to_vkVoidFunction(get_instance_func); 868 if (string_eq(pName, "vkEnumerateInstanceLayerProperties")) return to_vkVoidFunction(test_vkEnumerateInstanceLayerProperties); 869 if (string_eq(pName, "vkEnumerateInstanceExtensionProperties")) 870 return to_vkVoidFunction(test_vkEnumerateInstanceExtensionProperties); 871 if (string_eq(pName, "vkEnumerateInstanceVersion")) return to_vkVoidFunction(test_vkEnumerateInstanceVersion); 872 if (string_eq(pName, "vkCreateInstance")) return to_vkVoidFunction(test_vkCreateInstance); 873 if (string_eq(pName, "vkDestroyInstance")) return to_vkVoidFunction(test_vkDestroyInstance); 874 if (string_eq(pName, "vkCreateDevice")) return to_vkVoidFunction(test_vkCreateDevice); 875 if (string_eq(pName, "vkGetDeviceProcAddr")) return to_vkVoidFunction(get_device_func); 876 877 PFN_vkVoidFunction ret_phys_dev = get_physical_device_func(instance, pName); 878 if (ret_phys_dev != nullptr) return ret_phys_dev; 879 880 PFN_vkVoidFunction ret_dev = get_device_func_impl(nullptr, pName); 881 if (ret_dev != nullptr) return ret_dev; 882 883 return nullptr; 884} 885 886VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_instance_func(VkInstance instance, const char* pName) { 887 PFN_vkVoidFunction ret_dev = get_instance_func_impl(instance, pName); 888 if (ret_dev != nullptr) return ret_dev; 889 890 return layer.next_vkGetInstanceProcAddr(instance, pName); 891} 892 893// Exported functions 894extern "C" { 895#if TEST_LAYER_EXPORT_ENUMERATE_FUNCTIONS 896 897// Pre-instance handling functions 898 899FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL test_preinst_vkEnumerateInstanceLayerProperties( 900 const VkEnumerateInstanceLayerPropertiesChain* pChain, uint32_t* pPropertyCount, VkLayerProperties* pProperties) { 901 VkResult res = pChain->pfnNextLayer(pChain->pNextLink, pPropertyCount, pProperties); 902 if (nullptr == pProperties) { 903 *pPropertyCount = layer.reported_layer_props; 904 } else { 905 uint32_t count = layer.reported_layer_props; 906 if (*pPropertyCount < layer.reported_layer_props) { 907 count = *pPropertyCount; 908 res = VK_INCOMPLETE; 909 } 910 for (uint32_t i = 0; i < count; ++i) { 911 snprintf(pProperties[i].layerName, VK_MAX_EXTENSION_NAME_SIZE, "%02d_layer", count); 912 pProperties[i].specVersion = count; 913 pProperties[i].implementationVersion = 0xABCD0000 + count; 914 } 915 } 916 return res; 917} 918 919FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL test_preinst_vkEnumerateInstanceExtensionProperties( 920 const VkEnumerateInstanceExtensionPropertiesChain* pChain, const char* pLayerName, uint32_t* pPropertyCount, 921 VkExtensionProperties* pProperties) { 922 VkResult res = pChain->pfnNextLayer(pChain->pNextLink, pLayerName, pPropertyCount, pProperties); 923 if (nullptr == pProperties) { 924 *pPropertyCount = layer.reported_extension_props; 925 } else { 926 uint32_t count = layer.reported_extension_props; 927 if (*pPropertyCount < layer.reported_extension_props) { 928 count = *pPropertyCount; 929 res = VK_INCOMPLETE; 930 } 931 for (uint32_t i = 0; i < count; ++i) { 932 snprintf(pProperties[i].extensionName, VK_MAX_EXTENSION_NAME_SIZE, "%02d_ext", count); 933 pProperties[i].specVersion = count; 934 } 935 } 936 return res; 937} 938 939FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 940test_preinst_vkEnumerateInstanceVersion(const VkEnumerateInstanceVersionChain* pChain, uint32_t* pApiVersion) { 941 VkResult res = pChain->pfnNextLayer(pChain->pNextLink, pApiVersion); 942 *pApiVersion = layer.reported_instance_version; 943 return res; 944} 945 946FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t* pPropertyCount, 947 VkLayerProperties* pProperties) { 948 return test_vkEnumerateInstanceLayerProperties(pPropertyCount, pProperties); 949} 950FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char* pLayerName, 951 uint32_t* pPropertyCount, 952 VkExtensionProperties* pProperties) { 953 return test_vkEnumerateInstanceExtensionProperties(pLayerName, pPropertyCount, pProperties); 954} 955 956FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, 957 uint32_t* pPropertyCount, 958 VkLayerProperties* pProperties) { 959 return test_vkEnumerateDeviceLayerProperties(physicalDevice, pPropertyCount, pProperties); 960} 961FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, 962 const char* pLayerName, 963 uint32_t* pPropertyCount, 964 VkExtensionProperties* pProperties) { 965 return test_vkEnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pPropertyCount, pProperties); 966} 967#endif 968 969#if TEST_LAYER_EXPORT_LAYER_NAMED_GIPA 970FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_layer_GetInstanceProcAddr(VkInstance instance, const char* pName) { 971 return get_instance_func(instance, pName); 972} 973#endif 974 975#if TEST_LAYER_EXPORT_OVERRIDE_GIPA 976FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_override_vkGetInstanceProcAddr(VkInstance instance, 977 const char* pName) { 978 if (string_eq(pName, "vkCreateInstance")) return to_vkVoidFunction(test_override_vkCreateInstance); 979 return get_instance_func(instance, pName); 980} 981#endif 982 983#if TEST_LAYER_EXPORT_LAYER_VK_GIPA 984FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* pName) { 985 return get_instance_func(instance, pName); 986} 987#endif 988 989#if TEST_LAYER_EXPORT_LAYER_NAMED_GDPA 990FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_layer_GetDeviceProcAddr(VkDevice device, const char* pName) { 991 return get_device_func(device, pName); 992} 993#endif 994 995#if TEST_LAYER_EXPORT_OVERRIDE_GDPA 996FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_override_GetDeviceProcAddr(VkDevice device, const char* pName) { 997 return get_device_func(device, pName); 998} 999#endif 1000 1001#if TEST_LAYER_EXPORT_LAYER_VK_GDPA 1002FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* pName) { 1003 return get_device_func(device, pName); 1004} 1005#endif 1006 1007#if TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR 1008FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance, 1009 const char* pName) { 1010 auto func = get_physical_device_func(instance, pName); 1011 if (func != nullptr) return func; 1012 return layer.next_GetPhysicalDeviceProcAddr(instance, pName); 1013} 1014#endif 1015 1016#if LAYER_EXPORT_NEGOTIATE_LOADER_LAYER_INTERFACE_VERSION 1017// vk_layer.h has a forward declaration of vkNegotiateLoaderLayerInterfaceVersion, which doesn't have any attributes 1018// Since FRAMEWORK_EXPORT adds __declspec(dllexport), we can't do that here, thus we need our own macro 1019#if (defined(__GNUC__) && (__GNUC__ >= 4)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) 1020#define EXPORT_NEGOTIATE_FUNCTION __attribute__((visibility("default"))) 1021#else 1022#define EXPORT_NEGOTIATE_FUNCTION 1023#endif 1024 1025EXPORT_NEGOTIATE_FUNCTION VKAPI_ATTR VkResult VKAPI_CALL 1026vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface* pVersionStruct) { 1027 if (pVersionStruct) { 1028 if (pVersionStruct->loaderLayerInterfaceVersion < layer.min_implementation_version) { 1029 return VK_ERROR_INITIALIZATION_FAILED; 1030 } 1031 1032 pVersionStruct->loaderLayerInterfaceVersion = layer.implementation_version; 1033 pVersionStruct->pfnGetInstanceProcAddr = get_instance_func; 1034 pVersionStruct->pfnGetDeviceProcAddr = get_device_func; 1035#if TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR 1036 pVersionStruct->pfnGetPhysicalDeviceProcAddr = vk_layerGetPhysicalDeviceProcAddr; 1037#else 1038 pVersionStruct->pfnGetPhysicalDeviceProcAddr = nullptr; 1039#endif 1040 1041 return VK_SUCCESS; 1042 } 1043 return VK_ERROR_INITIALIZATION_FAILED; 1044} 1045#endif 1046} // extern "C" 1047