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