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