1 /*
2 * Copyright (c) 2021-2023 The Khronos Group Inc.
3 * Copyright (c) 2021-2023 Valve Corporation
4 * Copyright (c) 2021-2023 LunarG, Inc.
5 * Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
6 * Copyright (c) 2023-2023 RasterGrid Kft.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and/or associated documentation files (the "Materials"), to
10 * deal in the Materials without restriction, including without limitation the
11 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12 * sell copies of the Materials, and to permit persons to whom the Materials are
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice(s) and this permission notice shall be included in
16 * all copies or substantial portions of the Materials.
17 *
18 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 *
22 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
23 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
25 * USE OR OTHER DEALINGS IN THE MATERIALS.
26 *
27 * Author: Charles Giessen <charles@lunarg.com>
28 */
29
30 #include "test_icd.h"
31
32 // export vk_icdGetInstanceProcAddr
33 #if !defined(TEST_ICD_EXPORT_ICD_GIPA)
34 #define TEST_ICD_EXPORT_ICD_GIPA 0
35 #endif
36
37 // export vk_icdNegotiateLoaderICDInterfaceVersion
38 #if !defined(TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION)
39 #define TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION 0
40 #endif
41
42 // export vk_icdGetPhysicalDeviceProcAddr
43 #if !defined(TEST_ICD_EXPORT_ICD_GPDPA)
44 #define TEST_ICD_EXPORT_ICD_GPDPA 0
45 #endif
46
47 // export vk_icdEnumerateAdapterPhysicalDevices
48 #if !defined(TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES)
49 #define TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES 0
50 #endif
51
52 // expose vk_icdNegotiateLoaderICDInterfaceVersion, vk_icdEnumerateAdapterPhysicalDevices, and vk_icdGetPhysicalDeviceProcAddr
53 // through vk_icdGetInstanceProcAddr or vkGetInstanceProcAddr
54 #if !defined(TEST_ICD_EXPOSE_VERSION_7)
55 #define TEST_ICD_EXPOSE_VERSION_7 0
56 #endif
57
58 TestICD icd;
59 extern "C" {
get_test_icd_func()60 FRAMEWORK_EXPORT TestICD* get_test_icd_func() { return &icd; }
reset_icd_func()61 FRAMEWORK_EXPORT TestICD* reset_icd_func() {
62 icd.~TestICD();
63 return new (&icd) TestICD();
64 }
65 }
66
FindLayer(std::vector<LayerDefinition>& layers, std::string layerName)67 LayerDefinition& FindLayer(std::vector<LayerDefinition>& layers, std::string layerName) {
68 for (auto& layer : layers) {
69 if (layer.layerName == layerName) return layer;
70 }
71 assert(false && "Layer name not found!");
72 return layers[0];
73 }
CheckLayer(std::vector<LayerDefinition>& layers, std::string layerName)74 bool CheckLayer(std::vector<LayerDefinition>& layers, std::string layerName) {
75 for (auto& layer : layers) {
76 if (layer.layerName == layerName) return true;
77 }
78 return false;
79 }
80
IsInstanceExtensionSupported(const char* extension_name)81 bool IsInstanceExtensionSupported(const char* extension_name) {
82 return icd.instance_extensions.end() !=
83 std::find_if(icd.instance_extensions.begin(), icd.instance_extensions.end(),
84 [extension_name](Extension const& ext) { return string_eq(&ext.extensionName[0], extension_name); });
85 }
86
87 bool IsInstanceExtensionEnabled(const char* extension_name) {
88 return icd.enabled_instance_extensions.end() !=
89 std::find_if(icd.enabled_instance_extensions.begin(), icd.enabled_instance_extensions.end(),
90 [extension_name](Extension const& ext) { return string_eq(&ext.extensionName[0], extension_name); });
91 }
92
93 bool IsPhysicalDeviceExtensionAvailable(const char* extension_name) {
94 for (auto& phys_dev : icd.physical_devices) {
95 if (phys_dev.extensions.end() !=
96 std::find_if(phys_dev.extensions.begin(), phys_dev.extensions.end(),
97 [extension_name](Extension const& ext) { return ext.extensionName == extension_name; })) {
98 return true;
99 }
100 }
101 return false;
102 }
103
104 // typename T must have '.get()' function that returns a type U
105 template <typename T, typename U>
106 VkResult FillCountPtr(std::vector<T> const& data_vec, uint32_t* pCount, U* pData) {
107 if (pCount == nullptr) {
108 return VK_ERROR_OUT_OF_HOST_MEMORY;
109 }
110 if (pData == nullptr) {
111 *pCount = static_cast<uint32_t>(data_vec.size());
112 return VK_SUCCESS;
113 }
114 uint32_t amount_written = 0;
115 uint32_t amount_to_write = static_cast<uint32_t>(data_vec.size());
116 if (*pCount < data_vec.size()) {
117 amount_to_write = *pCount;
118 }
119 for (size_t i = 0; i < amount_to_write; i++) {
120 pData[i] = data_vec[i].get();
121 amount_written++;
122 }
123 if (*pCount < data_vec.size()) {
124 *pCount = amount_written;
125 return VK_INCOMPLETE;
126 }
127 *pCount = amount_written;
128 return VK_SUCCESS;
129 }
130
131 template <typename T>
132 VkResult FillCountPtr(std::vector<T> const& data_vec, uint32_t* pCount, T* pData) {
133 if (pCount == nullptr) {
134 return VK_ERROR_OUT_OF_HOST_MEMORY;
135 }
136 if (pData == nullptr) {
137 *pCount = static_cast<uint32_t>(data_vec.size());
138 return VK_SUCCESS;
139 }
140 uint32_t amount_written = 0;
141 uint32_t amount_to_write = static_cast<uint32_t>(data_vec.size());
142 if (*pCount < data_vec.size()) {
143 amount_to_write = *pCount;
144 }
145 for (size_t i = 0; i < amount_to_write; i++) {
146 pData[i] = data_vec[i];
147 amount_written++;
148 }
149 if (*pCount < data_vec.size()) {
150 *pCount = amount_written;
151 return VK_INCOMPLETE;
152 }
153 *pCount = amount_written;
154 return VK_SUCCESS;
155 }
156
157 //// Instance Functions ////
158
159 // VK_SUCCESS,VK_INCOMPLETE
160 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceExtensionProperties(const char* pLayerName, uint32_t* pPropertyCount,
161 VkExtensionProperties* pProperties) {
162 if (pLayerName != nullptr) {
163 auto& layer = FindLayer(icd.instance_layers, std::string(pLayerName));
164 return FillCountPtr(layer.extensions, pPropertyCount, pProperties);
165 } else { // instance extensions
166 FillCountPtr(icd.instance_extensions, pPropertyCount, pProperties);
167 }
168
169 return VK_SUCCESS;
170 }
171
172 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceLayerProperties(uint32_t* pPropertyCount, VkLayerProperties* pProperties) {
173 return FillCountPtr(icd.instance_layers, pPropertyCount, pProperties);
174 }
175
176 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceVersion(uint32_t* pApiVersion) {
177 if (pApiVersion != nullptr) {
178 *pApiVersion = icd.icd_api_version;
179 }
180 return VK_SUCCESS;
181 }
182
183 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
184 [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
185 VkInstance* pInstance) {
186 if (pCreateInfo == nullptr || pCreateInfo->pApplicationInfo == nullptr) {
187 return VK_ERROR_OUT_OF_HOST_MEMORY;
188 }
189
190 if (icd.icd_api_version < VK_API_VERSION_1_1) {
191 if (pCreateInfo->pApplicationInfo->apiVersion > VK_API_VERSION_1_0) {
192 return VK_ERROR_INCOMPATIBLE_DRIVER;
193 }
194 }
195
196 // Add to the list of enabled extensions only those that the ICD actively supports
197 for (uint32_t iii = 0; iii < pCreateInfo->enabledExtensionCount; ++iii) {
198 if (IsInstanceExtensionSupported(pCreateInfo->ppEnabledExtensionNames[iii])) {
199 icd.add_enabled_instance_extension({pCreateInfo->ppEnabledExtensionNames[iii]});
200 }
201 }
202
203 // VK_SUCCESS
204 *pInstance = icd.instance_handle.handle;
205
206 icd.passed_in_instance_create_flags = pCreateInfo->flags;
207
208 return VK_SUCCESS;
209 }
210
211 VKAPI_ATTR void VKAPI_CALL test_vkDestroyInstance([[maybe_unused]] VkInstance instance,
212 [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {}
213
214 // VK_SUCCESS,VK_INCOMPLETE
215 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDevices([[maybe_unused]] VkInstance instance, uint32_t* pPhysicalDeviceCount,
216 VkPhysicalDevice* pPhysicalDevices) {
217 if (pPhysicalDevices == nullptr) {
218 *pPhysicalDeviceCount = static_cast<uint32_t>(icd.physical_devices.size());
219 } else {
220 uint32_t handles_written = 0;
221 for (size_t i = 0; i < icd.physical_devices.size(); i++) {
222 if (i < *pPhysicalDeviceCount) {
223 handles_written++;
224 pPhysicalDevices[i] = icd.physical_devices[i].vk_physical_device.handle;
225 } else {
226 *pPhysicalDeviceCount = handles_written;
227 return VK_INCOMPLETE;
228 }
229 }
230 *pPhysicalDeviceCount = handles_written;
231 }
232 return VK_SUCCESS;
233 }
234
235 // VK_SUCCESS,VK_INCOMPLETE, VK_ERROR_INITIALIZATION_FAILED
236 VKAPI_ATTR VkResult VKAPI_CALL
237 test_vkEnumeratePhysicalDeviceGroups([[maybe_unused]] VkInstance instance, uint32_t* pPhysicalDeviceGroupCount,
238 VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
239 VkResult result = VK_SUCCESS;
240
241 if (pPhysicalDeviceGroupProperties == nullptr) {
242 if (0 == icd.physical_device_groups.size()) {
243 *pPhysicalDeviceGroupCount = static_cast<uint32_t>(icd.physical_devices.size());
244 } else {
245 *pPhysicalDeviceGroupCount = static_cast<uint32_t>(icd.physical_device_groups.size());
246 }
247 } else {
248 // NOTE: This is a fake struct to make sure the pNext chain is properly passed down to the ICD
249 // vkEnumeratePhysicalDeviceGroups.
250 // The two versions must match:
251 // "FakePNext" test in loader_regresion_tests.cpp
252 // "test_vkEnumeratePhysicalDeviceGroups" in test_icd.cpp
253 struct FakePnextSharedWithICD {
254 VkStructureType sType;
255 void* pNext;
256 uint32_t value;
257 };
258
259 uint32_t group_count = 0;
260 if (0 == icd.physical_device_groups.size()) {
261 group_count = static_cast<uint32_t>(icd.physical_devices.size());
262 for (size_t device_group = 0; device_group < icd.physical_devices.size(); device_group++) {
263 if (device_group >= *pPhysicalDeviceGroupCount) {
264 group_count = *pPhysicalDeviceGroupCount;
265 result = VK_INCOMPLETE;
266 break;
267 }
268 pPhysicalDeviceGroupProperties[device_group].subsetAllocation = false;
269 pPhysicalDeviceGroupProperties[device_group].physicalDeviceCount = 1;
270 pPhysicalDeviceGroupProperties[device_group].physicalDevices[0] =
271 icd.physical_devices[device_group].vk_physical_device.handle;
272 for (size_t i = 1; i < VK_MAX_DEVICE_GROUP_SIZE; i++) {
273 pPhysicalDeviceGroupProperties[device_group].physicalDevices[i] = {};
274 }
275 }
276 } else {
277 group_count = static_cast<uint32_t>(icd.physical_device_groups.size());
278 for (size_t device_group = 0; device_group < icd.physical_device_groups.size(); device_group++) {
279 if (device_group >= *pPhysicalDeviceGroupCount) {
280 group_count = *pPhysicalDeviceGroupCount;
281 result = VK_INCOMPLETE;
282 break;
283 }
284 pPhysicalDeviceGroupProperties[device_group].subsetAllocation =
285 icd.physical_device_groups[device_group].subset_allocation;
286 uint32_t handles_written = 0;
287 for (size_t i = 0; i < icd.physical_device_groups[device_group].physical_device_handles.size(); i++) {
288 handles_written++;
289 pPhysicalDeviceGroupProperties[device_group].physicalDevices[i] =
290 icd.physical_device_groups[device_group].physical_device_handles[i]->vk_physical_device.handle;
291 }
292 for (size_t i = handles_written; i < VK_MAX_DEVICE_GROUP_SIZE; i++) {
293 pPhysicalDeviceGroupProperties[device_group].physicalDevices[i] = {};
294 }
295 pPhysicalDeviceGroupProperties[device_group].physicalDeviceCount = handles_written;
296 }
297 }
298 // NOTE: The following code is purely to test pNext passing in vkEnumeratePhysicalDevice groups
299 // and includes normally invalid information.
300 for (size_t device_group = 0; device_group < group_count; device_group++) {
301 if (nullptr != pPhysicalDeviceGroupProperties[device_group].pNext) {
302 VkBaseInStructure* base = reinterpret_cast<VkBaseInStructure*>(pPhysicalDeviceGroupProperties[device_group].pNext);
303 if (base->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT) {
304 FakePnextSharedWithICD* fake = reinterpret_cast<FakePnextSharedWithICD*>(base);
305 fake->value = 0xDECAFBAD;
306 }
307 }
308 }
309 *pPhysicalDeviceGroupCount = static_cast<uint32_t>(group_count);
310 }
311 return result;
312 }
313
314 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDebugUtilsMessengerEXT(
315 [[maybe_unused]] VkInstance instance, [[maybe_unused]] const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
316 [[maybe_unused]] const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pMessenger) {
317 if (nullptr != pMessenger) {
318 uint64_t fake_msgr_handle = reinterpret_cast<uint64_t>(new uint8_t);
319 icd.messenger_handles.push_back(fake_msgr_handle);
320 #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || \
321 defined(_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
322 *pMessenger = reinterpret_cast<VkDebugUtilsMessengerEXT>(fake_msgr_handle);
323 #else
324 *pMessenger = fake_msgr_handle;
325 #endif
326 }
327 return VK_SUCCESS;
328 }
329
330 VKAPI_ATTR void VKAPI_CALL test_vkDestroyDebugUtilsMessengerEXT([[maybe_unused]] VkInstance instance,
331 VkDebugUtilsMessengerEXT messenger,
332 [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {
333 if (messenger != VK_NULL_HANDLE) {
334 uint64_t fake_msgr_handle = (uint64_t)(messenger);
335 auto found_iter = std::find(icd.messenger_handles.begin(), icd.messenger_handles.end(), fake_msgr_handle);
336 if (found_iter != icd.messenger_handles.end()) {
337 // Remove it from the list
338 icd.messenger_handles.erase(found_iter);
339 // Delete the handle
340 delete (uint8_t*)fake_msgr_handle;
341 } else {
342 assert(false && "Messenger not found during destroy!");
343 }
344 }
345 }
346
347 // Debug utils & debug marker ext stubs
348 VKAPI_ATTR VkResult VKAPI_CALL test_vkDebugMarkerSetObjectTagEXT(VkDevice dev, const VkDebugMarkerObjectTagInfoEXT* pTagInfo) {
349 if (pTagInfo && pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {
350 VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pTagInfo->object);
351 if (pd != icd.physical_devices.at(icd.lookup_device(dev).phys_dev_index).vk_physical_device.handle)
352 return VK_ERROR_DEVICE_LOST;
353 }
354 if (pTagInfo && pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {
355 if (pTagInfo->object != icd.surface_handles.at(0)) return VK_ERROR_DEVICE_LOST;
356 }
357 if (pTagInfo && pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT) {
358 if (pTagInfo->object != (uint64_t)(uintptr_t)icd.instance_handle.handle) return VK_ERROR_DEVICE_LOST;
359 }
360 return VK_SUCCESS;
361 }
362 VKAPI_ATTR VkResult VKAPI_CALL test_vkDebugMarkerSetObjectNameEXT(VkDevice dev, const VkDebugMarkerObjectNameInfoEXT* pNameInfo) {
363 if (pNameInfo && pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {
364 VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pNameInfo->object);
365 if (pd != icd.physical_devices.at(icd.lookup_device(dev).phys_dev_index).vk_physical_device.handle)
366 return VK_ERROR_DEVICE_LOST;
367 }
368 if (pNameInfo && pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {
369 if (pNameInfo->object != icd.surface_handles.at(0)) return VK_ERROR_DEVICE_LOST;
370 }
371 if (pNameInfo && pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT) {
372 if (pNameInfo->object != (uint64_t)(uintptr_t)icd.instance_handle.handle) return VK_ERROR_DEVICE_LOST;
373 }
374 return VK_SUCCESS;
375 }
376 VKAPI_ATTR void VKAPI_CALL test_vkCmdDebugMarkerBeginEXT(VkCommandBuffer, const VkDebugMarkerMarkerInfoEXT*) {}
377 VKAPI_ATTR void VKAPI_CALL test_vkCmdDebugMarkerEndEXT(VkCommandBuffer) {}
378 VKAPI_ATTR void VKAPI_CALL test_vkCmdDebugMarkerInsertEXT(VkCommandBuffer, const VkDebugMarkerMarkerInfoEXT*) {}
379
380 VKAPI_ATTR VkResult VKAPI_CALL test_vkSetDebugUtilsObjectNameEXT(VkDevice dev, const VkDebugUtilsObjectNameInfoEXT* pNameInfo) {
381 if (pNameInfo && pNameInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {
382 VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pNameInfo->objectHandle);
383 if (pd != icd.physical_devices.at(icd.lookup_device(dev).phys_dev_index).vk_physical_device.handle)
384 return VK_ERROR_DEVICE_LOST;
385 }
386 if (pNameInfo && pNameInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) {
387 if (pNameInfo->objectHandle != icd.surface_handles.at(0)) return VK_ERROR_DEVICE_LOST;
388 }
389 if (pNameInfo && pNameInfo->objectType == VK_OBJECT_TYPE_INSTANCE) {
390 if (pNameInfo->objectHandle != (uint64_t)(uintptr_t)icd.instance_handle.handle) return VK_ERROR_DEVICE_LOST;
391 }
392 return VK_SUCCESS;
393 }
394 VKAPI_ATTR VkResult VKAPI_CALL test_vkSetDebugUtilsObjectTagEXT(VkDevice dev, const VkDebugUtilsObjectTagInfoEXT* pTagInfo) {
395 if (pTagInfo && pTagInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {
396 VkPhysicalDevice pd = (VkPhysicalDevice)(uintptr_t)(pTagInfo->objectHandle);
397 if (pd != icd.physical_devices.at(icd.lookup_device(dev).phys_dev_index).vk_physical_device.handle)
398 return VK_ERROR_DEVICE_LOST;
399 }
400 if (pTagInfo && pTagInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) {
401 if (pTagInfo->objectHandle != icd.surface_handles.at(0)) return VK_ERROR_DEVICE_LOST;
402 }
403 if (pTagInfo && pTagInfo->objectType == VK_OBJECT_TYPE_INSTANCE) {
404 if (pTagInfo->objectHandle != (uint64_t)(uintptr_t)icd.instance_handle.handle) return VK_ERROR_DEVICE_LOST;
405 }
406 return VK_SUCCESS;
407 }
408 VKAPI_ATTR void VKAPI_CALL test_vkQueueBeginDebugUtilsLabelEXT(VkQueue, const VkDebugUtilsLabelEXT*) {}
409 VKAPI_ATTR void VKAPI_CALL test_vkQueueEndDebugUtilsLabelEXT(VkQueue) {}
410 VKAPI_ATTR void VKAPI_CALL test_vkQueueInsertDebugUtilsLabelEXT(VkQueue, const VkDebugUtilsLabelEXT*) {}
411 VKAPI_ATTR void VKAPI_CALL test_vkCmdBeginDebugUtilsLabelEXT(VkCommandBuffer, const VkDebugUtilsLabelEXT*) {}
412 VKAPI_ATTR void VKAPI_CALL test_vkCmdEndDebugUtilsLabelEXT(VkCommandBuffer) {}
413 VKAPI_ATTR void VKAPI_CALL test_vkCmdInsertDebugUtilsLabelEXT(VkCommandBuffer, const VkDebugUtilsLabelEXT*) {}
414
415 //// Physical Device functions ////
416
417 // VK_SUCCESS,VK_INCOMPLETE
418 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceLayerProperties(VkPhysicalDevice, uint32_t*, VkLayerProperties*) {
419 assert(false && "ICD's don't contain layers???");
420 return VK_SUCCESS;
421 }
422
423 // VK_SUCCESS, VK_INCOMPLETE, VK_ERROR_LAYER_NOT_PRESENT
424 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char* pLayerName,
425 uint32_t* pPropertyCount,
426 VkExtensionProperties* pProperties) {
427 auto& phys_dev = icd.GetPhysDevice(physicalDevice);
428 if (pLayerName != nullptr) {
429 assert(false && "Drivers don't contain layers???");
430 return VK_SUCCESS;
431 } else { // instance extensions
432 return FillCountPtr(phys_dev.extensions, pPropertyCount, pProperties);
433 }
434 }
435
436 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
437 uint32_t* pQueueFamilyPropertyCount,
438 VkQueueFamilyProperties* pQueueFamilyProperties) {
439 auto& phys_dev = icd.GetPhysDevice(physicalDevice);
440 FillCountPtr(phys_dev.queue_family_properties, pQueueFamilyPropertyCount, pQueueFamilyProperties);
441 }
442
443 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo,
444 [[maybe_unused]] const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) {
445 // VK_SUCCESS
446 auto found = std::find_if(icd.physical_devices.begin(), icd.physical_devices.end(), [physicalDevice](PhysicalDevice& phys_dev) {
447 return phys_dev.vk_physical_device.handle == physicalDevice;
448 });
449 if (found == icd.physical_devices.end()) return VK_ERROR_INITIALIZATION_FAILED;
450 auto device_handle = DispatchableHandle<VkDevice>();
451 *pDevice = device_handle.handle;
452 found->device_handles.push_back(device_handle.handle);
453 found->device_create_infos.push_back(DeviceCreateInfo{pCreateInfo});
454 for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
455 found->queue_handles.emplace_back();
456 }
457 icd.device_handles.emplace_back(std::move(device_handle));
458
459 return VK_SUCCESS;
460 }
461
462 VKAPI_ATTR void VKAPI_CALL test_vkDestroyDevice(VkDevice device, [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {
463 auto found = std::find(icd.device_handles.begin(), icd.device_handles.end(), device);
464 if (found != icd.device_handles.end()) icd.device_handles.erase(found);
465 auto fd = icd.lookup_device(device);
466 if (!fd.found) return;
467 auto& phys_dev = icd.physical_devices.at(fd.phys_dev_index);
468 phys_dev.device_handles.erase(phys_dev.device_handles.begin() + fd.dev_index);
469 phys_dev.device_create_infos.erase(phys_dev.device_create_infos.begin() + fd.dev_index);
470 }
471
472 VKAPI_ATTR VkResult VKAPI_CALL generic_tool_props_function([[maybe_unused]] VkPhysicalDevice physicalDevice, uint32_t* pToolCount,
473 VkPhysicalDeviceToolPropertiesEXT* pToolProperties) {
474 if (icd.tooling_properties.size() == 0) {
475 return VK_SUCCESS;
476 }
477 if (pToolProperties == nullptr && pToolCount != nullptr) {
478 *pToolCount = static_cast<uint32_t>(icd.tooling_properties.size());
479 } else if (pToolCount != nullptr) {
480 for (size_t i = 0; i < *pToolCount; i++) {
481 if (i >= icd.tooling_properties.size()) {
482 return VK_INCOMPLETE;
483 }
484 pToolProperties[i] = icd.tooling_properties[i];
485 }
486 }
487 return VK_SUCCESS;
488 }
489
490 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceToolPropertiesEXT(VkPhysicalDevice physicalDevice, uint32_t* pToolCount,
491 VkPhysicalDeviceToolPropertiesEXT* pToolProperties) {
492 return generic_tool_props_function(physicalDevice, pToolCount, pToolProperties);
493 }
494
495 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceToolProperties(VkPhysicalDevice physicalDevice, uint32_t* pToolCount,
496 VkPhysicalDeviceToolPropertiesEXT* pToolProperties) {
497 return generic_tool_props_function(physicalDevice, pToolCount, pToolProperties);
498 }
499
500 template <typename T>
501 T to_nondispatch_handle(uint64_t handle) {
502 #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || \
503 defined(_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
504 return reinterpret_cast<T>(handle);
505 #else
506 return handle;
507 #endif
508 }
509
510 template <typename T>
511 uint64_t from_nondispatch_handle(T handle) {
512 #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || \
513 defined(_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
514 return reinterpret_cast<uint64_t>(handle);
515 #else
516 return handle;
517 #endif
518 }
519
520 //// WSI ////
521 template <typename HandleType>
522 void common_nondispatch_handle_creation(std::vector<uint64_t>& handles, HandleType* pHandle) {
523 if (nullptr != pHandle) {
524 if (handles.size() == 0)
525 handles.push_back(800851234);
526 else
527 handles.push_back(handles.back() + 102030);
528 *pHandle = to_nondispatch_handle<HandleType>(handles.back());
529 }
530 }
531 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
532
533 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo,
534 const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
535 common_nondispatch_handle_creation(icd.surface_handles, pSurface);
536 return VK_SUCCESS;
537 }
538 #endif
539
540 #if defined(VK_USE_PLATFORM_WIN32_KHR)
541 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateWin32SurfaceKHR([[maybe_unused]] VkInstance instance,
542 [[maybe_unused]] const VkWin32SurfaceCreateInfoKHR* pCreateInfo,
543 [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
544 VkSurfaceKHR* pSurface) {
545 common_nondispatch_handle_creation(icd.surface_handles, pSurface);
546 return VK_SUCCESS;
547 }
548
549 VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice, uint32_t) { return VK_TRUE; }
550 #endif // VK_USE_PLATFORM_WIN32_KHR
551
552 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
553 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateWaylandSurfaceKHR([[maybe_unused]] VkInstance instance,
554 [[maybe_unused]] const VkWaylandSurfaceCreateInfoKHR* pCreateInfo,
555 [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
556 VkSurfaceKHR* pSurface) {
557 common_nondispatch_handle_creation(icd.surface_handles, pSurface);
558 return VK_SUCCESS;
559 }
560
561 VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice, uint32_t,
562 struct wl_display*) {
563 return VK_TRUE;
564 }
565 #endif // VK_USE_PLATFORM_WAYLAND_KHR
566 #if defined(VK_USE_PLATFORM_XCB_KHR)
567 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateXcbSurfaceKHR([[maybe_unused]] VkInstance instance,
568 [[maybe_unused]] const VkXcbSurfaceCreateInfoKHR* pCreateInfo,
569 [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
570 VkSurfaceKHR* pSurface) {
571 common_nondispatch_handle_creation(icd.surface_handles, pSurface);
572 return VK_SUCCESS;
573 }
574
575 VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice, uint32_t, xcb_connection_t*,
576 xcb_visualid_t) {
577 return VK_TRUE;
578 }
579 #endif // VK_USE_PLATFORM_XCB_KHR
580
581 #if defined(VK_USE_PLATFORM_XLIB_KHR)
582 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateXlibSurfaceKHR([[maybe_unused]] VkInstance instance,
583 [[maybe_unused]] const VkXlibSurfaceCreateInfoKHR* pCreateInfo,
584 [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
585 VkSurfaceKHR* pSurface) {
586 common_nondispatch_handle_creation(icd.surface_handles, pSurface);
587 return VK_SUCCESS;
588 }
589
590 VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice, uint32_t, Display*, VisualID) {
591 return VK_TRUE;
592 }
593 #endif // VK_USE_PLATFORM_XLIB_KHR
594
595 #if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
596 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDirectFBSurfaceEXT(VkInstance instance,
597 const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo,
598 const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
599 common_nondispatch_handle_creation(icd.surface_handles, pSurface);
600 return VK_SUCCESS;
601 }
602
603 VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceDirectFBPresentationSupportEXT(VkPhysicalDevice physicalDevice,
604 uint32_t queueFamilyIndex, IDirectFB* dfb) {
605 return VK_TRUE;
606 }
607
608 #endif // VK_USE_PLATFORM_DIRECTFB_EXT
609
610 #if defined(VK_USE_PLATFORM_MACOS_MVK)
611 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateMacOSSurfaceMVK([[maybe_unused]] VkInstance instance,
612 [[maybe_unused]] const VkMacOSSurfaceCreateInfoMVK* pCreateInfo,
613 [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
614 VkSurfaceKHR* pSurface) {
615 common_nondispatch_handle_creation(icd.surface_handles, pSurface);
616 return VK_SUCCESS;
617 }
618 #endif // VK_USE_PLATFORM_MACOS_MVK
619
620 #if defined(VK_USE_PLATFORM_IOS_MVK)
621 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateIOSSurfaceMVK([[maybe_unused]] VkInstance instance,
622 [[maybe_unused]] const VkIOSSurfaceCreateInfoMVK* pCreateInfo,
623 [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
624 VkSurfaceKHR* pSurface) {
625 common_nondispatch_handle_creation(icd.surface_handles, pSurface);
626 return VK_SUCCESS;
627 }
628 #endif // VK_USE_PLATFORM_IOS_MVK
629
630 #if defined(VK_USE_PLATFORM_GGP)
631 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateStreamDescriptorSurfaceGGP(VkInstance instance,
632 const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo,
633 const VkAllocationCallbacks* pAllocator,
634 VkSurfaceKHR* pSurface) {
635 common_nondispatch_handle_creation(icd.surface_handles, pSurface);
636 return VK_SUCCESS;
637 }
638 #endif // VK_USE_PLATFORM_GGP
639
640 #if defined(VK_USE_PLATFORM_METAL_EXT)
641 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateMetalSurfaceEXT([[maybe_unused]] VkInstance instance,
642 [[maybe_unused]] const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
643 [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
644 VkSurfaceKHR* pSurface) {
645 common_nondispatch_handle_creation(icd.surface_handles, pSurface);
646 return VK_SUCCESS;
647 }
648 #endif // VK_USE_PLATFORM_METAL_EXT
649
650 #if defined(VK_USE_PLATFORM_SCREEN_QNX)
651 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateScreenSurfaceQNX(VkInstance instance, const VkScreenSurfaceCreateInfoQNX* pCreateInfo,
652 const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
653 common_nondispatch_handle_creation(icd.surface_handles, pSurface);
654 return VK_SUCCESS;
655 }
656
657 VKAPI_ATTR VkBool32 VKAPI_CALL test_vkGetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice,
658 uint32_t queueFamilyIndex,
659 struct _screen_window* window) {
660 return VK_TRUE;
661 }
662 #endif // VK_USE_PLATFORM_SCREEN_QNX
663
664 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateHeadlessSurfaceEXT([[maybe_unused]] VkInstance instance,
665 [[maybe_unused]] const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo,
666 [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
667 VkSurfaceKHR* pSurface) {
668 common_nondispatch_handle_creation(icd.surface_handles, pSurface);
669 return VK_SUCCESS;
670 }
671
672 VKAPI_ATTR void VKAPI_CALL test_vkDestroySurfaceKHR([[maybe_unused]] VkInstance instance, VkSurfaceKHR surface,
673 [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {
674 if (surface != VK_NULL_HANDLE) {
675 uint64_t fake_surf_handle = from_nondispatch_handle(surface);
676 auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
677 if (found_iter != icd.surface_handles.end()) {
678 // Remove it from the list
679 icd.surface_handles.erase(found_iter);
680 } else {
681 assert(false && "Surface not found during destroy!");
682 }
683 }
684 }
685 // VK_KHR_swapchain
686 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateSwapchainKHR([[maybe_unused]] VkDevice device,
687 [[maybe_unused]] const VkSwapchainCreateInfoKHR* pCreateInfo,
688 [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
689 VkSwapchainKHR* pSwapchain) {
690 common_nondispatch_handle_creation(icd.swapchain_handles, pSwapchain);
691 return VK_SUCCESS;
692 }
693
694 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetSwapchainImagesKHR([[maybe_unused]] VkDevice device,
695 [[maybe_unused]] VkSwapchainKHR swapchain,
696 uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages) {
697 std::vector<uint64_t> handles{123, 234, 345, 345, 456};
698 if (pSwapchainImages == nullptr) {
699 if (pSwapchainImageCount) *pSwapchainImageCount = static_cast<uint32_t>(handles.size());
700 } else if (pSwapchainImageCount) {
701 for (uint32_t i = 0; i < *pSwapchainImageCount && i < handles.size(); i++) {
702 pSwapchainImages[i] = to_nondispatch_handle<VkImage>(handles.back());
703 }
704 if (*pSwapchainImageCount < handles.size()) return VK_INCOMPLETE;
705 }
706 return VK_SUCCESS;
707 }
708
709 VKAPI_ATTR void VKAPI_CALL test_vkDestroySwapchainKHR([[maybe_unused]] VkDevice device, VkSwapchainKHR swapchain,
710 [[maybe_unused]] const VkAllocationCallbacks* pAllocator) {
711 if (swapchain != VK_NULL_HANDLE) {
712 uint64_t fake_swapchain_handle = from_nondispatch_handle(swapchain);
713 auto found_iter = icd.swapchain_handles.erase(
714 std::remove(icd.swapchain_handles.begin(), icd.swapchain_handles.end(), fake_swapchain_handle),
715 icd.swapchain_handles.end());
716 if (!icd.swapchain_handles.empty() && found_iter == icd.swapchain_handles.end()) {
717 assert(false && "Swapchain not found during destroy!");
718 }
719 }
720 }
721 // VK_KHR_swapchain with 1.1
722 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDeviceGroupSurfacePresentModesKHR([[maybe_unused]] VkDevice device,
723 [[maybe_unused]] VkSurfaceKHR surface,
724 VkDeviceGroupPresentModeFlagsKHR* pModes) {
725 if (!pModes) return VK_ERROR_INITIALIZATION_FAILED;
726 *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR;
727 return VK_SUCCESS;
728 }
729
730 // VK_KHR_surface
731 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
732 VkSurfaceKHR surface, VkBool32* pSupported) {
733 if (surface != VK_NULL_HANDLE) {
734 uint64_t fake_surf_handle = (uint64_t)(surface);
735 auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
736 if (found_iter == icd.surface_handles.end()) {
737 assert(false && "Surface not found during GetPhysicalDeviceSurfaceSupportKHR query!");
738 return VK_ERROR_UNKNOWN;
739 }
740 }
741 if (nullptr != pSupported) {
742 *pSupported = icd.GetPhysDevice(physicalDevice).queue_family_properties.at(queueFamilyIndex).support_present;
743 }
744 return VK_SUCCESS;
745 }
746 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
747 VkSurfaceCapabilitiesKHR* pSurfaceCapabilities) {
748 if (surface != VK_NULL_HANDLE) {
749 uint64_t fake_surf_handle = (uint64_t)(surface);
750 auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
751 if (found_iter == icd.surface_handles.end()) {
752 assert(false && "Surface not found during GetPhysicalDeviceSurfaceCapabilitiesKHR query!");
753 return VK_ERROR_UNKNOWN;
754 }
755 }
756 if (nullptr != pSurfaceCapabilities) {
757 *pSurfaceCapabilities = icd.GetPhysDevice(physicalDevice).surface_capabilities;
758 }
759 return VK_SUCCESS;
760 }
761 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
762 uint32_t* pSurfaceFormatCount,
763 VkSurfaceFormatKHR* pSurfaceFormats) {
764 if (surface != VK_NULL_HANDLE) {
765 uint64_t fake_surf_handle = (uint64_t)(surface);
766 auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
767 if (found_iter == icd.surface_handles.end()) {
768 assert(false && "Surface not found during GetPhysicalDeviceSurfaceFormatsKHR query!");
769 return VK_ERROR_UNKNOWN;
770 }
771 }
772 FillCountPtr(icd.GetPhysDevice(physicalDevice).surface_formats, pSurfaceFormatCount, pSurfaceFormats);
773 return VK_SUCCESS;
774 }
775 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
776 uint32_t* pPresentModeCount,
777 VkPresentModeKHR* pPresentModes) {
778 if (surface != VK_NULL_HANDLE) {
779 uint64_t fake_surf_handle = (uint64_t)(surface);
780 auto found_iter = std::find(icd.surface_handles.begin(), icd.surface_handles.end(), fake_surf_handle);
781 if (found_iter == icd.surface_handles.end()) {
782 assert(false && "Surface not found during GetPhysicalDeviceSurfacePresentModesKHR query!");
783 return VK_ERROR_UNKNOWN;
784 }
785 }
786 FillCountPtr(icd.GetPhysDevice(physicalDevice).surface_present_modes, pPresentModeCount, pPresentModes);
787 return VK_SUCCESS;
788 }
789
790 // VK_KHR_display
791 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
792 uint32_t* pPropertyCount,
793 VkDisplayPropertiesKHR* pProperties) {
794 FillCountPtr(icd.GetPhysDevice(physicalDevice).display_properties, pPropertyCount, pProperties);
795 return VK_SUCCESS;
796 }
797 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,
798 uint32_t* pPropertyCount,
799 VkDisplayPlanePropertiesKHR* pProperties) {
800 FillCountPtr(icd.GetPhysDevice(physicalDevice).display_plane_properties, pPropertyCount, pProperties);
801 return VK_SUCCESS;
802 }
803 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice,
804 [[maybe_unused]] uint32_t planeIndex,
805 uint32_t* pDisplayCount, VkDisplayKHR* pDisplays) {
806 FillCountPtr(icd.GetPhysDevice(physicalDevice).displays, pDisplayCount, pDisplays);
807 return VK_SUCCESS;
808 }
809 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice,
810 [[maybe_unused]] VkDisplayKHR display, uint32_t* pPropertyCount,
811 VkDisplayModePropertiesKHR* pProperties) {
812 FillCountPtr(icd.GetPhysDevice(physicalDevice).display_mode_properties, pPropertyCount, pProperties);
813 return VK_SUCCESS;
814 }
815 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, [[maybe_unused]] VkDisplayKHR display,
816 [[maybe_unused]] const VkDisplayModeCreateInfoKHR* pCreateInfo,
817 [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
818 VkDisplayModeKHR* pMode) {
819 if (nullptr != pMode) {
820 *pMode = icd.GetPhysDevice(physicalDevice).display_mode;
821 }
822 return VK_SUCCESS;
823 }
824 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice,
825 [[maybe_unused]] VkDisplayModeKHR mode,
826 [[maybe_unused]] uint32_t planeIndex,
827 VkDisplayPlaneCapabilitiesKHR* pCapabilities) {
828 if (nullptr != pCapabilities) {
829 *pCapabilities = icd.GetPhysDevice(physicalDevice).display_plane_capabilities;
830 }
831 return VK_SUCCESS;
832 }
833 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDisplayPlaneSurfaceKHR(
834 [[maybe_unused]] VkInstance instance, [[maybe_unused]] const VkDisplaySurfaceCreateInfoKHR* pCreateInfo,
835 [[maybe_unused]] const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) {
836 common_nondispatch_handle_creation(icd.surface_handles, pSurface);
837 return VK_SUCCESS;
838 }
839
840 // VK_KHR_get_surface_capabilities2
841 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,
842 const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
843 VkSurfaceCapabilities2KHR* pSurfaceCapabilities) {
844 if (nullptr != pSurfaceInfo && nullptr != pSurfaceCapabilities) {
845 return test_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, pSurfaceInfo->surface,
846 &pSurfaceCapabilities->surfaceCapabilities);
847 }
848 return VK_SUCCESS;
849 }
850 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
851 const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
852 uint32_t* pSurfaceFormatCount,
853 VkSurfaceFormat2KHR* pSurfaceFormats) {
854 if (nullptr != pSurfaceFormatCount) {
855 test_vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, pSurfaceInfo->surface, pSurfaceFormatCount, nullptr);
856 if (nullptr != pSurfaceFormats) {
857 auto& phys_dev = icd.GetPhysDevice(physicalDevice);
858 // Since the structures are different, we have to copy each item over seperately. Since we have multiple, we
859 // have to manually copy the data here instead of calling the next function
860 for (uint32_t cnt = 0; cnt < *pSurfaceFormatCount; ++cnt) {
861 memcpy(&pSurfaceFormats[cnt].surfaceFormat, &phys_dev.surface_formats[cnt], sizeof(VkSurfaceFormatKHR));
862 }
863 }
864 }
865 return VK_SUCCESS;
866 }
867 // VK_KHR_display_swapchain
868 VkResult test_vkCreateSharedSwapchainsKHR([[maybe_unused]] VkDevice device, uint32_t swapchainCount,
869 [[maybe_unused]] const VkSwapchainCreateInfoKHR* pCreateInfos,
870 [[maybe_unused]] const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains) {
871 for (uint32_t i = 0; i < swapchainCount; i++) {
872 common_nondispatch_handle_creation(icd.swapchain_handles, &pSwapchains[i]);
873 }
874 return VK_SUCCESS;
875 }
876
877 //// misc
878 VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateCommandPool([[maybe_unused]] VkDevice device,
879 [[maybe_unused]] const VkCommandPoolCreateInfo* pCreateInfo,
880 [[maybe_unused]] const VkAllocationCallbacks* pAllocator,
881 VkCommandPool* pCommandPool) {
882 if (pCommandPool != nullptr) {
883 pCommandPool = reinterpret_cast<VkCommandPool*>(0xdeadbeefdeadbeef);
884 }
885 return VK_SUCCESS;
886 }
887
888 VKAPI_ATTR void VKAPI_CALL test_vkDestroyCommandPool(VkDevice, VkCommandPool, const VkAllocationCallbacks*) {
889 // do nothing, leak memory for now
890 }
891 VKAPI_ATTR VkResult VKAPI_CALL test_vkAllocateCommandBuffers([[maybe_unused]] VkDevice device,
892 const VkCommandBufferAllocateInfo* pAllocateInfo,
893 VkCommandBuffer* pCommandBuffers) {
894 if (pAllocateInfo != nullptr && pCommandBuffers != nullptr) {
895 for (size_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
896 icd.allocated_command_buffers.push_back({});
897 pCommandBuffers[i] = icd.allocated_command_buffers.back().handle;
898 }
899 }
900 return VK_SUCCESS;
901 }
902
903 VKAPI_ATTR void VKAPI_CALL test_vkGetDeviceQueue([[maybe_unused]] VkDevice device, [[maybe_unused]] uint32_t queueFamilyIndex,
904 uint32_t queueIndex, VkQueue* pQueue) {
905 auto fd = icd.lookup_device(device);
906 if (fd.found) {
907 *pQueue = icd.physical_devices.at(fd.phys_dev_index).queue_handles[queueIndex].handle;
908 }
909 }
910
911 // VK_EXT_acquire_drm_display
912 VKAPI_ATTR VkResult VKAPI_CALL test_vkAcquireDrmDisplayEXT(VkPhysicalDevice, int32_t, VkDisplayKHR) { return VK_SUCCESS; }
913
914 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDrmDisplayEXT(VkPhysicalDevice physicalDevice, [[maybe_unused]] int32_t drmFd,
915 [[maybe_unused]] uint32_t connectorId, VkDisplayKHR* display) {
916 if (nullptr != display && icd.GetPhysDevice(physicalDevice).displays.size() > 0) {
917 *display = icd.GetPhysDevice(physicalDevice).displays[0];
918 }
919 return VK_SUCCESS;
920 }
921
922 //// stubs
923 // 1.0
924 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures) {
925 if (nullptr != pFeatures) {
926 memcpy(pFeatures, &icd.GetPhysDevice(physicalDevice).features, sizeof(VkPhysicalDeviceFeatures));
927 }
928 }
929 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
930 VkPhysicalDeviceProperties* pProperties) {
931 if (nullptr != pProperties) {
932 auto& phys_dev = icd.GetPhysDevice(physicalDevice);
933 memcpy(pProperties, &phys_dev.properties, sizeof(VkPhysicalDeviceProperties));
934 size_t max_len = (phys_dev.deviceName.length() > VK_MAX_PHYSICAL_DEVICE_NAME_SIZE) ? VK_MAX_PHYSICAL_DEVICE_NAME_SIZE
935 : phys_dev.deviceName.length();
936 std::copy(phys_dev.deviceName.c_str(), phys_dev.deviceName.c_str() + max_len, pProperties->deviceName);
937 pProperties->deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE - 1] = '\0';
938 }
939 }
940 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,
941 VkPhysicalDeviceMemoryProperties* pMemoryProperties) {
942 if (nullptr != pMemoryProperties) {
943 memcpy(pMemoryProperties, &icd.GetPhysDevice(physicalDevice).memory_properties, sizeof(VkPhysicalDeviceMemoryProperties));
944 }
945 }
946 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceSparseImageFormatProperties(
947 VkPhysicalDevice physicalDevice, [[maybe_unused]] VkFormat format, [[maybe_unused]] VkImageType type,
948 [[maybe_unused]] VkSampleCountFlagBits samples, [[maybe_unused]] VkImageUsageFlags usage, [[maybe_unused]] VkImageTiling tiling,
949 uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties) {
950 FillCountPtr(icd.GetPhysDevice(physicalDevice).sparse_image_format_properties, pPropertyCount, pProperties);
951 }
952 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
953 VkFormatProperties* pFormatProperties) {
954 if (nullptr != pFormatProperties) {
955 memcpy(pFormatProperties, &icd.GetPhysDevice(physicalDevice).format_properties[static_cast<uint32_t>(format)],
956 sizeof(VkFormatProperties));
957 }
958 }
959 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceImageFormatProperties(
960 VkPhysicalDevice physicalDevice, [[maybe_unused]] VkFormat format, [[maybe_unused]] VkImageType type,
961 [[maybe_unused]] VkImageTiling tiling, [[maybe_unused]] VkImageUsageFlags usage, [[maybe_unused]] VkImageCreateFlags flags,
962 VkImageFormatProperties* pImageFormatProperties) {
963 if (nullptr != pImageFormatProperties) {
964 memcpy(pImageFormatProperties, &icd.GetPhysDevice(physicalDevice).image_format_properties, sizeof(VkImageFormatProperties));
965 }
966 return VK_SUCCESS;
967 }
968
969 // 1.1
970 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
971 VkPhysicalDeviceFeatures2* pFeatures) {
972 if (nullptr != pFeatures) {
973 test_vkGetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
974 }
975 }
976 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
977 VkPhysicalDeviceProperties2* pProperties) {
978 if (nullptr != pProperties) {
979 auto& phys_dev = icd.GetPhysDevice(physicalDevice);
980 test_vkGetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
981 VkBaseInStructure* pNext = reinterpret_cast<VkBaseInStructure*>(pProperties->pNext);
982 while (pNext) {
983 if (pNext->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT) {
984 auto* bus_info = reinterpret_cast<VkPhysicalDevicePCIBusInfoPropertiesEXT*>(pNext);
985 bus_info->pciBus = phys_dev.pci_bus;
986 }
987 if (pNext->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LAYERED_DRIVER_PROPERTIES_MSFT) {
988 auto* layered_driver_props = reinterpret_cast<VkPhysicalDeviceLayeredDriverPropertiesMSFT*>(pNext);
989 layered_driver_props->underlyingAPI = phys_dev.layered_driver_underlying_api;
990 }
991 pNext = reinterpret_cast<VkBaseInStructure*>(const_cast<VkBaseInStructure*>(pNext->pNext));
992 }
993 }
994 }
995 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice,
996 VkPhysicalDeviceMemoryProperties2* pMemoryProperties) {
997 if (nullptr != pMemoryProperties) {
998 test_vkGetPhysicalDeviceMemoryProperties(physicalDevice, &pMemoryProperties->memoryProperties);
999 }
1000 }
1001 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
1002 uint32_t* pQueueFamilyPropertyCount,
1003 VkQueueFamilyProperties2* pQueueFamilyProperties) {
1004 if (nullptr != pQueueFamilyPropertyCount) {
1005 test_vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, nullptr);
1006 if (nullptr != pQueueFamilyProperties) {
1007 auto& phys_dev = icd.GetPhysDevice(physicalDevice);
1008 // Since the structures are different, we have to copy each item over seperately. Since we have multiple, we
1009 // have to manually copy the data here instead of calling the next function
1010 for (uint32_t queue = 0; queue < *pQueueFamilyPropertyCount; ++queue) {
1011 memcpy(&pQueueFamilyProperties[queue].queueFamilyProperties, &phys_dev.queue_family_properties[queue].properties,
1012 sizeof(VkQueueFamilyProperties));
1013 }
1014 }
1015 }
1016 }
1017 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceSparseImageFormatProperties2(
1018 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount,
1019 VkSparseImageFormatProperties2* pProperties) {
1020 if (nullptr != pPropertyCount) {
1021 test_vkGetPhysicalDeviceSparseImageFormatProperties(physicalDevice, pFormatInfo->format, pFormatInfo->type,
1022 pFormatInfo->samples, pFormatInfo->usage, pFormatInfo->tiling,
1023 pPropertyCount, nullptr);
1024 if (nullptr != pProperties) {
1025 auto& phys_dev = icd.GetPhysDevice(physicalDevice);
1026 // Since the structures are different, we have to copy each item over seperately. Since we have multiple, we
1027 // have to manually copy the data here instead of calling the next function
1028 for (uint32_t cnt = 0; cnt < *pPropertyCount; ++cnt) {
1029 memcpy(&pProperties[cnt].properties, &phys_dev.sparse_image_format_properties[cnt],
1030 sizeof(VkSparseImageFormatProperties));
1031 }
1032 }
1033 }
1034 }
1035 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
1036 VkFormatProperties2* pFormatProperties) {
1037 if (nullptr != pFormatProperties) {
1038 test_vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &pFormatProperties->formatProperties);
1039 }
1040 }
1041 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceImageFormatProperties2(
1042 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
1043 VkImageFormatProperties2* pImageFormatProperties) {
1044 if (nullptr != pImageFormatInfo) {
1045 VkImageFormatProperties* ptr = nullptr;
1046 if (pImageFormatProperties) {
1047 ptr = &pImageFormatProperties->imageFormatProperties;
1048 }
1049 test_vkGetPhysicalDeviceImageFormatProperties(physicalDevice, pImageFormatInfo->format, pImageFormatInfo->type,
1050 pImageFormatInfo->tiling, pImageFormatInfo->usage, pImageFormatInfo->flags,
1051 ptr);
1052 }
1053 return VK_SUCCESS;
1054 }
1055 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceExternalBufferProperties(
1056 VkPhysicalDevice physicalDevice, [[maybe_unused]] const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
1057 VkExternalBufferProperties* pExternalBufferProperties) {
1058 if (nullptr != pExternalBufferProperties) {
1059 auto& phys_dev = icd.GetPhysDevice(physicalDevice);
1060 memcpy(&pExternalBufferProperties->externalMemoryProperties, &phys_dev.external_memory_properties,
1061 sizeof(VkExternalMemoryProperties));
1062 }
1063 }
1064 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceExternalSemaphoreProperties(
1065 VkPhysicalDevice physicalDevice, [[maybe_unused]] const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
1066 VkExternalSemaphoreProperties* pExternalSemaphoreProperties) {
1067 if (nullptr != pExternalSemaphoreProperties) {
1068 auto& phys_dev = icd.GetPhysDevice(physicalDevice);
1069 memcpy(pExternalSemaphoreProperties, &phys_dev.external_semaphore_properties, sizeof(VkExternalSemaphoreProperties));
1070 }
1071 }
1072 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceExternalFenceProperties(
1073 VkPhysicalDevice physicalDevice, [[maybe_unused]] const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo,
1074 VkExternalFenceProperties* pExternalFenceProperties) {
1075 if (nullptr != pExternalFenceProperties) {
1076 auto& phys_dev = icd.GetPhysDevice(physicalDevice);
1077 memcpy(pExternalFenceProperties, &phys_dev.external_fence_properties, sizeof(VkExternalFenceProperties));
1078 }
1079 }
1080 // Entry-points associated with the VK_KHR_performance_query extension
1081 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
1082 VkPhysicalDevice, uint32_t, uint32_t*, VkPerformanceCounterKHR*, VkPerformanceCounterDescriptionKHR*) {
1083 return VK_SUCCESS;
1084 }
1085 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(VkPhysicalDevice,
1086 const VkQueryPoolPerformanceCreateInfoKHR*,
1087 uint32_t*) {}
1088 VKAPI_ATTR VkResult VKAPI_CALL test_vkAcquireProfilingLockKHR(VkDevice, const VkAcquireProfilingLockInfoKHR*) { return VK_SUCCESS; }
1089 VKAPI_ATTR void VKAPI_CALL test_vkReleaseProfilingLockKHR(VkDevice) {}
1090 // Entry-points associated with the VK_EXT_sample_locations extension
1091 VKAPI_ATTR void VKAPI_CALL test_vkCmdSetSampleLocationsEXT(VkCommandBuffer, const VkSampleLocationsInfoEXT*) {}
1092 VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceMultisamplePropertiesEXT(VkPhysicalDevice, VkSampleCountFlagBits,
1093 VkMultisamplePropertiesEXT*) {}
1094 // Entry-points associated with the VK_EXT_calibrated_timestamps extension
1095 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT(VkPhysicalDevice, uint32_t*, VkTimeDomainEXT*) {
1096 return VK_SUCCESS;
1097 }
1098 VKAPI_ATTR VkResult VKAPI_CALL test_vkGetCalibratedTimestampsEXT(VkDevice, uint32_t, const VkCalibratedTimestampInfoEXT*, uint64_t*,
1099 uint64_t*) {
1100 return VK_SUCCESS;
1101 }
1102
1103 #if defined(WIN32)
1104 VKAPI_ATTR VkResult VKAPI_CALL test_vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID,
1105 uint32_t* pPhysicalDeviceCount,
1106 VkPhysicalDevice* pPhysicalDevices) {
1107 if (adapterLUID.LowPart != icd.adapterLUID.LowPart || adapterLUID.HighPart != icd.adapterLUID.HighPart) {
1108 *pPhysicalDeviceCount = 0;
1109 return VK_ERROR_INCOMPATIBLE_DRIVER;
1110 }
1111 icd.called_enumerate_adapter_physical_devices = true;
1112 VkResult res = test_vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
1113 // For this testing, flip order intentionally
1114 if (nullptr != pPhysicalDevices) {
1115 std::reverse(pPhysicalDevices, pPhysicalDevices + *pPhysicalDeviceCount);
1116 }
1117 return res;
1118 }
1119 #endif // defined(WIN32)
1120
1121 VkResult test_vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) {
1122 if (icd.called_vk_icd_gipa == CalledICDGIPA::not_called &&
1123 icd.called_negotiate_interface == CalledNegotiateInterface::not_called)
1124 icd.called_negotiate_interface = CalledNegotiateInterface::vk_icd_negotiate;
1125 else if (icd.called_vk_icd_gipa != CalledICDGIPA::not_called)
1126 icd.called_negotiate_interface = CalledNegotiateInterface::vk_icd_gipa_first;
1127
1128 // loader puts the minimum it supports in pSupportedVersion, if that is lower than our minimum
1129 // If the ICD doesn't supports the interface version provided by the loader, report VK_ERROR_INCOMPATIBLE_DRIVER
1130 if (icd.min_icd_interface_version > *pSupportedVersion) {
1131 icd.interface_version_check = InterfaceVersionCheck::loader_version_too_old;
1132 *pSupportedVersion = icd.min_icd_interface_version;
1133 return VK_ERROR_INCOMPATIBLE_DRIVER;
1134 }
1135
1136 // the loader-provided interface version is newer than that supported by the ICD
1137 if (icd.max_icd_interface_version < *pSupportedVersion) {
1138 icd.interface_version_check = InterfaceVersionCheck::loader_version_too_new;
1139 *pSupportedVersion = icd.max_icd_interface_version;
1140 }
1141 // ICD interface version is greater than the loader's, return the loader's version
1142 else if (icd.max_icd_interface_version > *pSupportedVersion) {
1143 icd.interface_version_check = InterfaceVersionCheck::icd_version_too_new;
1144 // don't change *pSupportedVersion
1145 } else {
1146 icd.interface_version_check = InterfaceVersionCheck::version_is_supported;
1147 *pSupportedVersion = icd.max_icd_interface_version;
1148 }
1149
1150 return VK_SUCCESS;
1151 }
1152
1153 // Forward declarations for trampolines
1154 extern "C" {
1155 #if TEST_ICD_EXPOSE_VERSION_7
1156 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion);
1157 #if TEST_ICD_EXPORT_ICD_GPDPA
1158 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName);
1159 #endif
1160 #if defined(WIN32) && TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES
1161 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID,
1162 uint32_t* pPhysicalDeviceCount,
1163 VkPhysicalDevice* pPhysicalDevices);
1164 #endif
1165 #endif
1166 }
1167
1168 //// trampolines
1169
1170 PFN_vkVoidFunction get_instance_func_ver_1_1([[maybe_unused]] VkInstance instance, const char* pName) {
1171 if (icd.icd_api_version >= VK_API_VERSION_1_1) {
1172 if (string_eq(pName, "test_vkEnumerateInstanceVersion")) {
1173 return icd.can_query_vkEnumerateInstanceVersion ? to_vkVoidFunction(test_vkEnumerateInstanceVersion) : nullptr;
1174 }
1175 if (string_eq(pName, "vkEnumeratePhysicalDeviceGroups")) {
1176 return to_vkVoidFunction(test_vkEnumeratePhysicalDeviceGroups);
1177 }
1178 }
1179 return nullptr;
1180 }
1181
1182 PFN_vkVoidFunction get_physical_device_func_wsi([[maybe_unused]] VkInstance instance, const char* pName) {
1183 if (IsInstanceExtensionEnabled("VK_KHR_surface")) {
1184 if (string_eq(pName, "vkGetPhysicalDeviceSurfaceSupportKHR"))
1185 return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfaceSupportKHR);
1186 if (string_eq(pName, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"))
1187 return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
1188 if (string_eq(pName, "vkGetPhysicalDeviceSurfaceFormatsKHR"))
1189 return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfaceFormatsKHR);
1190 if (string_eq(pName, "vkGetPhysicalDeviceSurfacePresentModesKHR"))
1191 return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfacePresentModesKHR);
1192 }
1193 if (IsInstanceExtensionEnabled("VK_KHR_get_surface_capabilities2")) {
1194 if (string_eq(pName, "vkGetPhysicalDeviceSurfaceCapabilities2KHR"))
1195 return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfaceCapabilities2KHR);
1196 if (string_eq(pName, "vkGetPhysicalDeviceSurfaceFormats2KHR"))
1197 return to_vkVoidFunction(test_vkGetPhysicalDeviceSurfaceFormats2KHR);
1198 }
1199 if (IsInstanceExtensionEnabled("VK_KHR_display")) {
1200 if (string_eq(pName, "vkGetPhysicalDeviceDisplayPropertiesKHR"))
1201 return to_vkVoidFunction(test_vkGetPhysicalDeviceDisplayPropertiesKHR);
1202 if (string_eq(pName, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR"))
1203 return to_vkVoidFunction(test_vkGetPhysicalDeviceDisplayPlanePropertiesKHR);
1204 if (string_eq(pName, "vkGetDisplayPlaneSupportedDisplaysKHR"))
1205 return to_vkVoidFunction(test_vkGetDisplayPlaneSupportedDisplaysKHR);
1206 if (string_eq(pName, "vkGetDisplayModePropertiesKHR")) return to_vkVoidFunction(test_vkGetDisplayModePropertiesKHR);
1207 if (string_eq(pName, "vkCreateDisplayModeKHR")) return to_vkVoidFunction(test_vkCreateDisplayModeKHR);
1208 if (string_eq(pName, "vkGetDisplayPlaneCapabilitiesKHR")) return to_vkVoidFunction(test_vkGetDisplayPlaneCapabilitiesKHR);
1209 if (string_eq(pName, "vkCreateDisplayPlaneSurfaceKHR")) return to_vkVoidFunction(test_vkCreateDisplayPlaneSurfaceKHR);
1210 }
1211 if (IsInstanceExtensionEnabled("VK_EXT_acquire_drm_display")) {
1212 if (string_eq(pName, "vkAcquireDrmDisplayEXT")) return to_vkVoidFunction(test_vkAcquireDrmDisplayEXT);
1213 if (string_eq(pName, "vkGetDrmDisplayEXT")) return to_vkVoidFunction(test_vkGetDrmDisplayEXT);
1214 }
1215 return nullptr;
1216 }
1217
1218 PFN_vkVoidFunction get_instance_func_wsi(VkInstance instance, const char* pName) {
1219 if (icd.min_icd_interface_version >= 3 && icd.enable_icd_wsi == true) {
1220 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
1221 if (string_eq(pName, "vkCreateAndroidSurfaceKHR")) {
1222 icd.is_using_icd_wsi = true;
1223 return to_vkVoidFunction(test_vkCreateAndroidSurfaceKHR);
1224 }
1225 #endif
1226 #if defined(VK_USE_PLATFORM_METAL_EXT)
1227 if (string_eq(pName, "vkCreateMetalSurfaceEXT")) {
1228 return to_vkVoidFunction(test_vkCreateMetalSurfaceEXT);
1229 }
1230 #endif
1231 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
1232 if (string_eq(pName, "vkCreateWaylandSurfaceKHR")) {
1233 return to_vkVoidFunction(test_vkCreateWaylandSurfaceKHR);
1234 }
1235 if (string_eq(pName, "vkGetPhysicalDeviceWaylandPresentationSupportKHR")) {
1236 return to_vkVoidFunction(test_vkGetPhysicalDeviceWaylandPresentationSupportKHR);
1237 }
1238 #endif
1239 #if defined(VK_USE_PLATFORM_XCB_KHR)
1240 if (string_eq(pName, "vkCreateXcbSurfaceKHR")) {
1241 return to_vkVoidFunction(test_vkCreateXcbSurfaceKHR);
1242 }
1243 if (string_eq(pName, "vkGetPhysicalDeviceXcbPresentationSupportKHR")) {
1244 return to_vkVoidFunction(test_vkGetPhysicalDeviceXcbPresentationSupportKHR);
1245 }
1246 #endif
1247 #if defined(VK_USE_PLATFORM_XLIB_KHR)
1248 if (string_eq(pName, "vkCreateXlibSurfaceKHR")) {
1249 return to_vkVoidFunction(test_vkCreateXlibSurfaceKHR);
1250 }
1251 if (string_eq(pName, "vkGetPhysicalDeviceXlibPresentationSupportKHR")) {
1252 return to_vkVoidFunction(test_vkGetPhysicalDeviceXlibPresentationSupportKHR);
1253 }
1254 #endif
1255 #if defined(VK_USE_PLATFORM_WIN32_KHR)
1256 if (string_eq(pName, "vkCreateWin32SurfaceKHR")) {
1257 return to_vkVoidFunction(test_vkCreateWin32SurfaceKHR);
1258 }
1259 if (string_eq(pName, "vkGetPhysicalDeviceWin32PresentationSupportKHR")) {
1260 return to_vkVoidFunction(test_vkGetPhysicalDeviceWin32PresentationSupportKHR);
1261 }
1262 #endif
1263 #if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
1264 if (string_eq(pName, "vkCreateDirectFBSurfaceEXT")) {
1265 return to_vkVoidFunction(test_vkCreateDirectFBSurfaceEXT);
1266 }
1267 if (string_eq(pName, "vkGetPhysicalDeviceDirectFBPresentationSupportEXT")) {
1268 return to_vkVoidFunction(test_vkGetPhysicalDeviceDirectFBPresentationSupportEXT);
1269 }
1270 #endif // VK_USE_PLATFORM_DIRECTFB_EXT
1271
1272 #if defined(VK_USE_PLATFORM_MACOS_MVK)
1273 if (string_eq(pName, "vkCreateMacOSSurfaceMVK")) {
1274 return to_vkVoidFunction(test_vkCreateMacOSSurfaceMVK);
1275 }
1276 #endif // VK_USE_PLATFORM_MACOS_MVK
1277
1278 #if defined(VK_USE_PLATFORM_IOS_MVK)
1279 if (string_eq(pName, "vkCreateIOSSurfaceMVK")) {
1280 return to_vkVoidFunction(test_vkCreateIOSSurfaceMVK);
1281 }
1282 #endif // VK_USE_PLATFORM_IOS_MVK
1283
1284 #if defined(VK_USE_PLATFORM_GGP)
1285 if (string_eq(pName, "vkCreateStreamDescriptorSurfaceGGP")) {
1286 return to_vkVoidFunction(test_vkCreateStreamDescriptorSurfaceGGP);
1287 }
1288 #endif // VK_USE_PLATFORM_GGP
1289
1290 #if defined(VK_USE_PLATFORM_SCREEN_QNX)
1291 if (string_eq(pName, "vkCreateScreenSurfaceQNX")) {
1292 return to_vkVoidFunction(test_vkCreateScreenSurfaceQNX);
1293 }
1294 if (string_eq(pName, "vkGetPhysicalDeviceScreenPresentationSupportQNX")) {
1295 return to_vkVoidFunction(test_vkGetPhysicalDeviceScreenPresentationSupportQNX);
1296 }
1297 #endif // VK_USE_PLATFORM_SCREEN_QNX
1298
1299 if (string_eq(pName, "vkCreateHeadlessSurfaceEXT")) {
1300 return to_vkVoidFunction(test_vkCreateHeadlessSurfaceEXT);
1301 }
1302
1303 if (string_eq(pName, "vkDestroySurfaceKHR")) {
1304 icd.is_using_icd_wsi = true;
1305 return to_vkVoidFunction(test_vkDestroySurfaceKHR);
1306 }
1307 }
1308 if (IsInstanceExtensionEnabled(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
1309 if (string_eq(pName, "vkCreateDebugUtilsMessengerEXT")) {
1310 return to_vkVoidFunction(test_vkCreateDebugUtilsMessengerEXT);
1311 }
1312 if (string_eq(pName, "vkDestroyDebugUtilsMessengerEXT")) {
1313 return to_vkVoidFunction(test_vkDestroyDebugUtilsMessengerEXT);
1314 }
1315 }
1316
1317 PFN_vkVoidFunction ret_phys_dev_wsi = get_physical_device_func_wsi(instance, pName);
1318 if (ret_phys_dev_wsi != nullptr) return ret_phys_dev_wsi;
1319 return nullptr;
1320 }
1321 PFN_vkVoidFunction get_physical_device_func([[maybe_unused]] VkInstance instance, const char* pName) {
1322 if (string_eq(pName, "vkEnumerateDeviceLayerProperties")) return to_vkVoidFunction(test_vkEnumerateDeviceLayerProperties);
1323 if (string_eq(pName, "vkEnumerateDeviceExtensionProperties"))
1324 return to_vkVoidFunction(test_vkEnumerateDeviceExtensionProperties);
1325 if (string_eq(pName, "vkGetPhysicalDeviceQueueFamilyProperties"))
1326 return to_vkVoidFunction(test_vkGetPhysicalDeviceQueueFamilyProperties);
1327 if (string_eq(pName, "vkCreateDevice")) return to_vkVoidFunction(test_vkCreateDevice);
1328
1329 if (string_eq(pName, "vkGetPhysicalDeviceFeatures"))
1330 return icd.can_query_GetPhysicalDeviceFuncs ? to_vkVoidFunction(test_vkGetPhysicalDeviceFeatures) : nullptr;
1331 if (string_eq(pName, "vkGetPhysicalDeviceProperties"))
1332 return icd.can_query_GetPhysicalDeviceFuncs ? to_vkVoidFunction(test_vkGetPhysicalDeviceProperties) : nullptr;
1333 if (string_eq(pName, "vkGetPhysicalDeviceMemoryProperties"))
1334 return icd.can_query_GetPhysicalDeviceFuncs ? to_vkVoidFunction(test_vkGetPhysicalDeviceMemoryProperties) : nullptr;
1335 if (string_eq(pName, "vkGetPhysicalDeviceSparseImageFormatProperties"))
1336 return icd.can_query_GetPhysicalDeviceFuncs ? to_vkVoidFunction(test_vkGetPhysicalDeviceSparseImageFormatProperties)
1337 : nullptr;
1338 if (string_eq(pName, "vkGetPhysicalDeviceFormatProperties"))
1339 return icd.can_query_GetPhysicalDeviceFuncs ? to_vkVoidFunction(test_vkGetPhysicalDeviceFormatProperties) : nullptr;
1340 if (string_eq(pName, "vkGetPhysicalDeviceImageFormatProperties"))
1341 return icd.can_query_GetPhysicalDeviceFuncs ? to_vkVoidFunction(test_vkGetPhysicalDeviceImageFormatProperties) : nullptr;
1342
1343 if (IsInstanceExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
1344 if (string_eq(pName, "vkGetPhysicalDeviceFeatures2KHR")) return to_vkVoidFunction(test_vkGetPhysicalDeviceFeatures2);
1345 if (string_eq(pName, "vkGetPhysicalDeviceProperties2KHR")) return to_vkVoidFunction(test_vkGetPhysicalDeviceProperties2);
1346 if (string_eq(pName, "vkGetPhysicalDeviceFormatProperties2KHR"))
1347 return to_vkVoidFunction(test_vkGetPhysicalDeviceFormatProperties2);
1348 if (string_eq(pName, "vkGetPhysicalDeviceMemoryProperties2KHR"))
1349 return to_vkVoidFunction(test_vkGetPhysicalDeviceMemoryProperties2);
1350
1351 if (string_eq(pName, "vkGetPhysicalDeviceQueueFamilyProperties2KHR"))
1352 return to_vkVoidFunction(test_vkGetPhysicalDeviceQueueFamilyProperties2);
1353
1354 if (string_eq(pName, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR"))
1355 return to_vkVoidFunction(test_vkGetPhysicalDeviceSparseImageFormatProperties2);
1356
1357 if (string_eq(pName, "vkGetPhysicalDeviceImageFormatProperties2KHR")) {
1358 return to_vkVoidFunction(test_vkGetPhysicalDeviceImageFormatProperties2);
1359 }
1360 }
1361 if (IsInstanceExtensionEnabled(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) {
1362 if (string_eq(pName, "vkGetPhysicalDeviceExternalBufferPropertiesKHR"))
1363 return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalBufferProperties);
1364 }
1365 if (IsInstanceExtensionEnabled(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) {
1366 if (string_eq(pName, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR"))
1367 return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalSemaphoreProperties);
1368 }
1369 if (IsInstanceExtensionEnabled(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME)) {
1370 if (string_eq(pName, "vkGetPhysicalDeviceExternalFencePropertiesKHR"))
1371 return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalFenceProperties);
1372 }
1373
1374 // The following physical device extensions only need 1 device to support them for the ICD to export
1375 // them
1376 if (IsPhysicalDeviceExtensionAvailable(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME)) {
1377 if (string_eq(pName, "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR"))
1378 return to_vkVoidFunction(test_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR);
1379 if (string_eq(pName, "vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR"))
1380 return to_vkVoidFunction(test_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR);
1381 if (string_eq(pName, "vkAcquireProfilingLockKHR")) return to_vkVoidFunction(test_vkAcquireProfilingLockKHR);
1382 if (string_eq(pName, "vkReleaseProfilingLockKHR")) return to_vkVoidFunction(test_vkReleaseProfilingLockKHR);
1383 }
1384 if (IsPhysicalDeviceExtensionAvailable(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME)) {
1385 if (string_eq(pName, "vkCmdSetSampleLocationsEXT")) return to_vkVoidFunction(test_vkCmdSetSampleLocationsEXT);
1386 if (string_eq(pName, "vkGetPhysicalDeviceMultisamplePropertiesEXT"))
1387 return to_vkVoidFunction(test_vkGetPhysicalDeviceMultisamplePropertiesEXT);
1388 }
1389 if (IsPhysicalDeviceExtensionAvailable(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME)) {
1390 if (string_eq(pName, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT"))
1391 return to_vkVoidFunction(test_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT);
1392 if (string_eq(pName, "vkGetCalibratedTimestampsEXT")) return to_vkVoidFunction(test_vkGetCalibratedTimestampsEXT);
1393 }
1394
1395 if (icd.icd_api_version >= VK_MAKE_API_VERSION(0, 1, 1, 0)) {
1396 if (string_eq(pName, "vkGetPhysicalDeviceFeatures2")) return to_vkVoidFunction(test_vkGetPhysicalDeviceFeatures2);
1397 if (string_eq(pName, "vkGetPhysicalDeviceProperties2")) return to_vkVoidFunction(test_vkGetPhysicalDeviceProperties2);
1398 if (string_eq(pName, "vkGetPhysicalDeviceFormatProperties2"))
1399 return to_vkVoidFunction(test_vkGetPhysicalDeviceFormatProperties2);
1400 if (string_eq(pName, "vkGetPhysicalDeviceMemoryProperties2"))
1401 return to_vkVoidFunction(test_vkGetPhysicalDeviceMemoryProperties2);
1402
1403 if (string_eq(pName, "vkGetPhysicalDeviceQueueFamilyProperties2"))
1404 return to_vkVoidFunction(test_vkGetPhysicalDeviceQueueFamilyProperties2);
1405
1406 if (string_eq(pName, "vkGetPhysicalDeviceSparseImageFormatProperties2"))
1407 return to_vkVoidFunction(test_vkGetPhysicalDeviceSparseImageFormatProperties2);
1408
1409 if (string_eq(pName, "vkGetPhysicalDeviceImageFormatProperties2")) {
1410 return to_vkVoidFunction(test_vkGetPhysicalDeviceImageFormatProperties2);
1411 }
1412
1413 if (string_eq(pName, "vkGetPhysicalDeviceExternalBufferProperties"))
1414 return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalBufferProperties);
1415 if (string_eq(pName, "vkGetPhysicalDeviceExternalSemaphoreProperties"))
1416 return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalSemaphoreProperties);
1417 if (string_eq(pName, "vkGetPhysicalDeviceExternalFenceProperties"))
1418 return to_vkVoidFunction(test_vkGetPhysicalDeviceExternalFenceProperties);
1419 }
1420
1421 if (icd.supports_tooling_info_core) {
1422 if (string_eq(pName, "vkGetPhysicalDeviceToolProperties")) return to_vkVoidFunction(test_vkGetPhysicalDeviceToolProperties);
1423 }
1424 if (icd.supports_tooling_info_ext) {
1425 if (string_eq(pName, "vkGetPhysicalDeviceToolPropertiesEXT"))
1426 return to_vkVoidFunction(test_vkGetPhysicalDeviceToolPropertiesEXT);
1427 }
1428
1429 for (auto& phys_dev : icd.physical_devices) {
1430 for (auto& func : phys_dev.custom_physical_device_functions) {
1431 if (func.name == pName) {
1432 return to_vkVoidFunction(func.function);
1433 }
1434 }
1435 }
1436 return nullptr;
1437 }
1438
1439 PFN_vkVoidFunction get_instance_func(VkInstance instance, const char* pName) {
1440 if (string_eq(pName, "vkDestroyInstance")) return to_vkVoidFunction(test_vkDestroyInstance);
1441 if (string_eq(pName, "vkEnumeratePhysicalDevices")) return to_vkVoidFunction(test_vkEnumeratePhysicalDevices);
1442
1443 if (IsInstanceExtensionEnabled(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME)) {
1444 if (string_eq(pName, "vkEnumeratePhysicalDeviceGroupsKHR")) return to_vkVoidFunction(test_vkEnumeratePhysicalDeviceGroups);
1445 }
1446
1447 PFN_vkVoidFunction ret_phys_dev = get_physical_device_func(instance, pName);
1448 if (ret_phys_dev != nullptr) return ret_phys_dev;
1449
1450 PFN_vkVoidFunction ret_1_1 = get_instance_func_ver_1_1(instance, pName);
1451 if (ret_1_1 != nullptr) return ret_1_1;
1452
1453 PFN_vkVoidFunction ret_wsi = get_instance_func_wsi(instance, pName);
1454 if (ret_wsi != nullptr) return ret_wsi;
1455
1456 for (auto& func : icd.custom_instance_functions) {
1457 if (func.name == pName) {
1458 return to_vkVoidFunction(func.function);
1459 }
1460 }
1461
1462 return nullptr;
1463 }
1464
1465 bool should_check(std::vector<const char*> const& exts, VkDevice device, const char* ext_name) {
1466 if (device == NULL) return true; // always look if device is NULL
1467 for (auto const& ext : exts) {
1468 if (string_eq(ext, ext_name)) {
1469 return true;
1470 }
1471 }
1472 return false;
1473 }
1474
1475 PFN_vkVoidFunction get_device_func(VkDevice device, const char* pName) {
1476 TestICD::FindDevice fd{};
1477 DeviceCreateInfo create_info{};
1478 if (device != nullptr) {
1479 fd = icd.lookup_device(device);
1480 if (!fd.found) return NULL;
1481 create_info = icd.physical_devices.at(fd.phys_dev_index).device_create_infos.at(fd.dev_index);
1482 }
1483 if (string_eq(pName, "vkCreateCommandPool")) return to_vkVoidFunction(test_vkCreateCommandPool);
1484 if (string_eq(pName, "vkAllocateCommandBuffers")) return to_vkVoidFunction(test_vkAllocateCommandBuffers);
1485 if (string_eq(pName, "vkDestroyCommandPool")) return to_vkVoidFunction(test_vkDestroyCommandPool);
1486 if (string_eq(pName, "vkGetDeviceQueue")) return to_vkVoidFunction(test_vkGetDeviceQueue);
1487 if (string_eq(pName, "vkDestroyDevice")) return to_vkVoidFunction(test_vkDestroyDevice);
1488 if (should_check(create_info.enabled_extensions, device, "VK_KHR_swapchain")) {
1489 if (string_eq(pName, "vkCreateSwapchainKHR")) return to_vkVoidFunction(test_vkCreateSwapchainKHR);
1490 if (string_eq(pName, "vkGetSwapchainImagesKHR")) return to_vkVoidFunction(test_vkGetSwapchainImagesKHR);
1491 if (string_eq(pName, "vkDestroySwapchainKHR")) return to_vkVoidFunction(test_vkDestroySwapchainKHR);
1492
1493 if (icd.icd_api_version >= VK_API_VERSION_1_1 && string_eq(pName, "vkGetDeviceGroupSurfacePresentModesKHR"))
1494 return to_vkVoidFunction(test_vkGetDeviceGroupSurfacePresentModesKHR);
1495 }
1496 if (should_check(create_info.enabled_extensions, device, "VK_KHR_display_swapchain")) {
1497 if (string_eq(pName, "vkCreateSharedSwapchainsKHR")) return to_vkVoidFunction(test_vkCreateSharedSwapchainsKHR);
1498 }
1499 if (should_check(create_info.enabled_extensions, device, "VK_KHR_device_group")) {
1500 if (string_eq(pName, "vkGetDeviceGroupSurfacePresentModesKHR"))
1501 return to_vkVoidFunction(test_vkGetDeviceGroupSurfacePresentModesKHR);
1502 }
1503 if (should_check(create_info.enabled_extensions, device, "VK_EXT_debug_marker")) {
1504 if (string_eq(pName, "vkDebugMarkerSetObjectTagEXT")) return to_vkVoidFunction(test_vkDebugMarkerSetObjectTagEXT);
1505 if (string_eq(pName, "vkDebugMarkerSetObjectNameEXT")) return to_vkVoidFunction(test_vkDebugMarkerSetObjectNameEXT);
1506 if (string_eq(pName, "vkCmdDebugMarkerBeginEXT")) return to_vkVoidFunction(test_vkCmdDebugMarkerBeginEXT);
1507 if (string_eq(pName, "vkCmdDebugMarkerEndEXT")) return to_vkVoidFunction(test_vkCmdDebugMarkerEndEXT);
1508 if (string_eq(pName, "vkCmdDebugMarkerInsertEXT")) return to_vkVoidFunction(test_vkCmdDebugMarkerInsertEXT);
1509 }
1510 if (IsInstanceExtensionEnabled("VK_EXT_debug_utils")) {
1511 if (string_eq(pName, "vkSetDebugUtilsObjectNameEXT")) return to_vkVoidFunction(test_vkSetDebugUtilsObjectNameEXT);
1512 if (string_eq(pName, "vkSetDebugUtilsObjectTagEXT")) return to_vkVoidFunction(test_vkSetDebugUtilsObjectTagEXT);
1513 if (string_eq(pName, "vkQueueBeginDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueBeginDebugUtilsLabelEXT);
1514 if (string_eq(pName, "vkQueueEndDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueEndDebugUtilsLabelEXT);
1515 if (string_eq(pName, "vkQueueInsertDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueInsertDebugUtilsLabelEXT);
1516 if (string_eq(pName, "vkCmdBeginDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdBeginDebugUtilsLabelEXT);
1517 if (string_eq(pName, "vkCmdEndDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdEndDebugUtilsLabelEXT);
1518 if (string_eq(pName, "vkCmdInsertDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdInsertDebugUtilsLabelEXT);
1519 }
1520 // look for device functions setup from a test
1521 for (const auto& phys_dev : icd.physical_devices) {
1522 for (const auto& function : phys_dev.known_device_functions) {
1523 if (function.name == pName) {
1524 return to_vkVoidFunction(function.function);
1525 }
1526 }
1527 }
1528 return nullptr;
1529 }
1530
1531 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_vkGetInstanceProcAddr(VkInstance instance, const char* pName) {
1532 return get_instance_func(instance, pName);
1533 }
1534
1535 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_vkGetDeviceProcAddr(VkDevice device, const char* pName) {
1536 return get_device_func(device, pName);
1537 }
1538
1539 PFN_vkVoidFunction base_get_instance_proc_addr(VkInstance instance, const char* pName) {
1540 if (pName == nullptr) return nullptr;
1541 if (instance == NULL) {
1542 #if TEST_ICD_EXPOSE_VERSION_7
1543 if (string_eq(pName, "vk_icdNegotiateLoaderICDInterfaceVersion"))
1544 return icd.exposes_vk_icdNegotiateLoaderICDInterfaceVersion
1545 ? to_vkVoidFunction(vk_icdNegotiateLoaderICDInterfaceVersion)
1546 : NULL;
1547 #if TEST_ICD_EXPORT_ICD_GPDPA
1548 if (string_eq(pName, "vk_icdGetPhysicalDeviceProcAddr"))
1549 return icd.exposes_vk_icdGetPhysicalDeviceProcAddr ? to_vkVoidFunction(vk_icdGetPhysicalDeviceProcAddr) : NULL;
1550 #endif
1551 #if defined(WIN32) && TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES
1552 if (string_eq(pName, "vk_icdEnumerateAdapterPhysicalDevices"))
1553 return icd.exposes_vk_icdEnumerateAdapterPhysicalDevices ? to_vkVoidFunction(vk_icdEnumerateAdapterPhysicalDevices)
1554 : NULL;
1555 #endif // defined(WIN32)
1556 #endif // TEST_ICD_EXPOSE_VERSION_7
1557
1558 if (string_eq(pName, "vkGetInstanceProcAddr")) return to_vkVoidFunction(test_vkGetInstanceProcAddr);
1559 if (string_eq(pName, "vkEnumerateInstanceExtensionProperties"))
1560 return icd.exposes_vkEnumerateInstanceExtensionProperties
1561 ? to_vkVoidFunction(test_vkEnumerateInstanceExtensionProperties)
1562 : NULL;
1563 if (string_eq(pName, "vkEnumerateInstanceLayerProperties"))
1564 return to_vkVoidFunction(test_vkEnumerateInstanceLayerProperties);
1565 if (string_eq(pName, "vkEnumerateInstanceVersion"))
1566 return icd.can_query_vkEnumerateInstanceVersion ? to_vkVoidFunction(test_vkEnumerateInstanceVersion) : nullptr;
1567 if (string_eq(pName, "vkCreateInstance")) return to_vkVoidFunction(test_vkCreateInstance);
1568 }
1569 if (string_eq(pName, "vkGetDeviceProcAddr")) return to_vkVoidFunction(test_vkGetDeviceProcAddr);
1570
1571 auto instance_func_return = get_instance_func(instance, pName);
1572 if (instance_func_return != nullptr) return instance_func_return;
1573
1574 // Need to return function pointers for device extensions
1575 auto device_func_return = get_device_func(nullptr, pName);
1576 if (device_func_return != nullptr) return device_func_return;
1577 return nullptr;
1578 }
1579
1580 // Exported functions
1581 extern "C" {
1582 #if TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION
1583 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) {
1584 return test_vk_icdNegotiateLoaderICDInterfaceVersion(pSupportedVersion);
1585 }
1586 #endif // TEST_ICD_EXPORT_NEGOTIATE_INTERFACE_VERSION
1587
1588 #if TEST_ICD_EXPORT_ICD_GPDPA
1589 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName) {
1590 return get_physical_device_func(instance, pName);
1591 }
1592 #endif // TEST_ICD_EXPORT_ICD_GPDPA
1593
1594 #if TEST_ICD_EXPORT_ICD_GIPA
1595 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName) {
1596 if (icd.called_vk_icd_gipa == CalledICDGIPA::not_called) icd.called_vk_icd_gipa = CalledICDGIPA::vk_icd_gipa;
1597 return base_get_instance_proc_addr(instance, pName);
1598 }
1599 #else // !TEST_ICD_EXPORT_ICD_GIPA
1600 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* pName) {
1601 if (icd.called_vk_icd_gipa == CalledICDGIPA::not_called) icd.called_vk_icd_gipa = CalledICDGIPA::vk_gipa;
1602 return base_get_instance_proc_addr(instance, pName);
1603 }
1604 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
1605 const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) {
1606 return test_vkCreateInstance(pCreateInfo, pAllocator, pInstance);
1607 }
1608 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char* pLayerName,
1609 uint32_t* pPropertyCount,
1610 VkExtensionProperties* pProperties) {
1611 return test_vkEnumerateInstanceExtensionProperties(pLayerName, pPropertyCount, pProperties);
1612 }
1613 #endif // TEST_ICD_EXPORT_ICD_GIPA
1614
1615 #if TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES
1616 #if defined(WIN32)
1617 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID,
1618 uint32_t* pPhysicalDeviceCount,
1619 VkPhysicalDevice* pPhysicalDevices) {
1620 return test_vk_icdEnumerateAdapterPhysicalDevices(instance, adapterLUID, pPhysicalDeviceCount, pPhysicalDevices);
1621 }
1622 #endif // defined(WIN32)
1623 #endif // TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES
1624
1625 } // extern "C"
1626