Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/KhronosGroup/Vulkan-Loader.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--loader/extension_manual.c34
-rw-r--r--loader/generated/vk_loader_extensions.c388
-rw-r--r--loader/generated/vk_loader_extensions.h48
-rw-r--r--loader/loader.c46
-rw-r--r--loader/loader_common.h1
-rw-r--r--loader/wsi.c110
-rw-r--r--scripts/loader_extension_generator.py312
-rw-r--r--tests/framework/icd/test_icd.cpp17
-rw-r--r--tests/framework/test_environment.cpp266
-rw-r--r--tests/framework/test_environment.h16
-rw-r--r--tests/framework/test_util.cpp5
-rw-r--r--tests/framework/test_util.h1
-rw-r--r--tests/loader_handle_validation_tests.cpp50
-rw-r--r--tests/loader_version_tests.cpp3
-rw-r--r--tests/loader_wsi_tests.cpp87
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);
+}