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 
81 TestLayer layer;
82 extern "C" {
get_test_layer_func()83 FRAMEWORK_EXPORT TestLayer* get_test_layer_func() { return &layer; }
reset_layer_func()84 FRAMEWORK_EXPORT TestLayer* reset_layer_func() {
85     layer.~TestLayer();
86     return new (&layer) TestLayer();
87 }
88 }
89 
IsInstanceExtensionSupported(const char* extension_name)90 bool 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 
96 bool 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 
102 bool 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 
114 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_instance_func(VkInstance instance, const char* pName);
115 
116 VkLayerInstanceCreateInfo* 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 
125 VkLayerDeviceCreateInfo* 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 
134 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceLayerProperties(uint32_t*, VkLayerProperties*) { return VK_SUCCESS; }
135 
136 VKAPI_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 
182 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceLayerProperties(VkPhysicalDevice, uint32_t*, VkLayerProperties*) {
183     return VK_SUCCESS;
184 }
185 
186 VKAPI_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 
234 VKAPI_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 
241 VKAPI_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 
370 VKAPI_ATTR VkResult VKAPI_CALL test_override_vkCreateInstance(const VkInstanceCreateInfo*, const VkAllocationCallbacks*,
371                                                               VkInstance*) {
372     return VK_ERROR_INVALID_SHADER_NV;
373 }
374 
375 VKAPI_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 
384 VKAPI_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 
464 VKAPI_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 
535 VKAPI_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 
559 VKAPI_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 
649 VKAPI_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 
673 VKAPI_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 
684 VKAPI_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
691 VKAPI_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 }
703 VKAPI_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 }
715 VKAPI_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 }
720 VKAPI_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 }
725 VKAPI_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 
731 VKAPI_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 }
743 VKAPI_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 }
755 VKAPI_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 }
760 VKAPI_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 }
765 VKAPI_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 }
770 VKAPI_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 }
775 VKAPI_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 }
780 VKAPI_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
788 extern "C" {
789 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName);
790 }
791 #endif
792 
793 // trampolines
794 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_device_func(VkDevice device, const char* pName);
795 VKAPI_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 
832 VKAPI_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 
839 VKAPI_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 }
864 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_instance_func(VkInstance instance, const char* pName);
865 VKAPI_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 
886 VKAPI_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
894 extern "C" {
895 #if TEST_LAYER_EXPORT_ENUMERATE_FUNCTIONS
896 
897 // Pre-instance handling functions
898 
899 FRAMEWORK_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 
919 FRAMEWORK_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 
939 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
940 test_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 
946 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t* pPropertyCount,
947                                                                                    VkLayerProperties* pProperties) {
948     return test_vkEnumerateInstanceLayerProperties(pPropertyCount, pProperties);
949 }
950 FRAMEWORK_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 
956 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
957                                                                                  uint32_t* pPropertyCount,
958                                                                                  VkLayerProperties* pProperties) {
959     return test_vkEnumerateDeviceLayerProperties(physicalDevice, pPropertyCount, pProperties);
960 }
961 FRAMEWORK_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
970 FRAMEWORK_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
976 FRAMEWORK_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
984 FRAMEWORK_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
990 FRAMEWORK_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
996 FRAMEWORK_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
1002 FRAMEWORK_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
1008 FRAMEWORK_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 
1025 EXPORT_NEGOTIATE_FUNCTION VKAPI_ATTR VkResult VKAPI_CALL
1026 vkNegotiateLoaderLayerInterfaceVersion(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