1/* 2 * Copyright (c) 2015-2022 Valve Corporation 3 * Copyright (c) 2015-2022 LunarG, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 * Author: Jon Ashburn <jon@lunarg.com> 18 */ 19 20#include <stdio.h> 21#include <stdlib.h> 22#include <ctype.h> 23#include <string> 24#include <algorithm> 25#include <assert.h> 26#include <unordered_map> 27#include <memory> 28#include <vector> 29 30#include "vulkan/vk_layer.h" 31#include "vk_dispatch_table_helper.h" 32#include "loader/vk_loader_layer.h" 33 34// Export full support of instance extension VK_EXT_direct_mode_display extension 35#if !defined(TEST_LAYER_EXPORT_DIRECT_DISP) 36#define TEST_LAYER_EXPORT_DIRECT_DISP 0 37#endif 38 39// Export full support of instance extension VK_EXT_display_surface_counter extension 40#if !defined(TEST_LAYER_EXPORT_DISP_SURF_COUNT) 41#define TEST_LAYER_EXPORT_DISP_SURF_COUNT 0 42#endif 43 44// Export full support of device extension VK_KHR_maintenance1 extension 45#if !defined(TEST_LAYER_EXPORT_MAINT_1) 46#define TEST_LAYER_EXPORT_MAINT_1 0 47#endif 48 49// Export full support of device extension VK_KHR_shared_presentable_image extension 50#if !defined(TEST_LAYER_EXPORT_PRESENT_IMAGE) 51#define TEST_LAYER_EXPORT_PRESENT_IMAGE 0 52#endif 53 54#if !defined(VK_LAYER_EXPORT) 55#if defined(__GNUC__) && __GNUC__ >= 4 56#define VK_LAYER_EXPORT __attribute__((visibility("default"))) 57#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590) 58#define VK_LAYER_EXPORT __attribute__((visibility("default"))) 59#else 60#define VK_LAYER_EXPORT 61#endif 62#endif 63 64struct wrapped_phys_dev_obj { 65 VkLayerInstanceDispatchTable *loader_disp; 66 struct wrapped_inst_obj *inst; // parent instance object 67 void *obj; 68}; 69 70struct wrapped_inst_obj { 71 VkLayerInstanceDispatchTable *loader_disp; 72 VkLayerInstanceDispatchTable layer_disp; // this layer's dispatch table 73 PFN_vkSetInstanceLoaderData pfn_inst_init; 74 struct wrapped_phys_dev_obj *ptr_phys_devs; // any enumerated phys devs 75 VkInstance obj; 76 bool layer_is_implicit; 77 bool direct_display_enabled; 78 bool display_surf_counter_enabled; 79 bool debug_utils_enabled; 80}; 81 82struct wrapped_dev_obj { 83 VkLayerDispatchTable *loader_disp; 84 VkLayerDispatchTable disp; 85 PFN_vkSetDeviceLoaderData pfn_dev_init; 86 PFN_vkGetDeviceProcAddr pfn_get_dev_proc_addr; 87 VkDevice obj; 88 bool maintanence_1_enabled; 89 bool present_image_enabled; 90 bool debug_utils_enabled; 91 bool debug_report_enabled; 92 bool debug_marker_enabled; 93}; 94 95struct wrapped_debug_util_mess_obj { 96 VkInstance inst; 97 VkDebugUtilsMessengerEXT obj; 98}; 99 100struct saved_wrapped_handles_storage { 101 std::vector<wrapped_inst_obj *> instances; 102 std::vector<wrapped_phys_dev_obj *> physical_devices; 103 std::vector<wrapped_dev_obj *> devices; 104 std::vector<wrapped_debug_util_mess_obj *> debug_util_messengers; 105}; 106 107saved_wrapped_handles_storage saved_wrapped_handles; 108 109VkInstance unwrap_instance(const VkInstance instance, wrapped_inst_obj **inst) { 110 *inst = reinterpret_cast<wrapped_inst_obj *>(instance); 111 auto it = std::find(saved_wrapped_handles.instances.begin(), saved_wrapped_handles.instances.end(), *inst); 112 return (it == saved_wrapped_handles.instances.end()) ? VK_NULL_HANDLE : (*inst)->obj; 113} 114 115VkPhysicalDevice unwrap_phys_dev(const VkPhysicalDevice physical_device, wrapped_phys_dev_obj **phys_dev) { 116 *phys_dev = reinterpret_cast<wrapped_phys_dev_obj *>(physical_device); 117 auto it = std::find(saved_wrapped_handles.physical_devices.begin(), saved_wrapped_handles.physical_devices.end(), *phys_dev); 118 return (it == saved_wrapped_handles.physical_devices.end()) ? VK_NULL_HANDLE 119 : reinterpret_cast<VkPhysicalDevice>((*phys_dev)->obj); 120} 121 122VkDevice unwrap_device(const VkDevice device, wrapped_dev_obj **dev) { 123 *dev = reinterpret_cast<wrapped_dev_obj *>(device); 124 auto it = std::find(saved_wrapped_handles.devices.begin(), saved_wrapped_handles.devices.end(), *dev); 125 return (it == saved_wrapped_handles.devices.end()) ? VK_NULL_HANDLE : (*dev)->obj; 126} 127 128VkDebugUtilsMessengerEXT unwrap_debug_util_messenger(const VkDebugUtilsMessengerEXT messenger, wrapped_debug_util_mess_obj **mess) { 129 *mess = reinterpret_cast<wrapped_debug_util_mess_obj *>(messenger); 130 auto it = 131 std::find(saved_wrapped_handles.debug_util_messengers.begin(), saved_wrapped_handles.debug_util_messengers.end(), *mess); 132 return (it == saved_wrapped_handles.debug_util_messengers.end()) ? VK_NULL_HANDLE : (*mess)->obj; 133} 134 135VkLayerInstanceCreateInfo *get_chain_info(const VkInstanceCreateInfo *pCreateInfo, VkLayerFunction func) { 136 VkLayerInstanceCreateInfo *chain_info = (VkLayerInstanceCreateInfo *)pCreateInfo->pNext; 137 while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO && chain_info->function == func)) { 138 chain_info = (VkLayerInstanceCreateInfo *)chain_info->pNext; 139 } 140 assert(chain_info != NULL); 141 return chain_info; 142} 143 144VkLayerDeviceCreateInfo *get_chain_info(const VkDeviceCreateInfo *pCreateInfo, VkLayerFunction func) { 145 VkLayerDeviceCreateInfo *chain_info = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext; 146 while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO && chain_info->function == func)) { 147 chain_info = (VkLayerDeviceCreateInfo *)chain_info->pNext; 148 } 149 assert(chain_info != NULL); 150 return chain_info; 151} 152 153namespace wrap_objects { 154 155const VkLayerProperties global_layer = { 156 "VK_LAYER_LUNARG_wrap_objects", 157 VK_HEADER_VERSION_COMPLETE, 158 1, 159 "LunarG Test Layer", 160}; 161 162uint32_t loader_layer_if_version = CURRENT_LOADER_LAYER_INTERFACE_VERSION; 163 164VKAPI_ATTR VkResult VKAPI_CALL wrap_vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, 165 const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) { 166 VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 167 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 168 PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance"); 169 if (fpCreateInstance == NULL) { 170 return VK_ERROR_INITIALIZATION_FAILED; 171 } 172 // Advance the link info for the next element on the chain 173 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 174 VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); 175 if (result != VK_SUCCESS) { 176 return result; 177 } 178 auto inst = new wrapped_inst_obj; 179 if (!inst) return VK_ERROR_OUT_OF_HOST_MEMORY; 180 saved_wrapped_handles.instances.push_back(inst); 181 memset(inst, 0, sizeof(*inst)); 182 inst->obj = (*pInstance); 183 *pInstance = reinterpret_cast<VkInstance>(inst); 184 // store the loader callback for initializing created dispatchable objects 185 chain_info = get_chain_info(pCreateInfo, VK_LOADER_DATA_CALLBACK); 186 if (chain_info) { 187 inst->pfn_inst_init = chain_info->u.pfnSetInstanceLoaderData; 188 result = inst->pfn_inst_init(inst->obj, reinterpret_cast<void *>(inst)); 189 if (VK_SUCCESS != result) return result; 190 } else { 191 inst->pfn_inst_init = NULL; 192 inst->loader_disp = *(reinterpret_cast<VkLayerInstanceDispatchTable **>(inst->obj)); 193 } 194 layer_init_instance_dispatch_table(inst->obj, &inst->layer_disp, fpGetInstanceProcAddr); 195 bool found = false; 196 for (uint32_t layer = 0; layer < pCreateInfo->enabledLayerCount; ++layer) { 197 std::string layer_name = pCreateInfo->ppEnabledLayerNames[layer]; 198 std::transform(layer_name.begin(), layer_name.end(), layer_name.begin(), 199 [](char c) { return static_cast<char>(::tolower(static_cast<char>(c))); }); 200 if (layer_name.find("wrap") != std::string::npos && layer_name.find("obj") != std::string::npos) { 201 found = true; 202 break; 203 } 204 } 205 if (!found) { 206 inst->layer_is_implicit = true; 207 } 208 209 for (uint32_t ext = 0; ext < pCreateInfo->enabledExtensionCount; ++ext) { 210 if (!strcmp(pCreateInfo->ppEnabledExtensionNames[ext], VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)) { 211#if TEST_LAYER_EXPORT_DIRECT_DISP 212 inst->direct_display_enabled = true; 213#endif 214 } 215 if (!strcmp(pCreateInfo->ppEnabledExtensionNames[ext], VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)) { 216#if TEST_LAYER_EXPORT_DISP_SURF_COUNT 217 inst->display_surf_counter_enabled = true; 218#endif 219 } 220 if (!strcmp(pCreateInfo->ppEnabledExtensionNames[ext], VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) { 221 inst->debug_utils_enabled = true; 222 } 223 } 224 225 return result; 226} 227 228VKAPI_ATTR void VKAPI_CALL wrap_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) { 229 wrapped_inst_obj *inst; 230 auto vk_inst = unwrap_instance(instance, &inst); 231 VkLayerInstanceDispatchTable *pDisp = &inst->layer_disp; 232 pDisp->DestroyInstance(vk_inst, pAllocator); 233 if (inst->ptr_phys_devs) delete[] inst->ptr_phys_devs; 234 delete inst; 235} 236 237VKAPI_ATTR VkResult VKAPI_CALL wrap_vkCreateDebugUtilsMessengerEXT(VkInstance instance, 238 const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, 239 const VkAllocationCallbacks *pAllocator, 240 VkDebugUtilsMessengerEXT *pMessenger) { 241 wrapped_inst_obj *inst; 242 auto vk_inst = unwrap_instance(instance, &inst); 243 VkLayerInstanceDispatchTable *pDisp = &inst->layer_disp; 244 VkResult result = pDisp->CreateDebugUtilsMessengerEXT(vk_inst, pCreateInfo, pAllocator, pMessenger); 245 auto mess = new wrapped_debug_util_mess_obj; 246 if (!mess) return VK_ERROR_OUT_OF_HOST_MEMORY; 247 saved_wrapped_handles.debug_util_messengers.push_back(mess); 248 memset(mess, 0, sizeof(*mess)); 249 mess->obj = (*pMessenger); 250 *pMessenger = reinterpret_cast<VkDebugUtilsMessengerEXT>(mess); 251 return result; 252} 253 254VKAPI_ATTR void VKAPI_CALL wrap_vkDestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger, 255 const VkAllocationCallbacks *pAllocator) { 256 wrapped_inst_obj *inst; 257 auto vk_inst = unwrap_instance(instance, &inst); 258 VkLayerInstanceDispatchTable *pDisp = &inst->layer_disp; 259 wrapped_debug_util_mess_obj *mess; 260 auto vk_mess = unwrap_debug_util_messenger(messenger, &mess); 261 pDisp->DestroyDebugUtilsMessengerEXT(vk_inst, vk_mess, pAllocator); 262 delete mess; 263} 264 265VKAPI_ATTR void VKAPI_CALL wrap_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, 266 const VkAllocationCallbacks *pAllocator) { 267 wrapped_inst_obj *inst; 268 auto vk_inst = unwrap_instance(instance, &inst); 269 VkLayerInstanceDispatchTable *pDisp = &inst->layer_disp; 270 pDisp->DestroySurfaceKHR(vk_inst, surface, pAllocator); 271} 272#if defined(VK_USE_PLATFORM_ANDROID_KHR) 273VKAPI_ATTR VkResult VKAPI_CALL wrap_vkCreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR *pCreateInfo, 274 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 275 wrapped_inst_obj *inst; 276 auto vk_inst = unwrap_instance(instance, &inst); 277 VkLayerInstanceDispatchTable *pDisp = &inst->layer_disp; 278 return pDisp->CreateAndroidSurfaceKHR(vk_inst, pCreateInfo, pAllocator, pSurface); 279} 280#endif 281 282#if defined(VK_USE_PLATFORM_WIN32_KHR) 283VKAPI_ATTR VkResult VKAPI_CALL wrap_vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, 284 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 285 wrapped_inst_obj *inst; 286 auto vk_inst = unwrap_instance(instance, &inst); 287 VkLayerInstanceDispatchTable *pDisp = &inst->layer_disp; 288 return pDisp->CreateWin32SurfaceKHR(vk_inst, pCreateInfo, pAllocator, pSurface); 289} 290#endif // VK_USE_PLATFORM_WIN32_KHR 291 292#if defined(VK_USE_PLATFORM_WAYLAND_KHR) 293VKAPI_ATTR VkResult VKAPI_CALL wrap_vkCreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, 294 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 295 wrapped_inst_obj *inst; 296 auto vk_inst = unwrap_instance(instance, &inst); 297 VkLayerInstanceDispatchTable *pDisp = &inst->layer_disp; 298 return pDisp->CreateWaylandSurfaceKHR(vk_inst, pCreateInfo, pAllocator, pSurface); 299} 300#endif // VK_USE_PLATFORM_WAYLAND_KHR 301 302#if defined(VK_USE_PLATFORM_XCB_KHR) 303VKAPI_ATTR VkResult VKAPI_CALL wrap_vkCreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo, 304 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 305 wrapped_inst_obj *inst; 306 auto vk_inst = unwrap_instance(instance, &inst); 307 VkLayerInstanceDispatchTable *pDisp = &inst->layer_disp; 308 return pDisp->CreateXcbSurfaceKHR(vk_inst, pCreateInfo, pAllocator, pSurface); 309} 310#endif // VK_USE_PLATFORM_XCB_KHR 311 312#if defined(VK_USE_PLATFORM_XLIB_KHR) 313VKAPI_ATTR VkResult VKAPI_CALL wrap_vkCreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo, 314 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 315 wrapped_inst_obj *inst; 316 auto vk_inst = unwrap_instance(instance, &inst); 317 VkLayerInstanceDispatchTable *pDisp = &inst->layer_disp; 318 return pDisp->CreateXlibSurfaceKHR(vk_inst, pCreateInfo, pAllocator, pSurface); 319} 320#endif // VK_USE_PLATFORM_XLIB_KHR 321 322#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) 323VKAPI_ATTR VkResult VKAPI_CALL wrap_vkCreateDirectFBSurfaceEXT(VkInstance instance, 324 const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo, 325 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 326 wrapped_inst_obj *inst; 327 auto vk_inst = unwrap_instance(instance, &inst); 328 VkLayerInstanceDispatchTable *pDisp = &inst->layer_disp; 329 return pDisp->CreateDirectFBSurfaceEXT(vk_inst, pCreateInfo, pAllocator, pSurface); 330} 331#endif // VK_USE_PLATFORM_DIRECTFB_EXT 332 333#if defined(VK_USE_PLATFORM_MACOS_MVK) 334VKAPI_ATTR VkResult VKAPI_CALL wrap_vkCreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo, 335 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 336 wrapped_inst_obj *inst; 337 auto vk_inst = unwrap_instance(instance, &inst); 338 VkLayerInstanceDispatchTable *pDisp = &inst->layer_disp; 339 return pDisp->CreateMacOSSurfaceMVK(vk_inst, pCreateInfo, pAllocator, pSurface); 340} 341#endif // VK_USE_PLATFORM_MACOS_MVK 342 343#if defined(VK_USE_PLATFORM_IOS_MVK) 344VKAPI_ATTR VkResult VKAPI_CALL wrap_vkCreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo, 345 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 346 wrapped_inst_obj *inst; 347 auto vk_inst = unwrap_instance(instance, &inst); 348 VkLayerInstanceDispatchTable *pDisp = &inst->layer_disp; 349 return pDisp->CreateIOSSurfaceMVK(vk_inst, pCreateInfo, pAllocator, pSurface); 350} 351#endif // VK_USE_PLATFORM_IOS_MVK 352 353#if defined(VK_USE_PLATFORM_GGP) 354VKAPI_ATTR VkResult VKAPI_CALL wrap_vkCreateStreamDescriptorSurfaceGGP(VkInstance instance, 355 const VkStreamDescriptorSurfaceCreateInfoGGP *pCreateInfo, 356 const VkAllocationCallbacks *pAllocator, 357 VkSurfaceKHR *pSurface) { 358 wrapped_inst_obj *inst; 359 auto vk_inst = unwrap_instance(instance, &inst); 360 VkLayerInstanceDispatchTable *pDisp = &inst->layer_disp; 361 return pDisp->CreateStreamDescriptorSurfaceGGP(vk_inst, pCreateInfo, pAllocator, pSurface); 362} 363#endif // VK_USE_PLATFORM_GGP 364 365#if defined(VK_USE_PLATFORM_METAL_EXT) 366VKAPI_ATTR VkResult VKAPI_CALL wrap_vkCreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT *pCreateInfo, 367 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 368 wrapped_inst_obj *inst; 369 auto vk_inst = unwrap_instance(instance, &inst); 370 VkLayerInstanceDispatchTable *pDisp = &inst->layer_disp; 371 return pDisp->CreateMetalSurfaceEXT(vk_inst, pCreateInfo, pAllocator, pSurface); 372} 373#endif // VK_USE_PLATFORM_METAL_EXT 374 375#if defined(VK_USE_PLATFORM_SCREEN_QNX) 376VKAPI_ATTR VkResult VKAPI_CALL wrap_vkCreateScreenSurfaceQNX(VkInstance instance, const VkScreenSurfaceCreateInfoQNX *pCreateInfo, 377 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 378 wrapped_inst_obj *inst; 379 auto vk_inst = unwrap_instance(instance, &inst); 380 VkLayerInstanceDispatchTable *pDisp = &inst->layer_disp; 381 return pDisp->CreateScreenSurfaceQNX(vk_inst, pCreateInfo, pAllocator, pSurface); 382} 383#endif // VK_USE_PLATFORM_SCREEN_QNX 384 385VKAPI_ATTR VkResult VKAPI_CALL wrap_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, 386 VkPhysicalDevice *pPhysicalDevices) { 387 wrapped_inst_obj *inst; 388 auto vk_inst = unwrap_instance(instance, &inst); 389 VkResult result = inst->layer_disp.EnumeratePhysicalDevices(vk_inst, pPhysicalDeviceCount, pPhysicalDevices); 390 391 if (VK_SUCCESS != result) return result; 392 393 if (pPhysicalDevices != NULL) { 394 assert(pPhysicalDeviceCount); 395 auto phys_devs = new wrapped_phys_dev_obj[*pPhysicalDeviceCount]; 396 if (!phys_devs) return VK_ERROR_OUT_OF_HOST_MEMORY; 397 saved_wrapped_handles.physical_devices.push_back(phys_devs); 398 if (inst->ptr_phys_devs) delete[] inst->ptr_phys_devs; 399 inst->ptr_phys_devs = phys_devs; 400 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) { 401 if (inst->pfn_inst_init == NULL) { 402 phys_devs[i].loader_disp = *(reinterpret_cast<VkLayerInstanceDispatchTable **>(pPhysicalDevices[i])); 403 } else { 404 result = inst->pfn_inst_init(vk_inst, reinterpret_cast<void *>(&phys_devs[i])); 405 if (VK_SUCCESS != result) return result; 406 } 407 phys_devs[i].obj = reinterpret_cast<void *>(pPhysicalDevices[i]); 408 phys_devs[i].inst = inst; 409 pPhysicalDevices[i] = reinterpret_cast<VkPhysicalDevice>(&phys_devs[i]); 410 } 411 } 412 return result; 413} 414 415VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties) { 416 wrapped_phys_dev_obj *phys_dev; 417 auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev); 418 phys_dev->inst->layer_disp.GetPhysicalDeviceProperties(vk_phys_dev, pProperties); 419} 420 421VKAPI_ATTR void VKAPI_CALL wrap_vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, 422 uint32_t *pQueueFamilyPropertyCount, 423 VkQueueFamilyProperties *pQueueFamilyProperties) { 424 wrapped_phys_dev_obj *phys_dev; 425 auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev); 426 phys_dev->inst->layer_disp.GetPhysicalDeviceQueueFamilyProperties(vk_phys_dev, pQueueFamilyPropertyCount, 427 pQueueFamilyProperties); 428} 429 430VKAPI_ATTR VkResult VKAPI_CALL wrap_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, 431 uint32_t *pPropertyCount, 432 VkExtensionProperties *pProperties) { 433 VkResult result = VK_SUCCESS; 434 wrapped_phys_dev_obj *phys_dev; 435 auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev); 436 437 if (phys_dev->inst->layer_is_implicit || (pLayerName && !strcmp(pLayerName, global_layer.layerName))) { 438 uint32_t ext_count = 0; 439#if TEST_LAYER_EXPORT_MAINT_1 440 ext_count++; 441#endif 442#if TEST_LAYER_EXPORT_PRESENT_IMAGE 443 ext_count++; 444#endif 445 if (pPropertyCount) { 446 if (pProperties) { 447 [[maybe_unused]] uint32_t count = ext_count; 448 if (count > *pPropertyCount) { 449 count = *pPropertyCount; 450 result = VK_INCOMPLETE; 451 } 452 453 ext_count = 0; 454#if TEST_LAYER_EXPORT_MAINT_1 455 if (ext_count < count) { 456#if defined(_WIN32) 457 strncpy_s(pProperties[ext_count].extensionName, VK_MAX_EXTENSION_NAME_SIZE, VK_KHR_MAINTENANCE1_EXTENSION_NAME, 458 strlen(VK_KHR_MAINTENANCE1_EXTENSION_NAME) + 1); 459#else 460 strncpy(pProperties[ext_count].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME, VK_MAX_EXTENSION_NAME_SIZE); 461#endif 462 pProperties[ext_count].specVersion = 2; 463 ext_count++; 464 } 465#endif 466#if TEST_LAYER_EXPORT_PRESENT_IMAGE 467 if (ext_count < count) { 468#if defined(_WIN32) 469 strncpy_s(pProperties[ext_count].extensionName, VK_MAX_EXTENSION_NAME_SIZE, 470 VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 471 strlen(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME) + 1); 472#else 473 strncpy(pProperties[ext_count].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 474 VK_MAX_EXTENSION_NAME_SIZE); 475#endif 476 pProperties[ext_count].specVersion = 1; 477 ext_count++; 478 } 479#endif 480 } 481 *pPropertyCount = ext_count; 482 } 483 return result; 484 } else { 485 return phys_dev->inst->layer_disp.EnumerateDeviceExtensionProperties(vk_phys_dev, pLayerName, pPropertyCount, pProperties); 486 } 487} 488 489VKAPI_ATTR VkResult VKAPI_CALL wrap_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, 490 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) { 491 wrapped_phys_dev_obj *phys_dev; 492 auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev); 493 VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 494 PFN_vkGetInstanceProcAddr pfn_get_inst_proc_addr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 495 PFN_vkGetDeviceProcAddr pfn_get_dev_proc_addr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; 496 PFN_vkCreateDevice pfn_create_device = (PFN_vkCreateDevice)pfn_get_inst_proc_addr(phys_dev->inst->obj, "vkCreateDevice"); 497 if (pfn_create_device == NULL) { 498 return VK_ERROR_INITIALIZATION_FAILED; 499 } 500 // Advance the link info for the next element on the chain 501 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 502 VkResult result = pfn_create_device(vk_phys_dev, pCreateInfo, pAllocator, pDevice); 503 if (result != VK_SUCCESS) { 504 return result; 505 } 506 auto dev = new wrapped_dev_obj; 507 if (!dev) { 508 return VK_ERROR_OUT_OF_HOST_MEMORY; 509 } 510 saved_wrapped_handles.devices.push_back(dev); 511 memset(dev, 0, sizeof(*dev)); 512 dev->obj = *pDevice; 513 dev->pfn_get_dev_proc_addr = pfn_get_dev_proc_addr; 514 *pDevice = reinterpret_cast<VkDevice>(dev); 515 516 // Store the loader callback for initializing created dispatchable objects 517 chain_info = get_chain_info(pCreateInfo, VK_LOADER_DATA_CALLBACK); 518 if (chain_info) { 519 dev->pfn_dev_init = chain_info->u.pfnSetDeviceLoaderData; 520 result = dev->pfn_dev_init(dev->obj, reinterpret_cast<void *>(dev)); 521 if (VK_SUCCESS != result) { 522 return result; 523 } 524 } else { 525 dev->pfn_dev_init = NULL; 526 } 527 528 // Initialize layer's dispatch table 529 layer_init_device_dispatch_table(dev->obj, &dev->disp, pfn_get_dev_proc_addr); 530 531 for (uint32_t ext = 0; ext < pCreateInfo->enabledExtensionCount; ++ext) { 532 if (!strcmp(pCreateInfo->ppEnabledExtensionNames[ext], VK_KHR_MAINTENANCE1_EXTENSION_NAME)) { 533#if TEST_LAYER_EXPORT_MAINT_1 534 dev->maintanence_1_enabled = true; 535#endif 536 } 537 if (!strcmp(pCreateInfo->ppEnabledExtensionNames[ext], VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)) { 538#if TEST_LAYER_EXPORT_PRESENT_IMAGE 539 dev->present_image_enabled = true; 540#endif 541 } 542 if (!strcmp(pCreateInfo->ppEnabledExtensionNames[ext], VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) { 543 dev->debug_marker_enabled = true; 544 } 545 } 546 dev->debug_utils_enabled = phys_dev->inst->debug_utils_enabled; 547 548 return result; 549} 550 551VKAPI_ATTR void VKAPI_CALL wrap_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) { 552 wrapped_dev_obj *dev; 553 auto vk_dev = unwrap_device(device, &dev); 554 dev->disp.DestroyDevice(vk_dev, pAllocator); 555 delete dev; 556} 557 558// Fake instance extension support 559VKAPI_ATTR VkResult VKAPI_CALL wrap_vkReleaseDisplayEXT(VkPhysicalDevice, VkDisplayKHR) { return VK_SUCCESS; } 560 561VKAPI_ATTR VkResult VKAPI_CALL wrap_vkGetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice, VkSurfaceKHR, 562 VkSurfaceCapabilities2EXT *pSurfaceCapabilities) { 563 if (nullptr != pSurfaceCapabilities) { 564 pSurfaceCapabilities->minImageCount = 7; 565 pSurfaceCapabilities->maxImageCount = 12; 566 pSurfaceCapabilities->maxImageArrayLayers = 365; 567 } 568 return VK_SUCCESS; 569} 570 571// Fake device extension support 572VKAPI_ATTR void VKAPI_CALL wrap_vkTrimCommandPoolKHR(VkDevice, VkCommandPool, VkCommandPoolTrimFlags) {} 573 574// Return an odd error so we can verify that this actually got called 575VKAPI_ATTR VkResult VKAPI_CALL wrap_vkGetSwapchainStatusKHR(VkDevice, VkSwapchainKHR) { return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR; } 576 577// Debug utils & debug marker ext stubs 578VKAPI_ATTR VkResult VKAPI_CALL wrap_vkDebugMarkerSetObjectTagEXT(VkDevice device, const VkDebugMarkerObjectTagInfoEXT *pTagInfo) { 579 VkDebugMarkerObjectTagInfoEXT new_info = *pTagInfo; 580 wrapped_dev_obj *dev; 581 auto vk_dev = unwrap_device(device, &dev); 582 if (pTagInfo && pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) { 583 wrapped_phys_dev_obj *phys_dev; 584 auto vk_phys_dev = unwrap_phys_dev((VkPhysicalDevice)(uintptr_t)(pTagInfo->object), &phys_dev); 585 if (vk_phys_dev == VK_NULL_HANDLE) return VK_ERROR_DEVICE_LOST; 586 new_info.object = (uint64_t)(uintptr_t)vk_phys_dev; 587 } 588 if (pTagInfo && pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) { 589 // TODO 590 } 591 if (pTagInfo && pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT) { 592 wrapped_inst_obj *inst; 593 auto instance = unwrap_instance((VkInstance)(uintptr_t)(pTagInfo->object), &inst); 594 if (instance == VK_NULL_HANDLE) return VK_ERROR_DEVICE_LOST; 595 new_info.object = (uint64_t)(uintptr_t)instance; 596 } 597 return dev->disp.DebugMarkerSetObjectTagEXT(vk_dev, &new_info); 598} 599VKAPI_ATTR VkResult VKAPI_CALL wrap_vkDebugMarkerSetObjectNameEXT(VkDevice device, 600 const VkDebugMarkerObjectNameInfoEXT *pNameInfo) { 601 VkDebugMarkerObjectNameInfoEXT new_info = *pNameInfo; 602 wrapped_dev_obj *dev; 603 auto vk_dev = unwrap_device(device, &dev); 604 if (pNameInfo && pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) { 605 wrapped_phys_dev_obj *phys_dev; 606 auto vk_phys_dev = unwrap_phys_dev((VkPhysicalDevice)(uintptr_t)(pNameInfo->object), &phys_dev); 607 if (vk_phys_dev == VK_NULL_HANDLE) return VK_ERROR_DEVICE_LOST; 608 new_info.object = (uint64_t)(uintptr_t)vk_phys_dev; 609 } 610 if (pNameInfo && pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) { 611 // TODO 612 } 613 if (pNameInfo && pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT) { 614 wrapped_inst_obj *inst; 615 auto instance = unwrap_instance((VkInstance)(uintptr_t)(pNameInfo->object), &inst); 616 if (instance == VK_NULL_HANDLE) return VK_ERROR_DEVICE_LOST; 617 new_info.object = (uint64_t)(uintptr_t)instance; 618 } 619 return dev->disp.DebugMarkerSetObjectNameEXT(vk_dev, &new_info); 620} 621// Debug Marker functions that are not supported: 622// vkCmdDebugMarkerBeginEXT 623// vkCmdDebugMarkerEndEXT 624// vkCmdDebugMarkerInsertEXT 625 626VKAPI_ATTR VkResult VKAPI_CALL wrap_vkSetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsObjectNameInfoEXT *pNameInfo) { 627 VkDebugUtilsObjectNameInfoEXT new_info = *pNameInfo; 628 wrapped_dev_obj *dev; 629 auto vk_dev = unwrap_device(device, &dev); 630 if (pNameInfo && pNameInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) { 631 wrapped_phys_dev_obj *phys_dev; 632 auto vk_phys_dev = unwrap_phys_dev((VkPhysicalDevice)(uintptr_t)(pNameInfo->objectHandle), &phys_dev); 633 if (vk_phys_dev == VK_NULL_HANDLE) return VK_ERROR_DEVICE_LOST; 634 new_info.objectHandle = (uint64_t)(uintptr_t)vk_phys_dev; 635 } 636 if (pNameInfo && pNameInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) { 637 // TODO 638 } 639 if (pNameInfo && pNameInfo->objectType == VK_OBJECT_TYPE_INSTANCE) { 640 wrapped_inst_obj *inst; 641 auto instance = unwrap_instance((VkInstance)(uintptr_t)(pNameInfo->objectHandle), &inst); 642 if (instance == VK_NULL_HANDLE) return VK_ERROR_DEVICE_LOST; 643 new_info.objectHandle = (uint64_t)(uintptr_t)instance; 644 } 645 return dev->disp.SetDebugUtilsObjectNameEXT(vk_dev, &new_info); 646} 647VKAPI_ATTR VkResult VKAPI_CALL wrap_vkSetDebugUtilsObjectTagEXT(VkDevice device, const VkDebugUtilsObjectTagInfoEXT *pTagInfo) { 648 VkDebugUtilsObjectTagInfoEXT new_info = *pTagInfo; 649 wrapped_dev_obj *dev; 650 auto vk_dev = unwrap_device(device, &dev); 651 if (pTagInfo && pTagInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) { 652 wrapped_phys_dev_obj *phys_dev; 653 auto vk_phys_dev = unwrap_phys_dev((VkPhysicalDevice)(uintptr_t)(pTagInfo->objectHandle), &phys_dev); 654 if (vk_phys_dev == VK_NULL_HANDLE) return VK_ERROR_DEVICE_LOST; 655 new_info.objectHandle = (uint64_t)(uintptr_t)vk_phys_dev; 656 } 657 if (pTagInfo && pTagInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) { 658 // TODO 659 } 660 if (pTagInfo && pTagInfo->objectType == VK_OBJECT_TYPE_INSTANCE) { 661 wrapped_inst_obj *inst; 662 auto instance = unwrap_instance((VkInstance)(uintptr_t)(pTagInfo->objectHandle), &inst); 663 if (instance == VK_NULL_HANDLE) return VK_ERROR_DEVICE_LOST; 664 new_info.objectHandle = (uint64_t)(uintptr_t)instance; 665 } 666 return dev->disp.SetDebugUtilsObjectTagEXT(vk_dev, &new_info); 667} 668// Debug utils functions that are not supported 669// vkQueueBeginDebugUtilsLabelEXT 670// vkQueueEndDebugUtilsLabelEXT 671// vkQueueInsertDebugUtilsLabelEXT 672// vkCmdBeginDebugUtilsLabelEXT 673// vkCmdEndDebugUtilsLabelEXT 674// vkCmdInsertDebugUtilsLabelEXT 675 676PFN_vkVoidFunction layer_intercept_device_proc(wrapped_dev_obj *dev, const char *name) { 677 if (!name || name[0] != 'v' || name[1] != 'k') return NULL; 678 679 name += 2; 680 if (!strcmp(name, "CreateDevice")) return (PFN_vkVoidFunction)wrap_vkCreateDevice; 681 if (!strcmp(name, "DestroyDevice")) return (PFN_vkVoidFunction)wrap_vkDestroyDevice; 682 683 if (dev->maintanence_1_enabled && !strcmp(name, "TrimCommandPoolKHR")) return (PFN_vkVoidFunction)wrap_vkTrimCommandPoolKHR; 684 if (dev->present_image_enabled && !strcmp(name, "GetSwapchainStatusKHR")) 685 return (PFN_vkVoidFunction)wrap_vkGetSwapchainStatusKHR; 686 687 if (dev->debug_marker_enabled && !strcmp(name, "DebugMarkerSetObjectTagEXT")) 688 return (PFN_vkVoidFunction)wrap_vkDebugMarkerSetObjectTagEXT; 689 if (dev->debug_marker_enabled && !strcmp(name, "DebugMarkerSetObjectNameEXT")) 690 return (PFN_vkVoidFunction)wrap_vkDebugMarkerSetObjectNameEXT; 691 if (dev->debug_utils_enabled && !strcmp(name, "SetDebugUtilsObjectNameEXT")) 692 return (PFN_vkVoidFunction)wrap_vkSetDebugUtilsObjectNameEXT; 693 if (dev->debug_utils_enabled && !strcmp(name, "SetDebugUtilsObjectTagEXT")) 694 return (PFN_vkVoidFunction)wrap_vkSetDebugUtilsObjectTagEXT; 695 696 return NULL; 697} 698 699VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL wrap_vkGetDeviceProcAddr(VkDevice device, const char *funcName) { 700 PFN_vkVoidFunction addr; 701 702 if (!strcmp("vkGetDeviceProcAddr", funcName)) { 703 return (PFN_vkVoidFunction)wrap_vkGetDeviceProcAddr; 704 } 705 706 if (device == VK_NULL_HANDLE) { 707 return NULL; 708 } 709 710 wrapped_dev_obj *dev; 711 unwrap_device(device, &dev); 712 713 addr = layer_intercept_device_proc(dev, funcName); 714 if (addr) return addr; 715 716 return dev->pfn_get_dev_proc_addr(dev->obj, funcName); 717} 718 719PFN_vkVoidFunction layer_intercept_instance_proc(wrapped_inst_obj *inst, const char *name) { 720 if (!name || name[0] != 'v' || name[1] != 'k') return NULL; 721 722 name += 2; 723 if (!strcmp(name, "DestroyInstance")) return (PFN_vkVoidFunction)wrap_vkDestroyInstance; 724 if (!strcmp(name, "CreateDevice")) return (PFN_vkVoidFunction)wrap_vkCreateDevice; 725 if (!strcmp(name, "EnumeratePhysicalDevices")) return (PFN_vkVoidFunction)wrap_vkEnumeratePhysicalDevices; 726 727 if (!strcmp(name, "EnumerateDeviceExtensionProperties")) return (PFN_vkVoidFunction)wrap_vkEnumerateDeviceExtensionProperties; 728 729 if (!strcmp(name, "CreateDebugUtilsMessengerEXT")) return (PFN_vkVoidFunction)wrap_vkCreateDebugUtilsMessengerEXT; 730 if (!strcmp(name, "DestroyDebugUtilsMessengerEXT")) return (PFN_vkVoidFunction)wrap_vkDestroyDebugUtilsMessengerEXT; 731 732 if (!strcmp(name, "GetPhysicalDeviceProperties")) return (PFN_vkVoidFunction)vkGetPhysicalDeviceProperties; 733 if (!strcmp(name, "GetPhysicalDeviceQueueFamilyProperties")) 734 return (PFN_vkVoidFunction)wrap_vkGetPhysicalDeviceQueueFamilyProperties; 735 736#if defined(VK_USE_PLATFORM_ANDROID_KHR) 737 if (!strcmp(name, "CreateAndroidSurfaceKHR")) return (PFN_vkVoidFunction)wrap_vkCreateAndroidSurfaceKHR; 738#endif // VK_USE_PLATFORM_ANDROID_KHR 739 740#if defined(VK_USE_PLATFORM_WIN32_KHR) 741 if (!strcmp(name, "CreateWin32SurfaceKHR")) return (PFN_vkVoidFunction)wrap_vkCreateWin32SurfaceKHR; 742#endif // VK_USE_PLATFORM_WIN32_KHR 743 744#if defined(VK_USE_PLATFORM_WAYLAND_KHR) 745 if (!strcmp(name, "CreateWaylandSurfaceKHR")) return (PFN_vkVoidFunction)wrap_vkCreateWaylandSurfaceKHR; 746#endif // VK_USE_PLATFORM_WAYLAND_KHR 747 748#if defined(VK_USE_PLATFORM_XCB_KHR) 749 if (!strcmp(name, "CreateXcbSurfaceKHR")) return (PFN_vkVoidFunction)wrap_vkCreateXcbSurfaceKHR; 750#endif // VK_USE_PLATFORM_XCB_KHR 751 752#if defined(VK_USE_PLATFORM_XLIB_KHR) 753 if (!strcmp(name, "CreateXlibSurfaceKHR")) return (PFN_vkVoidFunction)wrap_vkCreateXlibSurfaceKHR; 754#endif // VK_USE_PLATFORM_XLIB_KHR 755 756#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) 757 if (!strcmp(name, "CreateDirectFBSurfaceEXT")) return (PFN_vkVoidFunction)wrap_vkCreateDirectFBSurfaceEXT; 758#endif // VK_USE_PLATFORM_DIRECTFB_EXT 759 760#if defined(VK_USE_PLATFORM_MACOS_MVK) 761 if (!strcmp(name, "CreateMacOSSurfaceMVK")) return (PFN_vkVoidFunction)wrap_vkCreateMacOSSurfaceMVK; 762#endif // VK_USE_PLATFORM_MACOS_MVK 763 764#if defined(VK_USE_PLATFORM_IOS_MVK) 765 if (!strcmp(name, "CreateIOSSurfaceMVK")) return (PFN_vkVoidFunction)wrap_vkCreateIOSSurfaceMVK; 766#endif // VK_USE_PLATFORM_IOS_MVK 767 768#if defined(VK_USE_PLATFORM_GGP) 769 if (!strcmp(name, "CreateStreamDescriptorSurfaceGGP")) return (PFN_vkVoidFunction)wrap_vkCreateStreamDescriptorSurfaceGGP; 770#endif // VK_USE_PLATFORM_GGP 771 772#if defined(VK_USE_PLATFORM_METAL_EXT) 773 if (!strcmp(name, "CreateMetalSurfaceEXT")) return (PFN_vkVoidFunction)wrap_vkCreateMetalSurfaceEXT; 774#endif // VK_USE_PLATFORM_METAL_EXT 775 776#if defined(VK_USE_PLATFORM_SCREEN_QNX) 777 if (!strcmp(name, "CreateScreenSurfaceQNX")) return (PFN_vkVoidFunction)wrap_vkCreateScreenSurfaceQNX; 778#endif // VK_USE_PLATFORM_SCREEN_QNX 779 if (!strcmp(name, "DestroySurfaceKHR")) return (PFN_vkVoidFunction)wrap_vkDestroySurfaceKHR; 780 781 if (inst->direct_display_enabled && !strcmp(name, "ReleaseDisplayEXT")) return (PFN_vkVoidFunction)wrap_vkReleaseDisplayEXT; 782 if (inst->display_surf_counter_enabled && !strcmp(name, "GetPhysicalDeviceSurfaceCapabilities2EXT")) 783 return (PFN_vkVoidFunction)wrap_vkGetPhysicalDeviceSurfaceCapabilities2EXT; 784 785 // instance_proc needs to be able to query device commands even if the extension isn't enabled (because it isn't known at this 786 // time) 787 if (!strcmp(name, "TrimCommandPoolKHR")) return (PFN_vkVoidFunction)wrap_vkTrimCommandPoolKHR; 788 if (!strcmp(name, "GetSwapchainStatusKHR")) return (PFN_vkVoidFunction)wrap_vkGetSwapchainStatusKHR; 789 790 if (!strcmp(name, "DebugMarkerSetObjectTagEXT")) return (PFN_vkVoidFunction)wrap_vkDebugMarkerSetObjectTagEXT; 791 if (!strcmp(name, "DebugMarkerSetObjectNameEXT")) return (PFN_vkVoidFunction)wrap_vkDebugMarkerSetObjectNameEXT; 792 if (inst->debug_utils_enabled && !strcmp(name, "SetDebugUtilsObjectNameEXT")) 793 return (PFN_vkVoidFunction)wrap_vkSetDebugUtilsObjectNameEXT; 794 if (inst->debug_utils_enabled && !strcmp(name, "SetDebugUtilsObjectTagEXT")) 795 return (PFN_vkVoidFunction)wrap_vkSetDebugUtilsObjectTagEXT; 796 797 return NULL; 798} 799 800VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL wrap_vkGetInstanceProcAddr(VkInstance instance, const char *funcName) { 801 PFN_vkVoidFunction addr; 802 803 if (!strcmp(funcName, "vkGetInstanceProcAddr")) return (PFN_vkVoidFunction)wrap_vkGetInstanceProcAddr; 804 if (!strcmp(funcName, "vkCreateInstance")) return (PFN_vkVoidFunction)wrap_vkCreateInstance; 805 806 if (instance == VK_NULL_HANDLE) { 807 return NULL; 808 } 809 810 wrapped_inst_obj *inst; 811 unwrap_instance(instance, &inst); 812 813 addr = layer_intercept_instance_proc(inst, funcName); 814 if (addr) return addr; 815 816 VkLayerInstanceDispatchTable *pTable = &inst->layer_disp; 817 818 if (pTable->GetInstanceProcAddr == NULL) return NULL; 819 return pTable->GetInstanceProcAddr(inst->obj, funcName); 820} 821 822VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) { 823 assert(instance); 824 825 wrapped_inst_obj *inst; 826 unwrap_instance(instance, &inst); 827 VkLayerInstanceDispatchTable *pTable = &inst->layer_disp; 828 829 if (pTable->GetPhysicalDeviceProcAddr == NULL) return NULL; 830 return pTable->GetPhysicalDeviceProcAddr(inst->obj, funcName); 831} 832 833} // namespace wrap_objects 834 835extern "C" { 836// loader-layer interface v0, just wrappers since there is only a layer 837VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) { 838 return wrap_objects::wrap_vkGetInstanceProcAddr(instance, funcName); 839} 840 841VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char *funcName) { 842 return wrap_objects::wrap_vkGetDeviceProcAddr(device, funcName); 843} 844 845VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *, uint32_t *, 846 VkExtensionProperties *) { 847 assert(0); // TODO return wrap_objects::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties); 848 return VK_SUCCESS; 849} 850 851VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *, VkLayerProperties *) { 852 assert(0); // TODO return wrap_objects::EnumerateInstanceLayerProperties(pCount, pProperties); 853 return VK_SUCCESS; 854} 855 856VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 857vkEnumerateDeviceExtensionProperties([[maybe_unused]] VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pCount, 858 VkExtensionProperties *pProperties) { 859 // the layer command handles VK_NULL_HANDLE just fine internally 860 assert(physicalDevice == VK_NULL_HANDLE); 861 return wrap_objects::wrap_vkEnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties); 862} 863 864VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugUtilsMessengerEXT(VkInstance instance, 865 const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, 866 const VkAllocationCallbacks *pAllocator, 867 VkDebugUtilsMessengerEXT *pMessenger) { 868 return wrap_objects::wrap_vkCreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger); 869} 870 871VKAPI_ATTR void VKAPI_CALL vkDestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger, 872 const VkAllocationCallbacks *pAllocator) { 873 return wrap_objects::wrap_vkDestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator); 874} 875 876VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator) { 877 return wrap_objects::wrap_vkDestroySurfaceKHR(instance, surface, pAllocator); 878} 879 880#if defined(VK_USE_PLATFORM_ANDROID_KHR) 881VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR *pCreateInfo, 882 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 883 return wrap_objects::wrap_vkCreateAndroidSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); 884} 885#endif // VK_USE_PLATFORM_WIN32_KHR 886 887#if defined(VK_USE_PLATFORM_WIN32_KHR) 888VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, 889 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 890 return wrap_objects::wrap_vkCreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); 891} 892#endif // VK_USE_PLATFORM_WIN32_KHR 893 894#if defined(VK_USE_PLATFORM_WAYLAND_KHR) 895VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, 896 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 897 return wrap_objects::wrap_vkCreateWaylandSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); 898} 899#endif // VK_USE_PLATFORM_WAYLAND_KHR 900 901#if defined(VK_USE_PLATFORM_XCB_KHR) 902VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo, 903 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 904 return wrap_objects::wrap_vkCreateXcbSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); 905} 906#endif // VK_USE_PLATFORM_XCB_KHR 907 908#if defined(VK_USE_PLATFORM_XLIB_KHR) 909VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo, 910 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 911 return wrap_objects::wrap_vkCreateXlibSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); 912} 913#endif // VK_USE_PLATFORM_XLIB_KHR 914 915#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) 916VKAPI_ATTR VkResult VKAPI_CALL vkCreateDirectFBSurfaceEXT(VkInstance instance, const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo, 917 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 918 return wrap_objects::wrap_vkCreateDirectFBSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface); 919} 920#endif // VK_USE_PLATFORM_DIRECTFB_EXT 921 922#if defined(VK_USE_PLATFORM_MACOS_MVK) 923VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo, 924 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 925 return wrap_objects::wrap_vkCreateMacOSSurfaceMVK(instance, pCreateInfo, pAllocator, pSurface); 926} 927#endif // VK_USE_PLATFORM_MACOS_MVK 928 929#if defined(VK_USE_PLATFORM_IOS_MVK) 930VKAPI_ATTR VkResult VKAPI_CALL vkCreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo, 931 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 932 return wrap_objects::wrap_vkCreateIOSSurfaceMVK(instance, pCreateInfo, pAllocator, pSurface); 933} 934#endif // VK_USE_PLATFORM_IOS_MVK 935 936#if defined(VK_USE_PLATFORM_GGP) 937VKAPI_ATTR VkResult VKAPI_CALL vkCreateStreamDescriptorSurfaceGGP(VkInstance instance, 938 const VkStreamDescriptorSurfaceCreateInfoGGP *pCreateInfo, 939 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 940 return wrap_objects::wrap_vkCreateStreamDescriptorSurfaceGGP(instance, pCreateInfo, pAllocator, pSurface); 941} 942#endif // VK_USE_PLATFORM_GGP 943 944#if defined(VK_USE_PLATFORM_METAL_EXT) 945VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT *pCreateInfo, 946 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 947 return wrap_objects::wrap_vkCreateMetalSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface); 948} 949#endif // VK_USE_PLATFORM_METAL_EXT 950 951#if defined(VK_USE_PLATFORM_SCREEN_QNX) 952VKAPI_ATTR VkResult VKAPI_CALL vkCreateScreenSurfaceQNX(VkInstance instance, const VkScreenSurfaceCreateInfoQNX *pCreateInfo, 953 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 954 return wrap_objects::wrap_vkCreateScreenSurfaceQNX(instance, pCreateInfo, pAllocator, pSurface); 955} 956#endif // VK_USE_PLATFORM_SCREEN_QNX 957 958VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance, 959 const char *funcName) { 960 return wrap_objects::GetPhysicalDeviceProcAddr(instance, funcName); 961} 962 963VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface *pVersionStruct) { 964 assert(pVersionStruct != NULL); 965 assert(pVersionStruct->sType == LAYER_NEGOTIATE_INTERFACE_STRUCT); 966 967 // Fill in the function pointers if our version is at least capable of having the structure contain them. 968 if (pVersionStruct->loaderLayerInterfaceVersion >= 2) { 969 pVersionStruct->pfnGetInstanceProcAddr = wrap_objects::wrap_vkGetInstanceProcAddr; 970 pVersionStruct->pfnGetDeviceProcAddr = wrap_objects::wrap_vkGetDeviceProcAddr; 971 pVersionStruct->pfnGetPhysicalDeviceProcAddr = vk_layerGetPhysicalDeviceProcAddr; 972 } 973 974 if (pVersionStruct->loaderLayerInterfaceVersion < CURRENT_LOADER_LAYER_INTERFACE_VERSION) { 975 wrap_objects::loader_layer_if_version = pVersionStruct->loaderLayerInterfaceVersion; 976 } else if (pVersionStruct->loaderLayerInterfaceVersion > CURRENT_LOADER_LAYER_INTERFACE_VERSION) { 977 pVersionStruct->loaderLayerInterfaceVersion = CURRENT_LOADER_LAYER_INTERFACE_VERSION; 978 } 979 980 return VK_SUCCESS; 981} 982} 983