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:
authorCharles Giessen <charles@lunarg.com>2022-10-12 22:51:17 +0300
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>2022-11-01 02:19:23 +0300
commitd1db6c5bce9ed474ca124f0bffed9aa2468f3973 (patch)
treeb16b58efedad7dfd9f068e809425324d2c4dcf09
parentd4cb3b54bb822c819b378af478145b60320e6679 (diff)
Remove Device functions from ICD Dispatch table
There are numerous terminators to device level functions that the loader must insert in the call chain. However, the Device Dispatch Tables contain pointers to these terminators rather than the driver's function. This was worked around by storing the driver's functions in the ICD dispatch table and calling those. This leads to rather confusing code where the application is querying for the ICD dispatch table inside a device level function. The solution is to create a bespoke dispatch table for device level functions that require a terminator, and use that table when required.
-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);
+}