diff options
-rw-r--r-- | loader/extension_manual.c | 34 | ||||
-rw-r--r-- | loader/generated/vk_loader_extensions.c | 388 | ||||
-rw-r--r-- | loader/generated/vk_loader_extensions.h | 48 | ||||
-rw-r--r-- | loader/loader.c | 46 | ||||
-rw-r--r-- | loader/loader_common.h | 1 | ||||
-rw-r--r-- | loader/wsi.c | 110 | ||||
-rw-r--r-- | scripts/loader_extension_generator.py | 312 | ||||
-rw-r--r-- | tests/framework/icd/test_icd.cpp | 17 | ||||
-rw-r--r-- | tests/framework/test_environment.cpp | 266 | ||||
-rw-r--r-- | tests/framework/test_environment.h | 16 | ||||
-rw-r--r-- | tests/framework/test_util.cpp | 5 | ||||
-rw-r--r-- | tests/framework/test_util.h | 1 | ||||
-rw-r--r-- | tests/loader_handle_validation_tests.cpp | 50 | ||||
-rw-r--r-- | tests/loader_version_tests.cpp | 3 | ||||
-rw-r--r-- | tests/loader_wsi_tests.cpp | 87 |
15 files changed, 775 insertions, 609 deletions
diff --git a/loader/extension_manual.c b/loader/extension_manual.c index 196df20b1..50cc720fd 100644 --- a/loader/extension_manual.c +++ b/loader/extension_manual.c @@ -307,18 +307,30 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModes2EXT( uint32_t icd_index = 0; struct loader_device *dev; struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); - if (NULL != icd_term && NULL != icd_term->dispatch.GetDeviceGroupSurfacePresentModes2EXT) { - VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pSurfaceInfo->surface; - if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[icd_index]) { - VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy; - surface_info_copy.sType = pSurfaceInfo->sType; - surface_info_copy.pNext = pSurfaceInfo->pNext; - surface_info_copy.surface = icd_surface->real_icd_surfaces[icd_index]; - return icd_term->dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, &surface_info_copy, pModes); - } - return icd_term->dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, pSurfaceInfo, pModes); + if (NULL == icd_term || NULL == dev || + NULL == dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT) { + loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, + "vkGetDeviceGroupSurfacePresentModes2EXT Terminator: Invalid device handle. This is likely the result of a " + "layer wrapping device handles and failing to unwrap them in all functions. " + "[VUID-vkGetDeviceGroupSurfacePresentModes2EXT-device-parameter]"); + abort(); /* Intentionally fail so user can correct issue. */ + } + if (NULL == pSurfaceInfo) { + loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, + "vkGetDeviceGroupSurfacePresentModes2EXT: Invalid pSurfaceInfo pointer " + "[VUID-vkGetDeviceGroupSurfacePresentModes2EXT-pSurfaceInfo-parameter]"); + abort(); /* Intentionally fail so user can correct issue. */ + } + VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pSurfaceInfo->surface; + if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[icd_index]) { + VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy; + surface_info_copy.sType = pSurfaceInfo->sType; + surface_info_copy.pNext = pSurfaceInfo->pNext; + surface_info_copy.surface = icd_surface->real_icd_surfaces[icd_index]; + return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, &surface_info_copy, + pModes); } - return VK_SUCCESS; + return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, pSurfaceInfo, pModes); } #endif // VK_USE_PLATFORM_WIN32_KHR diff --git a/loader/generated/vk_loader_extensions.c b/loader/generated/vk_loader_extensions.c index 4960ab816..9ae9350cf 100644 --- a/loader/generated/vk_loader_extensions.c +++ b/loader/generated/vk_loader_extensions.c @@ -98,8 +98,6 @@ VKAPI_ATTR bool VKAPI_CALL loader_icd_init_entries(struct loader_icd_term *icd_t LOOKUP_GIPA(GetPhysicalDeviceSurfacePresentModesKHR, false); // ---- VK_KHR_swapchain extension commands - LOOKUP_GIPA(CreateSwapchainKHR, false); - LOOKUP_GIPA(GetDeviceGroupSurfacePresentModesKHR, false); LOOKUP_GIPA(GetPhysicalDevicePresentRectanglesKHR, false); // ---- VK_KHR_display extension commands @@ -111,9 +109,6 @@ VKAPI_ATTR bool VKAPI_CALL loader_icd_init_entries(struct loader_icd_term *icd_t LOOKUP_GIPA(GetDisplayPlaneCapabilitiesKHR, false); LOOKUP_GIPA(CreateDisplayPlaneSurfaceKHR, false); - // ---- VK_KHR_display_swapchain extension commands - LOOKUP_GIPA(CreateSharedSwapchainsKHR, false); - // ---- VK_KHR_xlib_surface extension commands #ifdef VK_USE_PLATFORM_XLIB_KHR LOOKUP_GIPA(CreateXlibSurfaceKHR, false); @@ -202,10 +197,6 @@ VKAPI_ATTR bool VKAPI_CALL loader_icd_init_entries(struct loader_icd_term *icd_t LOOKUP_GIPA(DestroyDebugReportCallbackEXT, false); LOOKUP_GIPA(DebugReportMessageEXT, false); - // ---- VK_EXT_debug_marker extension commands - LOOKUP_GIPA(DebugMarkerSetObjectTagEXT, false); - LOOKUP_GIPA(DebugMarkerSetObjectNameEXT, false); - // ---- VK_GGP_stream_descriptor_surface extension commands #ifdef VK_USE_PLATFORM_GGP LOOKUP_GIPA(CreateStreamDescriptorSurfaceGGP, false); @@ -244,14 +235,6 @@ VKAPI_ATTR bool VKAPI_CALL loader_icd_init_entries(struct loader_icd_term *icd_t #endif // VK_USE_PLATFORM_MACOS_MVK // ---- VK_EXT_debug_utils extension commands - LOOKUP_GIPA(SetDebugUtilsObjectNameEXT, false); - LOOKUP_GIPA(SetDebugUtilsObjectTagEXT, false); - LOOKUP_GIPA(QueueBeginDebugUtilsLabelEXT, false); - LOOKUP_GIPA(QueueEndDebugUtilsLabelEXT, false); - LOOKUP_GIPA(QueueInsertDebugUtilsLabelEXT, false); - LOOKUP_GIPA(CmdBeginDebugUtilsLabelEXT, false); - LOOKUP_GIPA(CmdEndDebugUtilsLabelEXT, false); - LOOKUP_GIPA(CmdInsertDebugUtilsLabelEXT, false); LOOKUP_GIPA(CreateDebugUtilsMessengerEXT, false); LOOKUP_GIPA(DestroyDebugUtilsMessengerEXT, false); LOOKUP_GIPA(SubmitDebugUtilsMessageEXT, false); @@ -285,9 +268,6 @@ VKAPI_ATTR bool VKAPI_CALL loader_icd_init_entries(struct loader_icd_term *icd_t #ifdef VK_USE_PLATFORM_WIN32_KHR LOOKUP_GIPA(GetPhysicalDeviceSurfacePresentModes2EXT, false); #endif // VK_USE_PLATFORM_WIN32_KHR -#ifdef VK_USE_PLATFORM_WIN32_KHR - LOOKUP_GIPA(GetDeviceGroupSurfacePresentModes2EXT, false); -#endif // VK_USE_PLATFORM_WIN32_KHR // ---- VK_EXT_headless_surface extension commands LOOKUP_GIPA(CreateHeadlessSurfaceEXT, false); @@ -1364,6 +1344,48 @@ VKAPI_ATTR void VKAPI_CALL loader_init_instance_extension_dispatch_table(VkLayer table->GetPhysicalDeviceOpticalFlowImageFormatsNV = (PFN_vkGetPhysicalDeviceOpticalFlowImageFormatsNV)gpa(inst, "vkGetPhysicalDeviceOpticalFlowImageFormatsNV"); } +// Functions that required a terminator need to have a separate dispatch table which contains their corresponding +// device function. This is used in the terminators themselves. +void init_extension_device_proc_terminator_dispatch(struct loader_device *dev) { + struct loader_device_terminator_dispatch* dispatch = &dev->loader_dispatch.extension_terminator_dispatch; + PFN_vkGetDeviceProcAddr gpda = (PFN_vkGetDeviceProcAddr)dev->phys_dev_term->this_icd_term->dispatch.GetDeviceProcAddr; + // ---- VK_KHR_swapchain extension commands + if (dev->extensions.khr_swapchain_enabled) + dispatch->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpda(dev->icd_device, "vkCreateSwapchainKHR"); + if (dev->extensions.khr_swapchain_enabled) + dispatch->GetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR)gpda(dev->icd_device, "vkGetDeviceGroupSurfacePresentModesKHR"); + // ---- VK_KHR_display_swapchain extension commands + if (dev->extensions.khr_display_swapchain_enabled) + dispatch->CreateSharedSwapchainsKHR = (PFN_vkCreateSharedSwapchainsKHR)gpda(dev->icd_device, "vkCreateSharedSwapchainsKHR"); + // ---- VK_EXT_debug_marker extension commands + if (dev->extensions.ext_debug_marker_enabled) + dispatch->DebugMarkerSetObjectTagEXT = (PFN_vkDebugMarkerSetObjectTagEXT)gpda(dev->icd_device, "vkDebugMarkerSetObjectTagEXT"); + if (dev->extensions.ext_debug_marker_enabled) + dispatch->DebugMarkerSetObjectNameEXT = (PFN_vkDebugMarkerSetObjectNameEXT)gpda(dev->icd_device, "vkDebugMarkerSetObjectNameEXT"); + // ---- VK_EXT_debug_utils extension commands + if (dev->extensions.ext_debug_utils_enabled) + dispatch->SetDebugUtilsObjectNameEXT = (PFN_vkSetDebugUtilsObjectNameEXT)gpda(dev->icd_device, "vkSetDebugUtilsObjectNameEXT"); + if (dev->extensions.ext_debug_utils_enabled) + dispatch->SetDebugUtilsObjectTagEXT = (PFN_vkSetDebugUtilsObjectTagEXT)gpda(dev->icd_device, "vkSetDebugUtilsObjectTagEXT"); + if (dev->extensions.ext_debug_utils_enabled) + dispatch->QueueBeginDebugUtilsLabelEXT = (PFN_vkQueueBeginDebugUtilsLabelEXT)gpda(dev->icd_device, "vkQueueBeginDebugUtilsLabelEXT"); + if (dev->extensions.ext_debug_utils_enabled) + dispatch->QueueEndDebugUtilsLabelEXT = (PFN_vkQueueEndDebugUtilsLabelEXT)gpda(dev->icd_device, "vkQueueEndDebugUtilsLabelEXT"); + if (dev->extensions.ext_debug_utils_enabled) + dispatch->QueueInsertDebugUtilsLabelEXT = (PFN_vkQueueInsertDebugUtilsLabelEXT)gpda(dev->icd_device, "vkQueueInsertDebugUtilsLabelEXT"); + if (dev->extensions.ext_debug_utils_enabled) + dispatch->CmdBeginDebugUtilsLabelEXT = (PFN_vkCmdBeginDebugUtilsLabelEXT)gpda(dev->icd_device, "vkCmdBeginDebugUtilsLabelEXT"); + if (dev->extensions.ext_debug_utils_enabled) + dispatch->CmdEndDebugUtilsLabelEXT = (PFN_vkCmdEndDebugUtilsLabelEXT)gpda(dev->icd_device, "vkCmdEndDebugUtilsLabelEXT"); + if (dev->extensions.ext_debug_utils_enabled) + dispatch->CmdInsertDebugUtilsLabelEXT = (PFN_vkCmdInsertDebugUtilsLabelEXT)gpda(dev->icd_device, "vkCmdInsertDebugUtilsLabelEXT"); +#ifdef VK_USE_PLATFORM_WIN32_KHR + // ---- VK_EXT_full_screen_exclusive extension commands + if (dev->extensions.ext_full_screen_exclusive_enabled && dev->extensions.khr_device_group_enabled) + dispatch->GetDeviceGroupSurfacePresentModes2EXT = (PFN_vkGetDeviceGroupSurfacePresentModes2EXT)gpda(dev->icd_device, "vkGetDeviceGroupSurfacePresentModes2EXT"); +#endif // None +} + // Device command lookup function VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDispatchTable *table, const char *name) { if (!name || name[0] != 'v' || name[1] != 'k') return NULL; @@ -3928,26 +3950,26 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_DebugMarkerSetObjectTagEXT( uint32_t icd_index = 0; struct loader_device *dev; struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); - if (NULL != icd_term && NULL != icd_term->dispatch.DebugMarkerSetObjectTagEXT) { - VkDebugMarkerObjectTagInfoEXT local_tag_info; - memcpy(&local_tag_info, pTagInfo, sizeof(VkDebugMarkerObjectTagInfoEXT)); - // If this is a physical device, we have to replace it with the proper one for the next call. - if (pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) { - struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t)pTagInfo->object; - local_tag_info.object = (uint64_t)(uintptr_t)phys_dev_term->phys_dev; - // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call. - } else if (pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) { - if (NULL != icd_term && NULL != icd_term->dispatch.CreateSwapchainKHR) { - VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pTagInfo->object; - if (NULL != icd_surface->real_icd_surfaces) { - local_tag_info.object = (uint64_t)icd_surface->real_icd_surfaces[icd_index]; - } + if (NULL == icd_term || NULL == dev || NULL == dev->loader_dispatch.extension_terminator_dispatch.DebugMarkerSetObjectTagEXT) { + loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "DebugMarkerSetObjectTagEXT: Invalid device handle"); + abort(); /* Intentionally fail so user can correct issue. */ + } + VkDebugMarkerObjectTagInfoEXT local_tag_info; + memcpy(&local_tag_info, pTagInfo, sizeof(VkDebugMarkerObjectTagInfoEXT)); + // If this is a physical device, we have to replace it with the proper one for the next call. + if (pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) { + struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t)pTagInfo->object; + local_tag_info.object = (uint64_t)(uintptr_t)phys_dev_term->phys_dev; + // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call. + } else if (pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) { + if (NULL != dev && NULL != dev->loader_dispatch.core_dispatch.CreateSwapchainKHR) { + VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pTagInfo->object; + if (NULL != icd_surface->real_icd_surfaces) { + local_tag_info.object = (uint64_t)icd_surface->real_icd_surfaces[icd_index]; } } - return icd_term->dispatch.DebugMarkerSetObjectTagEXT(device, &local_tag_info); - } else { - return VK_SUCCESS; } + return dev->loader_dispatch.extension_terminator_dispatch.DebugMarkerSetObjectTagEXT(device, &local_tag_info); } VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectNameEXT( @@ -3976,26 +3998,26 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_DebugMarkerSetObjectNameEXT( uint32_t icd_index = 0; struct loader_device *dev; struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); - if (NULL != icd_term && NULL != icd_term->dispatch.DebugMarkerSetObjectNameEXT) { - VkDebugMarkerObjectNameInfoEXT local_name_info; - memcpy(&local_name_info, pNameInfo, sizeof(VkDebugMarkerObjectNameInfoEXT)); - // If this is a physical device, we have to replace it with the proper one for the next call. - if (pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) { - struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t)pNameInfo->object; - local_name_info.object = (uint64_t)(uintptr_t)phys_dev_term->phys_dev; - // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call. - } else if (pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) { - if (NULL != icd_term && NULL != icd_term->dispatch.CreateSwapchainKHR) { - VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pNameInfo->object; - if (NULL != icd_surface->real_icd_surfaces) { - local_name_info.object = (uint64_t)icd_surface->real_icd_surfaces[icd_index]; - } + if (NULL == icd_term || NULL == dev || NULL == dev->loader_dispatch.extension_terminator_dispatch.DebugMarkerSetObjectNameEXT) { + loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "DebugMarkerSetObjectNameEXT: Invalid device handle"); + abort(); /* Intentionally fail so user can correct issue. */ + } + VkDebugMarkerObjectNameInfoEXT local_name_info; + memcpy(&local_name_info, pNameInfo, sizeof(VkDebugMarkerObjectNameInfoEXT)); + // If this is a physical device, we have to replace it with the proper one for the next call. + if (pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) { + struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t)pNameInfo->object; + local_name_info.object = (uint64_t)(uintptr_t)phys_dev_term->phys_dev; + // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call. + } else if (pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) { + if (NULL != dev && NULL != dev->loader_dispatch.core_dispatch.CreateSwapchainKHR) { + VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pNameInfo->object; + if (NULL != icd_surface->real_icd_surfaces) { + local_name_info.object = (uint64_t)icd_surface->real_icd_surfaces[icd_index]; } } - return icd_term->dispatch.DebugMarkerSetObjectNameEXT(device, &local_name_info); - } else { - return VK_SUCCESS; } + return dev->loader_dispatch.extension_terminator_dispatch.DebugMarkerSetObjectNameEXT(device, &local_name_info); } VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerBeginEXT( @@ -4530,26 +4552,26 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_SetDebugUtilsObjectNameEXT( uint32_t icd_index = 0; struct loader_device *dev; struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); - if (NULL != icd_term && NULL != icd_term->dispatch.SetDebugUtilsObjectNameEXT) { - VkDebugUtilsObjectNameInfoEXT local_name_info; - memcpy(&local_name_info, pNameInfo, sizeof(VkDebugUtilsObjectNameInfoEXT)); - // If this is a physical device, we have to replace it with the proper one for the next call. - if (pNameInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) { - struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t)pNameInfo->objectHandle; - local_name_info.objectHandle = (uint64_t)(uintptr_t)phys_dev_term->phys_dev; - // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call. - } else if (pNameInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) { - if (NULL != icd_term && NULL != icd_term->dispatch.CreateSwapchainKHR) { - VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pNameInfo->objectHandle; - if (NULL != icd_surface->real_icd_surfaces) { - local_name_info.objectHandle = (uint64_t)icd_surface->real_icd_surfaces[icd_index]; - } + if (NULL == icd_term || NULL == dev || NULL == dev->loader_dispatch.extension_terminator_dispatch.SetDebugUtilsObjectNameEXT) { + loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "SetDebugUtilsObjectNameEXT: Invalid device handle"); + abort(); /* Intentionally fail so user can correct issue. */ + } + VkDebugUtilsObjectNameInfoEXT local_name_info; + memcpy(&local_name_info, pNameInfo, sizeof(VkDebugUtilsObjectNameInfoEXT)); + // If this is a physical device, we have to replace it with the proper one for the next call. + if (pNameInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) { + struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t)pNameInfo->objectHandle; + local_name_info.objectHandle = (uint64_t)(uintptr_t)phys_dev_term->phys_dev; + // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call. + } else if (pNameInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) { + if (NULL != dev && NULL != dev->loader_dispatch.core_dispatch.CreateSwapchainKHR) { + VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pNameInfo->objectHandle; + if (NULL != icd_surface->real_icd_surfaces) { + local_name_info.objectHandle = (uint64_t)icd_surface->real_icd_surfaces[icd_index]; } } - return icd_term->dispatch.SetDebugUtilsObjectNameEXT(device, &local_name_info); - } else { - return VK_SUCCESS; } + return dev->loader_dispatch.extension_terminator_dispatch.SetDebugUtilsObjectNameEXT(device, &local_name_info); } VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectTagEXT( @@ -4582,26 +4604,26 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_SetDebugUtilsObjectTagEXT( uint32_t icd_index = 0; struct loader_device *dev; struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); - if (NULL != icd_term && NULL != icd_term->dispatch.SetDebugUtilsObjectTagEXT) { - VkDebugUtilsObjectTagInfoEXT local_tag_info; - memcpy(&local_tag_info, pTagInfo, sizeof(VkDebugUtilsObjectTagInfoEXT)); - // If this is a physical device, we have to replace it with the proper one for the next call. - if (pTagInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) { - struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t)pTagInfo->objectHandle; - local_tag_info.objectHandle = (uint64_t)(uintptr_t)phys_dev_term->phys_dev; - // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call. - } else if (pTagInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) { - if (NULL != icd_term && NULL != icd_term->dispatch.CreateSwapchainKHR) { - VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pTagInfo->objectHandle; - if (NULL != icd_surface->real_icd_surfaces) { - local_tag_info.objectHandle = (uint64_t)icd_surface->real_icd_surfaces[icd_index]; - } + if (NULL == icd_term || NULL == dev || NULL == dev->loader_dispatch.extension_terminator_dispatch.SetDebugUtilsObjectTagEXT) { + loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "SetDebugUtilsObjectTagEXT: Invalid device handle"); + abort(); /* Intentionally fail so user can correct issue. */ + } + VkDebugUtilsObjectTagInfoEXT local_tag_info; + memcpy(&local_tag_info, pTagInfo, sizeof(VkDebugUtilsObjectTagInfoEXT)); + // If this is a physical device, we have to replace it with the proper one for the next call. + if (pTagInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) { + struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t)pTagInfo->objectHandle; + local_tag_info.objectHandle = (uint64_t)(uintptr_t)phys_dev_term->phys_dev; + // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call. + } else if (pTagInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) { + if (NULL != dev && NULL != dev->loader_dispatch.core_dispatch.CreateSwapchainKHR) { + VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pTagInfo->objectHandle; + if (NULL != icd_surface->real_icd_surfaces) { + local_tag_info.objectHandle = (uint64_t)icd_surface->real_icd_surfaces[icd_index]; } } - return icd_term->dispatch.SetDebugUtilsObjectTagEXT(device, &local_tag_info); - } else { - return VK_SUCCESS; } + return dev->loader_dispatch.extension_terminator_dispatch.SetDebugUtilsObjectTagEXT(device, &local_tag_info); } VKAPI_ATTR void VKAPI_CALL QueueBeginDebugUtilsLabelEXT( @@ -4622,12 +4644,14 @@ VKAPI_ATTR void VKAPI_CALL QueueBeginDebugUtilsLabelEXT( VKAPI_ATTR void VKAPI_CALL terminator_QueueBeginDebugUtilsLabelEXT( VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo) { - uint32_t icd_index = 0; - struct loader_device *dev; - struct loader_icd_term *icd_term = loader_get_icd_and_device(queue, &dev, &icd_index); - if (NULL != icd_term && NULL != icd_term->dispatch.QueueBeginDebugUtilsLabelEXT) { - icd_term->dispatch.QueueBeginDebugUtilsLabelEXT(queue, pLabelInfo); + struct loader_dev_dispatch_table *dispatch_table = loader_get_dev_dispatch(queue); + if (NULL == dispatch_table) { + loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "VK_EXT_debug_utils: Invalid device handle"); + abort(); /* Intentionally fail so user can correct issue. */ } + // Only call down if the device supports the function + if (NULL != dispatch_table->extension_terminator_dispatch.QueueBeginDebugUtilsLabelEXT) + dispatch_table->extension_terminator_dispatch.QueueBeginDebugUtilsLabelEXT(queue, pLabelInfo); } VKAPI_ATTR void VKAPI_CALL QueueEndDebugUtilsLabelEXT( @@ -4646,12 +4670,14 @@ VKAPI_ATTR void VKAPI_CALL QueueEndDebugUtilsLabelEXT( VKAPI_ATTR void VKAPI_CALL terminator_QueueEndDebugUtilsLabelEXT( VkQueue queue) { - uint32_t icd_index = 0; - struct loader_device *dev; - struct loader_icd_term *icd_term = loader_get_icd_and_device(queue, &dev, &icd_index); - if (NULL != icd_term && NULL != icd_term->dispatch.QueueEndDebugUtilsLabelEXT) { - icd_term->dispatch.QueueEndDebugUtilsLabelEXT(queue); + struct loader_dev_dispatch_table *dispatch_table = loader_get_dev_dispatch(queue); + if (NULL == dispatch_table) { + loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "VK_EXT_debug_utils: Invalid device handle"); + abort(); /* Intentionally fail so user can correct issue. */ } + // Only call down if the device supports the function + if (NULL != dispatch_table->extension_terminator_dispatch.QueueEndDebugUtilsLabelEXT) + dispatch_table->extension_terminator_dispatch.QueueEndDebugUtilsLabelEXT(queue); } VKAPI_ATTR void VKAPI_CALL QueueInsertDebugUtilsLabelEXT( @@ -4672,12 +4698,14 @@ VKAPI_ATTR void VKAPI_CALL QueueInsertDebugUtilsLabelEXT( VKAPI_ATTR void VKAPI_CALL terminator_QueueInsertDebugUtilsLabelEXT( VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo) { - uint32_t icd_index = 0; - struct loader_device *dev; - struct loader_icd_term *icd_term = loader_get_icd_and_device(queue, &dev, &icd_index); - if (NULL != icd_term && NULL != icd_term->dispatch.QueueInsertDebugUtilsLabelEXT) { - icd_term->dispatch.QueueInsertDebugUtilsLabelEXT(queue, pLabelInfo); + struct loader_dev_dispatch_table *dispatch_table = loader_get_dev_dispatch(queue); + if (NULL == dispatch_table) { + loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "VK_EXT_debug_utils: Invalid device handle"); + abort(); /* Intentionally fail so user can correct issue. */ } + // Only call down if the device supports the function + if (NULL != dispatch_table->extension_terminator_dispatch.QueueInsertDebugUtilsLabelEXT) + dispatch_table->extension_terminator_dispatch.QueueInsertDebugUtilsLabelEXT(queue, pLabelInfo); } VKAPI_ATTR void VKAPI_CALL CmdBeginDebugUtilsLabelEXT( @@ -4698,12 +4726,14 @@ VKAPI_ATTR void VKAPI_CALL CmdBeginDebugUtilsLabelEXT( VKAPI_ATTR void VKAPI_CALL terminator_CmdBeginDebugUtilsLabelEXT( VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT* pLabelInfo) { - uint32_t icd_index = 0; - struct loader_device *dev; - struct loader_icd_term *icd_term = loader_get_icd_and_device(commandBuffer, &dev, &icd_index); - if (NULL != icd_term && NULL != icd_term->dispatch.CmdBeginDebugUtilsLabelEXT) { - icd_term->dispatch.CmdBeginDebugUtilsLabelEXT(commandBuffer, pLabelInfo); + struct loader_dev_dispatch_table *dispatch_table = loader_get_dev_dispatch(commandBuffer); + if (NULL == dispatch_table) { + loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "VK_EXT_debug_utils: Invalid device handle"); + abort(); /* Intentionally fail so user can correct issue. */ } + // Only call down if the device supports the function + if (NULL != dispatch_table->extension_terminator_dispatch.CmdBeginDebugUtilsLabelEXT) + dispatch_table->extension_terminator_dispatch.CmdBeginDebugUtilsLabelEXT(commandBuffer, pLabelInfo); } VKAPI_ATTR void VKAPI_CALL CmdEndDebugUtilsLabelEXT( @@ -4722,12 +4752,14 @@ VKAPI_ATTR void VKAPI_CALL CmdEndDebugUtilsLabelEXT( VKAPI_ATTR void VKAPI_CALL terminator_CmdEndDebugUtilsLabelEXT( VkCommandBuffer commandBuffer) { - uint32_t icd_index = 0; - struct loader_device *dev; - struct loader_icd_term *icd_term = loader_get_icd_and_device(commandBuffer, &dev, &icd_index); - if (NULL != icd_term && NULL != icd_term->dispatch.CmdEndDebugUtilsLabelEXT) { - icd_term->dispatch.CmdEndDebugUtilsLabelEXT(commandBuffer); + struct loader_dev_dispatch_table *dispatch_table = loader_get_dev_dispatch(commandBuffer); + if (NULL == dispatch_table) { + loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "VK_EXT_debug_utils: Invalid device handle"); + abort(); /* Intentionally fail so user can correct issue. */ } + // Only call down if the device supports the function + if (NULL != dispatch_table->extension_terminator_dispatch.CmdEndDebugUtilsLabelEXT) + dispatch_table->extension_terminator_dispatch.CmdEndDebugUtilsLabelEXT(commandBuffer); } VKAPI_ATTR void VKAPI_CALL CmdInsertDebugUtilsLabelEXT( @@ -4748,12 +4780,14 @@ VKAPI_ATTR void VKAPI_CALL CmdInsertDebugUtilsLabelEXT( VKAPI_ATTR void VKAPI_CALL terminator_CmdInsertDebugUtilsLabelEXT( VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT* pLabelInfo) { - uint32_t icd_index = 0; - struct loader_device *dev; - struct loader_icd_term *icd_term = loader_get_icd_and_device(commandBuffer, &dev, &icd_index); - if (NULL != icd_term && NULL != icd_term->dispatch.CmdInsertDebugUtilsLabelEXT) { - icd_term->dispatch.CmdInsertDebugUtilsLabelEXT(commandBuffer, pLabelInfo); + struct loader_dev_dispatch_table *dispatch_table = loader_get_dev_dispatch(commandBuffer); + if (NULL == dispatch_table) { + loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "VK_EXT_debug_utils: Invalid device handle"); + abort(); /* Intentionally fail so user can correct issue. */ } + // Only call down if the device supports the function + if (NULL != dispatch_table->extension_terminator_dispatch.CmdInsertDebugUtilsLabelEXT) + dispatch_table->extension_terminator_dispatch.CmdInsertDebugUtilsLabelEXT(commandBuffer, pLabelInfo); } @@ -9535,64 +9569,90 @@ void extensions_create_instance(struct loader_instance *ptr_instance, const VkIn // Some device commands still need a terminator because the loader needs to unwrap something about them. // In many cases, the item needing unwrapping is a VkPhysicalDevice or VkSurfaceKHR object. But there may be other items // in the future. -PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *pName) { - PFN_vkVoidFunction addr = NULL; - +PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *name, bool* found_name) { + *found_name = false; + if (!name || name[0] != 'v' || name[1] != 'k') { + return NULL; + } + name += 2; // ---- VK_KHR_swapchain extension commands - if (dev->extensions.khr_swapchain_enabled) { - if(!strcmp(pName, "vkCreateSwapchainKHR")) { - addr = (PFN_vkVoidFunction)terminator_CreateSwapchainKHR; - } else if(!strcmp(pName, "vkGetDeviceGroupSurfacePresentModesKHR")) { - addr = (PFN_vkVoidFunction)terminator_GetDeviceGroupSurfacePresentModesKHR; - } + if (!strcmp(name, "CreateSwapchainKHR")) { + *found_name = true; + return dev->extensions.khr_swapchain_enabled ? + (PFN_vkVoidFunction)terminator_CreateSwapchainKHR : NULL; + } + if (!strcmp(name, "GetDeviceGroupSurfacePresentModesKHR")) { + *found_name = true; + return dev->extensions.khr_swapchain_enabled ? + (PFN_vkVoidFunction)terminator_GetDeviceGroupSurfacePresentModesKHR : NULL; } - // ---- VK_KHR_display_swapchain extension commands - if (dev->extensions.khr_display_swapchain_enabled) { - if(!strcmp(pName, "vkCreateSharedSwapchainsKHR")) { - addr = (PFN_vkVoidFunction)terminator_CreateSharedSwapchainsKHR; - } + if (!strcmp(name, "CreateSharedSwapchainsKHR")) { + *found_name = true; + return dev->extensions.khr_display_swapchain_enabled ? + (PFN_vkVoidFunction)terminator_CreateSharedSwapchainsKHR : NULL; } - // ---- VK_EXT_debug_marker extension commands - if (dev->extensions.ext_debug_marker_enabled) { - if(!strcmp(pName, "vkDebugMarkerSetObjectTagEXT")) { - addr = (PFN_vkVoidFunction)terminator_DebugMarkerSetObjectTagEXT; - } else if(!strcmp(pName, "vkDebugMarkerSetObjectNameEXT")) { - addr = (PFN_vkVoidFunction)terminator_DebugMarkerSetObjectNameEXT; - } + if (!strcmp(name, "DebugMarkerSetObjectTagEXT")) { + *found_name = true; + return dev->extensions.ext_debug_marker_enabled ? + (PFN_vkVoidFunction)terminator_DebugMarkerSetObjectTagEXT : NULL; + } + if (!strcmp(name, "DebugMarkerSetObjectNameEXT")) { + *found_name = true; + return dev->extensions.ext_debug_marker_enabled ? + (PFN_vkVoidFunction)terminator_DebugMarkerSetObjectNameEXT : NULL; } - // ---- VK_EXT_debug_utils extension commands - if (dev->extensions.ext_debug_utils_enabled) { - if(!strcmp(pName, "vkSetDebugUtilsObjectNameEXT")) { - addr = (PFN_vkVoidFunction)terminator_SetDebugUtilsObjectNameEXT; - } else if(!strcmp(pName, "vkSetDebugUtilsObjectTagEXT")) { - addr = (PFN_vkVoidFunction)terminator_SetDebugUtilsObjectTagEXT; - } else if(!strcmp(pName, "vkQueueBeginDebugUtilsLabelEXT")) { - addr = (PFN_vkVoidFunction)terminator_QueueBeginDebugUtilsLabelEXT; - } else if(!strcmp(pName, "vkQueueEndDebugUtilsLabelEXT")) { - addr = (PFN_vkVoidFunction)terminator_QueueEndDebugUtilsLabelEXT; - } else if(!strcmp(pName, "vkQueueInsertDebugUtilsLabelEXT")) { - addr = (PFN_vkVoidFunction)terminator_QueueInsertDebugUtilsLabelEXT; - } else if(!strcmp(pName, "vkCmdBeginDebugUtilsLabelEXT")) { - addr = (PFN_vkVoidFunction)terminator_CmdBeginDebugUtilsLabelEXT; - } else if(!strcmp(pName, "vkCmdEndDebugUtilsLabelEXT")) { - addr = (PFN_vkVoidFunction)terminator_CmdEndDebugUtilsLabelEXT; - } else if(!strcmp(pName, "vkCmdInsertDebugUtilsLabelEXT")) { - addr = (PFN_vkVoidFunction)terminator_CmdInsertDebugUtilsLabelEXT; - } + if (!strcmp(name, "SetDebugUtilsObjectNameEXT")) { + *found_name = true; + return dev->extensions.ext_debug_utils_enabled ? + (PFN_vkVoidFunction)terminator_SetDebugUtilsObjectNameEXT : NULL; + } + if (!strcmp(name, "SetDebugUtilsObjectTagEXT")) { + *found_name = true; + return dev->extensions.ext_debug_utils_enabled ? + (PFN_vkVoidFunction)terminator_SetDebugUtilsObjectTagEXT : NULL; + } + if (!strcmp(name, "QueueBeginDebugUtilsLabelEXT")) { + *found_name = true; + return dev->extensions.ext_debug_utils_enabled ? + (PFN_vkVoidFunction)terminator_QueueBeginDebugUtilsLabelEXT : NULL; + } + if (!strcmp(name, "QueueEndDebugUtilsLabelEXT")) { + *found_name = true; + return dev->extensions.ext_debug_utils_enabled ? + (PFN_vkVoidFunction)terminator_QueueEndDebugUtilsLabelEXT : NULL; + } + if (!strcmp(name, "QueueInsertDebugUtilsLabelEXT")) { + *found_name = true; + return dev->extensions.ext_debug_utils_enabled ? + (PFN_vkVoidFunction)terminator_QueueInsertDebugUtilsLabelEXT : NULL; + } + if (!strcmp(name, "CmdBeginDebugUtilsLabelEXT")) { + *found_name = true; + return dev->extensions.ext_debug_utils_enabled ? + (PFN_vkVoidFunction)terminator_CmdBeginDebugUtilsLabelEXT : NULL; + } + if (!strcmp(name, "CmdEndDebugUtilsLabelEXT")) { + *found_name = true; + return dev->extensions.ext_debug_utils_enabled ? + (PFN_vkVoidFunction)terminator_CmdEndDebugUtilsLabelEXT : NULL; + } + if (!strcmp(name, "CmdInsertDebugUtilsLabelEXT")) { + *found_name = true; + return dev->extensions.ext_debug_utils_enabled ? + (PFN_vkVoidFunction)terminator_CmdInsertDebugUtilsLabelEXT : NULL; } #ifdef VK_USE_PLATFORM_WIN32_KHR - // ---- VK_EXT_full_screen_exclusive extension commands - if (dev->extensions.ext_full_screen_exclusive_enabled && dev->extensions.khr_device_group_enabled) { - if(!strcmp(pName, "vkGetDeviceGroupSurfacePresentModes2EXT")) { - addr = (PFN_vkVoidFunction)terminator_GetDeviceGroupSurfacePresentModes2EXT; - } + if (!strcmp(name, "GetDeviceGroupSurfacePresentModes2EXT")) { + *found_name = true; + return dev->extensions.ext_full_screen_exclusive_enabled && dev->extensions.khr_device_group_enabled ? + (PFN_vkVoidFunction)terminator_GetDeviceGroupSurfacePresentModes2EXT : NULL; } #endif // None - return addr; + return NULL; } // This table contains the loader's instance dispatch table, which contains diff --git a/loader/generated/vk_loader_extensions.h b/loader/generated/vk_loader_extensions.h index c0bcfa877..dfdb42b9b 100644 --- a/loader/generated/vk_loader_extensions.h +++ b/loader/generated/vk_loader_extensions.h @@ -45,7 +45,7 @@ void extensions_create_instance(struct loader_instance *ptr_instance, const VkIn // Extension interception for vkGetDeviceProcAddr function, so we can return // an appropriate terminator if this is one of those few device commands requiring // a terminator. -PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *pName); +PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *name, bool* found_name); // Dispatch table properly filled in with appropriate terminators for the // supported extensions. @@ -250,8 +250,6 @@ struct loader_icd_term_dispatch { PFN_vkGetPhysicalDeviceSurfacePresentModesKHR GetPhysicalDeviceSurfacePresentModesKHR; // ---- VK_KHR_swapchain extension commands - PFN_vkCreateSwapchainKHR CreateSwapchainKHR; - PFN_vkGetDeviceGroupSurfacePresentModesKHR GetDeviceGroupSurfacePresentModesKHR; PFN_vkGetPhysicalDevicePresentRectanglesKHR GetPhysicalDevicePresentRectanglesKHR; // ---- VK_KHR_display extension commands @@ -263,9 +261,6 @@ struct loader_icd_term_dispatch { PFN_vkGetDisplayPlaneCapabilitiesKHR GetDisplayPlaneCapabilitiesKHR; PFN_vkCreateDisplayPlaneSurfaceKHR CreateDisplayPlaneSurfaceKHR; - // ---- VK_KHR_display_swapchain extension commands - PFN_vkCreateSharedSwapchainsKHR CreateSharedSwapchainsKHR; - // ---- VK_KHR_xlib_surface extension commands #ifdef VK_USE_PLATFORM_XLIB_KHR PFN_vkCreateXlibSurfaceKHR CreateXlibSurfaceKHR; @@ -354,10 +349,6 @@ struct loader_icd_term_dispatch { PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT; PFN_vkDebugReportMessageEXT DebugReportMessageEXT; - // ---- VK_EXT_debug_marker extension commands - PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT; - PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT; - // ---- VK_GGP_stream_descriptor_surface extension commands #ifdef VK_USE_PLATFORM_GGP PFN_vkCreateStreamDescriptorSurfaceGGP CreateStreamDescriptorSurfaceGGP; @@ -396,14 +387,6 @@ struct loader_icd_term_dispatch { #endif // VK_USE_PLATFORM_MACOS_MVK // ---- VK_EXT_debug_utils extension commands - PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT; - PFN_vkSetDebugUtilsObjectTagEXT SetDebugUtilsObjectTagEXT; - PFN_vkQueueBeginDebugUtilsLabelEXT QueueBeginDebugUtilsLabelEXT; - PFN_vkQueueEndDebugUtilsLabelEXT QueueEndDebugUtilsLabelEXT; - PFN_vkQueueInsertDebugUtilsLabelEXT QueueInsertDebugUtilsLabelEXT; - PFN_vkCmdBeginDebugUtilsLabelEXT CmdBeginDebugUtilsLabelEXT; - PFN_vkCmdEndDebugUtilsLabelEXT CmdEndDebugUtilsLabelEXT; - PFN_vkCmdInsertDebugUtilsLabelEXT CmdInsertDebugUtilsLabelEXT; PFN_vkCreateDebugUtilsMessengerEXT CreateDebugUtilsMessengerEXT; PFN_vkDestroyDebugUtilsMessengerEXT DestroyDebugUtilsMessengerEXT; PFN_vkSubmitDebugUtilsMessageEXT SubmitDebugUtilsMessageEXT; @@ -437,9 +420,6 @@ struct loader_icd_term_dispatch { #ifdef VK_USE_PLATFORM_WIN32_KHR PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT GetPhysicalDeviceSurfacePresentModes2EXT; #endif // VK_USE_PLATFORM_WIN32_KHR -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkGetDeviceGroupSurfacePresentModes2EXT GetDeviceGroupSurfacePresentModes2EXT; -#endif // VK_USE_PLATFORM_WIN32_KHR // ---- VK_EXT_headless_surface extension commands PFN_vkCreateHeadlessSurfaceEXT CreateHeadlessSurfaceEXT; @@ -491,4 +471,30 @@ struct loader_instance_extension_enables { uint8_t ext_acquire_drm_display; }; +// Functions that required a terminator need to have a separate dispatch table which contains their corresponding +// device function. This is used in the terminators themselves. +struct loader_device_terminator_dispatch { + // ---- VK_KHR_swapchain extension commands + PFN_vkCreateSwapchainKHR CreateSwapchainKHR; + PFN_vkGetDeviceGroupSurfacePresentModesKHR GetDeviceGroupSurfacePresentModesKHR; + // ---- VK_KHR_display_swapchain extension commands + PFN_vkCreateSharedSwapchainsKHR CreateSharedSwapchainsKHR; + // ---- VK_EXT_debug_marker extension commands + PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT; + PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT; + // ---- VK_EXT_debug_utils extension commands + PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT; + PFN_vkSetDebugUtilsObjectTagEXT SetDebugUtilsObjectTagEXT; + PFN_vkQueueBeginDebugUtilsLabelEXT QueueBeginDebugUtilsLabelEXT; + PFN_vkQueueEndDebugUtilsLabelEXT QueueEndDebugUtilsLabelEXT; + PFN_vkQueueInsertDebugUtilsLabelEXT QueueInsertDebugUtilsLabelEXT; + PFN_vkCmdBeginDebugUtilsLabelEXT CmdBeginDebugUtilsLabelEXT; + PFN_vkCmdEndDebugUtilsLabelEXT CmdEndDebugUtilsLabelEXT; + PFN_vkCmdInsertDebugUtilsLabelEXT CmdInsertDebugUtilsLabelEXT; +#ifdef VK_USE_PLATFORM_WIN32_KHR + // ---- VK_EXT_full_screen_exclusive extension commands + PFN_vkGetDeviceGroupSurfacePresentModes2EXT GetDeviceGroupSurfacePresentModes2EXT; +#endif // None +}; + diff --git a/loader/loader.c b/loader/loader.c index ed4424f23..d79d8271f 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -3876,6 +3876,8 @@ static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpa_instance_terminator(V } // The VK_EXT_debug_utils functions need a special case here so the terminators can still be found from vkGetInstanceProcAddr + // This is because VK_EXT_debug_utils is an instance level extension with device level functions, and is 'supported' by the + // loader. There needs to be a terminator in case a driver doesn't support VK_EXT_debug_utils. if (!strcmp(pName, "vkSetDebugUtilsObjectNameEXT")) { return (PFN_vkVoidFunction)terminator_SetDebugUtilsObjectNameEXT; } @@ -3951,9 +3953,13 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpa_device_terminator(VkDevice d // object before passing the appropriate info along to the ICD. // This is why we also have to override the direct ICD call to // vkGetDeviceProcAddr to intercept those calls. - if(NULL != dev) { - PFN_vkVoidFunction addr = get_extension_device_proc_terminator(dev, pName); - if (NULL != addr) { + // If the pName is for a 'known' function but isn't available, due to + // the corresponding extension/feature not being enabled, we need to + // return NULL and not call down to the driver's GetDeviceProcAddr. + if (NULL != dev) { + bool found_name = false; + PFN_vkVoidFunction addr = get_extension_device_proc_terminator(dev, pName, &found_name); + if (found_name) { return addr; } } @@ -4702,8 +4708,8 @@ VkResult loader_create_device_chain(const VkPhysicalDevice pd, const VkDeviceCre continue; } - // Skip the layer if the handle is NULL - this is likely because the library failed to load but wasn't removed from the - // list. + // Skip the layer if the handle is NULL - this is likely because the library failed to load but wasn't removed from + // the list. if (!lib_handle) { continue; } @@ -4729,8 +4735,8 @@ VkResult loader_create_device_chain(const VkPhysicalDevice pd, const VkDeviceCre if (layerNextGDPA != NULL) { *layerNextGDPA = nextGDPA; } - // Break here because if fpGIPA is the same as callingLayer, that means a layer is trying to create a device, and - // once we don't want to continue any further as the next layer will be the calling layer + // Break here because if fpGIPA is the same as callingLayer, that means a layer is trying to create a device, + // and once we don't want to continue any further as the next layer will be the calling layer break; } @@ -4813,8 +4819,8 @@ VkResult loader_create_device_chain(const VkPhysicalDevice pd, const VkDeviceCre } dev->chain_device = created_device; - // Because we changed the pNext chain to use our own VkDeviceGroupDeviceCreateInfoKHR, we need to fixup the chain to point - // back at the original VkDeviceGroupDeviceCreateInfoKHR. + // Because we changed the pNext chain to use our own VkDeviceGroupDeviceCreateInfoKHR, we need to fixup the chain to + // point back at the original VkDeviceGroupDeviceCreateInfoKHR. VkBaseOutStructure *pNext = (VkBaseOutStructure *)loader_create_info.pNext; VkBaseOutStructure *pPrev = (VkBaseOutStructure *)&loader_create_info; while (NULL != pNext) { @@ -4839,6 +4845,9 @@ VkResult loader_create_device_chain(const VkPhysicalDevice pd, const VkDeviceCre // Initialize device dispatch table loader_init_device_dispatch_table(&dev->loader_dispatch, nextGDPA, dev->chain_device); + // Initialize the dispatch table to functions which need terminators + // These functions point directly to the driver, not the terminator functions + init_extension_device_proc_terminator_dispatch(dev); return res; } @@ -5978,7 +5987,8 @@ VkResult setup_loader_term_phys_devs(struct loader_instance *inst) { goto out; } - // Create an allocation large enough to hold both the windows sorting enumeration and non-windows physical device enumeration + // Create an allocation large enough to hold both the windows sorting enumeration and non-windows physical device + // enumeration new_phys_devs = loader_instance_heap_calloc(inst, sizeof(struct loader_physical_device_term *) * new_phys_devs_count, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); if (NULL == new_phys_devs) { @@ -6822,10 +6832,10 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups( new_phys_dev_groups[idx] = (VkPhysicalDeviceGroupPropertiesKHR *)loader_instance_heap_alloc( inst, sizeof(VkPhysicalDeviceGroupPropertiesKHR), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); if (NULL == new_phys_dev_groups[idx]) { - loader_log( - inst, VULKAN_LOADER_ERROR_BIT, 0, - "terminator_EnumeratePhysicalDeviceGroups: Failed to allocate physical device group Terminator object %d", - idx); + loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, + "terminator_EnumeratePhysicalDeviceGroups: Failed to allocate physical device group Terminator " + "object %d", + idx); total_count = idx; res = VK_ERROR_OUT_OF_HOST_MEMORY; goto out; @@ -6844,10 +6854,10 @@ out: if (NULL != new_phys_dev_groups) { // We've encountered an error, so we should free the new buffers. for (uint32_t i = 0; i < total_count; i++) { - // If an OOM occurred inside the copying of the new physical device groups into the existing array will leave - // some of the old physical device groups in the array which may have been copied into the new array, leading to - // them being freed twice. To avoid this we just make sure to not delete physical device groups which were - // copied. + // If an OOM occurred inside the copying of the new physical device groups into the existing array will + // leave some of the old physical device groups in the array which may have been copied into the new array, + // leading to them being freed twice. To avoid this we just make sure to not delete physical device groups + // which were copied. bool found = false; if (NULL != inst->phys_devs_term) { for (uint32_t old_idx = 0; old_idx < inst->phys_dev_group_count_term; old_idx++) { diff --git a/loader/loader_common.h b/loader/loader_common.h index 55584cf47..7cb225896 100644 --- a/loader/loader_common.h +++ b/loader/loader_common.h @@ -173,6 +173,7 @@ typedef VkResult(VKAPI_PTR *PFN_vkDevExt)(VkDevice device); struct loader_dev_dispatch_table { VkLayerDispatchTable core_dispatch; PFN_vkDevExt ext_dispatch[MAX_NUM_UNKNOWN_EXTS]; + struct loader_device_terminator_dispatch extension_terminator_dispatch; }; // per CreateDevice structure diff --git a/loader/wsi.c b/loader/wsi.c index e44c37fbf..d9eb89385 100644 --- a/loader/wsi.c +++ b/loader/wsi.c @@ -457,25 +457,35 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSwapchainKHR(VkDevice device, co uint32_t icd_index = 0; struct loader_device *dev; struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); - if (NULL != icd_term && NULL != icd_term->dispatch.CreateSwapchainKHR) { - VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfo->surface; - if (NULL != icd_surface->real_icd_surfaces) { - if ((VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) { - // We found the ICD, and there is an ICD KHR surface - // associated with it, so copy the CreateInfo struct - // and point it at the ICD's surface. - VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR)); - if (NULL == pCreateCopy) { - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - memcpy(pCreateCopy, pCreateInfo, sizeof(VkSwapchainCreateInfoKHR)); - pCreateCopy->surface = icd_surface->real_icd_surfaces[icd_index]; - return icd_term->dispatch.CreateSwapchainKHR(device, pCreateCopy, pAllocator, pSwapchain); + if (NULL == icd_term || NULL == dev || NULL == dev->loader_dispatch.extension_terminator_dispatch.CreateSwapchainKHR) { + loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, + "vkCreateSwapchainKHR Terminator: device handle. This is likely the result of a " + "layer wrapping device handles and failing to unwrap them in all functions. " + "[VUID-vkCreateSwapchainKHR-device-parameter]"); + abort(); /* Intentionally fail so user can correct issue. */ + } + if (NULL == pCreateInfo) { + loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, + "vkCreateSwapchainKHR: Invalid pCreateInfo pointer [VUID-vkCreateSwapchainKHR-pCreateInfo-parameter]"); + abort(); /* Intentionally fail so user can correct issue. */ + } + VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfo->surface; + if (NULL != icd_surface->real_icd_surfaces) { + if ((VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) { + // We found the ICD, and there is an ICD KHR surface + // associated with it, so copy the CreateInfo struct + // and point it at the ICD's surface. + VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR)); + if (NULL == pCreateCopy) { + return VK_ERROR_OUT_OF_HOST_MEMORY; } + memcpy(pCreateCopy, pCreateInfo, sizeof(VkSwapchainCreateInfoKHR)); + pCreateCopy->surface = icd_surface->real_icd_surfaces[icd_index]; + return dev->loader_dispatch.extension_terminator_dispatch.CreateSwapchainKHR(device, pCreateCopy, pAllocator, + pSwapchain); } - return icd_term->dispatch.CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain); } - return VK_SUCCESS; + return dev->loader_dispatch.extension_terminator_dispatch.CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain); } // This is the trampoline entrypoint for DestroySwapchainKHR @@ -2112,27 +2122,37 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSharedSwapchainsKHR(VkDevice dev uint32_t icd_index = 0; struct loader_device *dev; struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); - if (NULL != icd_term && NULL != icd_term->dispatch.CreateSharedSwapchainsKHR) { - VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfos->surface; - if (NULL != icd_surface->real_icd_surfaces) { - if ((VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) { - // We found the ICD, and there is an ICD KHR surface - // associated with it, so copy the CreateInfo struct - // and point it at the ICD's surface. - VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR) * swapchainCount); - if (NULL == pCreateCopy) { - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - memcpy(pCreateCopy, pCreateInfos, sizeof(VkSwapchainCreateInfoKHR) * swapchainCount); - for (uint32_t sc = 0; sc < swapchainCount; sc++) { - pCreateCopy[sc].surface = icd_surface->real_icd_surfaces[icd_index]; - } - return icd_term->dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateCopy, pAllocator, pSwapchains); - } + if (NULL == icd_term || NULL == dev || NULL == dev->loader_dispatch.extension_terminator_dispatch.CreateSharedSwapchainsKHR) { + loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, + "vkCreateSharedSwapchainsKHR Terminator: Invalid device handle. This is likely the result of a " + "layer wrapping device handles and failing to unwrap them in all functions. " + "[VUID-vkCreateSharedSwapchainsKHR-device-parameter]"); + abort(); /* Intentionally fail so user can correct issue. */ + } + if (NULL == pCreateInfos) { + loader_log( + NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, + "vkCreateSharedSwapchainsKHR: Invalid pCreateInfos pointer [VUID-vkCreateSharedSwapchainsKHR-pCreateInfos-parameter]"); + abort(); /* Intentionally fail so user can correct issue. */ + } + VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfos->surface; + if ((VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) { + // We found the ICD, and there is an ICD KHR surface + // associated with it, so copy the CreateInfo struct + // and point it at the ICD's surface. + VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR) * swapchainCount); + if (NULL == pCreateCopy) { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + memcpy(pCreateCopy, pCreateInfos, sizeof(VkSwapchainCreateInfoKHR) * swapchainCount); + for (uint32_t sc = 0; sc < swapchainCount; sc++) { + pCreateCopy[sc].surface = icd_surface->real_icd_surfaces[icd_index]; } - return icd_term->dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains); + return dev->loader_dispatch.extension_terminator_dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateCopy, + pAllocator, pSwapchains); } - return VK_SUCCESS; + return dev->loader_dispatch.extension_terminator_dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, + pAllocator, pSwapchains); } LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL @@ -2164,15 +2184,19 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModesKHR(V uint32_t icd_index = 0; struct loader_device *dev; struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); - if (NULL != icd_term && NULL != icd_term->dispatch.GetDeviceGroupSurfacePresentModesKHR) { - VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface; - if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) { - return icd_term->dispatch.GetDeviceGroupSurfacePresentModesKHR(device, icd_surface->real_icd_surfaces[icd_index], - pModes); - } - return icd_term->dispatch.GetDeviceGroupSurfacePresentModesKHR(device, surface, pModes); + if (NULL == icd_term || NULL == dev || + NULL == dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModesKHR) { + loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, + "vkGetDeviceGroupSurfacePresentModesKHR: Invalid device " + "[VUID-vkGetDeviceGroupSurfacePresentModesKHR-device-parameter]"); + abort(); /* Intentionally fail so user can correct issue. */ } - return VK_SUCCESS; + VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface; + if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) { + return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModesKHR( + device, icd_surface->real_icd_surfaces[icd_index], pModes); + } + return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModesKHR(device, surface, pModes); } LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice, diff --git a/scripts/loader_extension_generator.py b/scripts/loader_extension_generator.py index cee011f25..ae91e60ef 100644 --- a/scripts/loader_extension_generator.py +++ b/scripts/loader_extension_generator.py @@ -241,11 +241,13 @@ class LoaderExtensionOutputGenerator(OutputGenerator): file_data += self.OutputLoaderTerminators() file_data += self.OutputIcdDispatchTable() file_data += self.OutputIcdExtensionEnableUnion() + file_data += self.OutputDeviceFunctionTerminatorDispatchTable() elif self.genOpts.filename == 'vk_loader_extensions.c': file_data += self.OutputUtilitiesInSource() file_data += self.OutputIcdDispatchTableInit() file_data += self.OutputLoaderDispatchTables() + file_data += self.InitDeviceFunctionTerminatorDispatchTable() file_data += self.OutputLoaderLookupFunc() file_data += self.CreateTrampTermFuncs() file_data += self.InstExtensionGPA() @@ -444,7 +446,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator): protos += '// Extension interception for vkGetDeviceProcAddr function, so we can return\n' protos += '// an appropriate terminator if this is one of those few device commands requiring\n' protos += '// a terminator.\n' - protos += 'PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *pName);\n' + protos += 'PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *name, bool* found_name);\n' protos += '\n' protos += '// Dispatch table properly filled in with appropriate terminators for the\n' protos += '// supported extensions.\n' @@ -590,12 +592,22 @@ class LoaderExtensionOutputGenerator(OutputGenerator): return table # + # Common code between the dispatch table struct and the function filling out said struct + def ShouldPrintInIcdDispatchTable(self, cur_cmd, skip_list): + return cur_cmd.name == 'vkGetDeviceProcAddr' or \ + (cur_cmd.handle_type not in ['VkDevice', 'VkCommandBuffer', 'VkQueue'] and cur_cmd.name not in skip_list) + + # # Create a dispatch table from the appropriate list and return it as a string def OutputIcdDispatchTable(self): commands = [] table = '' cur_extension_name = '' + skip_commands = ['vkGetInstanceProcAddr', + 'vkEnumerateDeviceLayerProperties', + ] + table += '// ICD function pointer dispatch table\n' table += 'struct loader_icd_term_dispatch {\n' @@ -606,10 +618,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator): commands = self.ext_commands for cur_cmd in commands: - is_inst_handle_type = cur_cmd.name in ADD_INST_CMDS or cur_cmd.handle_type == 'VkInstance' or cur_cmd.handle_type == 'VkPhysicalDevice' - if ((is_inst_handle_type or cur_cmd.name in DEVICE_CMDS_NEED_TERM) and - (cur_cmd.name != 'vkGetInstanceProcAddr' and cur_cmd.name != 'vkEnumerateDeviceLayerProperties')): - + if (self.ShouldPrintInIcdDispatchTable(cur_cmd, skip_commands)): if cur_cmd.ext_name != cur_extension_name: if 'VK_VERSION_' in cur_cmd.ext_name: table += '\n // ---- Core %s commands\n' % cur_cmd.ext_name[11:] @@ -668,8 +677,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator): required = False for cur_cmd in commands: - is_inst_handle_type = cur_cmd.handle_type == 'VkInstance' or cur_cmd.handle_type == 'VkPhysicalDevice' - if ((is_inst_handle_type or cur_cmd.name in DEVICE_CMDS_NEED_TERM) and (cur_cmd.name not in skip_gipa_commands)): + if (self.ShouldPrintInIcdDispatchTable(cur_cmd, skip_gipa_commands)): if cur_cmd.ext_name != cur_extension_name: if 'VK_VERSION_' in cur_cmd.ext_name: @@ -918,7 +926,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator): return tables # - # Create the appropriate trampoline (and possibly terminator) functinos + # Create the appropriate trampoline (and possibly terminator) functions def CreateTrampTermFuncs(self): entries = [] funcs = '' @@ -1194,40 +1202,6 @@ class LoaderExtensionOutputGenerator(OutputGenerator): count += 1 funcs += ');\n' - elif has_surface == 1 and not (ext_cmd.handle_type == 'VkPhysicalDevice' or ext_cmd.handle_type == 'VkInstance'): - funcs += ' uint32_t icd_index = 0;\n' - funcs += ' struct loader_device *dev;\n' - funcs += ' struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);\n' - funcs += ' if (NULL != icd_term && NULL != icd_term->dispatch.%s) {\n' % base_name - funcs += ' VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)%s;\n' % (surface_var_name) - funcs += ' if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[icd_index]) {\n' - funcs += ' %sicd_term->dispatch.%s(' % (return_prefix, base_name) - count = 0 - for param in ext_cmd.params: - if count != 0: - funcs += ', ' - - if param.type == 'VkSurfaceKHR': - funcs += 'icd_surface->real_icd_surfaces[icd_index]' - else: - funcs += param.name - - count += 1 - funcs += ');\n' - if not has_return_type: - funcs += ' return;\n' - funcs += ' }\n' - funcs += ' %sicd_term->dispatch.%s(' % (return_prefix, base_name) - count = 0 - for param in ext_cmd.params: - if count != 0: - funcs += ', ' - funcs += param.name - count += 1 - funcs += ');\n' - funcs += ' }\n' - if has_return_type: - funcs += ' return VK_SUCCESS;\n' elif ext_cmd.handle_type == 'VkInstance': funcs += ' struct loader_instance *inst = loader_get_instance(%s);\n' % (instance_var_name) @@ -1238,83 +1212,51 @@ class LoaderExtensionOutputGenerator(OutputGenerator): funcs += ' abort(); /* Intentionally fail so user can correct issue. */\n' funcs += ' }\n' funcs += '#error("Not implemented. Likely needs to be manually generated!");\n' - elif 'DebugMarkerSetObject' in ext_cmd.name or 'SetDebugUtilsObject' in ext_cmd.name or 'DebugUtilsLabel' in ext_cmd.name: - funcs += ' uint32_t icd_index = 0;\n' - funcs += ' struct loader_device *dev;\n' - funcs += ' struct loader_icd_term *icd_term = loader_get_icd_and_device(%s, &dev, &icd_index);\n' % (ext_cmd.params[0].name) - funcs += ' if (NULL != icd_term && NULL != icd_term->dispatch.' - funcs += base_name - funcs += ') {\n' - if 'DebugMarkerSetObjectName' in ext_cmd.name: - funcs += ' VkDebugMarkerObjectNameInfoEXT local_name_info;\n' - funcs += ' memcpy(&local_name_info, pNameInfo, sizeof(VkDebugMarkerObjectNameInfoEXT));\n' - funcs += ' // If this is a physical device, we have to replace it with the proper one for the next call.\n' - funcs += ' if (pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {\n' - funcs += ' struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t)pNameInfo->object;\n' - funcs += ' local_name_info.object = (uint64_t)(uintptr_t)phys_dev_term->phys_dev;\n' - funcs += ' // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call.\n' - funcs += ' } else if (pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {\n' - funcs += ' if (NULL != icd_term && NULL != icd_term->dispatch.CreateSwapchainKHR) {\n' - funcs += ' VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pNameInfo->object;\n' - funcs += ' if (NULL != icd_surface->real_icd_surfaces) {\n' - funcs += ' local_name_info.object = (uint64_t)icd_surface->real_icd_surfaces[icd_index];\n' - funcs += ' }\n' - funcs += ' }\n' - funcs += ' }\n' - elif 'DebugMarkerSetObjectTag' in ext_cmd.name: - funcs += ' VkDebugMarkerObjectTagInfoEXT local_tag_info;\n' - funcs += ' memcpy(&local_tag_info, pTagInfo, sizeof(VkDebugMarkerObjectTagInfoEXT));\n' - funcs += ' // If this is a physical device, we have to replace it with the proper one for the next call.\n' - funcs += ' if (pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {\n' - funcs += ' struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t)pTagInfo->object;\n' - funcs += ' local_tag_info.object = (uint64_t)(uintptr_t)phys_dev_term->phys_dev;\n' - funcs += ' // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call.\n' - funcs += ' } else if (pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {\n' - funcs += ' if (NULL != icd_term && NULL != icd_term->dispatch.CreateSwapchainKHR) {\n' - funcs += ' VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pTagInfo->object;\n' - funcs += ' if (NULL != icd_surface->real_icd_surfaces) {\n' - funcs += ' local_tag_info.object = (uint64_t)icd_surface->real_icd_surfaces[icd_index];\n' - funcs += ' }\n' - funcs += ' }\n' - funcs += ' }\n' - elif 'SetDebugUtilsObjectName' in ext_cmd.name: - funcs += ' VkDebugUtilsObjectNameInfoEXT local_name_info;\n' - funcs += ' memcpy(&local_name_info, pNameInfo, sizeof(VkDebugUtilsObjectNameInfoEXT));\n' - funcs += ' // If this is a physical device, we have to replace it with the proper one for the next call.\n' - funcs += ' if (pNameInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {\n' - funcs += ' struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t)pNameInfo->objectHandle;\n' - funcs += ' local_name_info.objectHandle = (uint64_t)(uintptr_t)phys_dev_term->phys_dev;\n' - funcs += ' // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call.\n' - funcs += ' } else if (pNameInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) {\n' - funcs += ' if (NULL != icd_term && NULL != icd_term->dispatch.CreateSwapchainKHR) {\n' - funcs += ' VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pNameInfo->objectHandle;\n' - funcs += ' if (NULL != icd_surface->real_icd_surfaces) {\n' - funcs += ' local_name_info.objectHandle = (uint64_t)icd_surface->real_icd_surfaces[icd_index];\n' - funcs += ' }\n' - funcs += ' }\n' - funcs += ' }\n' - elif 'SetDebugUtilsObjectTag' in ext_cmd.name: - funcs += ' VkDebugUtilsObjectTagInfoEXT local_tag_info;\n' - funcs += ' memcpy(&local_tag_info, pTagInfo, sizeof(VkDebugUtilsObjectTagInfoEXT));\n' - funcs += ' // If this is a physical device, we have to replace it with the proper one for the next call.\n' - funcs += ' if (pTagInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {\n' - funcs += ' struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t)pTagInfo->objectHandle;\n' - funcs += ' local_tag_info.objectHandle = (uint64_t)(uintptr_t)phys_dev_term->phys_dev;\n' - funcs += ' // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call.\n' - funcs += ' } else if (pTagInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) {\n' - funcs += ' if (NULL != icd_term && NULL != icd_term->dispatch.CreateSwapchainKHR) {\n' - funcs += ' VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pTagInfo->objectHandle;\n' - funcs += ' if (NULL != icd_surface->real_icd_surfaces) {\n' - funcs += ' local_tag_info.objectHandle = (uint64_t)icd_surface->real_icd_surfaces[icd_index];\n' - funcs += ' }\n' + elif ext_cmd.ext_name in ['VK_EXT_debug_utils', 'VK_EXT_debug_marker']: + if ext_cmd.name in ['vkDebugMarkerSetObjectNameEXT', 'vkDebugMarkerSetObjectTagEXT', 'vkSetDebugUtilsObjectNameEXT' , 'vkSetDebugUtilsObjectTagEXT']: + + is_debug_utils = ext_cmd.ext_name == "VK_EXT_debug_utils" + debug_struct_name = ext_cmd.params[1].name + local_struct = 'local_name_info' if 'ObjectName' in ext_cmd.name else 'local_tag_info' + member_name = 'objectHandle' if is_debug_utils else 'object' + phys_dev_check = 'VK_OBJECT_TYPE_PHYSICAL_DEVICE' if is_debug_utils else 'VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT' + surf_check = 'VK_OBJECT_TYPE_SURFACE_KHR' if is_debug_utils else 'VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT' + funcs += ' uint32_t icd_index = 0;\n' + funcs += ' struct loader_device *dev;\n' + funcs += f' struct loader_icd_term *icd_term = loader_get_icd_and_device({ ext_cmd.params[0].name}, &dev, &icd_index);\n' + funcs += f' if (NULL == icd_term || NULL == dev || NULL == dev->loader_dispatch.extension_terminator_dispatch.{ext_cmd.name[2:]}) {{\n' + funcs += f' loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "{ext_cmd.name[2:]}: Invalid device handle");\n' + funcs += ' abort(); /* Intentionally fail so user can correct issue. */\n' + funcs += ' }\n' + funcs += f' { ext_cmd.params[1].type} {local_struct};\n' + funcs += f' memcpy(&{local_struct}, {debug_struct_name}, sizeof({ ext_cmd.params[1].type}));\n' + funcs += ' // If this is a physical device, we have to replace it with the proper one for the next call.\n' + funcs += f' if ({debug_struct_name}->objectType == {phys_dev_check}) {{\n' + funcs += f' struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t){debug_struct_name}->{member_name};\n' + funcs += f' {local_struct}.{member_name} = (uint64_t)(uintptr_t)phys_dev_term->phys_dev;\n' + funcs += ' // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call.\n' + funcs += f' }} else if ({debug_struct_name}->objectType == {surf_check}) {{\n' + funcs += ' if (NULL != dev && NULL != dev->loader_dispatch.core_dispatch.CreateSwapchainKHR) {\n' + funcs += f' VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t){debug_struct_name}->{member_name};\n' + funcs += ' if (NULL != icd_surface->real_icd_surfaces) {\n' + funcs += f' {local_struct}.{member_name} = (uint64_t)icd_surface->real_icd_surfaces[icd_index];\n' funcs += ' }\n' funcs += ' }\n' - funcs += ' ' + funcs += ' }\n' + dispatch = 'dev->loader_dispatch.' + else: + funcs += f' struct loader_dev_dispatch_table *dispatch_table = loader_get_dev_dispatch({ext_cmd.params[0].name});\n' + funcs += f' if (NULL == dispatch_table) {{\n' + funcs += f' loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "{ext_cmd.ext_name}: Invalid device handle");\n' + funcs += ' abort(); /* Intentionally fail so user can correct issue. */\n' + funcs += ' }\n' + funcs += ' // Only call down if the device supports the function\n' + funcs += f' if (NULL != dispatch_table->extension_terminator_dispatch.{base_name})\n ' + dispatch = 'dispatch_table->' + funcs += ' ' if has_return_type: funcs += 'return ' - funcs += 'icd_term->dispatch.' - funcs += base_name - funcs += '(' + funcs += f'{dispatch}extension_terminator_dispatch.{base_name}(' count = 0 for param in ext_cmd.params: if count != 0: @@ -1333,10 +1275,6 @@ class LoaderExtensionOutputGenerator(OutputGenerator): count += 1 funcs += ');\n' - if has_return_type: - funcs += ' } else {\n' - funcs += ' return VK_SUCCESS;\n' - funcs += ' }\n' else: funcs += '#error("Unknown error path!");\n' @@ -1357,6 +1295,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator): if ext_cmd.ext_name in NULL_CHECK_EXT_NAMES: funcs += ' if (disp->' + base_name + ' != NULL) {\n' + funcs += ' ' funcs += return_prefix funcs += 'disp->' funcs += base_name @@ -1480,60 +1419,115 @@ class LoaderExtensionOutputGenerator(OutputGenerator): # extension entrypoints and return it as a string def DeviceExtensionGetTerminator(self): term_func = '' - cur_extension_name = '' term_func += '// Some device commands still need a terminator because the loader needs to unwrap something about them.\n' term_func += '// In many cases, the item needing unwrapping is a VkPhysicalDevice or VkSurfaceKHR object. But there may be other items\n' term_func += '// in the future.\n' - term_func += 'PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *pName) {\n' - term_func += ' PFN_vkVoidFunction addr = NULL;\n' - - count = 0 - is_extension = False + term_func += 'PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *name, bool* found_name) {\n' + term_func += ''' *found_name = false; + if (!name || name[0] != 'v' || name[1] != 'k') { + return NULL; + } + name += 2; +''' last_protect = None + last_ext = None for ext_cmd in self.ext_commands: if ext_cmd.name in DEVICE_CMDS_NEED_TERM: - if ext_cmd.ext_name != cur_extension_name: - if count > 0: - count = 0; - term_func += ' }\n' - if is_extension: - term_func += ' }\n' - is_extension = False - - if 'VK_VERSION_' in ext_cmd.ext_name: - term_func += '\n // ---- Core %s commands\n' % ext_cmd.ext_name[11:] - else: - last_protect = ext_cmd.protect - if ext_cmd.protect is not None: - term_func += '#ifdef %s\n' % ext_cmd.protect - term_func += '\n // ---- %s extension commands\n' % ext_cmd.ext_name - if ext_cmd.require: - term_func += ' if (dev->extensions.%s_enabled && dev->extensions.%s_enabled) {\n' % (ext_cmd.ext_name[3:].lower(), ext_cmd.require[3:].lower()) - else: - term_func += ' if (dev->extensions.%s_enabled) {\n' % ext_cmd.ext_name[3:].lower() - is_extension = True - cur_extension_name = ext_cmd.ext_name + if 'VK_VERSION_' in ext_cmd.ext_name: + term_func += f' // ---- Core {ext_cmd.ext_name[11:]} commands\n' + else: + last_protect = ext_cmd.protect + if ext_cmd.protect is not None: + term_func += f'#ifdef {ext_cmd.protect}\n' + if (last_ext != ext_cmd.ext_name): + term_func += f' // ---- {ext_cmd.ext_name} extension commands\n' + last_ext = ext_cmd.ext_name + + term_func += f' if (!strcmp(name, "{ext_cmd.name[2:]}")) {{\n' + term_func += f' *found_name = true;\n' + if ext_cmd.require: + term_func += f' return dev->extensions.{ext_cmd.ext_name[3:].lower()}_enabled && dev->extensions.{ext_cmd.require[3:].lower()}_enabled ?\n' + else: + term_func += f' return dev->extensions.{ext_cmd.ext_name[3:].lower()}_enabled ?\n' + term_func += f' (PFN_vkVoidFunction)terminator_{(ext_cmd.name[2:])} : NULL;\n' + term_func += f' }}\n' + + if last_protect is not None: + term_func += '#endif // %s\n' % ext_cmd.protect + + term_func += ' return NULL;\n' + term_func += '}\n\n' + + return term_func + + # + # Create a dispatch table solely for device functions which have custom terminators + def OutputDeviceFunctionTerminatorDispatchTable(self): + term_func = '' + term_func += '// Functions that required a terminator need to have a separate dispatch table which contains their corresponding\n' + term_func += '// device function. This is used in the terminators themselves.\n' + term_func += 'struct loader_device_terminator_dispatch {\n' - if count == 0: - term_func += ' if' + last_protect = None + last_ext = None + for ext_cmd in self.ext_commands: + if ext_cmd.name in DEVICE_CMDS_NEED_TERM: + if 'VK_VERSION_' in ext_cmd.ext_name: + term_func += f' // ---- Core {ext_cmd.ext_name[11:]} commands\n' else: - term_func += ' } else if' + last_protect = ext_cmd.protect + if ext_cmd.protect is not None: + term_func += f'#ifdef {ext_cmd.protect}\n' + if (last_ext != ext_cmd.ext_name): + term_func += f' // ---- {ext_cmd.ext_name} extension commands\n' + last_ext = ext_cmd.ext_name + + term_func += f' PFN_{ext_cmd.name} {ext_cmd.name[2:]};\n' - term_func += '(!strcmp(pName, "%s")) {\n' % (ext_cmd.name) - term_func += ' addr = (PFN_vkVoidFunction)terminator_%s;\n' % (ext_cmd.name[2:]) + if last_protect is not None: + term_func += '#endif // %s\n' % ext_cmd.protect + term_func += '}; \n\n' - count += 1 + return term_func + + # + # Create code to initialize a dispatch table from the appropriate list of + # extension entrypoints and return it as a string + def InitDeviceFunctionTerminatorDispatchTable(self): + term_func = '' + + term_func += '// Functions that required a terminator need to have a separate dispatch table which contains their corresponding\n' + term_func += '// device function. This is used in the terminators themselves.\n' + term_func += 'void init_extension_device_proc_terminator_dispatch(struct loader_device *dev) {\n' + term_func += ' struct loader_device_terminator_dispatch* dispatch = &dev->loader_dispatch.extension_terminator_dispatch;\n' + term_func += ' PFN_vkGetDeviceProcAddr gpda = (PFN_vkGetDeviceProcAddr)dev->phys_dev_term->this_icd_term->dispatch.GetDeviceProcAddr;\n' + last_protect = None + last_ext = None + for ext_cmd in self.ext_commands: + if ext_cmd.name in DEVICE_CMDS_NEED_TERM: + if 'VK_VERSION_' in ext_cmd.ext_name: + term_func += f' // ---- Core {ext_cmd.ext_name[11:]} commands\n' + else: + last_protect = ext_cmd.protect + if ext_cmd.protect is not None: + term_func += f'#ifdef {ext_cmd.protect}\n' + if (last_ext != ext_cmd.ext_name): + term_func += f' // ---- {ext_cmd.ext_name} extension commands\n' + last_ext = ext_cmd.ext_name + + + if ext_cmd.require: + term_func += f' if (dev->extensions.{ext_cmd.ext_name[3:].lower()}_enabled && dev->extensions.{ext_cmd.require[3:].lower()}_enabled)\n' + term_func += f' dispatch->{ext_cmd.name[2:]} = (PFN_{(ext_cmd.name)})gpda(dev->icd_device, "{(ext_cmd.name)}");\n' + else: + term_func += f' if (dev->extensions.{ext_cmd.ext_name[3:].lower()}_enabled) \n' + term_func += f' dispatch->{ext_cmd.name[2:]} = (PFN_{(ext_cmd.name)})gpda(dev->icd_device, "{(ext_cmd.name)}");\n' - if count > 0: - term_func += ' }\n' - if is_extension: - term_func += ' }\n' - if last_protect is not None: - term_func += '#endif // %s\n' % ext_cmd.protect + if last_protect is not None: + term_func += '#endif // %s\n' % ext_cmd.protect - term_func += ' return addr;\n' term_func += '}\n\n' return term_func diff --git a/tests/framework/icd/test_icd.cpp b/tests/framework/icd/test_icd.cpp index 75ccb8191..890394d5d 100644 --- a/tests/framework/icd/test_icd.cpp +++ b/tests/framework/icd/test_icd.cpp @@ -593,6 +593,20 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateSwapchainKHR(VkDevice device, const return VK_SUCCESS; } +VKAPI_ATTR VkResult VKAPI_CALL test_vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, + uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages) { + std::vector<uint64_t> handles{123, 234, 345, 345, 456}; + if (pSwapchainImages == nullptr) { + if (pSwapchainImageCount) *pSwapchainImageCount = static_cast<uint32_t>(handles.size()); + } else if (pSwapchainImageCount) { + for (uint32_t i = 0; i < *pSwapchainImageCount && i < handles.size(); i++) { + pSwapchainImages[i] = to_nondispatch_handle<VkImage>(handles.back()); + } + if (*pSwapchainImageCount < handles.size()) return VK_INCOMPLETE; + } + return VK_SUCCESS; +} + VKAPI_ATTR void VKAPI_CALL test_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator) { if (swapchain != VK_NULL_HANDLE) { @@ -600,7 +614,7 @@ VKAPI_ATTR void VKAPI_CALL test_vkDestroySwapchainKHR(VkDevice device, VkSwapcha auto found_iter = icd.swapchain_handles.erase( std::remove(icd.swapchain_handles.begin(), icd.swapchain_handles.end(), fake_swapchain_handle), icd.swapchain_handles.end()); - if (found_iter == icd.swapchain_handles.end()) { + if (!icd.swapchain_handles.empty() && found_iter == icd.swapchain_handles.end()) { assert(false && "Swapchain not found during destroy!"); } } @@ -1295,6 +1309,7 @@ PFN_vkVoidFunction get_device_func(VkDevice device, const char* pName) { } if (string_eq(pName, "vkDestroyDevice")) return to_vkVoidFunction(test_vkDestroyDevice); if (string_eq(pName, "vkCreateSwapchainKHR")) return to_vkVoidFunction(test_vkCreateSwapchainKHR); + if (string_eq(pName, "vkGetSwapchainImagesKHR")) return to_vkVoidFunction(test_vkGetSwapchainImagesKHR); if (string_eq(pName, "vkDestroySwapchainKHR")) return to_vkVoidFunction(test_vkDestroySwapchainKHR); if (string_eq(pName, "vkCreateCommandPool")) return to_vkVoidFunction(test_vkCreateCommandPool); if (string_eq(pName, "vkAllocateCommandBuffers")) return to_vkVoidFunction(test_vkAllocateCommandBuffers); diff --git a/tests/framework/test_environment.cpp b/tests/framework/test_environment.cpp index 8431b2473..bb9b6a9b9 100644 --- a/tests/framework/test_environment.cpp +++ b/tests/framework/test_environment.cpp @@ -346,169 +346,111 @@ fs::FolderManager& FrameworkEnvironment::get_folder(ManifestLocation location) n // index it directly using the enum location since they will always be in that order return folders.at(static_cast<size_t>(location)); } -void setup_WSI_in_ICD(TestICD& icd) { +const char* get_platform_wsi_extension(const char* api_selection) { +#if defined(VK_USE_PLATFORM_ANDROID_KHR) + return "VK_KHR_android_surface"; +#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) + return "VK_EXT_directfb_surface"; +#elif defined(VK_USE_PLATFORM_FUCHSIA) + return "VK_FUCHSIA_imagepipe_surface"; +#elif defined(VK_USE_PLATFORM_GGP) + return "VK_GGP_stream_descriptor_surface"; +#elif defined(VK_USE_PLATFORM_IOS_MVK) + return "VK_MVK_ios_surface"; +#elif defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) +#if defined(VK_USE_PLATFORM_MACOS_MVK) + if (string_eq(api_selection, "VK_USE_PLATFORM_MACOS_MVK")) return "VK_MVK_macos_surface"; +#endif +#if defined(VK_USE_PLATFORM_METAL_EXT) + if (string_eq(api_selection, "VK_USE_PLATFORM_METAL_EXT")) return "VK_EXT_metal_surface"; + return "VK_EXT_metal_surface"; +#endif +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + return "VK_QNX_screen_surface"; +#elif defined(VK_USE_PLATFORM_VI_NN) + return "VK_NN_vi_surface"; +#elif defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WAYLAND_KHR) +#if defined(VK_USE_PLATFORM_XCB_KHR) + if (string_eq(api_selection, "VK_USE_PLATFORM_XCB_KHR")) return "VK_KHR_xcb_surface"; +#endif +#if defined(VK_USE_PLATFORM_XLIB_KHR) + if (string_eq(api_selection, "VK_USE_PLATFORM_XLIB_KHR")) return "VK_KHR_xlib_surface"; +#endif +#if defined(VK_USE_PLATFORM_WAYLAND_KHR) + if (string_eq(api_selection, "VK_USE_PLATFORM_WAYLAND_KHR")) return "VK_KHR_wayland_surface"; +#endif +#if defined(VK_USE_PLATFORM_XCB_KHR) + return "VK_KHR_xcb_surface"; +#endif +#elif defined(VK_USE_PLATFORM_WIN32_KHR) + return "VK_KHR_win32_surface"; +#else + return "VK_KHR_display"; +#endif +} + +void setup_WSI_in_ICD(TestICD& icd, const char* api_selection) { icd.enable_icd_wsi = true; -#ifdef VK_USE_PLATFORM_ANDROID_KHR - icd.add_instance_extensions({"VK_KHR_surface", "VK_KHR_android_surface"}); -#endif -#ifdef VK_USE_PLATFORM_DIRECTFB_EXT - icd.add_instance_extensions({"VK_KHR_surface", "VK_EXT_directfb_surface"}); -#endif -#ifdef VK_USE_PLATFORM_FUCHSIA - icd.add_instance_extensions({"VK_KHR_surface", "VK_FUCHSIA_imagepipe_surface"}); -#endif -#ifdef VK_USE_PLATFORM_GGP - icd.add_instance_extensions({"VK_KHR_surface", "VK_GGP_stream_descriptor_surface"}); -#endif -#ifdef VK_USE_PLATFORM_IOS_MVK - icd.add_instance_extensions({"VK_KHR_surface", "VK_MVK_ios_surface"}); -#endif -#ifdef VK_USE_PLATFORM_MACOS_MVK - icd.add_instance_extensions({"VK_KHR_surface", "VK_MVK_macos_surface"}); -#endif -#ifdef VK_USE_PLATFORM_METAL_EXT - icd.add_instance_extensions({"VK_KHR_surface", "VK_EXT_metal_surface"}); -#endif -#ifdef VK_USE_PLATFORM_SCREEN_QNX - icd.add_instance_extensions({"VK_KHR_surface", "VK_QNX_screen_surface"}); -#endif -#ifdef VK_USE_PLATFORM_VI_NN - icd.add_instance_extensions({"VK_KHR_surface", "VK_NN_vi_surface"}); -#endif -#ifdef VK_USE_PLATFORM_XCB_KHR - icd.add_instance_extensions({"VK_KHR_surface", "VK_KHR_xcb_surface"}); -#endif -#ifdef VK_USE_PLATFORM_XLIB_KHR - icd.add_instance_extensions({"VK_KHR_surface", "VK_KHR_xlib_surface"}); -#endif -#ifdef VK_USE_PLATFORM_WAYLAND_KHR - icd.add_instance_extensions({"VK_KHR_surface", "VK_KHR_wayland_surface"}); -#endif -#ifdef VK_USE_PLATFORM_WIN32_KHR - icd.add_instance_extensions({"VK_KHR_surface", "VK_KHR_win32_surface"}); -#endif -} -void setup_WSI_in_create_instance(InstWrapper& inst) { -#ifdef VK_USE_PLATFORM_ANDROID_KHR - inst.create_info.add_extensions({"VK_KHR_surface", "VK_KHR_android_surface"}); -#endif -#ifdef VK_USE_PLATFORM_DIRECTFB_EXT - inst.create_info.add_extensions({"VK_KHR_surface", "VK_EXT_directfb_surface"}); -#endif -#ifdef VK_USE_PLATFORM_FUCHSIA - inst.create_info.add_extensions({"VK_KHR_surface", "VK_FUCHSIA_imagepipe_surface"}); -#endif -#ifdef VK_USE_PLATFORM_GGP - inst.create_info.add_extensions({"VK_KHR_surface", "VK_GGP_stream_descriptor_surface"}); -#endif -#ifdef VK_USE_PLATFORM_IOS_MVK - inst.create_info.add_extensions({"VK_KHR_surface", "VK_MVK_ios_surface"}); -#endif -#ifdef VK_USE_PLATFORM_MACOS_MVK - inst.create_info.add_extensions({"VK_KHR_surface", "VK_MVK_macos_surface"}); -#endif -#ifdef VK_USE_PLATFORM_METAL_EXT - inst.create_info.add_extensions({"VK_KHR_surface", "VK_EXT_metal_surface"}); -#endif -#ifdef VK_USE_PLATFORM_SCREEN_QNX - inst.create_info.add_extensions({"VK_KHR_surface", "VK_QNX_screen_surface"}); -#endif -#ifdef VK_USE_PLATFORM_VI_NN - inst.create_info.add_extensions({"VK_KHR_surface", "VK_NN_vi_surface"}); -#endif -#ifdef VK_USE_PLATFORM_XCB_KHR - inst.create_info.add_extensions({"VK_KHR_surface", "VK_KHR_xcb_surface"}); -#endif -#ifdef VK_USE_PLATFORM_XLIB_KHR - inst.create_info.add_extensions({"VK_KHR_surface", "VK_KHR_xlib_surface"}); -#endif -#ifdef VK_USE_PLATFORM_WAYLAND_KHR - inst.create_info.add_extensions({"VK_KHR_surface", "VK_KHR_wayland_surface"}); -#endif -#ifdef VK_USE_PLATFORM_WIN32_KHR - inst.create_info.add_extensions({"VK_KHR_surface", "VK_KHR_win32_surface"}); -#endif -} -VkSurfaceKHR create_surface(InstWrapper& inst, const char* api_selection) { - VkSurfaceKHR surface{}; -#ifdef VK_USE_PLATFORM_ANDROID_KHR - PFN_vkCreateAndroidSurfaceKHR pfn_CreateSurface = inst.load("vkCreateAndroidSurfaceKHR"); - VkAndroidSurfaceCreateInfoKHR surf_create_info{}; - EXPECT_EQ(VK_SUCCESS, pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface)); -#endif -#ifdef VK_USE_PLATFORM_DIRECTFB_EXT - PFN_vkCreateDirectFBSurfaceEXT pfn_CreateSurface = inst.load("vkCreateDirectFBSurfaceEXT"); - VkDirectFBSurfaceCreateInfoEXT surf_create_info{}; - EXPECT_EQ(VK_SUCCESS, pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface)); -#endif -#ifdef VK_USE_PLATFORM_FUCHSIA - PFN_vkCreateImagePipeSurfaceFUCHSIA pfn_CreateSurface = inst.load("vkCreateImagePipeSurfaceFUCHSIA"); - VkImagePipeSurfaceCreateInfoFUCHSIA surf_create_info{}; - EXPECT_EQ(VK_SUCCESS, pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface)); -#endif -#ifdef VK_USE_PLATFORM_GGP - PFN__vkCreateStreamDescriptorSurfaceGGP pfn_CreateSurface = inst.load("vkCreateStreamDescriptorSurfaceGGP"); - VkStreamDescriptorSurfaceCreateInfoGGP surf_create_info{}; - EXPECT_EQ(VK_SUCCESS, pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface)); -#endif -#ifdef VK_USE_PLATFORM_IOS_MVK - PFN_vkCreateIOSSurfaceMVK pfn_CreateSurface = inst.load("vkCreateIOSSurfaceMVK"); - VkIOSSurfaceCreateInfoMVK surf_create_info{}; - EXPECT_EQ(VK_SUCCESS, pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface)); -#endif -#ifdef VK_USE_PLATFORM_MACOS_MVK - if (string_eq(api_selection, "VK_USE_PLATFORM_MACOS_MVK")) { - PFN_vkCreateMacOSSurfaceMVK pfn_CreateSurface = inst.load("vkCreateMacOSSurfaceMVK"); - VkMacOSSurfaceCreateInfoMVK surf_create_info{}; - EXPECT_EQ(VK_SUCCESS, pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface)); - } -#endif -#ifdef VK_USE_PLATFORM_METAL_EXT - if (string_eq(api_selection, "VK_USE_PLATFORM_METAL_EXT")) { - PFN_vkCreateMetalSurfaceEXT pfn_CreateSurface = inst.load("vkCreateMetalSurfaceEXT"); - VkMetalSurfaceCreateInfoEXT surf_create_info{}; - EXPECT_EQ(VK_SUCCESS, pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface)); - } -#endif -#ifdef VK_USE_PLATFORM_SCREEN_QNX - PFN_vkCreateScreenSurfaceQNX pfn_CreateSurface = inst.load("vkCreateScreenSurfaceQNX"); - VkScreenSurfaceCreateInfoQNX surf_create_info{}; - EXPECT_EQ(VK_SUCCESS, pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface)); -#endif -#ifdef VK_USE_PLATFORM_VI_NN - PFN_vkCreateViSurfaceNN pfn_CreateSurface = inst.load("vkCreateViSurfaceNN"); - VkViSurfaceCreateInfoNN surf_create_info{}; - EXPECT_EQ(VK_SUCCESS, pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface)); -#endif -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkCreateWin32SurfaceKHR pfn_CreateSurface = inst.load("vkCreateWin32SurfaceKHR"); - VkWin32SurfaceCreateInfoKHR surf_create_info{}; - EXPECT_EQ(VK_SUCCESS, pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface)); -#endif - -#ifdef VK_USE_PLATFORM_XCB_KHR - if (string_eq(api_selection, "VK_USE_PLATFORM_XCB_KHR")) { - PFN_vkCreateXcbSurfaceKHR pfn_CreateSurface = inst.load("vkCreateXcbSurfaceKHR"); - VkXcbSurfaceCreateInfoKHR surf_create_info{}; - EXPECT_EQ(VK_SUCCESS, pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface)); - } -#endif -#ifdef VK_USE_PLATFORM_XLIB_KHR - if (string_eq(api_selection, "VK_USE_PLATFORM_XLIB_KHR")) { - PFN_vkCreateXlibSurfaceKHR pfn_CreateSurface = inst.load("vkCreateXlibSurfaceKHR"); - VkXlibSurfaceCreateInfoKHR surf_create_info{}; - EXPECT_EQ(VK_SUCCESS, pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface)); - } -#endif -#ifdef VK_USE_PLATFORM_WAYLAND_KHR - if (string_eq(api_selection, "VK_USE_PLATFORM_WAYLAND_KHR")) { - PFN_vkCreateWaylandSurfaceKHR pfn_CreateSurface = inst.load("vkCreateWaylandSurfaceKHR"); - VkWaylandSurfaceCreateInfoKHR surf_create_info{}; - EXPECT_EQ(VK_SUCCESS, pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface)); - } -#endif - - return surface; + icd.add_instance_extensions({"VK_KHR_surface", get_platform_wsi_extension(api_selection)}); +} +void setup_WSI_in_create_instance(InstWrapper& inst, const char* api_selection) { + inst.create_info.add_extensions({"VK_KHR_surface", get_platform_wsi_extension(api_selection)}); +} + +template <typename CreationFunc, typename CreateInfo> +void create_surface_helper(InstWrapper& inst, VkSurfaceKHR& surface, const char* load_func_name) { + CreationFunc pfn_CreateSurface = inst.load(load_func_name); + CreateInfo surf_create_info{}; + ASSERT_EQ(VK_SUCCESS, pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface)); +} +void create_surface(InstWrapper& inst, VkSurfaceKHR& surface, const char* api_selection) { +#if defined(VK_USE_PLATFORM_ANDROID_KHR) + create_surface_helper<PFN_vkCreateAndroidSurfaceKHR, VkAndroidSurfaceCreateInfoKHR>(inst, surface, "vkCreateAndroidSurfaceKHR"); +#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) + create_surface_helper<PFN_vkCreateDirectFBSurfaceEXT, VkDirectFBSurfaceCreateInfoEXT>(inst, surface, + "vkCreateDirectFBSurfaceEXT"); +#elif defined(VK_USE_PLATFORM_FUCHSIA) + create_surface_helper<PFN_vkCreateImagePipeSurfaceFUCHSIA, VkImagePipeSurfaceCreateInfoFUCHSIA>( + inst, surface, "vkCreateImagePipeSurfaceFUCHSIA"); +#elif defined(VK_USE_PLATFORM_GGP) + create_surface_helper<PFN__vkCreateStreamDescriptorSurfaceGGP, VkStreamDescriptorSurfaceCreateInfoGGP>( + inst, surface, "vkCreateStreamDescriptorSurfaceGGP"); +#elif defined(VK_USE_PLATFORM_IOS_MVK) + create_surface_helper<PFN_vkCreateIOSSurfaceMVK, VkIOSSurfaceCreateInfoMVK>(inst, surface, "vkCreateIOSSurfaceMVK"); +#elif defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) +#if defined(VK_USE_PLATFORM_MACOS_MVK) + if (api_selection != nullptr && string_eq(api_selection, "VK_USE_PLATFORM_MACOS_MVK")) + create_surface_helper<PFN_vkCreateMacOSSurfaceMVK, VkMacOSSurfaceCreateInfoMVK>(inst, surface, "vkCreateMacOSSurfaceMVK"); +#endif +#if defined(VK_USE_PLATFORM_METAL_EXT) + if (api_selection == nullptr || (api_selection != nullptr && string_eq(api_selection, "VK_USE_PLATFORM_METAL_EXT"))) + create_surface_helper<PFN_vkCreateMetalSurfaceEXT, VkMetalSurfaceCreateInfoEXT>(inst, surface, "vkCreateMetalSurfaceEXT"); +#endif +#elif defined(VK_USE_PLATFORM_SCREEN_QNX) + create_surface_helper<PFN_vkCreateScreenSurfaceQNX, VkScreenSurfaceCreateInfoQNX>(inst, surface, "vkCreateScreenSurfaceQNX"); +#elif defined(VK_USE_PLATFORM_VI_NN) + create_surface_helper<PFN_vkCreateViSurfaceNN, VkViSurfaceCreateInfoNN>(inst, surface, "vkCreateViSurfaceNN"); +#elif defined(VK_USE_PLATFORM_WIN32_KHR) + create_surface_helper<PFN_vkCreateWin32SurfaceKHR, VkWin32SurfaceCreateInfoKHR>(inst, surface, "vkCreateWin32SurfaceKHR"); +#elif defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WAYLAND_KHR) +#if defined(VK_USE_PLATFORM_XLIB_KHR) + if (string_eq(api_selection, "VK_USE_PLATFORM_XLIB_KHR")) + create_surface_helper<PFN_vkCreateXlibSurfaceKHR, VkXlibSurfaceCreateInfoKHR>(inst, surface, "vkCreateXlibSurfaceKHR"); +#endif +#if defined(VK_USE_PLATFORM_WAYLAND_KHR) + if (string_eq(api_selection, "VK_USE_PLATFORM_WAYLAND_KHR")) + create_surface_helper<PFN_vkCreateWaylandSurfaceKHR, VkWaylandSurfaceCreateInfoKHR>(inst, surface, + "vkCreateWaylandSurfaceKHR"); +#endif +#if defined(VK_USE_PLATFORM_XCB_KHR) + if (api_selection == nullptr || string_eq(api_selection, "VK_USE_PLATFORM_XCB_KHR")) + create_surface_helper<PFN_vkCreateXcbSurfaceKHR, VkXcbSurfaceCreateInfoKHR>(inst, surface, "vkCreateXcbSurfaceKHR"); +#endif +#else + create_surface_helper<PFN_vkCreateDisplayPlaneSurfaceKHR, VkDisplaySurfaceCreateInfoKHR>(inst, surface, + "vkCreateDisplayPlaneSurfaceKHR"); +#endif + assert(surface != VK_NULL_HANDLE); } extern "C" { diff --git a/tests/framework/test_environment.h b/tests/framework/test_environment.h index 20a25307a..b814cfb4b 100644 --- a/tests/framework/test_environment.h +++ b/tests/framework/test_environment.h @@ -387,10 +387,16 @@ struct FrameworkEnvironment { void add_layer_impl(TestLayerDetails layer_details, ManifestCategory category); }; +// helper function which return a valid WSI platform extension +// const char* api_selection: use this to select an extension on platforms that support multiple extensions +const char* get_platform_wsi_extension(const char* api_selection = nullptr); + // The following helpers setup an icd with the required extensions and setting to use with WSI // By default they use whatever the set VK_USE_PLATFORM_XXX macros define -void setup_WSI_in_ICD(TestICD& icd); -void setup_WSI_in_create_instance(InstWrapper& inst); -// api_selection: optionally provide a VK_USE_PLATFORM_XXX string to select which API to create a surface with -// Note: MUST provide api_selection on platforms with multiple viable API's, such as linux and MacOS -VkSurfaceKHR create_surface(InstWrapper& inst, const char* api_selection = nullptr); +void setup_WSI_in_ICD(TestICD& icd, const char* api_selection = nullptr); +void setup_WSI_in_create_instance(InstWrapper& inst, const char* api_selection = nullptr); + +// Create a surface using a platform specific API +// api_selection: optionally provide a VK_USE_PLATFORM_XXX string to select which API to create a surface with. +// defaults to Metal on macOS and XCB on linux if not provided +void create_surface(InstWrapper& inst, VkSurfaceKHR& out_surface, const char* api_selection = nullptr); diff --git a/tests/framework/test_util.cpp b/tests/framework/test_util.cpp index f7acaee19..d14775a6c 100644 --- a/tests/framework/test_util.cpp +++ b/tests/framework/test_util.cpp @@ -514,8 +514,8 @@ path FolderManager::copy_file(path const& file, std::string const& new_name) { } } // namespace fs -bool string_eq(const char* a, const char* b) noexcept { return strcmp(a, b) == 0; } -bool string_eq(const char* a, const char* b, size_t len) noexcept { return strncmp(a, b, len) == 0; } +bool string_eq(const char* a, const char* b) noexcept { return a && b && strcmp(a, b) == 0; } +bool string_eq(const char* a, const char* b, size_t len) noexcept { return a && b && strncmp(a, b, len) == 0; } fs::path get_loader_path() { auto loader_path = fs::path(FRAMEWORK_VULKAN_LIBRARY_PATH); @@ -637,6 +637,7 @@ DeviceFunctions::DeviceFunctions(const VulkanFunctions& vulkan_functions, VkDevi vkAllocateCommandBuffers = load(device, "vkAllocateCommandBuffers"); vkDestroyCommandPool = load(device, "vkDestroyCommandPool"); vkCreateSwapchainKHR = load(device, "vkCreateSwapchainKHR"); + vkGetSwapchainImagesKHR = load(device, "vkGetSwapchainImagesKHR"); vkDestroySwapchainKHR = load(device, "vkDestroySwapchainKHR"); } diff --git a/tests/framework/test_util.h b/tests/framework/test_util.h index 37791c265..7ff100aae 100644 --- a/tests/framework/test_util.h +++ b/tests/framework/test_util.h @@ -769,6 +769,7 @@ struct DeviceFunctions { PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers = nullptr; PFN_vkDestroyCommandPool vkDestroyCommandPool = nullptr; PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR = nullptr; + PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR = nullptr; PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR = nullptr; DeviceFunctions() = default; diff --git a/tests/loader_handle_validation_tests.cpp b/tests/loader_handle_validation_tests.cpp index 614e4336f..e7751ce20 100644 --- a/tests/loader_handle_validation_tests.cpp +++ b/tests/loader_handle_validation_tests.cpp @@ -1588,8 +1588,8 @@ TEST(LoaderHandleValidTests, VerifyHandleWrappingAndroidSurface) { InstWrapper instance(env.vulkan_functions); setup_WSI_in_create_instance(instance); - instance.CheckCreate(); instance.create_info.add_layer(wrap_objects_name); + instance.CheckCreate(); VkAndroidSurfaceCreateInfoKHR surf_create_info = {}; surf_create_info.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; @@ -1622,8 +1622,8 @@ TEST(LoaderHandleValidTests, VerifyHandleWrappingDirectFBSurf) { InstWrapper instance(env.vulkan_functions); setup_WSI_in_create_instance(instance); - instance.CheckCreate(); instance.create_info.add_layer(wrap_objects_name); + instance.CheckCreate(); VkDirectFBSurfaceCreateInfoEXT surf_create_info = {}; surf_create_info.sType = VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT; @@ -1656,8 +1656,8 @@ TEST(LoaderHandleValidTests, VerifyHandleWrappingFuchsiaSurf) { InstWrapper instance(env.vulkan_functions); setup_WSI_in_create_instance(instance); - instance.CheckCreate(); instance.create_info.add_layer(wrap_objects_name); + instance.CheckCreate(); VkImagePipeSurfaceCreateInfoFUCHSIA surf_create_info = {}; surf_create_info.sType = VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA; @@ -1690,8 +1690,8 @@ TEST(LoaderHandleValidTests, VerifyHandleWrappingGGPSurf) { InstWrapper instance(env.vulkan_functions); setup_WSI_in_create_instance(instance); - instance.CheckCreate(); instance.create_info.add_layer(wrap_objects_name); + instance.CheckCreate(); VkStreamDescriptorSurfaceCreateInfoGGP surf_create_info = {}; surf_create_info.sType = VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP; @@ -1724,8 +1724,8 @@ TEST(LoaderHandleValidTests, VerifyHandleWrappingIOSSurf) { InstWrapper instance(env.vulkan_functions); setup_WSI_in_create_instance(instance); - instance.CheckCreate(); instance.create_info.add_layer(wrap_objects_name); + instance.CheckCreate(); VkIOSSurfaceCreateInfoMVK surf_create_info = {}; surf_create_info.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK; @@ -1745,7 +1745,7 @@ TEST(LoaderHandleValidTests, VerifyHandleWrappingMacOSSurf) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)); auto& driver = env.get_test_icd(); - setup_WSI_in_ICD(driver); + setup_WSI_in_ICD(driver, "VK_USE_PLATFORM_MACOS_MVK"); const char* wrap_objects_name = "WrapObjectsLayer"; env.add_explicit_layer(ManifestLayer{}.add_layer( @@ -1757,9 +1757,9 @@ TEST(LoaderHandleValidTests, VerifyHandleWrappingMacOSSurf) { driver.physical_devices.back().queue_family_properties.push_back(family_props); InstWrapper instance(env.vulkan_functions); - setup_WSI_in_create_instance(instance); - instance.CheckCreate(); + setup_WSI_in_create_instance(instance, "VK_USE_PLATFORM_MACOS_MVK"); instance.create_info.add_layer(wrap_objects_name); + instance.CheckCreate(); VkMacOSSurfaceCreateInfoMVK surf_create_info = {}; surf_create_info.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; @@ -1779,7 +1779,7 @@ TEST(LoaderHandleValidTests, VerifyHandleWrappingMetalSurf) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)); auto& driver = env.get_test_icd(); - setup_WSI_in_ICD(driver); + setup_WSI_in_ICD(driver, "VK_USE_PLATFORM_METAL_EXT"); const char* wrap_objects_name = "WrapObjectsLayer"; env.add_explicit_layer(ManifestLayer{}.add_layer( @@ -1791,9 +1791,9 @@ TEST(LoaderHandleValidTests, VerifyHandleWrappingMetalSurf) { driver.physical_devices.back().queue_family_properties.push_back(family_props); InstWrapper instance(env.vulkan_functions); - setup_WSI_in_create_instance(instance); - instance.CheckCreate(); + setup_WSI_in_create_instance(instance, "VK_USE_PLATFORM_METAL_EXT"); instance.create_info.add_layer(wrap_objects_name); + instance.CheckCreate(); VkMetalSurfaceCreateInfoEXT surf_create_info = {}; surf_create_info.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; @@ -1826,8 +1826,8 @@ TEST(LoaderHandleValidTests, VerifyHandleWrappingQNXSurf) { InstWrapper instance(env.vulkan_functions); setup_WSI_in_create_instance(instance); - instance.CheckCreate(); instance.create_info.add_layer(wrap_objects_name); + instance.CheckCreate(); VkScreenSurfaceCreateInfoQNX surf_create_info = {}; surf_create_info.sType = VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX; @@ -1860,8 +1860,8 @@ TEST(LoaderHandleValidTests, VerifyHandleWrappingViNNSurf) { InstWrapper instance(env.vulkan_functions); setup_WSI_in_create_instance(instance); - instance.CheckCreate(); instance.create_info.add_layer(wrap_objects_name); + instance.CheckCreate(); VkViSurfaceCreateInfoNN surf_create_info = {}; surf_create_info.sType = VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN; @@ -1881,7 +1881,7 @@ TEST(LoaderHandleValidTests, VerifyHandleWrappingWaylandSurf) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)); auto& driver = env.get_test_icd(); - setup_WSI_in_ICD(driver); + setup_WSI_in_ICD(driver, "VK_USE_PLATFORM_WAYLAND_KHR"); const char* wrap_objects_name = "WrapObjectsLayer"; env.add_explicit_layer(ManifestLayer{}.add_layer( @@ -1893,9 +1893,9 @@ TEST(LoaderHandleValidTests, VerifyHandleWrappingWaylandSurf) { driver.physical_devices.back().queue_family_properties.push_back(family_props); InstWrapper instance(env.vulkan_functions); - setup_WSI_in_create_instance(instance); - instance.CheckCreate(); + setup_WSI_in_create_instance(instance, "VK_USE_PLATFORM_WAYLAND_KHR"); instance.create_info.add_layer(wrap_objects_name); + instance.CheckCreate(); VkWaylandSurfaceCreateInfoKHR surf_create_info = {}; surf_create_info.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; @@ -1928,8 +1928,8 @@ TEST(LoaderHandleValidTests, VerifyHandleWrappingWin32Surf) { InstWrapper instance(env.vulkan_functions); setup_WSI_in_create_instance(instance); - instance.CheckCreate(); instance.create_info.add_layer(wrap_objects_name); + instance.CheckCreate(); VkWin32SurfaceCreateInfoKHR surf_create_info = {}; surf_create_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; @@ -1962,8 +1962,8 @@ TEST(LoaderHandleValidTests, VerifyHandleWrappingXCBSurf) { InstWrapper instance(env.vulkan_functions); setup_WSI_in_create_instance(instance); - instance.CheckCreate(); instance.create_info.add_layer(wrap_objects_name); + instance.CheckCreate(); VkXcbSurfaceCreateInfoKHR surf_create_info = {}; surf_create_info.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; @@ -1983,8 +1983,10 @@ TEST(LoaderHandleValidTests, VerifyHandleWrappingXlibSurf) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)); auto& driver = env.get_test_icd(); - setup_WSI_in_ICD(driver); - + setup_WSI_in_ICD(driver, "VK_USE_PLATFORM_XLIB_KHR"); + for (auto& ext : driver.instance_extensions) { + std::cout << ext.extensionName << "\n"; + } const char* wrap_objects_name = "WrapObjectsLayer"; env.add_explicit_layer(ManifestLayer{}.add_layer( ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)), @@ -1995,9 +1997,13 @@ TEST(LoaderHandleValidTests, VerifyHandleWrappingXlibSurf) { driver.physical_devices.back().queue_family_properties.push_back(family_props); InstWrapper instance(env.vulkan_functions); - setup_WSI_in_create_instance(instance); - instance.CheckCreate(); + setup_WSI_in_create_instance(instance, "VK_USE_PLATFORM_XLIB_KHR"); + // + for (auto& ext : instance.create_info.enabled_extensions) { + std::cout << ext << "\n"; + } instance.create_info.add_layer(wrap_objects_name); + instance.CheckCreate(); VkXlibSurfaceCreateInfoKHR surf_create_info = {}; surf_create_info.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; diff --git a/tests/loader_version_tests.cpp b/tests/loader_version_tests.cpp index 04c22acea..3cf094c39 100644 --- a/tests/loader_version_tests.cpp +++ b/tests/loader_version_tests.cpp @@ -516,7 +516,8 @@ TEST(MultipleICDConfig, version_5_and_version_6) { env.vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, physical_device_handles.data())); ASSERT_EQ(physical_count, returned_physical_count); - VkSurfaceKHR surface = create_surface(inst); + VkSurfaceKHR surface{}; + create_surface(inst, surface); for (const auto& handle : physical_device_handles) { handle_assert_has_value(handle); diff --git a/tests/loader_wsi_tests.cpp b/tests/loader_wsi_tests.cpp index 265c2cc23..a05e7c1ee 100644 --- a/tests/loader_wsi_tests.cpp +++ b/tests/loader_wsi_tests.cpp @@ -784,3 +784,90 @@ TEST(WsiTests, WaylandGetPhysicalDeviceSurfaceSupportKHR) { env.vulkan_functions.vkDestroySurfaceKHR(instance.inst, surface, nullptr); } #endif + +TEST(WsiTests, ForgetEnableSurfaceExtensions) { + FrameworkEnvironment env{}; + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)); + auto& driver = env.get_test_icd(); + setup_WSI_in_ICD(driver); + MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true}; + + driver.physical_devices.emplace_back("physical_device_0"); + driver.physical_devices.back().queue_family_properties.push_back(family_props); + driver.physical_devices.back().add_extension("VK_KHR_swapchain"); + + InstWrapper inst{env.vulkan_functions}; + setup_WSI_in_create_instance(inst); + inst.create_info.enabled_extensions.clear(); // setup_WSI() adds extensions to Instance CreateInfo, we don't want that + inst.CheckCreate(); + + VkSurfaceKHR surface{}; + ASSERT_DEATH(create_surface(inst, surface), ""); +} + +TEST(WsiTests, SwapchainFunctional) { + FrameworkEnvironment env{}; + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)); + auto& driver = env.get_test_icd(); + setup_WSI_in_ICD(driver); + MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true}; + + driver.physical_devices.emplace_back("physical_device_0"); + driver.physical_devices.back().queue_family_properties.push_back(family_props); + driver.physical_devices.back().add_extension("VK_KHR_swapchain"); + + InstWrapper inst{env.vulkan_functions}; + setup_WSI_in_create_instance(inst); + inst.CheckCreate(); + VkSurfaceKHR surface{}; + create_surface(inst, surface); + VkPhysicalDevice phys_dev = inst.GetPhysDev(); + + uint32_t familyCount = 0; + inst->vkGetPhysicalDeviceQueueFamilyProperties(phys_dev, &familyCount, nullptr); + ASSERT_EQ(familyCount, 1U); + + VkQueueFamilyProperties families; + inst->vkGetPhysicalDeviceQueueFamilyProperties(phys_dev, &familyCount, &families); + ASSERT_EQ(familyCount, 1U); + ASSERT_EQ(families, family_props.properties); + { + DeviceWrapper dev{inst}; + dev.create_info.add_extension("VK_KHR_swapchain"); + dev.create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f)); + + dev.CheckCreate(phys_dev); + + VkSwapchainKHR swapchain{}; + VkSwapchainCreateInfoKHR swap_create_info{}; + swap_create_info.surface = surface; + DeviceFunctions funcs{*inst.functions, dev}; + ASSERT_EQ(VK_SUCCESS, funcs.vkCreateSwapchainKHR(dev, &swap_create_info, nullptr, &swapchain)); + uint32_t count = 0; + ASSERT_EQ(VK_SUCCESS, funcs.vkGetSwapchainImagesKHR(dev, swapchain, &count, nullptr)); + ASSERT_GT(count, 0U); + std::array<VkImage, 16> images; + ASSERT_EQ(VK_SUCCESS, funcs.vkGetSwapchainImagesKHR(dev, swapchain, &count, images.data())); + funcs.vkDestroySwapchainKHR(dev, swapchain, nullptr); + } + { // forget to enable the extension + DeviceWrapper dev{inst}; + dev.CheckCreate(phys_dev); + + DeviceFunctions funcs{*inst.functions, dev}; + ASSERT_EQ(funcs.vkCreateSwapchainKHR, nullptr); + } + { // forget to set the surface + DeviceWrapper dev{inst}; + dev.create_info.add_extension("VK_KHR_swapchain"); + dev.create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f)); + + dev.CheckCreate(phys_dev); + + VkSwapchainKHR swapchain{}; + VkSwapchainCreateInfoKHR swap_create_info{}; + DeviceFunctions funcs{*inst.functions, dev}; + ASSERT_DEATH(funcs.vkCreateSwapchainKHR(dev, &swap_create_info, nullptr, &swapchain), ""); + } + env.vulkan_functions.vkDestroySurfaceKHR(inst.inst, surface, nullptr); +} |