1 /*
2  * Copyright (c) 2021-2023 The Khronos Group Inc.
3  * Copyright (c) 2021-2023 Valve Corporation
4  * Copyright (c) 2021-2023 LunarG, Inc.
5  * Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
6  * Copyright (c) 2023-2023 RasterGrid Kft.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and/or associated documentation files (the "Materials"), to
10  * deal in the Materials without restriction, including without limitation the
11  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12  * sell copies of the Materials, and to permit persons to whom the Materials are
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice(s) and this permission notice shall be included in
16  * all copies or substantial portions of the Materials.
17  *
18  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  *
22  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
23  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
25  * USE OR OTHER DEALINGS IN THE MATERIALS.
26  *
27  * Author: Charles Giessen <charles@lunarg.com>
28  */
29 
30 #include "test_icd.h"
31 
32 // export vk_icdGetInstanceProcAddr
33 #if !defined(TEST_ICD_EXPORT_ICD_GIPA)
34 #define TEST_ICD_EXPORT_ICD_GIPA 0
35 #endif
36 
37 // export vk_icdNegotiateLoaderICDInterfaceVersion
38 #if !defined(TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION)
39 #define TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION 0
40 #endif
41 
42 // export vk_icdGetPhysicalDeviceProcAddr
43 #if !defined(TEST_ICD_EXPORT_ICD_GPDPA)
44 #define TEST_ICD_EXPORT_ICD_GPDPA 0
45 #endif
46 
47 // export vk_icdEnumerateAdapterPhysicalDevices
48 #if !defined(TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES)
49 #define TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES 0
50 #endif
51 
52 // expose vk_icdNegotiateLoaderICDInterfaceVersion, vk_icdEnumerateAdapterPhysicalDevices, and vk_icdGetPhysicalDeviceProcAddr
53 // through vk_icdGetInstanceProcAddr or vkGetInstanceProcAddr
54 #if !defined(TEST_ICD_EXPOSE_VERSION_7)
55 #define TEST_ICD_EXPOSE_VERSION_7 0
56 #endif
57 
58 TestICD icd;
59 extern "C" {
get_test_icd_func()60 FRAMEWORK_EXPORT TestICD* get_test_icd_func() { return &icd; }
reset_icd_func()61 FRAMEWORK_EXPORT TestICD* reset_icd_func() {
62     icd.~TestICD();
63     return new (&icd) TestICD();
64 }
65 }
66 
FindLayer(std::vector<LayerDefinition>& layers, std::string layerName)67 LayerDefinition& FindLayer(std::vector<LayerDefinition>& layers, std::string layerName) {
68     for (auto& layer : layers) {
69         if (layer.layerName == layerName) return layer;
70     }
71     assert(false && "Layer name not found!");
72     return layers[0];
73 }
CheckLayer(std::vector<LayerDefinition>& layers, std::string layerName)74 bool CheckLayer(std::vector<LayerDefinition>& layers, std::string layerName) {
75     for (auto& layer : layers) {
76         if (layer.layerName == layerName) return true;
77     }
78     return false;
79 }
80 
IsInstanceExtensionSupported(const char* extension_name)81 bool IsInstanceExtensionSupported(const char* extension_name) {
82     return icd.instance_extensions.end() !=
83            std::find_if(icd.instance_extensions.begin(), icd.instance_extensions.end(),
84                         [extension_name](Extension const& ext) { return string_eq(&ext.extensionName[0], extension_name); });
85 }
86 
87 bool IsInstanceExtensionEnabled(const char* extension_name) {
88     return icd.enabled_instance_extensions.end() !=
89            std::find_if(icd.enabled_instance_extensions.begin(), icd.enabled_instance_extensions.end(),
90                         [extension_name](Extension const& ext) { return string_eq(&ext.extensionName[0], extension_name); });
91 }
92 
93 bool IsPhysicalDeviceExtensionAvailable(const char* extension_name) {
94     for (auto& phys_dev : icd.physical_devices) {
95         if (phys_dev.extensions.end() !=
96             std::find_if(phys_dev.extensions.begin(), phys_dev.extensions.end(),
97                          [extension_name](Extension const& ext) { return ext.extensionName == extension_name; })) {
98             return true;
99         }
100     }
101     return false;
102 }
103 
104 // typename T must have '.get()' function that returns a type U
105 template <typename T, typename U>
106 VkResult FillCountPtr(std::vector<T> const& data_vec, uint32_t* pCount, U* pData) {
107     if (pCount == nullptr) {
108         return VK_ERROR_OUT_OF_HOST_MEMORY;
109     }
110     if (pData == nullptr) {
111         *pCount = static_cast<uint32_t>(data_vec.size());
112         return VK_SUCCESS;
113     }
114     uint32_t amount_written = 0;
115     uint32_t amount_to_write = static_cast<uint32_t>(data_vec.size());
116     if (*pCount < data_vec.size()) {
117         amount_to_write = *pCount;
118     }
119     for (size_t i = 0; i < amount_to_write; i++) {
120         pData[i] = data_vec[i].get();
121         amount_written++;
122     }
123     if (*pCount < data_vec.size()) {
124         *pCount = amount_written;
125         return VK_INCOMPLETE;
126     }
127     *pCount = amount_written;
128     return VK_SUCCESS;
129 }
130 
131 template <typename T>
132 VkResult FillCountPtr(std::vector<T> const& data_vec, uint32_t* pCount, T* pData) {
133     if (pCount == nullptr) {
134         return VK_ERROR_OUT_OF_HOST_MEMORY;
135     }
136     if (pData == nullptr) {
137         *pCount = static_cast<uint32_t>(data_vec.size());
138         return VK_SUCCESS;
139     }
140     uint32_t amount_written = 0;
141     uint32_t amount_to_write = static_cast<uint32_t>(data_vec.size());
142     if (*pCount < data_vec.size()) {
143         amount_to_write = *pCount;
144     }
145     for (size_t i = 0; i < amount_to_write; i++) {
146         pData[i] = data_vec[i];
147         amount_written++;
148     }
149     if (*pCount < data_vec.size()) {
150         *pCount = amount_written;
151         return VK_INCOMPLETE;
152     }
153     *pCount = amount_written;
154     return VK_SUCCESS;
155 }
156 
157 //// Instance Functions ////
158 
159 // VK_SUCCESS,VK_INCOMPLETE
160 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceExtensionProperties(const char* pLayerName, uint32_t* pPropertyCount,
161                                                                            VkExtensionProperties* pProperties) {
162     if (pLayerName != nullptr) {
163         auto& layer = FindLayer(icd.instance_layers, std::string(pLayerName));
164         return FillCountPtr(layer.extensions, pPropertyCount, pProperties);
165     } else {  // instance extensions
166         FillCountPtr(icd.instance_extensions, pPropertyCount, pProperties);
167     }
168 
169     return VK_SUCCESS;
170 }
171 
172 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceLayerProperties(uint32_t* pPropertyCount, VkLayerProperties* pProperties) {
173     return FillCountPtr(icd.instance_layers, pPropertyCount, pProperties);
174 }
175 
176 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceVersion(uint32_t* pApiVersion) {
177     if (pApiVersion != nullptr) {
178         *pApiVersion = icd.icd_api_version;
179     }
180     return VK_SUCCESS;
181 }
182 
183 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
184                                                      [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
185                                                      VkInstance* pInstance) {
186     if (pCreateInfo == nullptr || pCreateInfo->pApplicationInfo == nullptr) {
187         return VK_ERROR_OUT_OF_HOST_MEMORY;
188     }
189 
190     if (icd.icd_api_version < VK_API_VERSION_1_1) {
191         if (pCreateInfo->pApplicationInfo->apiVersion > VK_API_VERSION_1_0) {
192             return VK_ERROR_INCOMPATIBLE_DRIVER;
193         }
194     }
195 
196     // Add to the list of enabled extensions only those that the ICD actively supports
197     for (uint32_t iii = 0; iii < pCreateInfo->enabledExtensionCount; ++iii) {
198         if (IsInstanceExtensionSupported(pCreateInfo->ppEnabledExtensionNames[iii])) {
199             icd.add_enabled_instance_extension({pCreateInfo->ppEnabledExtensionNames[iii]});
200         }
201     }
202 
203     // VK_SUCCESS
204     *pInstance = icd.instance_handle.handle;
205 
206     icd.passed_in_instance_create_flags = pCreateInfo->flags;
207 
208     return VK_SUCCESS;
209 }
210 
211 VKAPI_ATTR void VKAPI_CALL test_vkDestroyInstance([[maybe_unused]] VkInstance instance,
212                                                   [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {}
213 
214 // VK_SUCCESS,VK_INCOMPLETE
215 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDevices([[maybe_unused]] VkInstance instance, uint32_t* pPhysicalDeviceCount,
216                                                                VkPhysicalDevice* pPhysicalDevices) {
217     if (pPhysicalDevices == nullptr) {
218         *pPhysicalDeviceCount = static_cast<uint32_t>(icd.physical_devices.size());
219     } else {
220         uint32_t handles_written = 0;
221         for (size_t i = 0; i < icd.physical_devices.size(); i++) {
222             if (i < *pPhysicalDeviceCount) {
223                 handles_written++;
224                 pPhysicalDevices[i] = icd.physical_devices[i].vk_physical_device.handle;
225             } else {
226                 *pPhysicalDeviceCount = handles_written;
227                 return VK_INCOMPLETE;
228             }
229         }
230         *pPhysicalDeviceCount = handles_written;
231     }
232     return VK_SUCCESS;
233 }
234 
235 // VK_SUCCESS,VK_INCOMPLETE, VK_ERROR_INITIALIZATION_FAILED
236 VKAPI_ATTR VkResult VKAPI_CALL
237 test_vkEnumeratePhysicalDeviceGroups([[maybe_unused]] VkInstance instance, uint32_t* pPhysicalDeviceGroupCount,
238                                      VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
239     VkResult result = VK_SUCCESS;
240 
241     if (pPhysicalDeviceGroupProperties == nullptr) {
242         if (0 == icd.physical_device_groups.size()) {
243             *pPhysicalDeviceGroupCount = static_cast<uint32_t>(icd.physical_devices.size());
244         } else {
245             *pPhysicalDeviceGroupCount = static_cast<uint32_t>(icd.physical_device_groups.size());
246         }
247     } else {
248         // NOTE: This is a fake struct to make sure the pNext chain is properly passed down to the ICD
249         //       vkEnumeratePhysicalDeviceGroups.
250         //       The two versions must match:
251         //           "FakePNext" test in loader_regresion_tests.cpp
252         //           "test_vkEnumeratePhysicalDeviceGroups" in test_icd.cpp
253         struct FakePnextSharedWithICD {
254             VkStructureType sType;
255             void* pNext;
256             uint32_t value;
257         };
258 
259         uint32_t group_count = 0;
260         if (0 == icd.physical_device_groups.size()) {
261             group_count = static_cast<uint32_t>(icd.physical_devices.size());
262             for (size_t device_group = 0; device_group < icd.physical_devices.size(); device_group++) {
263                 if (device_group >= *pPhysicalDeviceGroupCount) {
264                     group_count = *pPhysicalDeviceGroupCount;
265                     result = VK_INCOMPLETE;
266                     break;
267                 }
268                 pPhysicalDeviceGroupProperties[device_group].subsetAllocation = false;
269                 pPhysicalDeviceGroupProperties[device_group].physicalDeviceCount = 1;
270                 pPhysicalDeviceGroupProperties[device_group].physicalDevices[0] =
271                     icd.physical_devices[device_group].vk_physical_device.handle;
272                 for (size_t i = 1; i < VK_MAX_DEVICE_GROUP_SIZE; i++) {
273                     pPhysicalDeviceGroupProperties[device_group].physicalDevices[i] = {};
274                 }
275             }
276         } else {
277             group_count = static_cast<uint32_t>(icd.physical_device_groups.size());
278             for (size_t device_group = 0; device_group < icd.physical_device_groups.size(); device_group++) {
279                 if (device_group >= *pPhysicalDeviceGroupCount) {
280                     group_count = *pPhysicalDeviceGroupCount;
281                     result = VK_INCOMPLETE;
282                     break;
283                 }
284                 pPhysicalDeviceGroupProperties[device_group].subsetAllocation =
285                     icd.physical_device_groups[device_group].subset_allocation;
286                 uint32_t handles_written = 0;
287                 for (size_t i = 0; i < icd.physical_device_groups[device_group].physical_device_handles.size(); i++) {
288                     handles_written++;
289                     pPhysicalDeviceGroupProperties[device_group].physicalDevices[i] =
290                         icd.physical_device_groups[device_group].physical_device_handles[i]->vk_physical_device.handle;
291                 }
292                 for (size_t i = handles_written; i < VK_MAX_DEVICE_GROUP_SIZE; i++) {
293                     pPhysicalDeviceGroupProperties[device_group].physicalDevices[i] = {};
294                 }
295                 pPhysicalDeviceGroupProperties[device_group].physicalDeviceCount = handles_written;
296             }
297         }
298         // NOTE: The following code is purely to test pNext passing in vkEnumeratePhysicalDevice groups
299         //       and includes normally invalid information.
300         for (size_t device_group = 0; device_group < group_count; device_group++) {
301             if (nullptr != pPhysicalDeviceGroupProperties[device_group].pNext) {
302                 VkBaseInStructure* base = reinterpret_cast<VkBaseInStructure*>(pPhysicalDeviceGroupProperties[device_group].pNext);
303                 if (base->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT) {
304                     FakePnextSharedWithICD* fake = reinterpret_cast<FakePnextSharedWithICD*>(base);
305                     fake->value = 0xDECAFBAD;
306                 }
307             }
308         }
309         *pPhysicalDeviceGroupCount = static_cast<uint32_t>(group_count);
310     }
311     return result;
312 }
313 
314 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDebugUtilsMessengerEXT(
315     [[maybe_unused]] VkInstance instance, [[maybe_unused]] const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
316     [[maybe_unused]] const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pMessenger) {
317     if (nullptr != pMessenger) {
318         uint64_t fake_msgr_handle = reinterpret_cast<uint64_t>(new uint8_t);
319         icd.messenger_handles.push_back(fake_msgr_handle);
320 #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || \
321     defined(_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
322         *pMessenger = reinterpret_cast<VkDebugUtilsMessengerEXT>(fake_msgr_handle);
323 #else
324         *pMessenger = fake_msgr_handle;
325 #endif
326     }
327     return VK_SUCCESS;
328 }
329 
330 VKAPI_ATTR void VKAPI_CALL test_vkDestroyDebugUtilsMessengerEXT([[maybe_unused]] VkInstance instance,
331                                                                 VkDebugUtilsMessengerEXT messenger,
332                                                                 [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {
333     if (messenger != VK_NULL_HANDLE) {
334         uint64_t fake_msgr_handle = (uint64_t)(messenger);
335         auto found_iter = std::find(icd.messenger_handles.begin(), icd.messenger_handles.end(), fake_msgr_handle);
336         if (found_iter != icd.messenger_handles.end()) {
337             // Remove it from the list
338             icd.messenger_handles.erase(found_iter);
339             // Delete the handle
340             delete (uint8_t*)fake_msgr_handle;
341         } else {
342             assert(false && "Messenger not found during destroy!");
343         }
344     }
345 }
346 
347 // Debug utils & debug marker ext stubs
348 VKAPI_ATTR VkResult VKAPI_CALL test_vkDebugMarkerSetObjectTagEXT(VkDevice dev, const VkDebugMarkerObjectTagInfoEXT* pTagInfo) {
349     if (pTagInfo && pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {
350         VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pTagInfo->object);
351         if (pd != icd.physical_devices.at(icd.lookup_device(dev).phys_dev_index).vk_physical_device.handle)
352             return VK_ERROR_DEVICE_LOST;
353     }
354     if (pTagInfo && pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {
355         if (pTagInfo->object != icd.surface_handles.at(0)) return VK_ERROR_DEVICE_LOST;
356     }
357     if (pTagInfo && pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT) {
358         if (pTagInfo->object != (uint64_t)(uintptr_t)icd.instance_handle.handle) return VK_ERROR_DEVICE_LOST;
359     }
360     return VK_SUCCESS;
361 }
362 VKAPI_ATTR VkResult VKAPI_CALL test_vkDebugMarkerSetObjectNameEXT(VkDevice dev, const VkDebugMarkerObjectNameInfoEXT* pNameInfo) {
363     if (pNameInfo && pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {
364         VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pNameInfo->object);
365         if (pd != icd.physical_devices.at(icd.lookup_device(dev).phys_dev_index).vk_physical_device.handle)
366             return VK_ERROR_DEVICE_LOST;
367     }
368     if (pNameInfo && pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {
369         if (pNameInfo->object != icd.surface_handles.at(0)) return VK_ERROR_DEVICE_LOST;
370     }
371     if (pNameInfo && pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT) {
372         if (pNameInfo->object != (uint64_t)(uintptr_t)icd.instance_handle.handle) return VK_ERROR_DEVICE_LOST;
373     }
374     return VK_SUCCESS;
375 }
376 VKAPI_ATTR void VKAPI_CALL test_vkCmdDebugMarkerBeginEXT(VkCommandBuffer, const VkDebugMarkerMarkerInfoEXT*) {}
377 VKAPI_ATTR void VKAPI_CALL test_vkCmdDebugMarkerEndEXT(VkCommandBuffer) {}
378 VKAPI_ATTR void VKAPI_CALL test_vkCmdDebugMarkerInsertEXT(VkCommandBuffer, const VkDebugMarkerMarkerInfoEXT*) {}
379 
380 VKAPI_ATTR VkResult VKAPI_CALL test_vkSetDebugUtilsObjectNameEXT(VkDevice dev, const VkDebugUtilsObjectNameInfoEXT* pNameInfo) {
381     if (pNameInfo && pNameInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {
382         VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pNameInfo->objectHandle);
383         if (pd != icd.physical_devices.at(icd.lookup_device(dev).phys_dev_index).vk_physical_device.handle)
384             return VK_ERROR_DEVICE_LOST;
385     }
386     if (pNameInfo && pNameInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) {
387         if (pNameInfo->objectHandle != icd.surface_handles.at(0)) return VK_ERROR_DEVICE_LOST;
388     }
389     if (pNameInfo && pNameInfo->objectType == VK_OBJECT_TYPE_INSTANCE) {
390         if (pNameInfo->objectHandle != (uint64_t)(uintptr_t)icd.instance_handle.handle) return VK_ERROR_DEVICE_LOST;
391     }
392     return VK_SUCCESS;
393 }
394 VKAPI_ATTR VkResult VKAPI_CALL test_vkSetDebugUtilsObjectTagEXT(VkDevice dev, const VkDebugUtilsObjectTagInfoEXT* pTagInfo) {
395     if (pTagInfo && pTagInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {
396         VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pTagInfo->objectHandle);
397         if (pd != icd.physical_devices.at(icd.lookup_device(dev).phys_dev_index).vk_physical_device.handle)
398             return VK_ERROR_DEVICE_LOST;
399     }
400     if (pTagInfo && pTagInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) {
401         if (pTagInfo->objectHandle != icd.surface_handles.at(0)) return VK_ERROR_DEVICE_LOST;
402     }
403     if (pTagInfo && pTagInfo->objectType == VK_OBJECT_TYPE_INSTANCE) {
404         if (pTagInfo->objectHandle != (uint64_t)(uintptr_t)icd.instance_handle.handle) return VK_ERROR_DEVICE_LOST;
405     }
406     return VK_SUCCESS;
407 }
408 VKAPI_ATTR void VKAPI_CALL test_vkQueueBeginDebugUtilsLabelEXT(VkQueue, const VkDebugUtilsLabelEXT*) {}
409 VKAPI_ATTR void VKAPI_CALL test_vkQueueEndDebugUtilsLabelEXT(VkQueue) {}
410 VKAPI_ATTR void VKAPI_CALL test_vkQueueInsertDebugUtilsLabelEXT(VkQueue, const VkDebugUtilsLabelEXT*) {}
411 VKAPI_ATTR void VKAPI_CALL test_vkCmdBeginDebugUtilsLabelEXT(VkCommandBuffer, const VkDebugUtilsLabelEXT*) {}
412 VKAPI_ATTR void VKAPI_CALL test_vkCmdEndDebugUtilsLabelEXT(VkCommandBuffer) {}
413 VKAPI_ATTR void VKAPI_CALL test_vkCmdInsertDebugUtilsLabelEXT(VkCommandBuffer, const VkDebugUtilsLabelEXT*) {}
414 
415 //// Physical Device functions ////
416 
417 // VK_SUCCESS,VK_INCOMPLETE
418 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceLayerProperties(VkPhysicalDevice, uint32_t*, VkLayerProperties*) {
419     assert(false && "ICD's don't contain layers???");
420     return VK_SUCCESS;
421 }
422 
423 // VK_SUCCESS, VK_INCOMPLETE, VK_ERROR_LAYER_NOT_PRESENT
424 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char* pLayerName,
425                                                                          uint32_t* pPropertyCount,
426                                                                          VkExtensionProperties* pProperties) {
427     auto& phys_dev = icd.GetPhysDevice(physicalDevice);
428     if (pLayerName != nullptr) {
429         assert(false && "Drivers don't contain layers???");
430         return VK_SUCCESS;
431     } else {  // instance extensions
432         return FillCountPtr(phys_dev.extensions, pPropertyCount, pProperties);
433     }
434 }
435 
436 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
437                                                                          uint32_t* pQueueFamilyPropertyCount,
438                                                                          VkQueueFamilyProperties* pQueueFamilyProperties) {
439     auto& phys_dev = icd.GetPhysDevice(physicalDevice);
440     FillCountPtr(phys_dev.queue_family_properties, pQueueFamilyPropertyCount, pQueueFamilyProperties);
441 }
442 
443 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo,
444                                                    [[maybe_unused]] const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) {
445     // VK_SUCCESS
446     auto found = std::find_if(icd.physical_devices.begin(), icd.physical_devices.end(), [physicalDevice](PhysicalDevice& phys_dev) {
447         return phys_dev.vk_physical_device.handle == physicalDevice;
448     });
449     if (found == icd.physical_devices.end()) return VK_ERROR_INITIALIZATION_FAILED;
450     auto device_handle = DispatchableHandle<VkDevice>();
451     *pDevice = device_handle.handle;
452     found->device_handles.push_back(device_handle.handle);
453     found->device_create_infos.push_back(DeviceCreateInfo{pCreateInfo});
454     for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
455         found->queue_handles.emplace_back();
456     }
457     icd.device_handles.emplace_back(std::move(device_handle));
458 
459     return VK_SUCCESS;
460 }
461 
462 VKAPI_ATTR void VKAPI_CALL test_vkDestroyDevice(VkDevice device, [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {
463     auto found = std::find(icd.device_handles.begin(), icd.device_handles.end(), device);
464     if (found != icd.device_handles.end()) icd.device_handles.erase(found);
465     auto fd = icd.lookup_device(device);
466     if (!fd.found) return;
467     auto& phys_dev = icd.physical_devices.at(fd.phys_dev_index);
468     phys_dev.device_handles.erase(phys_dev.device_handles.begin() + fd.dev_index);
469     phys_dev.device_create_infos.erase(phys_dev.device_create_infos.begin() + fd.dev_index);
470 }
471 
472 VKAPI_ATTR VkResult VKAPI_CALL generic_tool_props_function([[maybe_unused]] VkPhysicalDevice physicalDevice, uint32_t* pToolCount,
473                                                            VkPhysicalDeviceToolPropertiesEXT* pToolProperties) {
474     if (icd.tooling_properties.size() == 0) {
475         return VK_SUCCESS;
476     }
477     if (pToolProperties == nullptr && pToolCount != nullptr) {
478         *pToolCount = static_cast<uint32_t>(icd.tooling_properties.size());
479     } else if (pToolCount != nullptr) {
480         for (size_t i = 0; i < *pToolCount; i++) {
481             if (i >= icd.tooling_properties.size()) {
482                 return VK_INCOMPLETE;
483             }
484             pToolProperties[i] = icd.tooling_properties[i];
485         }
486     }
487     return VK_SUCCESS;
488 }
489 
490 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceToolPropertiesEXT(VkPhysicalDevice physicalDevice, uint32_t* pToolCount,
491                                                                          VkPhysicalDeviceToolPropertiesEXT* pToolProperties) {
492     return generic_tool_props_function(physicalDevice, pToolCount, pToolProperties);
493 }
494 
495 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceToolProperties(VkPhysicalDevice physicalDevice, uint32_t* pToolCount,
496                                                                       VkPhysicalDeviceToolPropertiesEXT* pToolProperties) {
497     return generic_tool_props_function(physicalDevice, pToolCount, pToolProperties);
498 }
499 
500 template <typename T>
501 T to_nondispatch_handle(uint64_t handle) {
502 #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || \
503     defined(_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
504     return reinterpret_cast<T>(handle);
505 #else
506     return handle;
507 #endif
508 }
509 
510 template <typename T>
511 uint64_t from_nondispatch_handle(T handle) {
512 #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || \
513     defined(_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
514     return reinterpret_cast<uint64_t>(handle);
515 #else
516     return handle;
517 #endif
518 }
519 
520 //// WSI ////
521 template <typename HandleType>
522 void common_nondispatch_handle_creation(std::vector<uint64_t>& handles, HandleType* pHandle) {
523     if (nullptr != pHandle) {
524         if (handles.size() == 0)
525             handles.push_back(800851234);
526         else
527             handles.push_back(handles.back() + 102030);
528         *pHandle = to_nondispatch_handle<HandleType>(handles.back());
529     }
530 }
531 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
532 
533 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo,
534                                                               const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
535     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
536     return VK_SUCCESS;
537 }
538 #endif
539 
540 #if defined(VK_USE_PLATFORM_WIN32_KHR)
541 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateWin32SurfaceKHR([[maybe_unused]] VkInstance instance,
542                                                             [[maybe_unused]] const VkWin32SurfaceCreateInfoKHR* pCreateInfo,
543                                                             [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
544                                                             VkSurfaceKHR* pSurface) {
545     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
546     return VK_SUCCESS;
547 }
548 
549 VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice, uint32_t) { return VK_TRUE; }
550 #endif  // VK_USE_PLATFORM_WIN32_KHR
551 
552 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
553 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateWaylandSurfaceKHR([[maybe_unused]] VkInstance instance,
554                                                               [[maybe_unused]] const VkWaylandSurfaceCreateInfoKHR* pCreateInfo,
555                                                               [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
556                                                               VkSurfaceKHR* pSurface) {
557     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
558     return VK_SUCCESS;
559 }
560 
561 VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice, uint32_t,
562                                                                                      struct wl_display*) {
563     return VK_TRUE;
564 }
565 #endif  // VK_USE_PLATFORM_WAYLAND_KHR
566 #if defined(VK_USE_PLATFORM_XCB_KHR)
567 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateXcbSurfaceKHR([[maybe_unused]] VkInstance instance,
568                                                           [[maybe_unused]] const VkXcbSurfaceCreateInfoKHR* pCreateInfo,
569                                                           [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
570                                                           VkSurfaceKHR* pSurface) {
571     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
572     return VK_SUCCESS;
573 }
574 
575 VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice, uint32_t, xcb_connection_t*,
576                                                                                  xcb_visualid_t) {
577     return VK_TRUE;
578 }
579 #endif  // VK_USE_PLATFORM_XCB_KHR
580 
581 #if defined(VK_USE_PLATFORM_XLIB_KHR)
582 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateXlibSurfaceKHR([[maybe_unused]] VkInstance instance,
583                                                            [[maybe_unused]] const VkXlibSurfaceCreateInfoKHR* pCreateInfo,
584                                                            [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
585                                                            VkSurfaceKHR* pSurface) {
586     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
587     return VK_SUCCESS;
588 }
589 
590 VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice, uint32_t, Display*, VisualID) {
591     return VK_TRUE;
592 }
593 #endif  // VK_USE_PLATFORM_XLIB_KHR
594 
595 #if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
596 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDirectFBSurfaceEXT(VkInstance instance,
597                                                                const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo,
598                                                                const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
599     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
600     return VK_SUCCESS;
601 }
602 
603 VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceDirectFBPresentationSupportEXT(VkPhysicalDevice physicalDevice,
604                                                                                       uint32_t queueFamilyIndex, IDirectFB* dfb) {
605     return VK_TRUE;
606 }
607 
608 #endif  // VK_USE_PLATFORM_DIRECTFB_EXT
609 
610 #if defined(VK_USE_PLATFORM_MACOS_MVK)
611 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateMacOSSurfaceMVK([[maybe_unused]] VkInstance instance,
612                                                             [[maybe_unused]] const VkMacOSSurfaceCreateInfoMVK* pCreateInfo,
613                                                             [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
614                                                             VkSurfaceKHR* pSurface) {
615     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
616     return VK_SUCCESS;
617 }
618 #endif  // VK_USE_PLATFORM_MACOS_MVK
619 
620 #if defined(VK_USE_PLATFORM_IOS_MVK)
621 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateIOSSurfaceMVK([[maybe_unused]] VkInstance instance,
622                                                           [[maybe_unused]] const VkIOSSurfaceCreateInfoMVK* pCreateInfo,
623                                                           [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
624                                                           VkSurfaceKHR* pSurface) {
625     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
626     return VK_SUCCESS;
627 }
628 #endif  // VK_USE_PLATFORM_IOS_MVK
629 
630 #if defined(VK_USE_PLATFORM_GGP)
631 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateStreamDescriptorSurfaceGGP(VkInstance instance,
632                                                                        const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo,
633                                                                        const VkAllocationCallbacks* pAllocator,
634                                                                        VkSurfaceKHR* pSurface) {
635     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
636     return VK_SUCCESS;
637 }
638 #endif  // VK_USE_PLATFORM_GGP
639 
640 #if defined(VK_USE_PLATFORM_METAL_EXT)
641 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateMetalSurfaceEXT([[maybe_unused]] VkInstance instance,
642                                                             [[maybe_unused]] const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
643                                                             [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
644                                                             VkSurfaceKHR* pSurface) {
645     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
646     return VK_SUCCESS;
647 }
648 #endif  // VK_USE_PLATFORM_METAL_EXT
649 
650 #if defined(VK_USE_PLATFORM_SCREEN_QNX)
651 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateScreenSurfaceQNX(VkInstance instance, const VkScreenSurfaceCreateInfoQNX* pCreateInfo,
652                                                              const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
653     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
654     return VK_SUCCESS;
655 }
656 
657 VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice,
658                                                                                     uint32_t queueFamilyIndex,
659                                                                                     struct _screen_window* window) {
660     return VK_TRUE;
661 }
662 #endif  // VK_USE_PLATFORM_SCREEN_QNX
663 
664 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateHeadlessSurfaceEXT([[maybe_unused]] VkInstance instance,
665                                                                [[maybe_unused]] const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo,
666                                                                [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
667                                                                VkSurfaceKHR* pSurface) {
668     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
669     return VK_SUCCESS;
670 }
671 
672 VKAPI_ATTR void VKAPI_CALL test_vkDestroySurfaceKHR([[maybe_unused]] VkInstance instance, VkSurfaceKHR surface,
673                                                     [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {
674     if (surface != VK_NULL_HANDLE) {
675         uint64_t fake_surf_handle = from_nondispatch_handle(surface);
676         auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
677         if (found_iter != icd.surface_handles.end()) {
678             // Remove it from the list
679             icd.surface_handles.erase(found_iter);
680         } else {
681             assert(false && "Surface not found during destroy!");
682         }
683     }
684 }
685 // VK_KHR_swapchain
686 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateSwapchainKHR([[maybe_unused]] VkDevice device,
687                                                          [[maybe_unused]] const VkSwapchainCreateInfoKHR* pCreateInfo,
688                                                          [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
689                                                          VkSwapchainKHR* pSwapchain) {
690     common_nondispatch_handle_creation(icd.swapchain_handles, pSwapchain);
691     return VK_SUCCESS;
692 }
693 
694 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetSwapchainImagesKHR([[maybe_unused]] VkDevice device,
695                                                             [[maybe_unused]] VkSwapchainKHR swapchain,
696                                                             uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages) {
697     std::vector<uint64_t> handles{123, 234, 345, 345, 456};
698     if (pSwapchainImages == nullptr) {
699         if (pSwapchainImageCount) *pSwapchainImageCount = static_cast<uint32_t>(handles.size());
700     } else if (pSwapchainImageCount) {
701         for (uint32_t i = 0; i < *pSwapchainImageCount && i < handles.size(); i++) {
702             pSwapchainImages[i] = to_nondispatch_handle<VkImage>(handles.back());
703         }
704         if (*pSwapchainImageCount < handles.size()) return VK_INCOMPLETE;
705     }
706     return VK_SUCCESS;
707 }
708 
709 VKAPI_ATTR void VKAPI_CALL test_vkDestroySwapchainKHR([[maybe_unused]] VkDevice device, VkSwapchainKHR swapchain,
710                                                       [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {
711     if (swapchain != VK_NULL_HANDLE) {
712         uint64_t fake_swapchain_handle = from_nondispatch_handle(swapchain);
713         auto found_iter = icd.swapchain_handles.erase(
714             std::remove(icd.swapchain_handles.begin(), icd.swapchain_handles.end(), fake_swapchain_handle),
715             icd.swapchain_handles.end());
716         if (!icd.swapchain_handles.empty() && found_iter == icd.swapchain_handles.end()) {
717             assert(false && "Swapchain not found during destroy!");
718         }
719     }
720 }
721 // VK_KHR_swapchain with 1.1
722 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDeviceGroupSurfacePresentModesKHR([[maybe_unused]] VkDevice device,
723                                                                            [[maybe_unused]] VkSurfaceKHR surface,
724                                                                            VkDeviceGroupPresentModeFlagsKHR* pModes) {
725     if (!pModes) return VK_ERROR_INITIALIZATION_FAILED;
726     *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR;
727     return VK_SUCCESS;
728 }
729 
730 // VK_KHR_surface
731 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
732                                                                          VkSurfaceKHR surface, VkBool32* pSupported) {
733     if (surface != VK_NULL_HANDLE) {
734         uint64_t fake_surf_handle = (uint64_t)(surface);
735         auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
736         if (found_iter == icd.surface_handles.end()) {
737             assert(false && "Surface not found during GetPhysicalDeviceSurfaceSupportKHR query!");
738             return VK_ERROR_UNKNOWN;
739         }
740     }
741     if (nullptr != pSupported) {
742         *pSupported = icd.GetPhysDevice(physicalDevice).queue_family_properties.at(queueFamilyIndex).support_present;
743     }
744     return VK_SUCCESS;
745 }
746 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
747                                                                               VkSurfaceCapabilitiesKHR* pSurfaceCapabilities) {
748     if (surface != VK_NULL_HANDLE) {
749         uint64_t fake_surf_handle = (uint64_t)(surface);
750         auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
751         if (found_iter == icd.surface_handles.end()) {
752             assert(false && "Surface not found during GetPhysicalDeviceSurfaceCapabilitiesKHR query!");
753             return VK_ERROR_UNKNOWN;
754         }
755     }
756     if (nullptr != pSurfaceCapabilities) {
757         *pSurfaceCapabilities = icd.GetPhysDevice(physicalDevice).surface_capabilities;
758     }
759     return VK_SUCCESS;
760 }
761 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
762                                                                          uint32_t* pSurfaceFormatCount,
763                                                                          VkSurfaceFormatKHR* pSurfaceFormats) {
764     if (surface != VK_NULL_HANDLE) {
765         uint64_t fake_surf_handle = (uint64_t)(surface);
766         auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
767         if (found_iter == icd.surface_handles.end()) {
768             assert(false && "Surface not found during GetPhysicalDeviceSurfaceFormatsKHR query!");
769             return VK_ERROR_UNKNOWN;
770         }
771     }
772     FillCountPtr(icd.GetPhysDevice(physicalDevice).surface_formats, pSurfaceFormatCount, pSurfaceFormats);
773     return VK_SUCCESS;
774 }
775 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
776                                                                               uint32_t* pPresentModeCount,
777                                                                               VkPresentModeKHR* pPresentModes) {
778     if (surface != VK_NULL_HANDLE) {
779         uint64_t fake_surf_handle = (uint64_t)(surface);
780         auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
781         if (found_iter == icd.surface_handles.end()) {
782             assert(false && "Surface not found during GetPhysicalDeviceSurfacePresentModesKHR query!");
783             return VK_ERROR_UNKNOWN;
784         }
785     }
786     FillCountPtr(icd.GetPhysDevice(physicalDevice).surface_present_modes, pPresentModeCount, pPresentModes);
787     return VK_SUCCESS;
788 }
789 
790 // VK_KHR_display
791 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
792                                                                             uint32_t* pPropertyCount,
793                                                                             VkDisplayPropertiesKHR* pProperties) {
794     FillCountPtr(icd.GetPhysDevice(physicalDevice).display_properties, pPropertyCount, pProperties);
795     return VK_SUCCESS;
796 }
797 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,
798                                                                                  uint32_t* pPropertyCount,
799                                                                                  VkDisplayPlanePropertiesKHR* pProperties) {
800     FillCountPtr(icd.GetPhysDevice(physicalDevice).display_plane_properties, pPropertyCount, pProperties);
801     return VK_SUCCESS;
802 }
803 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice,
804                                                                           [[maybe_unused]] uint32_t planeIndex,
805                                                                           uint32_t* pDisplayCount, VkDisplayKHR* pDisplays) {
806     FillCountPtr(icd.GetPhysDevice(physicalDevice).displays, pDisplayCount, pDisplays);
807     return VK_SUCCESS;
808 }
809 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice,
810                                                                   [[maybe_unused]] VkDisplayKHR display, uint32_t* pPropertyCount,
811                                                                   VkDisplayModePropertiesKHR* pProperties) {
812     FillCountPtr(icd.GetPhysDevice(physicalDevice).display_mode_properties, pPropertyCount, pProperties);
813     return VK_SUCCESS;
814 }
815 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, [[maybe_unused]] VkDisplayKHR display,
816                                                            [[maybe_unused]] const VkDisplayModeCreateInfoKHR* pCreateInfo,
817                                                            [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
818                                                            VkDisplayModeKHR* pMode) {
819     if (nullptr != pMode) {
820         *pMode = icd.GetPhysDevice(physicalDevice).display_mode;
821     }
822     return VK_SUCCESS;
823 }
824 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice,
825                                                                      [[maybe_unused]] VkDisplayModeKHR mode,
826                                                                      [[maybe_unused]] uint32_t planeIndex,
827                                                                      VkDisplayPlaneCapabilitiesKHR* pCapabilities) {
828     if (nullptr != pCapabilities) {
829         *pCapabilities = icd.GetPhysDevice(physicalDevice).display_plane_capabilities;
830     }
831     return VK_SUCCESS;
832 }
833 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDisplayPlaneSurfaceKHR(
834     [[maybe_unused]] VkInstance instance, [[maybe_unused]] const VkDisplaySurfaceCreateInfoKHR* pCreateInfo,
835     [[maybe_unused]] const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
836     common_nondispatch_handle_creation(icd.surface_handles, pSurface);
837     return VK_SUCCESS;
838 }
839 
840 // VK_KHR_get_surface_capabilities2
841 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,
842                                                                                const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
843                                                                                VkSurfaceCapabilities2KHR* pSurfaceCapabilities) {
844     if (nullptr != pSurfaceInfo && nullptr != pSurfaceCapabilities) {
845         return test_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, pSurfaceInfo->surface,
846                                                               &pSurfaceCapabilities->surfaceCapabilities);
847     }
848     return VK_SUCCESS;
849 }
850 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
851                                                                           const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
852                                                                           uint32_t* pSurfaceFormatCount,
853                                                                           VkSurfaceFormat2KHR* pSurfaceFormats) {
854     if (nullptr != pSurfaceFormatCount) {
855         test_vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, pSurfaceInfo->surface, pSurfaceFormatCount, nullptr);
856         if (nullptr != pSurfaceFormats) {
857             auto& phys_dev = icd.GetPhysDevice(physicalDevice);
858             // Since the structures are different, we have to copy each item over seperately.  Since we have multiple, we
859             // have to manually copy the data here instead of calling the next function
860             for (uint32_t cnt = 0; cnt < *pSurfaceFormatCount; ++cnt) {
861                 memcpy(&pSurfaceFormats[cnt].surfaceFormat, &phys_dev.surface_formats[cnt], sizeof(VkSurfaceFormatKHR));
862             }
863         }
864     }
865     return VK_SUCCESS;
866 }
867 // VK_KHR_display_swapchain
868 VkResult test_vkCreateSharedSwapchainsKHR([[maybe_unused]] VkDevice device, uint32_t swapchainCount,
869                                           [[maybe_unused]] const VkSwapchainCreateInfoKHR* pCreateInfos,
870                                           [[maybe_unused]] const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains) {
871     for (uint32_t i = 0; i < swapchainCount; i++) {
872         common_nondispatch_handle_creation(icd.swapchain_handles, &pSwapchains[i]);
873     }
874     return VK_SUCCESS;
875 }
876 
877 //// misc
878 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateCommandPool([[maybe_unused]] VkDevice device,
879                                                         [[maybe_unused]] const VkCommandPoolCreateInfo* pCreateInfo,
880                                                         [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
881                                                         VkCommandPool* pCommandPool) {
882     if (pCommandPool != nullptr) {
883         pCommandPool = reinterpret_cast<VkCommandPool*>(0xdeadbeefdeadbeef);
884     }
885     return VK_SUCCESS;
886 }
887 
888 VKAPI_ATTR void VKAPI_CALL test_vkDestroyCommandPool(VkDevice, VkCommandPool, const VkAllocationCallbacks*) {
889     // do nothing, leak memory for now
890 }
891 VKAPI_ATTR VkResult VKAPI_CALL test_vkAllocateCommandBuffers([[maybe_unused]] VkDevice device,
892                                                              const VkCommandBufferAllocateInfo* pAllocateInfo,
893                                                              VkCommandBuffer* pCommandBuffers) {
894     if (pAllocateInfo != nullptr && pCommandBuffers != nullptr) {
895         for (size_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
896             icd.allocated_command_buffers.push_back({});
897             pCommandBuffers[i] = icd.allocated_command_buffers.back().handle;
898         }
899     }
900     return VK_SUCCESS;
901 }
902 
903 VKAPI_ATTR void VKAPI_CALL test_vkGetDeviceQueue([[maybe_unused]] VkDevice device, [[maybe_unused]] uint32_t queueFamilyIndex,
904                                                  uint32_t queueIndex, VkQueue* pQueue) {
905     auto fd = icd.lookup_device(device);
906     if (fd.found) {
907         *pQueue = icd.physical_devices.at(fd.phys_dev_index).queue_handles[queueIndex].handle;
908     }
909 }
910 
911 // VK_EXT_acquire_drm_display
912 VKAPI_ATTR VkResult VKAPI_CALL test_vkAcquireDrmDisplayEXT(VkPhysicalDevice, int32_t, VkDisplayKHR) { return VK_SUCCESS; }
913 
914 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDrmDisplayEXT(VkPhysicalDevice physicalDevice, [[maybe_unused]] int32_t drmFd,
915                                                        [[maybe_unused]] uint32_t connectorId, VkDisplayKHR* display) {
916     if (nullptr != display && icd.GetPhysDevice(physicalDevice).displays.size() > 0) {
917         *display = icd.GetPhysDevice(physicalDevice).displays[0];
918     }
919     return VK_SUCCESS;
920 }
921 
922 //// stubs
923 // 1.0
924 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures) {
925     if (nullptr != pFeatures) {
926         memcpy(pFeatures, &icd.GetPhysDevice(physicalDevice).features, sizeof(VkPhysicalDeviceFeatures));
927     }
928 }
929 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
930                                                               VkPhysicalDeviceProperties* pProperties) {
931     if (nullptr != pProperties) {
932         auto& phys_dev = icd.GetPhysDevice(physicalDevice);
933         memcpy(pProperties, &phys_dev.properties, sizeof(VkPhysicalDeviceProperties));
934         size_t max_len = (phys_dev.deviceName.length() > VK_MAX_PHYSICAL_DEVICE_NAME_SIZE) ? VK_MAX_PHYSICAL_DEVICE_NAME_SIZE
935                                                                                            : phys_dev.deviceName.length();
936         std::copy(phys_dev.deviceName.c_str(), phys_dev.deviceName.c_str() + max_len, pProperties->deviceName);
937         pProperties->deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE - 1] = '\0';
938     }
939 }
940 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,
941                                                                     VkPhysicalDeviceMemoryProperties* pMemoryProperties) {
942     if (nullptr != pMemoryProperties) {
943         memcpy(pMemoryProperties, &icd.GetPhysDevice(physicalDevice).memory_properties, sizeof(VkPhysicalDeviceMemoryProperties));
944     }
945 }
946 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceSparseImageFormatProperties(
947     VkPhysicalDevice physicalDevice, [[maybe_unused]] VkFormat format, [[maybe_unused]] VkImageType type,
948     [[maybe_unused]] VkSampleCountFlagBits samples, [[maybe_unused]] VkImageUsageFlags usage, [[maybe_unused]] VkImageTiling tiling,
949     uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties) {
950     FillCountPtr(icd.GetPhysDevice(physicalDevice).sparse_image_format_properties, pPropertyCount, pProperties);
951 }
952 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
953                                                                     VkFormatProperties* pFormatProperties) {
954     if (nullptr != pFormatProperties) {
955         memcpy(pFormatProperties, &icd.GetPhysDevice(physicalDevice).format_properties[static_cast<uint32_t>(format)],
956                sizeof(VkFormatProperties));
957     }
958 }
959 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceImageFormatProperties(
960     VkPhysicalDevice physicalDevice, [[maybe_unused]] VkFormat format, [[maybe_unused]] VkImageType type,
961     [[maybe_unused]] VkImageTiling tiling, [[maybe_unused]] VkImageUsageFlags usage, [[maybe_unused]] VkImageCreateFlags flags,
962     VkImageFormatProperties* pImageFormatProperties) {
963     if (nullptr != pImageFormatProperties) {
964         memcpy(pImageFormatProperties, &icd.GetPhysDevice(physicalDevice).image_format_properties, sizeof(VkImageFormatProperties));
965     }
966     return VK_SUCCESS;
967 }
968 
969 // 1.1
970 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
971                                                              VkPhysicalDeviceFeatures2* pFeatures) {
972     if (nullptr != pFeatures) {
973         test_vkGetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
974     }
975 }
976 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
977                                                                VkPhysicalDeviceProperties2* pProperties) {
978     if (nullptr != pProperties) {
979         auto& phys_dev = icd.GetPhysDevice(physicalDevice);
980         test_vkGetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
981         VkBaseInStructure* pNext = reinterpret_cast<VkBaseInStructure*>(pProperties->pNext);
982         while (pNext) {
983             if (pNext->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT) {
984                 auto* bus_info = reinterpret_cast<VkPhysicalDevicePCIBusInfoPropertiesEXT*>(pNext);
985                 bus_info->pciBus = phys_dev.pci_bus;
986             }
987             if (pNext->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LAYERED_DRIVER_PROPERTIES_MSFT) {
988                 auto* layered_driver_props = reinterpret_cast<VkPhysicalDeviceLayeredDriverPropertiesMSFT*>(pNext);
989                 layered_driver_props->underlyingAPI = phys_dev.layered_driver_underlying_api;
990             }
991             pNext = reinterpret_cast<VkBaseInStructure*>(const_cast<VkBaseInStructure*>(pNext->pNext));
992         }
993     }
994 }
995 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice,
996                                                                      VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
997     if (nullptr != pMemoryProperties) {
998         test_vkGetPhysicalDeviceMemoryProperties(physicalDevice, &pMemoryProperties->memoryProperties);
999     }
1000 }
1001 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
1002                                                                           uint32_t* pQueueFamilyPropertyCount,
1003                                                                           VkQueueFamilyProperties2* pQueueFamilyProperties) {
1004     if (nullptr != pQueueFamilyPropertyCount) {
1005         test_vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, nullptr);
1006         if (nullptr != pQueueFamilyProperties) {
1007             auto& phys_dev = icd.GetPhysDevice(physicalDevice);
1008             // Since the structures are different, we have to copy each item over seperately.  Since we have multiple, we
1009             // have to manually copy the data here instead of calling the next function
1010             for (uint32_t queue = 0; queue < *pQueueFamilyPropertyCount; ++queue) {
1011                 memcpy(&pQueueFamilyProperties[queue].queueFamilyProperties, &phys_dev.queue_family_properties[queue].properties,
1012                        sizeof(VkQueueFamilyProperties));
1013             }
1014         }
1015     }
1016 }
1017 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceSparseImageFormatProperties2(
1018     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount,
1019     VkSparseImageFormatProperties2* pProperties) {
1020     if (nullptr != pPropertyCount) {
1021         test_vkGetPhysicalDeviceSparseImageFormatProperties(physicalDevice, pFormatInfo->format, pFormatInfo->type,
1022                                                             pFormatInfo->samples, pFormatInfo->usage, pFormatInfo->tiling,
1023                                                             pPropertyCount, nullptr);
1024         if (nullptr != pProperties) {
1025             auto& phys_dev = icd.GetPhysDevice(physicalDevice);
1026             // Since the structures are different, we have to copy each item over seperately.  Since we have multiple, we
1027             // have to manually copy the data here instead of calling the next function
1028             for (uint32_t cnt = 0; cnt < *pPropertyCount; ++cnt) {
1029                 memcpy(&pProperties[cnt].properties, &phys_dev.sparse_image_format_properties[cnt],
1030                        sizeof(VkSparseImageFormatProperties));
1031             }
1032         }
1033     }
1034 }
1035 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
1036                                                                      VkFormatProperties2* pFormatProperties) {
1037     if (nullptr != pFormatProperties) {
1038         test_vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &pFormatProperties->formatProperties);
1039     }
1040 }
1041 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceImageFormatProperties2(
1042     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
1043     VkImageFormatProperties2* pImageFormatProperties) {
1044     if (nullptr != pImageFormatInfo) {
1045         VkImageFormatProperties* ptr = nullptr;
1046         if (pImageFormatProperties) {
1047             ptr = &pImageFormatProperties->imageFormatProperties;
1048         }
1049         test_vkGetPhysicalDeviceImageFormatProperties(physicalDevice, pImageFormatInfo->format, pImageFormatInfo->type,
1050                                                       pImageFormatInfo->tiling, pImageFormatInfo->usage, pImageFormatInfo->flags,
1051                                                       ptr);
1052     }
1053     return VK_SUCCESS;
1054 }
1055 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceExternalBufferProperties(
1056     VkPhysicalDevice physicalDevice, [[maybe_unused]] const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
1057     VkExternalBufferProperties* pExternalBufferProperties) {
1058     if (nullptr != pExternalBufferProperties) {
1059         auto& phys_dev = icd.GetPhysDevice(physicalDevice);
1060         memcpy(&pExternalBufferProperties->externalMemoryProperties, &phys_dev.external_memory_properties,
1061                sizeof(VkExternalMemoryProperties));
1062     }
1063 }
1064 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceExternalSemaphoreProperties(
1065     VkPhysicalDevice physicalDevice, [[maybe_unused]] const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
1066     VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
1067     if (nullptr != pExternalSemaphoreProperties) {
1068         auto& phys_dev = icd.GetPhysDevice(physicalDevice);
1069         memcpy(pExternalSemaphoreProperties, &phys_dev.external_semaphore_properties, sizeof(VkExternalSemaphoreProperties));
1070     }
1071 }
1072 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceExternalFenceProperties(
1073     VkPhysicalDevice physicalDevice, [[maybe_unused]] const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo,
1074     VkExternalFenceProperties* pExternalFenceProperties) {
1075     if (nullptr != pExternalFenceProperties) {
1076         auto& phys_dev = icd.GetPhysDevice(physicalDevice);
1077         memcpy(pExternalFenceProperties, &phys_dev.external_fence_properties, sizeof(VkExternalFenceProperties));
1078     }
1079 }
1080 // Entry-points associated with the VK_KHR_performance_query extension
1081 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
1082     VkPhysicalDevice, uint32_t, uint32_t*, VkPerformanceCounterKHR*, VkPerformanceCounterDescriptionKHR*) {
1083     return VK_SUCCESS;
1084 }
1085 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(VkPhysicalDevice,
1086                                                                                         const VkQueryPoolPerformanceCreateInfoKHR*,
1087                                                                                         uint32_t*) {}
1088 VKAPI_ATTR VkResult VKAPI_CALL test_vkAcquireProfilingLockKHR(VkDevice, const VkAcquireProfilingLockInfoKHR*) { return VK_SUCCESS; }
1089 VKAPI_ATTR void VKAPI_CALL test_vkReleaseProfilingLockKHR(VkDevice) {}
1090 // Entry-points associated with the VK_EXT_sample_locations extension
1091 VKAPI_ATTR void VKAPI_CALL test_vkCmdSetSampleLocationsEXT(VkCommandBuffer, const VkSampleLocationsInfoEXT*) {}
1092 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceMultisamplePropertiesEXT(VkPhysicalDevice, VkSampleCountFlagBits,
1093                                                                             VkMultisamplePropertiesEXT*) {}
1094 // Entry-points associated with the VK_EXT_calibrated_timestamps extension
1095 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT(VkPhysicalDevice, uint32_t*, VkTimeDomainEXT*) {
1096     return VK_SUCCESS;
1097 }
1098 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetCalibratedTimestampsEXT(VkDevice, uint32_t, const VkCalibratedTimestampInfoEXT*, uint64_t*,
1099                                                                  uint64_t*) {
1100     return VK_SUCCESS;
1101 }
1102 
1103 #if defined(WIN32)
1104 VKAPI_ATTR VkResult VKAPI_CALL test_vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID,
1105                                                                           uint32_t* pPhysicalDeviceCount,
1106                                                                           VkPhysicalDevice* pPhysicalDevices) {
1107     if (adapterLUID.LowPart != icd.adapterLUID.LowPart || adapterLUID.HighPart != icd.adapterLUID.HighPart) {
1108         *pPhysicalDeviceCount = 0;
1109         return VK_ERROR_INCOMPATIBLE_DRIVER;
1110     }
1111     icd.called_enumerate_adapter_physical_devices = true;
1112     VkResult res = test_vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
1113     // For this testing, flip order intentionally
1114     if (nullptr != pPhysicalDevices) {
1115         std::reverse(pPhysicalDevices, pPhysicalDevices + *pPhysicalDeviceCount);
1116     }
1117     return res;
1118 }
1119 #endif  // defined(WIN32)
1120 
1121 VkResult test_vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) {
1122     if (icd.called_vk_icd_gipa == CalledICDGIPA::not_called &&
1123         icd.called_negotiate_interface == CalledNegotiateInterface::not_called)
1124         icd.called_negotiate_interface = CalledNegotiateInterface::vk_icd_negotiate;
1125     else if (icd.called_vk_icd_gipa != CalledICDGIPA::not_called)
1126         icd.called_negotiate_interface = CalledNegotiateInterface::vk_icd_gipa_first;
1127 
1128     // loader puts the minimum it supports in pSupportedVersion, if that is lower than our minimum
1129     // If the ICD doesn't supports the interface version provided by the loader, report VK_ERROR_INCOMPATIBLE_DRIVER
1130     if (icd.min_icd_interface_version > *pSupportedVersion) {
1131         icd.interface_version_check = InterfaceVersionCheck::loader_version_too_old;
1132         *pSupportedVersion = icd.min_icd_interface_version;
1133         return VK_ERROR_INCOMPATIBLE_DRIVER;
1134     }
1135 
1136     // the loader-provided interface version is newer than that supported by the ICD
1137     if (icd.max_icd_interface_version < *pSupportedVersion) {
1138         icd.interface_version_check = InterfaceVersionCheck::loader_version_too_new;
1139         *pSupportedVersion = icd.max_icd_interface_version;
1140     }
1141     // ICD interface version is greater than the loader's,  return the loader's version
1142     else if (icd.max_icd_interface_version > *pSupportedVersion) {
1143         icd.interface_version_check = InterfaceVersionCheck::icd_version_too_new;
1144         // don't change *pSupportedVersion
1145     } else {
1146         icd.interface_version_check = InterfaceVersionCheck::version_is_supported;
1147         *pSupportedVersion = icd.max_icd_interface_version;
1148     }
1149 
1150     return VK_SUCCESS;
1151 }
1152 
1153 // Forward declarations for trampolines
1154 extern "C" {
1155 #if TEST_ICD_EXPOSE_VERSION_7
1156 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion);
1157 #if TEST_ICD_EXPORT_ICD_GPDPA
1158 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName);
1159 #endif
1160 #if defined(WIN32) && TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES
1161 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID,
1162                                                                                       uint32_t* pPhysicalDeviceCount,
1163                                                                                       VkPhysicalDevice* pPhysicalDevices);
1164 #endif
1165 #endif
1166 }
1167 
1168 //// trampolines
1169 
1170 PFN_vkVoidFunction get_instance_func_ver_1_1([[maybe_unused]] VkInstance instance, const char* pName) {
1171     if (icd.icd_api_version >= VK_API_VERSION_1_1) {
1172         if (string_eq(pName, "test_vkEnumerateInstanceVersion")) {
1173             return icd.can_query_vkEnumerateInstanceVersion ? to_vkVoidFunction(test_vkEnumerateInstanceVersion) : nullptr;
1174         }
1175         if (string_eq(pName, "vkEnumeratePhysicalDeviceGroups")) {
1176             return to_vkVoidFunction(test_vkEnumeratePhysicalDeviceGroups);
1177         }
1178     }
1179     return nullptr;
1180 }
1181 
1182 PFN_vkVoidFunction get_physical_device_func_wsi([[maybe_unused]] VkInstance instance, const char* pName) {
1183     if (IsInstanceExtensionEnabled("VK_KHR_surface")) {
1184         if (string_eq(pName, "vkGetPhysicalDeviceSurfaceSupportKHR"))
1185             return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfaceSupportKHR);
1186         if (string_eq(pName, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"))
1187             return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
1188         if (string_eq(pName, "vkGetPhysicalDeviceSurfaceFormatsKHR"))
1189             return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfaceFormatsKHR);
1190         if (string_eq(pName, "vkGetPhysicalDeviceSurfacePresentModesKHR"))
1191             return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfacePresentModesKHR);
1192     }
1193     if (IsInstanceExtensionEnabled("VK_KHR_get_surface_capabilities2")) {
1194         if (string_eq(pName, "vkGetPhysicalDeviceSurfaceCapabilities2KHR"))
1195             return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfaceCapabilities2KHR);
1196         if (string_eq(pName, "vkGetPhysicalDeviceSurfaceFormats2KHR"))
1197             return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfaceFormats2KHR);
1198     }
1199     if (IsInstanceExtensionEnabled("VK_KHR_display")) {
1200         if (string_eq(pName, "vkGetPhysicalDeviceDisplayPropertiesKHR"))
1201             return to_vkVoidFunction(test_vkGetPhysicalDeviceDisplayPropertiesKHR);
1202         if (string_eq(pName, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR"))
1203             return to_vkVoidFunction(test_vkGetPhysicalDeviceDisplayPlanePropertiesKHR);
1204         if (string_eq(pName, "vkGetDisplayPlaneSupportedDisplaysKHR"))
1205             return to_vkVoidFunction(test_vkGetDisplayPlaneSupportedDisplaysKHR);
1206         if (string_eq(pName, "vkGetDisplayModePropertiesKHR")) return to_vkVoidFunction(test_vkGetDisplayModePropertiesKHR);
1207         if (string_eq(pName, "vkCreateDisplayModeKHR")) return to_vkVoidFunction(test_vkCreateDisplayModeKHR);
1208         if (string_eq(pName, "vkGetDisplayPlaneCapabilitiesKHR")) return to_vkVoidFunction(test_vkGetDisplayPlaneCapabilitiesKHR);
1209         if (string_eq(pName, "vkCreateDisplayPlaneSurfaceKHR")) return to_vkVoidFunction(test_vkCreateDisplayPlaneSurfaceKHR);
1210     }
1211     if (IsInstanceExtensionEnabled("VK_EXT_acquire_drm_display")) {
1212         if (string_eq(pName, "vkAcquireDrmDisplayEXT")) return to_vkVoidFunction(test_vkAcquireDrmDisplayEXT);
1213         if (string_eq(pName, "vkGetDrmDisplayEXT")) return to_vkVoidFunction(test_vkGetDrmDisplayEXT);
1214     }
1215     return nullptr;
1216 }
1217 
1218 PFN_vkVoidFunction get_instance_func_wsi(VkInstance instance, const char* pName) {
1219     if (icd.min_icd_interface_version >= 3 && icd.enable_icd_wsi == true) {
1220 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
1221         if (string_eq(pName, "vkCreateAndroidSurfaceKHR")) {
1222             icd.is_using_icd_wsi = true;
1223             return to_vkVoidFunction(test_vkCreateAndroidSurfaceKHR);
1224         }
1225 #endif
1226 #if defined(VK_USE_PLATFORM_METAL_EXT)
1227         if (string_eq(pName, "vkCreateMetalSurfaceEXT")) {
1228             return to_vkVoidFunction(test_vkCreateMetalSurfaceEXT);
1229         }
1230 #endif
1231 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
1232         if (string_eq(pName, "vkCreateWaylandSurfaceKHR")) {
1233             return to_vkVoidFunction(test_vkCreateWaylandSurfaceKHR);
1234         }
1235         if (string_eq(pName, "vkGetPhysicalDeviceWaylandPresentationSupportKHR")) {
1236             return to_vkVoidFunction(test_vkGetPhysicalDeviceWaylandPresentationSupportKHR);
1237         }
1238 #endif
1239 #if defined(VK_USE_PLATFORM_XCB_KHR)
1240         if (string_eq(pName, "vkCreateXcbSurfaceKHR")) {
1241             return to_vkVoidFunction(test_vkCreateXcbSurfaceKHR);
1242         }
1243         if (string_eq(pName, "vkGetPhysicalDeviceXcbPresentationSupportKHR")) {
1244             return to_vkVoidFunction(test_vkGetPhysicalDeviceXcbPresentationSupportKHR);
1245         }
1246 #endif
1247 #if defined(VK_USE_PLATFORM_XLIB_KHR)
1248         if (string_eq(pName, "vkCreateXlibSurfaceKHR")) {
1249             return to_vkVoidFunction(test_vkCreateXlibSurfaceKHR);
1250         }
1251         if (string_eq(pName, "vkGetPhysicalDeviceXlibPresentationSupportKHR")) {
1252             return to_vkVoidFunction(test_vkGetPhysicalDeviceXlibPresentationSupportKHR);
1253         }
1254 #endif
1255 #if defined(VK_USE_PLATFORM_WIN32_KHR)
1256         if (string_eq(pName, "vkCreateWin32SurfaceKHR")) {
1257             return to_vkVoidFunction(test_vkCreateWin32SurfaceKHR);
1258         }
1259         if (string_eq(pName, "vkGetPhysicalDeviceWin32PresentationSupportKHR")) {
1260             return to_vkVoidFunction(test_vkGetPhysicalDeviceWin32PresentationSupportKHR);
1261         }
1262 #endif
1263 #if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
1264         if (string_eq(pName, "vkCreateDirectFBSurfaceEXT")) {
1265             return to_vkVoidFunction(test_vkCreateDirectFBSurfaceEXT);
1266         }
1267         if (string_eq(pName, "vkGetPhysicalDeviceDirectFBPresentationSupportEXT")) {
1268             return to_vkVoidFunction(test_vkGetPhysicalDeviceDirectFBPresentationSupportEXT);
1269         }
1270 #endif  // VK_USE_PLATFORM_DIRECTFB_EXT
1271 
1272 #if defined(VK_USE_PLATFORM_MACOS_MVK)
1273         if (string_eq(pName, "vkCreateMacOSSurfaceMVK")) {
1274             return to_vkVoidFunction(test_vkCreateMacOSSurfaceMVK);
1275         }
1276 #endif  // VK_USE_PLATFORM_MACOS_MVK
1277 
1278 #if defined(VK_USE_PLATFORM_IOS_MVK)
1279         if (string_eq(pName, "vkCreateIOSSurfaceMVK")) {
1280             return to_vkVoidFunction(test_vkCreateIOSSurfaceMVK);
1281         }
1282 #endif  // VK_USE_PLATFORM_IOS_MVK
1283 
1284 #if defined(VK_USE_PLATFORM_GGP)
1285         if (string_eq(pName, "vkCreateStreamDescriptorSurfaceGGP")) {
1286             return to_vkVoidFunction(test_vkCreateStreamDescriptorSurfaceGGP);
1287         }
1288 #endif  // VK_USE_PLATFORM_GGP
1289 
1290 #if defined(VK_USE_PLATFORM_SCREEN_QNX)
1291         if (string_eq(pName, "vkCreateScreenSurfaceQNX")) {
1292             return to_vkVoidFunction(test_vkCreateScreenSurfaceQNX);
1293         }
1294         if (string_eq(pName, "vkGetPhysicalDeviceScreenPresentationSupportQNX")) {
1295             return to_vkVoidFunction(test_vkGetPhysicalDeviceScreenPresentationSupportQNX);
1296         }
1297 #endif  // VK_USE_PLATFORM_SCREEN_QNX
1298 
1299         if (string_eq(pName, "vkCreateHeadlessSurfaceEXT")) {
1300             return to_vkVoidFunction(test_vkCreateHeadlessSurfaceEXT);
1301         }
1302 
1303         if (string_eq(pName, "vkDestroySurfaceKHR")) {
1304             icd.is_using_icd_wsi = true;
1305             return to_vkVoidFunction(test_vkDestroySurfaceKHR);
1306         }
1307     }
1308     if (IsInstanceExtensionEnabled(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
1309         if (string_eq(pName, "vkCreateDebugUtilsMessengerEXT")) {
1310             return to_vkVoidFunction(test_vkCreateDebugUtilsMessengerEXT);
1311         }
1312         if (string_eq(pName, "vkDestroyDebugUtilsMessengerEXT")) {
1313             return to_vkVoidFunction(test_vkDestroyDebugUtilsMessengerEXT);
1314         }
1315     }
1316 
1317     PFN_vkVoidFunction ret_phys_dev_wsi = get_physical_device_func_wsi(instance, pName);
1318     if (ret_phys_dev_wsi != nullptr) return ret_phys_dev_wsi;
1319     return nullptr;
1320 }
1321 PFN_vkVoidFunction get_physical_device_func([[maybe_unused]] VkInstance instance, const char* pName) {
1322     if (string_eq(pName, "vkEnumerateDeviceLayerProperties")) return to_vkVoidFunction(test_vkEnumerateDeviceLayerProperties);
1323     if (string_eq(pName, "vkEnumerateDeviceExtensionProperties"))
1324         return to_vkVoidFunction(test_vkEnumerateDeviceExtensionProperties);
1325     if (string_eq(pName, "vkGetPhysicalDeviceQueueFamilyProperties"))
1326         return to_vkVoidFunction(test_vkGetPhysicalDeviceQueueFamilyProperties);
1327     if (string_eq(pName, "vkCreateDevice")) return to_vkVoidFunction(test_vkCreateDevice);
1328 
1329     if (string_eq(pName, "vkGetPhysicalDeviceFeatures"))
1330         return icd.can_query_GetPhysicalDeviceFuncs ? to_vkVoidFunction(test_vkGetPhysicalDeviceFeatures) : nullptr;
1331     if (string_eq(pName, "vkGetPhysicalDeviceProperties"))
1332         return icd.can_query_GetPhysicalDeviceFuncs ? to_vkVoidFunction(test_vkGetPhysicalDeviceProperties) : nullptr;
1333     if (string_eq(pName, "vkGetPhysicalDeviceMemoryProperties"))
1334         return icd.can_query_GetPhysicalDeviceFuncs ? to_vkVoidFunction(test_vkGetPhysicalDeviceMemoryProperties) : nullptr;
1335     if (string_eq(pName, "vkGetPhysicalDeviceSparseImageFormatProperties"))
1336         return icd.can_query_GetPhysicalDeviceFuncs ? to_vkVoidFunction(test_vkGetPhysicalDeviceSparseImageFormatProperties)
1337                                                     : nullptr;
1338     if (string_eq(pName, "vkGetPhysicalDeviceFormatProperties"))
1339         return icd.can_query_GetPhysicalDeviceFuncs ? to_vkVoidFunction(test_vkGetPhysicalDeviceFormatProperties) : nullptr;
1340     if (string_eq(pName, "vkGetPhysicalDeviceImageFormatProperties"))
1341         return icd.can_query_GetPhysicalDeviceFuncs ? to_vkVoidFunction(test_vkGetPhysicalDeviceImageFormatProperties) : nullptr;
1342 
1343     if (IsInstanceExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
1344         if (string_eq(pName, "vkGetPhysicalDeviceFeatures2KHR")) return to_vkVoidFunction(test_vkGetPhysicalDeviceFeatures2);
1345         if (string_eq(pName, "vkGetPhysicalDeviceProperties2KHR")) return to_vkVoidFunction(test_vkGetPhysicalDeviceProperties2);
1346         if (string_eq(pName, "vkGetPhysicalDeviceFormatProperties2KHR"))
1347             return to_vkVoidFunction(test_vkGetPhysicalDeviceFormatProperties2);
1348         if (string_eq(pName, "vkGetPhysicalDeviceMemoryProperties2KHR"))
1349             return to_vkVoidFunction(test_vkGetPhysicalDeviceMemoryProperties2);
1350 
1351         if (string_eq(pName, "vkGetPhysicalDeviceQueueFamilyProperties2KHR"))
1352             return to_vkVoidFunction(test_vkGetPhysicalDeviceQueueFamilyProperties2);
1353 
1354         if (string_eq(pName, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR"))
1355             return to_vkVoidFunction(test_vkGetPhysicalDeviceSparseImageFormatProperties2);
1356 
1357         if (string_eq(pName, "vkGetPhysicalDeviceImageFormatProperties2KHR")) {
1358             return to_vkVoidFunction(test_vkGetPhysicalDeviceImageFormatProperties2);
1359         }
1360     }
1361     if (IsInstanceExtensionEnabled(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) {
1362         if (string_eq(pName, "vkGetPhysicalDeviceExternalBufferPropertiesKHR"))
1363             return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalBufferProperties);
1364     }
1365     if (IsInstanceExtensionEnabled(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) {
1366         if (string_eq(pName, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR"))
1367             return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalSemaphoreProperties);
1368     }
1369     if (IsInstanceExtensionEnabled(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME)) {
1370         if (string_eq(pName, "vkGetPhysicalDeviceExternalFencePropertiesKHR"))
1371             return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalFenceProperties);
1372     }
1373 
1374     // The following physical device extensions only need 1 device to support them for the ICD to export
1375     // them
1376     if (IsPhysicalDeviceExtensionAvailable(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME)) {
1377         if (string_eq(pName, "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR"))
1378             return to_vkVoidFunction(test_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR);
1379         if (string_eq(pName, "vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR"))
1380             return to_vkVoidFunction(test_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR);
1381         if (string_eq(pName, "vkAcquireProfilingLockKHR")) return to_vkVoidFunction(test_vkAcquireProfilingLockKHR);
1382         if (string_eq(pName, "vkReleaseProfilingLockKHR")) return to_vkVoidFunction(test_vkReleaseProfilingLockKHR);
1383     }
1384     if (IsPhysicalDeviceExtensionAvailable(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME)) {
1385         if (string_eq(pName, "vkCmdSetSampleLocationsEXT")) return to_vkVoidFunction(test_vkCmdSetSampleLocationsEXT);
1386         if (string_eq(pName, "vkGetPhysicalDeviceMultisamplePropertiesEXT"))
1387             return to_vkVoidFunction(test_vkGetPhysicalDeviceMultisamplePropertiesEXT);
1388     }
1389     if (IsPhysicalDeviceExtensionAvailable(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME)) {
1390         if (string_eq(pName, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT"))
1391             return to_vkVoidFunction(test_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT);
1392         if (string_eq(pName, "vkGetCalibratedTimestampsEXT")) return to_vkVoidFunction(test_vkGetCalibratedTimestampsEXT);
1393     }
1394 
1395     if (icd.icd_api_version >= VK_MAKE_API_VERSION(0, 1, 1, 0)) {
1396         if (string_eq(pName, "vkGetPhysicalDeviceFeatures2")) return to_vkVoidFunction(test_vkGetPhysicalDeviceFeatures2);
1397         if (string_eq(pName, "vkGetPhysicalDeviceProperties2")) return to_vkVoidFunction(test_vkGetPhysicalDeviceProperties2);
1398         if (string_eq(pName, "vkGetPhysicalDeviceFormatProperties2"))
1399             return to_vkVoidFunction(test_vkGetPhysicalDeviceFormatProperties2);
1400         if (string_eq(pName, "vkGetPhysicalDeviceMemoryProperties2"))
1401             return to_vkVoidFunction(test_vkGetPhysicalDeviceMemoryProperties2);
1402 
1403         if (string_eq(pName, "vkGetPhysicalDeviceQueueFamilyProperties2"))
1404             return to_vkVoidFunction(test_vkGetPhysicalDeviceQueueFamilyProperties2);
1405 
1406         if (string_eq(pName, "vkGetPhysicalDeviceSparseImageFormatProperties2"))
1407             return to_vkVoidFunction(test_vkGetPhysicalDeviceSparseImageFormatProperties2);
1408 
1409         if (string_eq(pName, "vkGetPhysicalDeviceImageFormatProperties2")) {
1410             return to_vkVoidFunction(test_vkGetPhysicalDeviceImageFormatProperties2);
1411         }
1412 
1413         if (string_eq(pName, "vkGetPhysicalDeviceExternalBufferProperties"))
1414             return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalBufferProperties);
1415         if (string_eq(pName, "vkGetPhysicalDeviceExternalSemaphoreProperties"))
1416             return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalSemaphoreProperties);
1417         if (string_eq(pName, "vkGetPhysicalDeviceExternalFenceProperties"))
1418             return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalFenceProperties);
1419     }
1420 
1421     if (icd.supports_tooling_info_core) {
1422         if (string_eq(pName, "vkGetPhysicalDeviceToolProperties")) return to_vkVoidFunction(test_vkGetPhysicalDeviceToolProperties);
1423     }
1424     if (icd.supports_tooling_info_ext) {
1425         if (string_eq(pName, "vkGetPhysicalDeviceToolPropertiesEXT"))
1426             return to_vkVoidFunction(test_vkGetPhysicalDeviceToolPropertiesEXT);
1427     }
1428 
1429     for (auto& phys_dev : icd.physical_devices) {
1430         for (auto& func : phys_dev.custom_physical_device_functions) {
1431             if (func.name == pName) {
1432                 return to_vkVoidFunction(func.function);
1433             }
1434         }
1435     }
1436     return nullptr;
1437 }
1438 
1439 PFN_vkVoidFunction get_instance_func(VkInstance instance, const char* pName) {
1440     if (string_eq(pName, "vkDestroyInstance")) return to_vkVoidFunction(test_vkDestroyInstance);
1441     if (string_eq(pName, "vkEnumeratePhysicalDevices")) return to_vkVoidFunction(test_vkEnumeratePhysicalDevices);
1442 
1443     if (IsInstanceExtensionEnabled(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME)) {
1444         if (string_eq(pName, "vkEnumeratePhysicalDeviceGroupsKHR")) return to_vkVoidFunction(test_vkEnumeratePhysicalDeviceGroups);
1445     }
1446 
1447     PFN_vkVoidFunction ret_phys_dev = get_physical_device_func(instance, pName);
1448     if (ret_phys_dev != nullptr) return ret_phys_dev;
1449 
1450     PFN_vkVoidFunction ret_1_1 = get_instance_func_ver_1_1(instance, pName);
1451     if (ret_1_1 != nullptr) return ret_1_1;
1452 
1453     PFN_vkVoidFunction ret_wsi = get_instance_func_wsi(instance, pName);
1454     if (ret_wsi != nullptr) return ret_wsi;
1455 
1456     for (auto& func : icd.custom_instance_functions) {
1457         if (func.name == pName) {
1458             return to_vkVoidFunction(func.function);
1459         }
1460     }
1461 
1462     return nullptr;
1463 }
1464 
1465 bool should_check(std::vector<const char*> const& exts, VkDevice device, const char* ext_name) {
1466     if (device == NULL) return true;  // always look if device is NULL
1467     for (auto const& ext : exts) {
1468         if (string_eq(ext, ext_name)) {
1469             return true;
1470         }
1471     }
1472     return false;
1473 }
1474 
1475 PFN_vkVoidFunction get_device_func(VkDevice device, const char* pName) {
1476     TestICD::FindDevice fd{};
1477     DeviceCreateInfo create_info{};
1478     if (device != nullptr) {
1479         fd = icd.lookup_device(device);
1480         if (!fd.found) return NULL;
1481         create_info = icd.physical_devices.at(fd.phys_dev_index).device_create_infos.at(fd.dev_index);
1482     }
1483     if (string_eq(pName, "vkCreateCommandPool")) return to_vkVoidFunction(test_vkCreateCommandPool);
1484     if (string_eq(pName, "vkAllocateCommandBuffers")) return to_vkVoidFunction(test_vkAllocateCommandBuffers);
1485     if (string_eq(pName, "vkDestroyCommandPool")) return to_vkVoidFunction(test_vkDestroyCommandPool);
1486     if (string_eq(pName, "vkGetDeviceQueue")) return to_vkVoidFunction(test_vkGetDeviceQueue);
1487     if (string_eq(pName, "vkDestroyDevice")) return to_vkVoidFunction(test_vkDestroyDevice);
1488     if (should_check(create_info.enabled_extensions, device, "VK_KHR_swapchain")) {
1489         if (string_eq(pName, "vkCreateSwapchainKHR")) return to_vkVoidFunction(test_vkCreateSwapchainKHR);
1490         if (string_eq(pName, "vkGetSwapchainImagesKHR")) return to_vkVoidFunction(test_vkGetSwapchainImagesKHR);
1491         if (string_eq(pName, "vkDestroySwapchainKHR")) return to_vkVoidFunction(test_vkDestroySwapchainKHR);
1492 
1493         if (icd.icd_api_version >= VK_API_VERSION_1_1 && string_eq(pName, "vkGetDeviceGroupSurfacePresentModesKHR"))
1494             return to_vkVoidFunction(test_vkGetDeviceGroupSurfacePresentModesKHR);
1495     }
1496     if (should_check(create_info.enabled_extensions, device, "VK_KHR_display_swapchain")) {
1497         if (string_eq(pName, "vkCreateSharedSwapchainsKHR")) return to_vkVoidFunction(test_vkCreateSharedSwapchainsKHR);
1498     }
1499     if (should_check(create_info.enabled_extensions, device, "VK_KHR_device_group")) {
1500         if (string_eq(pName, "vkGetDeviceGroupSurfacePresentModesKHR"))
1501             return to_vkVoidFunction(test_vkGetDeviceGroupSurfacePresentModesKHR);
1502     }
1503     if (should_check(create_info.enabled_extensions, device, "VK_EXT_debug_marker")) {
1504         if (string_eq(pName, "vkDebugMarkerSetObjectTagEXT")) return to_vkVoidFunction(test_vkDebugMarkerSetObjectTagEXT);
1505         if (string_eq(pName, "vkDebugMarkerSetObjectNameEXT")) return to_vkVoidFunction(test_vkDebugMarkerSetObjectNameEXT);
1506         if (string_eq(pName, "vkCmdDebugMarkerBeginEXT")) return to_vkVoidFunction(test_vkCmdDebugMarkerBeginEXT);
1507         if (string_eq(pName, "vkCmdDebugMarkerEndEXT")) return to_vkVoidFunction(test_vkCmdDebugMarkerEndEXT);
1508         if (string_eq(pName, "vkCmdDebugMarkerInsertEXT")) return to_vkVoidFunction(test_vkCmdDebugMarkerInsertEXT);
1509     }
1510     if (IsInstanceExtensionEnabled("VK_EXT_debug_utils")) {
1511         if (string_eq(pName, "vkSetDebugUtilsObjectNameEXT")) return to_vkVoidFunction(test_vkSetDebugUtilsObjectNameEXT);
1512         if (string_eq(pName, "vkSetDebugUtilsObjectTagEXT")) return to_vkVoidFunction(test_vkSetDebugUtilsObjectTagEXT);
1513         if (string_eq(pName, "vkQueueBeginDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueBeginDebugUtilsLabelEXT);
1514         if (string_eq(pName, "vkQueueEndDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueEndDebugUtilsLabelEXT);
1515         if (string_eq(pName, "vkQueueInsertDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueInsertDebugUtilsLabelEXT);
1516         if (string_eq(pName, "vkCmdBeginDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdBeginDebugUtilsLabelEXT);
1517         if (string_eq(pName, "vkCmdEndDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdEndDebugUtilsLabelEXT);
1518         if (string_eq(pName, "vkCmdInsertDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdInsertDebugUtilsLabelEXT);
1519     }
1520     // look for device functions setup from a test
1521     for (const auto& phys_dev : icd.physical_devices) {
1522         for (const auto& function : phys_dev.known_device_functions) {
1523             if (function.name == pName) {
1524                 return to_vkVoidFunction(function.function);
1525             }
1526         }
1527     }
1528     return nullptr;
1529 }
1530 
1531 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_vkGetInstanceProcAddr(VkInstance instance, const char* pName) {
1532     return get_instance_func(instance, pName);
1533 }
1534 
1535 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_vkGetDeviceProcAddr(VkDevice device, const char* pName) {
1536     return get_device_func(device, pName);
1537 }
1538 
1539 PFN_vkVoidFunction base_get_instance_proc_addr(VkInstance instance, const char* pName) {
1540     if (pName == nullptr) return nullptr;
1541     if (instance == NULL) {
1542 #if TEST_ICD_EXPOSE_VERSION_7
1543         if (string_eq(pName, "vk_icdNegotiateLoaderICDInterfaceVersion"))
1544             return icd.exposes_vk_icdNegotiateLoaderICDInterfaceVersion
1545                        ? to_vkVoidFunction(vk_icdNegotiateLoaderICDInterfaceVersion)
1546                        : NULL;
1547 #if TEST_ICD_EXPORT_ICD_GPDPA
1548         if (string_eq(pName, "vk_icdGetPhysicalDeviceProcAddr"))
1549             return icd.exposes_vk_icdGetPhysicalDeviceProcAddr ? to_vkVoidFunction(vk_icdGetPhysicalDeviceProcAddr) : NULL;
1550 #endif
1551 #if defined(WIN32) && TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES
1552         if (string_eq(pName, "vk_icdEnumerateAdapterPhysicalDevices"))
1553             return icd.exposes_vk_icdEnumerateAdapterPhysicalDevices ? to_vkVoidFunction(vk_icdEnumerateAdapterPhysicalDevices)
1554                                                                      : NULL;
1555 #endif  // defined(WIN32)
1556 #endif  // TEST_ICD_EXPOSE_VERSION_7
1557 
1558         if (string_eq(pName, "vkGetInstanceProcAddr")) return to_vkVoidFunction(test_vkGetInstanceProcAddr);
1559         if (string_eq(pName, "vkEnumerateInstanceExtensionProperties"))
1560             return icd.exposes_vkEnumerateInstanceExtensionProperties
1561                        ? to_vkVoidFunction(test_vkEnumerateInstanceExtensionProperties)
1562                        : NULL;
1563         if (string_eq(pName, "vkEnumerateInstanceLayerProperties"))
1564             return to_vkVoidFunction(test_vkEnumerateInstanceLayerProperties);
1565         if (string_eq(pName, "vkEnumerateInstanceVersion"))
1566             return icd.can_query_vkEnumerateInstanceVersion ? to_vkVoidFunction(test_vkEnumerateInstanceVersion) : nullptr;
1567         if (string_eq(pName, "vkCreateInstance")) return to_vkVoidFunction(test_vkCreateInstance);
1568     }
1569     if (string_eq(pName, "vkGetDeviceProcAddr")) return to_vkVoidFunction(test_vkGetDeviceProcAddr);
1570 
1571     auto instance_func_return = get_instance_func(instance, pName);
1572     if (instance_func_return != nullptr) return instance_func_return;
1573 
1574     // Need to return function pointers for device extensions
1575     auto device_func_return = get_device_func(nullptr, pName);
1576     if (device_func_return != nullptr) return device_func_return;
1577     return nullptr;
1578 }
1579 
1580 // Exported functions
1581 extern "C" {
1582 #if TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION
1583 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) {
1584     return test_vk_icdNegotiateLoaderICDInterfaceVersion(pSupportedVersion);
1585 }
1586 #endif  // TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION
1587 
1588 #if TEST_ICD_EXPORT_ICD_GPDPA
1589 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName) {
1590     return get_physical_device_func(instance, pName);
1591 }
1592 #endif  // TEST_ICD_EXPORT_ICD_GPDPA
1593 
1594 #if TEST_ICD_EXPORT_ICD_GIPA
1595 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName) {
1596     if (icd.called_vk_icd_gipa == CalledICDGIPA::not_called) icd.called_vk_icd_gipa = CalledICDGIPA::vk_icd_gipa;
1597     return base_get_instance_proc_addr(instance, pName);
1598 }
1599 #else   // !TEST_ICD_EXPORT_ICD_GIPA
1600 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* pName) {
1601     if (icd.called_vk_icd_gipa == CalledICDGIPA::not_called) icd.called_vk_icd_gipa = CalledICDGIPA::vk_gipa;
1602     return base_get_instance_proc_addr(instance, pName);
1603 }
1604 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
1605                                                                  const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) {
1606     return test_vkCreateInstance(pCreateInfo, pAllocator, pInstance);
1607 }
1608 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char* pLayerName,
1609                                                                                        uint32_t* pPropertyCount,
1610                                                                                        VkExtensionProperties* pProperties) {
1611     return test_vkEnumerateInstanceExtensionProperties(pLayerName, pPropertyCount, pProperties);
1612 }
1613 #endif  // TEST_ICD_EXPORT_ICD_GIPA
1614 
1615 #if TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES
1616 #if defined(WIN32)
1617 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID,
1618                                                                                       uint32_t* pPhysicalDeviceCount,
1619                                                                                       VkPhysicalDevice* pPhysicalDevices) {
1620     return test_vk_icdEnumerateAdapterPhysicalDevices(instance, adapterLUID, pPhysicalDeviceCount, pPhysicalDevices);
1621 }
1622 #endif  // defined(WIN32)
1623 #endif  // TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES
1624 
1625 }  // extern "C"
1626