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