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