• 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 "loader/generated/vk_dispatch_table_helper.h"
31 
32 // export the enumeration functions instance|device+layer|extension
33 #ifndef TEST_LAYER_EXPORT_ENUMERATE_FUNCTIONS
34 #define TEST_LAYER_EXPORT_ENUMERATE_FUNCTIONS 0
35 #endif
36 
37 // export test_layer_GetInstanceProcAddr
38 #ifndef TEST_LAYER_EXPORT_LAYER_NAMED_GIPA
39 #define TEST_LAYER_EXPORT_LAYER_NAMED_GIPA 0
40 #endif
41 
42 // export vkGetInstanceProcAddr
43 #ifndef TEST_LAYER_EXPORT_LAYER_VK_GIPA
44 #define TEST_LAYER_EXPORT_LAYER_VK_GIPA 0
45 #endif
46 
47 // export test_layer_GetDeviceProcAddr
48 #ifndef TEST_LAYER_EXPORT_LAYER_NAMED_GDPA
49 #define TEST_LAYER_EXPORT_LAYER_NAMED_GDPA 0
50 #endif
51 
52 // export vkGetDeviceProcAddr
53 #ifndef TEST_LAYER_EXPORT_LAYER_VK_GDPA
54 #define TEST_LAYER_EXPORT_LAYER_VK_GDPA 0
55 #endif
56 
57 // export GetInstanceProcAddr
58 #ifndef TEST_LAYER_EXPORT_NO_PREFIX_GIPA
59 #define TEST_LAYER_EXPORT_NO_PREFIX_GIPA 0
60 #endif
61 
62 // export GetDeviceProcAddr
63 #ifndef TEST_LAYER_EXPORT_NO_PREFIX_GDPA
64 #define TEST_LAYER_EXPORT_NO_PREFIX_GDPA 0
65 #endif
66 
67 // export vk_layerGetPhysicalDeviceProcAddr
68 #ifndef 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 #ifndef LAYER_EXPORT_NEGOTIATE_LOADER_LAYER_INTERFACE_VERSION
74 #define LAYER_EXPORT_NEGOTIATE_LOADER_LAYER_INTERFACE_VERSION 0
75 #endif
76 
77 #ifndef TEST_LAYER_NAME
78 #define TEST_LAYER_NAME "VkLayer_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 
get_chain_info(const VkInstanceCreateInfo * pCreateInfo,VkLayerFunction func)90 VkLayerInstanceCreateInfo* get_chain_info(const VkInstanceCreateInfo* pCreateInfo, VkLayerFunction func) {
91     VkLayerInstanceCreateInfo* chain_info = (VkLayerInstanceCreateInfo*)pCreateInfo->pNext;
92     while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO && chain_info->function == func)) {
93         chain_info = (VkLayerInstanceCreateInfo*)chain_info->pNext;
94     }
95     assert(chain_info != NULL);
96     return chain_info;
97 }
98 
get_chain_info(const VkDeviceCreateInfo * pCreateInfo,VkLayerFunction func)99 VkLayerDeviceCreateInfo* get_chain_info(const VkDeviceCreateInfo* pCreateInfo, VkLayerFunction func) {
100     VkLayerDeviceCreateInfo* chain_info = (VkLayerDeviceCreateInfo*)pCreateInfo->pNext;
101     while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO && chain_info->function == func)) {
102         chain_info = (VkLayerDeviceCreateInfo*)chain_info->pNext;
103     }
104     assert(chain_info != NULL);
105     return chain_info;
106 }
107 
test_vkEnumerateInstanceLayerProperties(uint32_t * pPropertyCount,VkLayerProperties * pProperties)108 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceLayerProperties(uint32_t* pPropertyCount, VkLayerProperties* pProperties) {
109     return VK_SUCCESS;
110 }
111 
test_vkEnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)112 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceExtensionProperties(const char* pLayerName, uint32_t* pPropertyCount,
113                                                                            VkExtensionProperties* pProperties) {
114     if (pLayerName && string_eq(pLayerName, TEST_LAYER_NAME)) {
115         *pPropertyCount = 0;
116         return VK_SUCCESS;
117     }
118     return layer.instance_dispatch_table.EnumerateInstanceExtensionProperties(pLayerName, pPropertyCount, pProperties);
119 }
120 
test_vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pPropertyCount,VkLayerProperties * pProperties)121 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount,
122                                                                      VkLayerProperties* pProperties) {
123     return VK_SUCCESS;
124 }
125 
test_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)126 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char* pLayerName,
127                                                                          uint32_t* pPropertyCount,
128                                                                          VkExtensionProperties* pProperties) {
129     if (pLayerName && string_eq(pLayerName, TEST_LAYER_NAME)) {
130         *pPropertyCount = 0;
131         return VK_SUCCESS;
132     }
133     return layer.instance_dispatch_table.EnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pPropertyCount,
134                                                                             pProperties);
135 }
136 
test_vkEnumerateInstanceVersion(uint32_t * pApiVersion)137 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceVersion(uint32_t* pApiVersion) {
138     if (pApiVersion != nullptr) {
139         *pApiVersion = VK_API_VERSION_1_0;
140     }
141     return VK_SUCCESS;
142 }
143 
test_vkCreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)144 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
145                                                      const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) {
146     VkLayerInstanceCreateInfo* chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
147 
148     PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
149     PFN_vk_icdGetPhysicalDeviceProcAddr fpGetPhysicalDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetPhysicalDeviceProcAddr;
150     PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
151     if (fpCreateInstance == NULL) {
152         return VK_ERROR_INITIALIZATION_FAILED;
153     }
154 
155     // Advance the link info for the next element of the chain
156     chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
157     layer.next_vkGetInstanceProcAddr = fpGetInstanceProcAddr;
158 
159     // Continue call down the chain
160     VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
161     if (result != VK_SUCCESS) {
162         return result;
163     }
164     layer.instance_handle = *pInstance;
165     if (layer.use_gipa_GetPhysicalDeviceProcAddr) {
166         layer.next_GetPhysicalDeviceProcAddr =
167             reinterpret_cast<PFN_GetPhysicalDeviceProcAddr>(fpGetInstanceProcAddr(*pInstance, "vk_layerGetPhysicalDeviceProcAddr"));
168     } else {
169         layer.next_GetPhysicalDeviceProcAddr = fpGetPhysicalDeviceProcAddr;
170     }
171     // Init layer's dispatch table using GetInstanceProcAddr of
172     // next layer in the chain.
173     layer_init_instance_dispatch_table(layer.instance_handle, &layer.instance_dispatch_table, fpGetInstanceProcAddr);
174 
175     if (layer.create_instance_callback) result = layer.create_instance_callback(layer);
176 
177     for (auto& func : layer.custom_physical_device_interception_functions) {
178         auto next_func = layer.next_GetPhysicalDeviceProcAddr(*pInstance, func.name.c_str());
179         layer.custom_dispatch_functions.at(func.name.c_str()) = next_func;
180     }
181 
182     for (auto& func : layer.custom_device_interception_functions) {
183         auto next_func = layer.next_vkGetInstanceProcAddr(*pInstance, func.name.c_str());
184         layer.custom_dispatch_functions.at(func.name.c_str()) = next_func;
185     }
186 
187     if (layer.do_spurious_allocations_in_create_instance && pAllocator && pAllocator->pfnAllocation) {
188         layer.spurious_instance_memory_allocation =
189             pAllocator->pfnAllocation(pAllocator->pUserData, 100, 8, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
190         if (layer.spurious_instance_memory_allocation == nullptr) {
191             return VK_ERROR_OUT_OF_HOST_MEMORY;
192         }
193     }
194 
195     return result;
196 }
197 
test_override_vkCreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)198 VKAPI_ATTR VkResult VKAPI_CALL test_override_vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
199                                                               const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) {
200     return VK_ERROR_INVALID_SHADER_NV;
201 }
202 
test_vkDestroyInstance(VkInstance instance,const VkAllocationCallbacks * pAllocator)203 VKAPI_ATTR void VKAPI_CALL test_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator) {
204     if (layer.spurious_instance_memory_allocation && pAllocator && pAllocator->pfnFree) {
205         pAllocator->pfnFree(pAllocator->pUserData, layer.spurious_instance_memory_allocation);
206         layer.spurious_instance_memory_allocation = nullptr;
207     }
208 
209     layer.instance_dispatch_table.DestroyInstance(instance, pAllocator);
210 }
211 
test_vkCreateDevice(VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)212 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo,
213                                                    const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) {
214     VkLayerDeviceCreateInfo* chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
215 
216     PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
217     PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
218     PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(layer.instance_handle, "vkCreateDevice");
219     if (fpCreateDevice == NULL) {
220         return VK_ERROR_INITIALIZATION_FAILED;
221     }
222 
223     layer.next_vkGetDeviceProcAddr = fpGetDeviceProcAddr;
224 
225     // Advance the link info for the next element on the chain
226     chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
227 
228     VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
229     if (result != VK_SUCCESS) {
230         return result;
231     }
232     TestLayer::Device device{};
233     device.device_handle = *pDevice;
234 
235     // initialize layer's dispatch table
236     layer_init_device_dispatch_table(device.device_handle, &device.dispatch_table, fpGetDeviceProcAddr);
237 
238     for (auto& func : layer.custom_device_interception_functions) {
239         auto next_func = layer.next_vkGetDeviceProcAddr(*pDevice, func.name.c_str());
240         layer.custom_dispatch_functions.at(func.name.c_str()) = next_func;
241     }
242 
243     if (layer.create_device_callback) {
244         result = layer.create_device_callback(layer);
245     }
246 
247     // Need to add the created devices to the list so it can be freed
248     layer.created_devices.push_back(device);
249 
250     if (layer.do_spurious_allocations_in_create_device && pAllocator && pAllocator->pfnAllocation) {
251         void* allocation = pAllocator->pfnAllocation(pAllocator->pUserData, 110, 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
252         if (allocation == nullptr) {
253             return VK_ERROR_OUT_OF_HOST_MEMORY;
254         } else {
255             layer.spurious_device_memory_allocations.push_back({allocation, device.device_handle});
256         }
257     }
258 
259     return result;
260 }
261 
test_vkEnumeratePhysicalDevices(VkInstance instance,uint32_t * pPhysicalDeviceCount,VkPhysicalDevice * pPhysicalDevices)262 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount,
263                                                                VkPhysicalDevice* pPhysicalDevices) {
264     if (layer.add_phys_devs || layer.remove_phys_devs || layer.reorder_phys_devs) {
265         VkResult res = VK_SUCCESS;
266 
267         if (layer.complete_physical_devices.size() == 0) {
268             // Get list of all physical devices from lower down
269             // NOTE: This only works if we don't test changing the number of devices
270             //       underneath us when using this test.
271             uint32_t icd_count = 0;
272             layer.instance_dispatch_table.EnumeratePhysicalDevices(instance, &icd_count, nullptr);
273             std::vector<VkPhysicalDevice> tmp_vector;
274             tmp_vector.resize(icd_count);
275             layer.instance_dispatch_table.EnumeratePhysicalDevices(instance, &icd_count, tmp_vector.data());
276             layer.complete_physical_devices.clear();
277 
278             if (layer.remove_phys_devs) {
279                 // Erase the 3rd and 4th items
280                 layer.removed_physical_devices.push_back(tmp_vector[3]);
281                 layer.removed_physical_devices.push_back(tmp_vector[4]);
282                 tmp_vector.erase(tmp_vector.begin() + 3);
283                 tmp_vector.erase(tmp_vector.begin() + 3);
284             }
285 
286             if (layer.add_phys_devs) {
287                 // Insert a new device in the beginning, middle, and end
288                 uint32_t middle = static_cast<uint32_t>(tmp_vector.size() / 2);
289                 VkPhysicalDevice new_phys_dev = reinterpret_cast<VkPhysicalDevice>((size_t)(0xABCD0000));
290                 layer.added_physical_devices.push_back(new_phys_dev);
291                 tmp_vector.insert(tmp_vector.begin(), new_phys_dev);
292                 new_phys_dev = reinterpret_cast<VkPhysicalDevice>((size_t)(0xBADC0000));
293                 layer.added_physical_devices.push_back(new_phys_dev);
294                 tmp_vector.insert(tmp_vector.begin() + middle, new_phys_dev);
295                 new_phys_dev = reinterpret_cast<VkPhysicalDevice>((size_t)(0xDCBA0000));
296                 layer.added_physical_devices.push_back(new_phys_dev);
297                 tmp_vector.push_back(new_phys_dev);
298             }
299 
300             if (layer.reorder_phys_devs) {
301                 // Flip the order of items
302                 for (int32_t dev = static_cast<int32_t>(tmp_vector.size() - 1); dev >= 0; --dev) {
303                     layer.complete_physical_devices.push_back(tmp_vector[dev]);
304                 }
305             } else {
306                 // Otherwise, keep the order the same
307                 for (uint32_t dev = 0; dev < tmp_vector.size(); ++dev) {
308                     layer.complete_physical_devices.push_back(tmp_vector[dev]);
309                 }
310             }
311         }
312 
313         if (nullptr == pPhysicalDevices) {
314             *pPhysicalDeviceCount = static_cast<uint32_t>(layer.complete_physical_devices.size());
315         } else {
316             uint32_t adj_count = static_cast<uint32_t>(layer.complete_physical_devices.size());
317             if (*pPhysicalDeviceCount < adj_count) {
318                 adj_count = *pPhysicalDeviceCount;
319                 res = VK_INCOMPLETE;
320             }
321             for (uint32_t dev = 0; dev < adj_count; ++dev) {
322                 pPhysicalDevices[dev] = layer.complete_physical_devices[dev];
323             }
324             *pPhysicalDeviceCount = adj_count;
325         }
326 
327         return res;
328     } else {
329         return layer.instance_dispatch_table.EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
330     }
331 }
332 
test_vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties * pProperties)333 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
334                                                               VkPhysicalDeviceProperties* pProperties) {
335     if (std::find(layer.removed_physical_devices.begin(), layer.removed_physical_devices.end(), physicalDevice) !=
336         layer.removed_physical_devices.end()) {
337         // Should not get here since the application should not know about those devices
338         assert(false);
339     } else if (std::find(layer.added_physical_devices.begin(), layer.added_physical_devices.end(), physicalDevice) !=
340                layer.added_physical_devices.end()) {
341         // Added device so put in some placeholder info we can test against
342         pProperties->apiVersion = VK_API_VERSION_1_2;
343         pProperties->driverVersion = VK_MAKE_API_VERSION(0, 12, 14, 196);
344         pProperties->vendorID = 0xDECAFBAD;
345         pProperties->deviceID = 0xDEADBADD;
346 #if defined(_WIN32)
347         strncpy_s(pProperties->deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, "physdev_added_xx", 17);
348 #else
349         strncpy(pProperties->deviceName, "physdev_added_xx", VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
350 #endif
351     } else {
352         // Not an affected device so just return
353         layer.instance_dispatch_table.GetPhysicalDeviceProperties(physicalDevice, pProperties);
354     }
355 }
356 
test_vkEnumeratePhysicalDeviceGroups(VkInstance instance,uint32_t * pPhysicalDeviceGroupCount,VkPhysicalDeviceGroupProperties * pPhysicalDeviceGroupProperties)357 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDeviceGroups(
358     VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
359     if (layer.add_phys_devs || layer.remove_phys_devs || layer.reorder_phys_devs) {
360         VkResult res = VK_SUCCESS;
361 
362         if (layer.complete_physical_device_groups.size() == 0) {
363             uint32_t fake_count = 1000;
364             // Call EnumerateDevices to add remove devices as needed
365             test_vkEnumeratePhysicalDevices(instance, &fake_count, nullptr);
366 
367             // Get list of all physical devices from lower down
368             // NOTE: This only works if we don't test changing the number of devices
369             //       underneath us when using this test.
370             uint32_t icd_group_count = 0;
371             layer.instance_dispatch_table.EnumeratePhysicalDeviceGroups(instance, &icd_group_count, nullptr);
372             std::vector<VkPhysicalDeviceGroupProperties> tmp_vector(icd_group_count);
373             for (uint32_t group = 0; group < icd_group_count; ++group) {
374                 tmp_vector[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
375             }
376             layer.instance_dispatch_table.EnumeratePhysicalDeviceGroups(instance, &icd_group_count, tmp_vector.data());
377             layer.complete_physical_device_groups.clear();
378 
379             if (layer.remove_phys_devs) {
380                 // Now, if a device has been removed, and it was the only group, we need to remove the group as well.
381                 for (uint32_t rem_dev = 0; rem_dev < layer.removed_physical_devices.size(); ++rem_dev) {
382                     for (uint32_t group = 0; group < icd_group_count; ++group) {
383                         for (uint32_t grp_dev = 0; grp_dev < tmp_vector[group].physicalDeviceCount; ++grp_dev) {
384                             if (tmp_vector[group].physicalDevices[grp_dev] == layer.removed_physical_devices[rem_dev]) {
385                                 for (uint32_t cp_item = grp_dev + 1; cp_item < tmp_vector[group].physicalDeviceCount; ++cp_item) {
386                                     tmp_vector[group].physicalDevices[grp_dev] = tmp_vector[group].physicalDevices[cp_item];
387                                 }
388                                 tmp_vector[group].physicalDeviceCount--;
389                             }
390                         }
391                     }
392                 }
393                 for (uint32_t group = 0; group < tmp_vector.size(); ++group) {
394                     if (tmp_vector[group].physicalDeviceCount == 0) {
395                         layer.removed_physical_device_groups.push_back(tmp_vector[group]);
396                         tmp_vector.erase(tmp_vector.begin() + group);
397                         --group;
398                     }
399                 }
400             }
401 
402             if (layer.add_phys_devs) {
403                 // Add a new group for each physical device not associated with a current group
404                 for (uint32_t dev = 0; dev < layer.added_physical_devices.size(); ++dev) {
405                     VkPhysicalDeviceGroupProperties props{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES};
406                     props.physicalDeviceCount = 1;
407                     props.physicalDevices[0] = layer.added_physical_devices[dev];
408                     tmp_vector.push_back(props);
409                     layer.added_physical_device_groups.push_back(props);
410                 }
411             }
412 
413             if (layer.reorder_phys_devs) {
414                 // Flip the order of items
415                 for (int32_t dev = static_cast<int32_t>(tmp_vector.size() - 1); dev >= 0; --dev) {
416                     layer.complete_physical_device_groups.push_back(tmp_vector[dev]);
417                 }
418             } else {
419                 // Otherwise, keep the order the same
420                 for (uint32_t dev = 0; dev < tmp_vector.size(); ++dev) {
421                     layer.complete_physical_device_groups.push_back(tmp_vector[dev]);
422                 }
423             }
424         }
425 
426         if (nullptr == pPhysicalDeviceGroupProperties) {
427             *pPhysicalDeviceGroupCount = static_cast<uint32_t>(layer.complete_physical_device_groups.size());
428         } else {
429             uint32_t adj_count = static_cast<uint32_t>(layer.complete_physical_device_groups.size());
430             if (*pPhysicalDeviceGroupCount < adj_count) {
431                 adj_count = *pPhysicalDeviceGroupCount;
432                 res = VK_INCOMPLETE;
433             }
434             for (uint32_t dev = 0; dev < adj_count; ++dev) {
435                 pPhysicalDeviceGroupProperties[dev] = layer.complete_physical_device_groups[dev];
436             }
437             *pPhysicalDeviceGroupCount = adj_count;
438         }
439 
440         return res;
441     } else {
442         return layer.instance_dispatch_table.EnumeratePhysicalDeviceGroups(instance, pPhysicalDeviceGroupCount,
443                                                                            pPhysicalDeviceGroupProperties);
444     }
445 }
446 
447 // device functions
448 
test_vkDestroyDevice(VkDevice device,const VkAllocationCallbacks * pAllocator)449 VKAPI_ATTR void VKAPI_CALL test_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
450     for (uint32_t i = 0; i < layer.spurious_device_memory_allocations.size();) {
451         auto& allocation = layer.spurious_device_memory_allocations[i];
452         if (allocation.device == device && pAllocator && pAllocator->pfnFree) {
453             pAllocator->pfnFree(pAllocator->pUserData, allocation.allocation);
454             layer.spurious_device_memory_allocations.erase(layer.spurious_device_memory_allocations.begin() + i);
455         } else {
456             i++;
457         }
458     }
459 
460     for (auto& created_device : layer.created_devices) {
461         if (created_device.device_handle == device) {
462             created_device.dispatch_table.DestroyDevice(device, pAllocator);
463             break;
464         }
465     }
466 }
467 // forward declarations needed for trampolines
468 #if TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR
469 extern "C" {
470 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName);
471 }
472 #endif
473 
474 // trampolines
475 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_device_func(VkDevice device, const char* pName);
get_device_func_impl(VkDevice device,const char * pName)476 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_device_func_impl(VkDevice device, const char* pName) {
477     if (string_eq(pName, "vkGetDeviceProcAddr")) return to_vkVoidFunction(get_device_func);
478     if (string_eq(pName, "vkDestroyDevice")) return to_vkVoidFunction(test_vkDestroyDevice);
479 
480     for (auto& func : layer.custom_device_interception_functions) {
481         if (func.name == pName) {
482             return to_vkVoidFunction(func.function);
483         }
484     }
485 
486     for (auto& func : layer.custom_device_implementation_functions) {
487         if (func.name == pName) {
488             return to_vkVoidFunction(func.function);
489         }
490     }
491 
492     return nullptr;
493 }
494 
get_device_func(VkDevice device,const char * pName)495 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_device_func(VkDevice device, const char* pName) {
496     PFN_vkVoidFunction ret_dev = get_device_func_impl(device, pName);
497     if (ret_dev != nullptr) return ret_dev;
498 
499     return layer.next_vkGetDeviceProcAddr(device, pName);
500 }
501 
get_physical_device_func(VkInstance instance,const char * pName)502 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_physical_device_func(VkInstance instance, const char* pName) {
503     if (string_eq(pName, "vkEnumerateDeviceLayerProperties")) return to_vkVoidFunction(test_vkEnumerateDeviceLayerProperties);
504     if (string_eq(pName, "vkEnumerateDeviceExtensionProperties"))
505         return to_vkVoidFunction(test_vkEnumerateDeviceExtensionProperties);
506     if (string_eq(pName, "vkEnumeratePhysicalDevices")) return (PFN_vkVoidFunction)test_vkEnumeratePhysicalDevices;
507     if (string_eq(pName, "vkEnumeratePhysicalDeviceGroups")) return (PFN_vkVoidFunction)test_vkEnumeratePhysicalDeviceGroups;
508     if (string_eq(pName, "vkGetPhysicalDeviceProperties")) return (PFN_vkVoidFunction)test_vkGetPhysicalDeviceProperties;
509 
510     for (auto& func : layer.custom_physical_device_interception_functions) {
511         if (func.name == pName) {
512             return to_vkVoidFunction(func.function);
513         }
514     }
515 
516     for (auto& func : layer.custom_physical_device_implementation_functions) {
517         if (func.name == pName) {
518             return to_vkVoidFunction(func.function);
519         }
520     }
521 
522 #if TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR
523     if (string_eq(pName, "vk_layerGetPhysicalDeviceProcAddr")) return to_vkVoidFunction(vk_layerGetPhysicalDeviceProcAddr);
524 #endif
525     return nullptr;
526 }
527 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_instance_func(VkInstance instance, const char* pName);
get_instance_func_impl(VkInstance instance,const char * pName)528 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_instance_func_impl(VkInstance instance, const char* pName) {
529     if (pName == nullptr) return nullptr;
530     if (string_eq(pName, "vkGetInstanceProcAddr")) return to_vkVoidFunction(get_instance_func);
531     if (string_eq(pName, "vkEnumerateInstanceLayerProperties")) return to_vkVoidFunction(test_vkEnumerateInstanceLayerProperties);
532     if (string_eq(pName, "vkEnumerateInstanceExtensionProperties"))
533         return to_vkVoidFunction(test_vkEnumerateInstanceExtensionProperties);
534     if (string_eq(pName, "vkEnumerateInstanceVersion")) return to_vkVoidFunction(test_vkEnumerateInstanceVersion);
535     if (string_eq(pName, "vkCreateInstance")) return to_vkVoidFunction(test_vkCreateInstance);
536     if (string_eq(pName, "vkDestroyInstance")) return to_vkVoidFunction(test_vkDestroyInstance);
537     if (string_eq(pName, "vkCreateDevice")) return to_vkVoidFunction(test_vkCreateDevice);
538     if (string_eq(pName, "vkGetDeviceProcAddr")) return to_vkVoidFunction(get_device_func);
539 
540     PFN_vkVoidFunction ret_phys_dev = get_physical_device_func(instance, pName);
541     if (ret_phys_dev != nullptr) return ret_phys_dev;
542 
543     PFN_vkVoidFunction ret_dev = get_device_func_impl(nullptr, pName);
544     if (ret_dev != nullptr) return ret_dev;
545 
546     return nullptr;
547 }
548 
get_instance_func(VkInstance instance,const char * pName)549 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_instance_func(VkInstance instance, const char* pName) {
550     PFN_vkVoidFunction ret_dev = get_instance_func_impl(instance, pName);
551     if (ret_dev != nullptr) return ret_dev;
552 
553     return layer.next_vkGetInstanceProcAddr(instance, pName);
554 }
555 
556 // Exported functions
557 extern "C" {
558 #if TEST_LAYER_EXPORT_ENUMERATE_FUNCTIONS
559 
560 // Pre-instance handling functions
561 
test_preinst_vkEnumerateInstanceLayerProperties(const VkEnumerateInstanceLayerPropertiesChain * pChain,uint32_t * pPropertyCount,VkLayerProperties * pProperties)562 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL test_preinst_vkEnumerateInstanceLayerProperties(
563     const VkEnumerateInstanceLayerPropertiesChain* pChain, uint32_t* pPropertyCount, VkLayerProperties* pProperties) {
564     VkResult res = pChain->pfnNextLayer(pChain->pNextLink, pPropertyCount, pProperties);
565     if (nullptr == pProperties) {
566         *pPropertyCount = layer.reported_layer_props;
567     } else {
568         uint32_t count = layer.reported_layer_props;
569         if (*pPropertyCount < layer.reported_layer_props) {
570             count = *pPropertyCount;
571             res = VK_INCOMPLETE;
572         }
573         for (uint32_t i = 0; i < count; ++i) {
574             snprintf(pProperties[i].layerName, VK_MAX_EXTENSION_NAME_SIZE, "%02d_layer", count);
575             pProperties[i].specVersion = count;
576             pProperties[i].implementationVersion = 0xABCD0000 + count;
577         }
578     }
579     return res;
580 }
581 
test_preinst_vkEnumerateInstanceExtensionProperties(const VkEnumerateInstanceExtensionPropertiesChain * pChain,const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)582 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL test_preinst_vkEnumerateInstanceExtensionProperties(
583     const VkEnumerateInstanceExtensionPropertiesChain* pChain, const char* pLayerName, uint32_t* pPropertyCount,
584     VkExtensionProperties* pProperties) {
585     VkResult res = pChain->pfnNextLayer(pChain->pNextLink, pLayerName, pPropertyCount, pProperties);
586     if (nullptr == pProperties) {
587         *pPropertyCount = layer.reported_extension_props;
588     } else {
589         uint32_t count = layer.reported_extension_props;
590         if (*pPropertyCount < layer.reported_extension_props) {
591             count = *pPropertyCount;
592             res = VK_INCOMPLETE;
593         }
594         for (uint32_t i = 0; i < count; ++i) {
595             snprintf(pProperties[i].extensionName, VK_MAX_EXTENSION_NAME_SIZE, "%02d_ext", count);
596             pProperties[i].specVersion = count;
597         }
598     }
599     return res;
600 }
601 
602 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
test_preinst_vkEnumerateInstanceVersion(const VkEnumerateInstanceVersionChain * pChain,uint32_t * pApiVersion)603 test_preinst_vkEnumerateInstanceVersion(const VkEnumerateInstanceVersionChain* pChain, uint32_t* pApiVersion) {
604     VkResult res = pChain->pfnNextLayer(pChain->pNextLink, pApiVersion);
605     *pApiVersion = layer.reported_instance_version;
606     return res;
607 }
608 
vkEnumerateInstanceLayerProperties(uint32_t * pPropertyCount,VkLayerProperties * pProperties)609 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t* pPropertyCount,
610                                                                                    VkLayerProperties* pProperties) {
611     return test_vkEnumerateInstanceLayerProperties(pPropertyCount, pProperties);
612 }
vkEnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)613 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char* pLayerName,
614                                                                                        uint32_t* pPropertyCount,
615                                                                                        VkExtensionProperties* pProperties) {
616     return test_vkEnumerateInstanceExtensionProperties(pLayerName, pPropertyCount, pProperties);
617 }
618 
vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pPropertyCount,VkLayerProperties * pProperties)619 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
620                                                                                  uint32_t* pPropertyCount,
621                                                                                  VkLayerProperties* pProperties) {
622     return test_vkEnumerateDeviceLayerProperties(physicalDevice, pPropertyCount, pProperties);
623 }
vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)624 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
625                                                                                      const char* pLayerName,
626                                                                                      uint32_t* pPropertyCount,
627                                                                                      VkExtensionProperties* pProperties) {
628     return test_vkEnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pPropertyCount, pProperties);
629 }
630 #endif
631 
632 #if TEST_LAYER_EXPORT_LAYER_NAMED_GIPA
test_layer_GetInstanceProcAddr(VkInstance instance,const char * pName)633 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_layer_GetInstanceProcAddr(VkInstance instance, const char* pName) {
634     return get_instance_func(instance, pName);
635 }
test_override_vkGetInstanceProcAddr(VkInstance instance,const char * pName)636 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_override_vkGetInstanceProcAddr(VkInstance instance,
637                                                                                               const char* pName) {
638     if (string_eq(pName, "vkCreateInstance")) return to_vkVoidFunction(test_override_vkCreateInstance);
639     return get_instance_func(instance, pName);
640 }
641 #endif
642 
643 #if TEST_LAYER_EXPORT_LAYER_VK_GIPA
vkGetInstanceProcAddr(VkInstance instance,const char * pName)644 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* pName) {
645     return get_instance_func(instance, pName);
646 }
647 #endif
648 
649 #if TEST_LAYER_EXPORT_LAYER_NAMED_GDPA
test_layer_GetDeviceProcAddr(VkDevice device,const char * pName)650 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_layer_GetDeviceProcAddr(VkDevice device, const char* pName) {
651     return get_device_func(device, pName);
652 }
653 #endif
654 
655 #if TEST_LAYER_EXPORT_LAYER_VK_GDPA
vkGetDeviceProcAddr(VkDevice device,const char * pName)656 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* pName) {
657     return get_device_func(device, pName);
658 }
659 #endif
660 
661 #if TEST_LAYER_EXPORT_NO_PREFIX_GIPA
GetInstanceProcAddr(VkInstance instance,const char * pName)662 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char* pName) {
663     return get_instance_func(instance, pName);
664 }
665 #endif
666 
667 #if TEST_LAYER_EXPORT_NO_PREFIX_GDPA
GetDeviceProcAddr(VkDevice device,const char * pName)668 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char* pName) {
669     return get_device_func(device, pName);
670 }
671 #endif
672 
673 #if TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR
vk_layerGetPhysicalDeviceProcAddr(VkInstance instance,const char * pName)674 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance,
675                                                                                             const char* pName) {
676     auto func = get_physical_device_func(instance, pName);
677     if (func != nullptr) return func;
678     return layer.next_GetPhysicalDeviceProcAddr(instance, pName);
679 }
680 #endif
681 
682 #if LAYER_EXPORT_NEGOTIATE_LOADER_LAYER_INTERFACE_VERSION
683 // vk_layer.h has a forward declaration of vkNegotiateLoaderLayerInterfaceVersion, which doesn't have any attributes
684 // Since FRAMEWORK_EXPORT adds  __declspec(dllexport), we can't do that here, thus we need our own macro
685 #if (defined(__GNUC__) && (__GNUC__ >= 4)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
686 #define EXPORT_NEGOTIATE_FUNCTION __attribute__((visibility("default")))
687 #else
688 #define EXPORT_NEGOTIATE_FUNCTION
689 #endif
690 
691 EXPORT_NEGOTIATE_FUNCTION VKAPI_ATTR VkResult VKAPI_CALL
vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface * pVersionStruct)692 vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface* pVersionStruct) {
693     if (pVersionStruct) {
694         if (pVersionStruct->loaderLayerInterfaceVersion < layer.min_implementation_version) {
695             return VK_ERROR_INITIALIZATION_FAILED;
696         }
697 
698         pVersionStruct->loaderLayerInterfaceVersion = layer.implementation_version;
699         pVersionStruct->pfnGetInstanceProcAddr = get_instance_func;
700         pVersionStruct->pfnGetDeviceProcAddr = get_device_func;
701 #if TEST_LAYER_EXPORT_GET_PHYSICAL_DEVICE_PROC_ADDR
702         pVersionStruct->pfnGetPhysicalDeviceProcAddr = vk_layerGetPhysicalDeviceProcAddr;
703 #else
704         pVersionStruct->pfnGetPhysicalDeviceProcAddr = nullptr;
705 #endif
706 
707         return VK_SUCCESS;
708     }
709     return VK_ERROR_INITIALIZATION_FAILED;
710 }
711 #endif
712 }  // extern "C"
713