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-11-06 01:12:00 +0300
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>2022-11-10 00:02:42 +0300
commit7e61110364b45676700fcd3a25f73de3f62a0783 (patch)
tree58dbc024d9aacf52382ecb108e71a9a6b61fef89
parent5b054b4333fda50df118d6544c8cb24505890025 (diff)
Dont abort when WSI functions are NULL.
Commit d1db6c5bce9ed474ca124f0bffed9aa2468f3973 changed a few WSI functions to abort when the driver's function was NULL, which is a change of existing behavior. It should instead return VK_SUCCESS. At least now there is a warning message. This commit also adds tests for the above situation and for debug utils & debug marker functions to make sure the pre-existing behavior is maintained. This was tested by running the loader with a previous build through the new tests and verified that they both passed. The tests run the cases of whether the extensions were enabled, how the functions were queried (GIPA vs GDPA), and whether the hardware supports the extensions.
-rw-r--r--loader/generated/vk_loader_extensions.c26
-rw-r--r--loader/wsi.c39
-rw-r--r--scripts/loader_extension_generator.py2
-rw-r--r--tests/framework/icd/physical_device.h4
-rw-r--r--tests/framework/icd/test_icd.cpp101
-rw-r--r--tests/framework/icd/test_icd.h22
-rw-r--r--tests/framework/test_environment.cpp51
-rw-r--r--tests/framework/test_environment.h3
-rw-r--r--tests/framework/test_util.cpp23
-rw-r--r--tests/framework/test_util.h7
-rw-r--r--tests/live_verification/CMakeLists.txt2
-rw-r--r--tests/live_verification/dynamic_rendering_get_proc_addr.cpp6
-rw-r--r--tests/loader_debug_ext_tests.cpp160
-rw-r--r--tests/loader_get_proc_addr_tests.cpp109
-rw-r--r--tests/loader_wsi_tests.cpp49
15 files changed, 524 insertions, 80 deletions
diff --git a/loader/generated/vk_loader_extensions.c b/loader/generated/vk_loader_extensions.c
index 9b7772f74..5e527900b 100644
--- a/loader/generated/vk_loader_extensions.c
+++ b/loader/generated/vk_loader_extensions.c
@@ -1358,34 +1358,34 @@ 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)
+ if (dev->extensions.khr_swapchain_enabled)
dispatch->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpda(dev->icd_device, "vkCreateSwapchainKHR");
- if (dev->extensions.khr_swapchain_enabled)
+ 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)
+ 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)
+ if (dev->extensions.ext_debug_marker_enabled)
dispatch->DebugMarkerSetObjectTagEXT = (PFN_vkDebugMarkerSetObjectTagEXT)gpda(dev->icd_device, "vkDebugMarkerSetObjectTagEXT");
- if (dev->extensions.ext_debug_marker_enabled)
+ 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)
+ if (dev->extensions.ext_debug_utils_enabled)
dispatch->SetDebugUtilsObjectNameEXT = (PFN_vkSetDebugUtilsObjectNameEXT)gpda(dev->icd_device, "vkSetDebugUtilsObjectNameEXT");
- if (dev->extensions.ext_debug_utils_enabled)
+ if (dev->extensions.ext_debug_utils_enabled)
dispatch->SetDebugUtilsObjectTagEXT = (PFN_vkSetDebugUtilsObjectTagEXT)gpda(dev->icd_device, "vkSetDebugUtilsObjectTagEXT");
- if (dev->extensions.ext_debug_utils_enabled)
+ if (dev->extensions.ext_debug_utils_enabled)
dispatch->QueueBeginDebugUtilsLabelEXT = (PFN_vkQueueBeginDebugUtilsLabelEXT)gpda(dev->icd_device, "vkQueueBeginDebugUtilsLabelEXT");
- if (dev->extensions.ext_debug_utils_enabled)
+ if (dev->extensions.ext_debug_utils_enabled)
dispatch->QueueEndDebugUtilsLabelEXT = (PFN_vkQueueEndDebugUtilsLabelEXT)gpda(dev->icd_device, "vkQueueEndDebugUtilsLabelEXT");
- if (dev->extensions.ext_debug_utils_enabled)
+ if (dev->extensions.ext_debug_utils_enabled)
dispatch->QueueInsertDebugUtilsLabelEXT = (PFN_vkQueueInsertDebugUtilsLabelEXT)gpda(dev->icd_device, "vkQueueInsertDebugUtilsLabelEXT");
- if (dev->extensions.ext_debug_utils_enabled)
+ if (dev->extensions.ext_debug_utils_enabled)
dispatch->CmdBeginDebugUtilsLabelEXT = (PFN_vkCmdBeginDebugUtilsLabelEXT)gpda(dev->icd_device, "vkCmdBeginDebugUtilsLabelEXT");
- if (dev->extensions.ext_debug_utils_enabled)
+ if (dev->extensions.ext_debug_utils_enabled)
dispatch->CmdEndDebugUtilsLabelEXT = (PFN_vkCmdEndDebugUtilsLabelEXT)gpda(dev->icd_device, "vkCmdEndDebugUtilsLabelEXT");
- if (dev->extensions.ext_debug_utils_enabled)
+ 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
diff --git a/loader/wsi.c b/loader/wsi.c
index d9eb89385..8a97ca59a 100644
--- a/loader/wsi.c
+++ b/loader/wsi.c
@@ -449,6 +449,14 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(VkDevice devic
"vkCreateSwapchainKHR: Invalid device [VUID-vkCreateSwapchainKHR-device-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
+ if (NULL == disp->CreateSwapchainKHR) {
+ struct loader_device *dev = *((struct loader_device **)device);
+ loader_log(NULL != dev ? dev->phys_dev_term->this_icd_term->this_instance : NULL,
+ VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+ "vkCreateSwapchainKHR: Driver's function pointer was NULL, returning VK_SUCCESS. Was the VK_KHR_swapchain "
+ "extension enabled?");
+ abort();
+ }
return disp->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
}
@@ -457,7 +465,7 @@ 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 == dev || NULL == dev->loader_dispatch.extension_terminator_dispatch.CreateSwapchainKHR) {
+ if (NULL == icd_term || NULL == dev) {
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. "
@@ -469,6 +477,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSwapchainKHR(VkDevice device, co
"vkCreateSwapchainKHR: Invalid pCreateInfo pointer [VUID-vkCreateSwapchainKHR-pCreateInfo-parameter]");
abort(); /* Intentionally fail so user can correct issue. */
}
+ // Need to gracefully handle the function pointer not being found.
+ if (NULL == dev->loader_dispatch.extension_terminator_dispatch.CreateSwapchainKHR) {
+ loader_log(NULL, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
+ "vkCreateSwapchainKHR: Driver's function pointer was NULL, returning VK_SUCCESS. Was the VK_KHR_swapchain "
+ "extension enabled?");
+ return VK_SUCCESS;
+ }
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]) {
@@ -2122,18 +2137,18 @@ 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 == dev || NULL == dev->loader_dispatch.extension_terminator_dispatch.CreateSharedSwapchainsKHR) {
+ if (NULL == icd_term || NULL == dev) {
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. */
+ if (NULL == dev->loader_dispatch.extension_terminator_dispatch.CreateSharedSwapchainsKHR) {
+ loader_log(NULL, VULKAN_LOADER_ERROR_BIT, 0,
+ "vkCreateSharedSwapchainsKHR: Driver's function pointer was NULL, returning VK_SUCCESS. Was the "
+ "VK_KHR_display_swapchain extension enabled?");
+ return VK_SUCCESS;
}
VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfos->surface;
if ((VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) {
@@ -2184,13 +2199,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 == dev ||
- NULL == dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModesKHR) {
+ if (NULL == icd_term || NULL == dev) {
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. */
}
+ if (NULL == dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModesKHR) {
+ loader_log(NULL, VULKAN_LOADER_ERROR_BIT, 0,
+ "vkGetDeviceGroupSurfacePresentModesKHR: Driver's function pointer was NULL, returning VK_SUCCESS. Was either "
+ "Vulkan 1.1 and VK_KHR_swapchain enabled or both the VK_KHR_device_group and VK_KHR_surface "
+ "extensions enabled when using Vulkan 1.0?");
+ 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(
diff --git a/scripts/loader_extension_generator.py b/scripts/loader_extension_generator.py
index d178544cf..e5a4ca882 100644
--- a/scripts/loader_extension_generator.py
+++ b/scripts/loader_extension_generator.py
@@ -1525,7 +1525,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator):
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' 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 last_protect is not None:
diff --git a/tests/framework/icd/physical_device.h b/tests/framework/icd/physical_device.h
index fbe5cb14f..e5129b0ab 100644
--- a/tests/framework/icd/physical_device.h
+++ b/tests/framework/icd/physical_device.h
@@ -64,9 +64,9 @@ struct PhysicalDevice {
BUILDER_VALUE(PhysicalDevice, VkDisplayModeKHR, display_mode, {})
BUILDER_VALUE(PhysicalDevice, VkDisplayPlaneCapabilitiesKHR, display_plane_capabilities, {})
- // VkDevice handles created from this physical device
+ // Objects created from this physical device
std::vector<VkDevice> device_handles;
-
+ std::vector<DeviceCreateInfo> device_create_infos;
std::vector<DispatchableHandle<VkQueue>> queue_handles;
// Unknown physical device functions. Add a `VulkanFunction` to this list which will be searched in
diff --git a/tests/framework/icd/test_icd.cpp b/tests/framework/icd/test_icd.cpp
index 890394d5d..079e80650 100644
--- a/tests/framework/icd/test_icd.cpp
+++ b/tests/framework/icd/test_icd.cpp
@@ -327,6 +327,26 @@ VKAPI_ATTR void VKAPI_CALL test_vkDestroyDebugUtilsMessengerEXT(VkInstance insta
}
}
+// Debug utils & debug marker ext stubs
+VKAPI_ATTR VkResult VKAPI_CALL test_vkDebugMarkerSetObjectTagEXT(VkDevice dev, const VkDebugMarkerObjectTagInfoEXT* pTagInfo) {
+ return VK_SUCCESS;
+}
+VKAPI_ATTR VkResult VKAPI_CALL test_vkDebugMarkerSetObjectNameEXT(VkDevice dev, const VkDebugMarkerObjectNameInfoEXT* pNameInfo) {
+ return VK_SUCCESS;
+}
+VKAPI_ATTR VkResult VKAPI_CALL test_vkSetDebugUtilsObjectNameEXT(VkDevice dev, const VkDebugUtilsObjectTagInfoEXT* pTagInfo) {
+ return VK_SUCCESS;
+}
+VKAPI_ATTR VkResult VKAPI_CALL test_vkSetDebugUtilsObjectTagEXT(VkDevice dev, const VkDebugUtilsObjectTagInfoEXT* pTagInfo) {
+ return VK_SUCCESS;
+}
+VKAPI_ATTR void VKAPI_CALL test_vkQueueBeginDebugUtilsLabelEXT(VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo) {}
+VKAPI_ATTR void VKAPI_CALL test_vkQueueEndDebugUtilsLabelEXT(VkQueue queue) {}
+VKAPI_ATTR void VKAPI_CALL test_vkQueueInsertDebugUtilsLabelEXT(VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo) {}
+VKAPI_ATTR void VKAPI_CALL test_vkCmdBeginDebugUtilsLabelEXT(VkCommandBuffer cmd_buf, const VkDebugUtilsLabelEXT* pLabelInfo) {}
+VKAPI_ATTR void VKAPI_CALL test_vkCmdEndDebugUtilsLabelEXT(VkCommandBuffer cmd_buf) {}
+VKAPI_ATTR void VKAPI_CALL test_vkCmdInsertDebugUtilsLabelEXT(VkCommandBuffer cmd_buf, const VkDebugUtilsLabelEXT* pLabelInfo) {}
+
//// Physical Device functions ////
// VK_SUCCESS,VK_INCOMPLETE
@@ -366,11 +386,11 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDevice(VkPhysicalDevice physicalDevi
auto device_handle = DispatchableHandle<VkDevice>();
*pDevice = device_handle.handle;
found->device_handles.push_back(device_handle.handle);
- icd.device_handles.emplace_back(std::move(device_handle));
-
+ found->device_create_infos.push_back(DeviceCreateInfo{pCreateInfo});
for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
found->queue_handles.emplace_back();
}
+ icd.device_handles.emplace_back(std::move(device_handle));
return VK_SUCCESS;
}
@@ -378,6 +398,11 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDevice(VkPhysicalDevice physicalDevi
VKAPI_ATTR void VKAPI_CALL test_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
auto found = std::find(icd.device_handles.begin(), icd.device_handles.end(), device);
if (found != icd.device_handles.end()) icd.device_handles.erase(found);
+ auto fd = icd.lookup_device(device);
+ if (!fd.found) return;
+ auto& phys_dev = icd.physical_devices.at(fd.phys_dev_index);
+ phys_dev.device_handles.erase(phys_dev.device_handles.begin() + fd.dev_index);
+ phys_dev.device_create_infos.erase(phys_dev.device_create_infos.begin() + fd.dev_index);
}
VKAPI_ATTR VkResult VKAPI_CALL generic_tool_props_function(VkPhysicalDevice physicalDevice, uint32_t* pToolCount,
@@ -586,7 +611,7 @@ VKAPI_ATTR void VKAPI_CALL test_vkDestroySurfaceKHR(VkInstance instance, VkSurfa
}
}
}
-
+// VK_KHR_swapchain
VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain) {
common_nondispatch_handle_creation(icd.swapchain_handles, pSwapchain);
@@ -619,6 +644,13 @@ VKAPI_ATTR void VKAPI_CALL test_vkDestroySwapchainKHR(VkDevice device, VkSwapcha
}
}
}
+// VK_KHR_swapchain with 1.1
+VKAPI_ATTR VkResult VKAPI_CALL test_vkGetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface,
+ VkDeviceGroupPresentModeFlagsKHR* pModes) {
+ if (!pModes) return VK_ERROR_INITIALIZATION_FAILED;
+ *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR;
+ return VK_SUCCESS;
+}
// VK_KHR_surface
VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
@@ -764,6 +796,14 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhys
}
return VK_SUCCESS;
}
+// VK_KHR_display_swapchain
+VkResult test_vkCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount, const VkSwapchainCreateInfoKHR* pCreateInfos,
+ const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains) {
+ for (uint32_t i = 0; i < swapchainCount; i++) {
+ common_nondispatch_handle_creation(icd.swapchain_handles, &pSwapchains[i]);
+ }
+ return VK_SUCCESS;
+}
//// misc
VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo,
@@ -1298,23 +1338,58 @@ PFN_vkVoidFunction get_instance_func(VkInstance instance, const char* pName) {
return nullptr;
}
+bool should_check(std::vector<const char*> const& exts, VkDevice device, const char* ext_name) {
+ if (device == NULL) return true; // always look if device is NULL
+ for (auto const& ext : exts) {
+ if (string_eq(ext, ext_name)) {
+ return true;
+ }
+ }
+ return false;
+}
+
PFN_vkVoidFunction get_device_func(VkDevice device, const char* pName) {
+ TestICD::FindDevice fd{};
+ DeviceCreateInfo create_info{};
if (device != nullptr) {
- if (!std::any_of(icd.physical_devices.begin(), icd.physical_devices.end(), [&](const PhysicalDevice& pd) {
- return std::any_of(pd.device_handles.begin(), pd.device_handles.end(),
- [&](const VkDevice& pd_device) { return pd_device == device; });
- })) {
- return nullptr;
- }
+ fd = icd.lookup_device(device);
+ if (!fd.found) return NULL;
+ create_info = icd.physical_devices.at(fd.phys_dev_index).device_create_infos.at(fd.dev_index);
}
- 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);
if (string_eq(pName, "vkDestroyCommandPool")) return to_vkVoidFunction(test_vkDestroyCommandPool);
if (string_eq(pName, "vkGetDeviceQueue")) return to_vkVoidFunction(test_vkGetDeviceQueue);
+ if (string_eq(pName, "vkDestroyDevice")) return to_vkVoidFunction(test_vkDestroyDevice);
+ if (should_check(create_info.enabled_extensions, device, "VK_KHR_swapchain")) {
+ 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 (icd.icd_api_version >= VK_API_VERSION_1_1 && string_eq(pName, "vkGetDeviceGroupSurfacePresentModesKHR"))
+ return to_vkVoidFunction(test_vkGetDeviceGroupSurfacePresentModesKHR);
+ }
+ if (should_check(create_info.enabled_extensions, device, "VK_KHR_display_swapchain")) {
+ if (string_eq(pName, "vkCreateSharedSwapchainsKHR")) return to_vkVoidFunction(test_vkCreateSharedSwapchainsKHR);
+ }
+ if (should_check(create_info.enabled_extensions, device, "VK_KHR_device_group")) {
+ if (string_eq(pName, "vkGetDeviceGroupSurfacePresentModesKHR"))
+ return to_vkVoidFunction(test_vkGetDeviceGroupSurfacePresentModesKHR);
+ }
+ if (should_check(create_info.enabled_extensions, device, "VK_EXT_debug_marker")) {
+ if (string_eq(pName, "vkDebugMarkerSetObjectTagEXT")) return to_vkVoidFunction(test_vkDebugMarkerSetObjectTagEXT);
+ if (string_eq(pName, "vkDebugMarkerSetObjectNameEXT")) return to_vkVoidFunction(test_vkDebugMarkerSetObjectNameEXT);
+ }
+ if (IsInstanceExtensionEnabled("VK_EXT_debug_utils")) {
+ if (string_eq(pName, "vkSetDebugUtilsObjectNameEXT")) return to_vkVoidFunction(test_vkSetDebugUtilsObjectNameEXT);
+ if (string_eq(pName, "vkSetDebugUtilsObjectTagEXT")) return to_vkVoidFunction(test_vkSetDebugUtilsObjectTagEXT);
+ if (string_eq(pName, "vkQueueBeginDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueBeginDebugUtilsLabelEXT);
+ if (string_eq(pName, "vkQueueEndDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueEndDebugUtilsLabelEXT);
+ if (string_eq(pName, "vkQueueInsertDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkQueueInsertDebugUtilsLabelEXT);
+ if (string_eq(pName, "vkCmdBeginDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdBeginDebugUtilsLabelEXT);
+ if (string_eq(pName, "vkCmdEndDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdEndDebugUtilsLabelEXT);
+ if (string_eq(pName, "vkCmdInsertDebugUtilsLabelEXT")) return to_vkVoidFunction(test_vkCmdInsertDebugUtilsLabelEXT);
+ }
// look for device functions setup from a test
for (const auto& phys_dev : icd.physical_devices) {
for (const auto& function : phys_dev.known_device_functions) {
diff --git a/tests/framework/icd/test_icd.h b/tests/framework/icd/test_icd.h
index 6acdab142..8134632ee 100644
--- a/tests/framework/icd/test_icd.h
+++ b/tests/framework/icd/test_icd.h
@@ -110,6 +110,28 @@ struct TestICD {
return info;
}
+ struct FindDevice {
+ bool found = false;
+ uint32_t phys_dev_index = 0;
+ uint32_t dev_index = 0;
+ };
+
+ FindDevice lookup_device(VkDevice device) {
+ FindDevice fd{};
+ for (uint32_t p = 0; p < physical_devices.size(); p++) {
+ auto const& phys_dev = physical_devices.at(p);
+ for (uint32_t d = 0; d < phys_dev.device_handles.size(); d++) {
+ if (phys_dev.device_handles.at(d) == device) {
+ fd.found = true;
+ fd.phys_dev_index = p;
+ fd.dev_index = d;
+ return fd;
+ }
+ }
+ }
+ return fd;
+ }
+
#if defined(WIN32)
BUILDER_VALUE(TestICD, LUID, adapterLUID, {})
#endif // defined(WIN32)
diff --git a/tests/framework/test_environment.cpp b/tests/framework/test_environment.cpp
index 4a99046ac..49d067db4 100644
--- a/tests/framework/test_environment.cpp
+++ b/tests/framework/test_environment.cpp
@@ -563,59 +563,68 @@ void setup_WSI_in_create_instance(InstWrapper& inst, const char* api_selection)
}
template <typename CreationFunc, typename CreateInfo>
-void create_surface_helper(InstWrapper& inst, VkSurfaceKHR& surface, const char* load_func_name) {
+testing::AssertionResult create_surface_helper(InstWrapper& inst, VkSurfaceKHR& surface, const char* load_func_name) {
CreationFunc pfn_CreateSurface = inst.load(load_func_name);
+ if (!pfn_CreateSurface) return testing::AssertionFailure();
CreateInfo surf_create_info{};
- ASSERT_EQ(VK_SUCCESS, pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface));
+ VkResult res = pfn_CreateSurface(inst, &surf_create_info, nullptr, &surface);
+ return res == VK_SUCCESS ? testing::AssertionSuccess() : testing::AssertionFailure();
}
-void create_surface(InstWrapper& inst, VkSurfaceKHR& surface, const char* api_selection) {
+testing::AssertionResult 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");
+ return 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");
+ return create_surface_helper<PFN_vkCreateDirectFBSurfaceEXT, VkDirectFBSurfaceCreateInfoEXT>(inst, surface,
+ "vkCreateDirectFBSurfaceEXT")
#elif defined(VK_USE_PLATFORM_FUCHSIA)
- create_surface_helper<PFN_vkCreateImagePipeSurfaceFUCHSIA, VkImagePipeSurfaceCreateInfoFUCHSIA>(
+ return create_surface_helper<PFN_vkCreateImagePipeSurfaceFUCHSIA, VkImagePipeSurfaceCreateInfoFUCHSIA>(
inst, surface, "vkCreateImagePipeSurfaceFUCHSIA");
#elif defined(VK_USE_PLATFORM_GGP)
- create_surface_helper<PFN__vkCreateStreamDescriptorSurfaceGGP, VkStreamDescriptorSurfaceCreateInfoGGP>(
+ return 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");
+ return 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");
+ return 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");
+ return create_surface_helper<PFN_vkCreateMetalSurfaceEXT, VkMetalSurfaceCreateInfoEXT>(inst, surface,
+ "vkCreateMetalSurfaceEXT");
#endif
+ return testing::AssertionFailure();
#elif defined(VK_USE_PLATFORM_SCREEN_QNX)
- create_surface_helper<PFN_vkCreateScreenSurfaceQNX, VkScreenSurfaceCreateInfoQNX>(inst, surface, "vkCreateScreenSurfaceQNX");
+ return 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");
+ return 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");
+ return 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");
+ return 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");
+ return 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");
+ return create_surface_helper<PFN_vkCreateXcbSurfaceKHR, VkXcbSurfaceCreateInfoKHR>(inst, surface, "vkCreateXcbSurfaceKHR");
#endif
+ return testing::AssertionFailure();
#else
- create_surface_helper<PFN_vkCreateDisplayPlaneSurfaceKHR, VkDisplaySurfaceCreateInfoKHR>(inst, surface,
- "vkCreateDisplayPlaneSurfaceKHR");
+ return 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 fcdd681db..261b85ff6 100644
--- a/tests/framework/test_environment.h
+++ b/tests/framework/test_environment.h
@@ -546,7 +546,8 @@ void setup_WSI_in_create_instance(InstWrapper& inst, const char* api_selection =
// 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);
+// Returns an assertion failure if the surface failed to be created
+testing::AssertionResult create_surface(InstWrapper& inst, VkSurfaceKHR& out_surface, const char* api_selection = nullptr);
struct EnvVarCleaner {
std::string env_var;
diff --git a/tests/framework/test_util.cpp b/tests/framework/test_util.cpp
index 4b67dba77..231e81eb6 100644
--- a/tests/framework/test_util.cpp
+++ b/tests/framework/test_util.cpp
@@ -544,13 +544,35 @@ InstanceCreateInfo& InstanceCreateInfo::set_api_version(uint32_t major, uint32_t
}
DeviceQueueCreateInfo::DeviceQueueCreateInfo() { queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; }
+DeviceQueueCreateInfo::DeviceQueueCreateInfo(const VkDeviceQueueCreateInfo* create_info) {
+ queue_create_info = *create_info;
+ for (uint32_t i = 0; i < create_info->queueCount; i++) {
+ priorities.push_back(create_info->pQueuePriorities[i]);
+ }
+}
VkDeviceQueueCreateInfo DeviceQueueCreateInfo::get() noexcept {
queue_create_info.pQueuePriorities = priorities.data();
+ queue_create_info.queueCount = 1;
+ queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
return queue_create_info;
}
+DeviceCreateInfo::DeviceCreateInfo(const VkDeviceCreateInfo* create_info) {
+ dev = *create_info;
+ for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
+ enabled_extensions.push_back(create_info->ppEnabledExtensionNames[i]);
+ }
+ for (uint32_t i = 0; i < create_info->enabledLayerCount; i++) {
+ enabled_layers.push_back(create_info->ppEnabledLayerNames[i]);
+ }
+ for (uint32_t i = 0; i < create_info->queueCreateInfoCount; i++) {
+ device_queue_infos.push_back(create_info->pQueueCreateInfos[i]);
+ }
+}
+
VkDeviceCreateInfo* DeviceCreateInfo::get() noexcept {
+ dev.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
dev.enabledLayerCount = static_cast<uint32_t>(enabled_layers.size());
dev.ppEnabledLayerNames = enabled_layers.data();
dev.enabledExtensionCount = static_cast<uint32_t>(enabled_extensions.size());
@@ -558,6 +580,7 @@ VkDeviceCreateInfo* DeviceCreateInfo::get() noexcept {
uint32_t index = 0;
for (auto& queue : queue_info_details) {
queue.queue_create_info.queueFamilyIndex = index++;
+ queue.queue_create_info.queueCount = 1;
device_queue_infos.push_back(queue.get());
}
diff --git a/tests/framework/test_util.h b/tests/framework/test_util.h
index 719b8e632..ed849cbf2 100644
--- a/tests/framework/test_util.h
+++ b/tests/framework/test_util.h
@@ -663,14 +663,19 @@ struct InstanceCreateInfo {
};
struct DeviceQueueCreateInfo {
+ DeviceQueueCreateInfo();
+ DeviceQueueCreateInfo(const VkDeviceQueueCreateInfo* create_info);
+
BUILDER_VALUE(DeviceQueueCreateInfo, VkDeviceQueueCreateInfo, queue_create_info, {})
BUILDER_VECTOR(DeviceQueueCreateInfo, float, priorities, priority)
- DeviceQueueCreateInfo();
VkDeviceQueueCreateInfo get() noexcept;
};
struct DeviceCreateInfo {
+ DeviceCreateInfo() = default;
+ DeviceCreateInfo(const VkDeviceCreateInfo* create_info);
+
BUILDER_VALUE(DeviceCreateInfo, VkDeviceCreateInfo, dev, {})
BUILDER_VECTOR(DeviceCreateInfo, const char*, enabled_extensions, extension)
BUILDER_VECTOR(DeviceCreateInfo, const char*, enabled_layers, layer)
diff --git a/tests/live_verification/CMakeLists.txt b/tests/live_verification/CMakeLists.txt
index 87155e23a..d9d51366a 100644
--- a/tests/live_verification/CMakeLists.txt
+++ b/tests/live_verification/CMakeLists.txt
@@ -29,4 +29,4 @@ if(APPLE AND BUILD_STATIC_LOADER)
target_compile_options(macos_static_loader_build PUBLIC -fsanitize=thread)
target_link_options(macos_static_loader_build PUBLIC -fsanitize=thread)
endif()
-endif() \ No newline at end of file
+endif()
diff --git a/tests/live_verification/dynamic_rendering_get_proc_addr.cpp b/tests/live_verification/dynamic_rendering_get_proc_addr.cpp
index f4a521fbc..95aea3e0d 100644
--- a/tests/live_verification/dynamic_rendering_get_proc_addr.cpp
+++ b/tests/live_verification/dynamic_rendering_get_proc_addr.cpp
@@ -69,7 +69,9 @@ int main() {
VkCommandBufferBeginInfo begin_info{};
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
VkResult res = vkBeginCommandBuffer(command_buffer, &begin_info);
- assert(res == VK_SUCCESS);
+ if (res != VK_SUCCESS) {
+ std::cout << "Failed to begin command buffer\n";
+ }
// call the dynamic rendering function -- should not go into the physical device function trampoline.
PFN_vkCmdBeginRenderingKHR vkCmdBeginRenderingKHR =
@@ -79,4 +81,4 @@ int main() {
vkCmdBeginRenderingKHR(command_buffer, &rendering_info);
}
}
-} \ No newline at end of file
+}
diff --git a/tests/loader_debug_ext_tests.cpp b/tests/loader_debug_ext_tests.cpp
index 1cefbb8c5..59bb80887 100644
--- a/tests/loader_debug_ext_tests.cpp
+++ b/tests/loader_debug_ext_tests.cpp
@@ -849,3 +849,163 @@ TEST_F(ManualMessage, InfoMessage) {
// Message should be found
ASSERT_EQ(true, message_found);
}
+
+void CheckDeviceFunctions(FrameworkEnvironment& env, bool use_GIPA, bool enable_debug_extensions) {
+ InstWrapper inst(env.vulkan_functions);
+ if (enable_debug_extensions) {
+ inst.create_info.add_extension("VK_EXT_debug_utils");
+ }
+ setup_WSI_in_create_instance(inst);
+ ASSERT_NO_FATAL_FAILURE(inst.CheckCreate());
+
+ auto phys_dev = inst.GetPhysDev();
+
+ DeviceWrapper dev{inst};
+ dev.create_info.add_extension("VK_KHR_swapchain");
+ dev.create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
+ if (enable_debug_extensions) {
+ dev.create_info.add_extension("VK_EXT_debug_marker");
+ }
+ // if the hardware doesn't support VK_EXT_debug_marker and we are trying to enable it, then we should exit since that will fail
+ // to create a device
+ if (enable_debug_extensions &&
+ env.get_test_icd().physical_devices.at(0).extensions.size() == 1 /*only swapchain should be available*/) {
+ dev.CheckCreate(phys_dev, VK_ERROR_EXTENSION_NOT_PRESENT);
+ return;
+ }
+ ASSERT_NO_FATAL_FAILURE(dev.CheckCreate(phys_dev));
+ DeviceFunctions dev_funcs{env.vulkan_functions, dev};
+
+ VkSurfaceKHR surface{};
+ ASSERT_NO_FATAL_FAILURE(create_surface(inst, surface));
+
+ VkSwapchainCreateInfoKHR info{};
+ info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+ info.surface = surface;
+
+ VkSwapchainKHR swapchain{};
+ ASSERT_EQ(VK_SUCCESS, dev_funcs.vkCreateSwapchainKHR(dev.dev, &info, nullptr, &swapchain));
+
+ PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT;
+ DebugMarkerSetObjectTagEXT = use_GIPA ? inst.load("vkDebugMarkerSetObjectTagEXT") : dev.load("vkDebugMarkerSetObjectTagEXT");
+ PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT;
+ DebugMarkerSetObjectNameEXT = use_GIPA ? inst.load("vkDebugMarkerSetObjectNameEXT") : dev.load("vkDebugMarkerSetObjectNameEXT");
+ PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT;
+ SetDebugUtilsObjectNameEXT = use_GIPA ? inst.load("vkSetDebugUtilsObjectNameEXT") : dev.load("vkSetDebugUtilsObjectNameEXT");
+ PFN_vkSetDebugUtilsObjectTagEXT SetDebugUtilsObjectTagEXT;
+ SetDebugUtilsObjectTagEXT = use_GIPA ? inst.load("vkSetDebugUtilsObjectTagEXT") : dev.load("vkSetDebugUtilsObjectTagEXT");
+ PFN_vkQueueBeginDebugUtilsLabelEXT QueueBeginDebugUtilsLabelEXT;
+ QueueBeginDebugUtilsLabelEXT =
+ use_GIPA ? inst.load("vkQueueBeginDebugUtilsLabelEXT") : dev.load("vkQueueBeginDebugUtilsLabelEXT");
+ PFN_vkQueueEndDebugUtilsLabelEXT QueueEndDebugUtilsLabelEXT;
+ QueueEndDebugUtilsLabelEXT = use_GIPA ? inst.load("vkQueueEndDebugUtilsLabelEXT") : dev.load("vkQueueEndDebugUtilsLabelEXT");
+ PFN_vkQueueInsertDebugUtilsLabelEXT QueueInsertDebugUtilsLabelEXT;
+ QueueInsertDebugUtilsLabelEXT =
+ use_GIPA ? inst.load("vkQueueInsertDebugUtilsLabelEXT") : dev.load("vkQueueInsertDebugUtilsLabelEXT");
+ PFN_vkCmdBeginDebugUtilsLabelEXT CmdBeginDebugUtilsLabelEXT;
+ CmdBeginDebugUtilsLabelEXT = use_GIPA ? inst.load("vkCmdBeginDebugUtilsLabelEXT") : dev.load("vkCmdBeginDebugUtilsLabelEXT");
+ PFN_vkCmdEndDebugUtilsLabelEXT CmdEndDebugUtilsLabelEXT;
+ CmdEndDebugUtilsLabelEXT = use_GIPA ? inst.load("vkCmdEndDebugUtilsLabelEXT") : dev.load("vkCmdEndDebugUtilsLabelEXT");
+ PFN_vkCmdInsertDebugUtilsLabelEXT CmdInsertDebugUtilsLabelEXT;
+ CmdInsertDebugUtilsLabelEXT = use_GIPA ? inst.load("vkCmdInsertDebugUtilsLabelEXT") : dev.load("vkCmdInsertDebugUtilsLabelEXT");
+
+ if (use_GIPA) {
+ // When querying from GIPA, these functions should always be found
+ ASSERT_TRUE(nullptr != DebugMarkerSetObjectTagEXT);
+ ASSERT_TRUE(nullptr != DebugMarkerSetObjectNameEXT);
+ // When querying from GIPA, these functions are found only if the extensions were enabled
+ ASSERT_EQ(enable_debug_extensions, nullptr != SetDebugUtilsObjectNameEXT);
+ ASSERT_EQ(enable_debug_extensions, nullptr != SetDebugUtilsObjectTagEXT);
+ ASSERT_EQ(enable_debug_extensions, nullptr != QueueBeginDebugUtilsLabelEXT);
+ ASSERT_EQ(enable_debug_extensions, nullptr != QueueEndDebugUtilsLabelEXT);
+ ASSERT_EQ(enable_debug_extensions, nullptr != QueueInsertDebugUtilsLabelEXT);
+ ASSERT_EQ(enable_debug_extensions, nullptr != CmdBeginDebugUtilsLabelEXT);
+ ASSERT_EQ(enable_debug_extensions, nullptr != CmdEndDebugUtilsLabelEXT);
+ ASSERT_EQ(enable_debug_extensions, nullptr != CmdInsertDebugUtilsLabelEXT);
+ } else {
+ // When querying from GDPA, these functions are found only if the extensions were enabled
+ ASSERT_EQ(enable_debug_extensions, nullptr != DebugMarkerSetObjectTagEXT);
+ ASSERT_EQ(enable_debug_extensions, nullptr != DebugMarkerSetObjectNameEXT);
+ // When querying from GDPA, these functions should always be found
+ ASSERT_TRUE(nullptr != SetDebugUtilsObjectNameEXT);
+ ASSERT_TRUE(nullptr != SetDebugUtilsObjectTagEXT);
+ ASSERT_TRUE(nullptr != QueueBeginDebugUtilsLabelEXT);
+ ASSERT_TRUE(nullptr != QueueEndDebugUtilsLabelEXT);
+ ASSERT_TRUE(nullptr != QueueInsertDebugUtilsLabelEXT);
+ ASSERT_TRUE(nullptr != CmdBeginDebugUtilsLabelEXT);
+ ASSERT_TRUE(nullptr != CmdEndDebugUtilsLabelEXT);
+ ASSERT_TRUE(nullptr != CmdInsertDebugUtilsLabelEXT);
+ }
+ VkDebugUtilsObjectNameInfoEXT obj_name_info{};
+ obj_name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
+ obj_name_info.objectHandle = (uint64_t)swapchain;
+ obj_name_info.objectType = VK_OBJECT_TYPE_SWAPCHAIN_KHR;
+ obj_name_info.pObjectName = " Your mom!";
+ if (SetDebugUtilsObjectNameEXT) SetDebugUtilsObjectNameEXT(dev.dev, &obj_name_info);
+
+ VkDebugMarkerObjectTagInfoEXT marker_object_tag{};
+ VkDebugMarkerObjectNameInfoEXT marker_object_name{};
+ if (use_GIPA && !enable_debug_extensions) {
+ // These functions crash when the extension isn't enabled and the function was acquired with GIPA.
+ ASSERT_DEATH(DebugMarkerSetObjectTagEXT(dev.dev, &marker_object_tag), "");
+ ASSERT_DEATH(DebugMarkerSetObjectNameEXT(dev.dev, &marker_object_name), "");
+ } else {
+ if (DebugMarkerSetObjectTagEXT) DebugMarkerSetObjectTagEXT(dev.dev, &marker_object_tag);
+ if (DebugMarkerSetObjectNameEXT) DebugMarkerSetObjectNameEXT(dev.dev, &marker_object_name);
+ }
+ if (SetDebugUtilsObjectNameEXT) SetDebugUtilsObjectNameEXT(dev.dev, &obj_name_info);
+ VkDebugUtilsObjectTagInfoEXT utils_object_tag{};
+ if (SetDebugUtilsObjectTagEXT) SetDebugUtilsObjectTagEXT(dev.dev, &utils_object_tag);
+ VkQueue queue{};
+ dev.functions->vkGetDeviceQueue(dev.dev, 0, 0, &queue);
+ VkDebugUtilsLabelEXT utils_label{};
+ utils_label.pLabelName = "Testing testing 123";
+ if (QueueBeginDebugUtilsLabelEXT) QueueBeginDebugUtilsLabelEXT(queue, &utils_label);
+ if (QueueEndDebugUtilsLabelEXT) QueueEndDebugUtilsLabelEXT(queue);
+ if (QueueInsertDebugUtilsLabelEXT) QueueInsertDebugUtilsLabelEXT(queue, &utils_label);
+ VkCommandBuffer cmd_buf{};
+ VkCommandPool cmd_pool;
+ VkCommandPoolCreateInfo cmd_pool_info{};
+ cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+ ASSERT_EQ(VK_SUCCESS, dev_funcs.vkCreateCommandPool(dev.dev, &cmd_pool_info, nullptr, &cmd_pool));
+ VkCommandBufferAllocateInfo cmd_buf_alloc_info{};
+ cmd_buf_alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+ cmd_buf_alloc_info.commandBufferCount = 1;
+ cmd_buf_alloc_info.commandPool = cmd_pool;
+ ASSERT_EQ(VK_SUCCESS, dev_funcs.vkAllocateCommandBuffers(dev.dev, &cmd_buf_alloc_info, &cmd_buf));
+ if (CmdBeginDebugUtilsLabelEXT) CmdBeginDebugUtilsLabelEXT(cmd_buf, &utils_label);
+ if (CmdEndDebugUtilsLabelEXT) CmdEndDebugUtilsLabelEXT(cmd_buf);
+ if (CmdInsertDebugUtilsLabelEXT) CmdInsertDebugUtilsLabelEXT(cmd_buf, &utils_label);
+
+ dev_funcs.vkDestroySwapchainKHR(dev.dev, swapchain, nullptr);
+ env.vulkan_functions.vkDestroySurfaceKHR(inst.inst, surface, nullptr);
+}
+
+TEST(GetDeviceProcAddr, DebugFuncsWithTerminator) {
+ FrameworkEnvironment env{};
+ env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+ setup_WSI_in_ICD(env.get_test_icd());
+ env.get_test_icd().physical_devices.emplace_back("physical_device_0");
+ env.get_test_icd().physical_devices.at(0).add_extensions({"VK_KHR_swapchain"});
+ // Hardware doesn't support the debug extensions
+
+ // Use getDeviceProcAddr & vary enabling the debug extensions
+ ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, false));
+ ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, true));
+
+ // Use getInstanceProcAddr & vary enabling the debug extensions
+ ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, false));
+ ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, true));
+
+ // Now set the hardware to support the extensions and run the situations again
+ env.get_test_icd().physical_devices.at(0).add_extensions({"VK_EXT_debug_marker"});
+ env.get_test_icd().add_instance_extension("VK_EXT_debug_utils");
+
+ // Use getDeviceProcAddr & vary enabling the debug extensions
+ ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, false));
+ ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, false, true));
+
+ // Use getInstanceProcAddr & vary enabling the debug extensions
+ ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, false));
+ ASSERT_NO_FATAL_FAILURE(CheckDeviceFunctions(env, true, true));
+}
diff --git a/tests/loader_get_proc_addr_tests.cpp b/tests/loader_get_proc_addr_tests.cpp
index 64a3c74d5..20f72685a 100644
--- a/tests/loader_get_proc_addr_tests.cpp
+++ b/tests/loader_get_proc_addr_tests.cpp
@@ -184,4 +184,111 @@ TEST(GetProcAddr, GlobalFunctions) {
EnumeratePhysicalDevices = reinterpret_cast<PFN_vkGetInstanceProcAddr>(gipa(NULL, "vkEnumeratePhysicalDevices"));
handle_assert_null(EnumeratePhysicalDevices);
}
-} \ No newline at end of file
+}
+
+// Swapchain functions which require a terminator in all cases have situations where the driver may have a
+// NULL function pointer but the loader shouldn't abort() if that is the case. Rather, it should log a message
+// and return VK_SUCCESS to maintain previous behavior.
+TEST(GetDeviceProcAddr, SwapchainFuncsWithTerminator) {
+ FrameworkEnvironment env{};
+ env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+ setup_WSI_in_ICD(env.get_test_icd());
+ env.get_test_icd().physical_devices.emplace_back("physical_device_0");
+
+ InstWrapper inst(env.vulkan_functions);
+ inst.create_info.add_extension("VK_EXT_debug_utils");
+ setup_WSI_in_create_instance(inst);
+ ASSERT_NO_FATAL_FAILURE(inst.CheckCreate());
+
+ VkSurfaceKHR surface{};
+ ASSERT_NO_FATAL_FAILURE(create_surface(inst, surface));
+
+ DebugUtilsWrapper log{inst};
+ ASSERT_EQ(VK_SUCCESS, CreateDebugUtilsMessenger(log));
+ auto phys_dev = inst.GetPhysDev();
+ {
+ DeviceWrapper dev{inst};
+ dev.create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
+ ASSERT_NO_FATAL_FAILURE(dev.CheckCreate(phys_dev));
+ DeviceFunctions dev_funcs{env.vulkan_functions, dev};
+
+ PFN_vkCreateSwapchainKHR CreateSwapchainKHR = dev.load("vkCreateSwapchainKHR");
+ PFN_vkCreateSwapchainKHR inst_CreateSwapchainKHR = inst.load("vkCreateSwapchainKHR");
+ PFN_vkGetDeviceGroupSurfacePresentModesKHR GetDeviceGroupSurfacePresentModesKHR =
+ dev.load("vkGetDeviceGroupSurfacePresentModesKHR");
+ PFN_vkCreateSharedSwapchainsKHR CreateSharedSwapchainsKHR = dev.load("vkCreateSharedSwapchainsKHR");
+ ASSERT_FALSE(CreateSwapchainKHR);
+ ASSERT_TRUE(inst_CreateSwapchainKHR);
+ ASSERT_FALSE(GetDeviceGroupSurfacePresentModesKHR);
+ ASSERT_FALSE(CreateSharedSwapchainsKHR);
+
+ VkSwapchainCreateInfoKHR info{};
+ info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+ info.surface = surface;
+
+ VkSwapchainKHR swapchain{};
+ if (CreateSwapchainKHR) CreateSwapchainKHR(dev.dev, &info, nullptr, &swapchain);
+ ASSERT_FALSE(
+ log.find("vkCreateSwapchainKHR: Driver's function pointer was NULL, returning VK_SUCCESS. Was the VK_KHR_swapchain "
+ "extension enabled?"));
+ log.logger.clear();
+ if (dev_funcs.vkDestroySwapchainKHR) dev_funcs.vkDestroySwapchainKHR(dev.dev, swapchain, nullptr);
+ // try to call the vkCreateSwapchainKHR acquired from the instance - this *should* abort due to not enabling the extension
+ if (inst_CreateSwapchainKHR) {
+ ASSERT_DEATH(inst_CreateSwapchainKHR(dev.dev, &info, nullptr, &swapchain),
+ "vkCreateSwapchainKHR: Driver's function pointer was NULL, returning VK_SUCCESS. Was the VK_KHR_swapchain "
+ "extension enabled?");
+ }
+ log.logger.clear();
+ if (dev_funcs.vkDestroySwapchainKHR) dev_funcs.vkDestroySwapchainKHR(dev.dev, swapchain, nullptr);
+
+ VkDeviceGroupPresentModeFlagsKHR modes{};
+ if (GetDeviceGroupSurfacePresentModesKHR) GetDeviceGroupSurfacePresentModesKHR(dev.dev, surface, &modes);
+
+ if (CreateSharedSwapchainsKHR) CreateSharedSwapchainsKHR(dev.dev, 1, &info, nullptr, &swapchain);
+ }
+ {
+ env.get_test_icd().physical_devices.at(0).add_extensions(
+ {"VK_KHR_swapchain", "VK_KHR_display_swapchain", "VK_EXT_debug_marker"});
+
+ DeviceWrapper dev{inst};
+ dev.create_info.add_extensions({"VK_KHR_swapchain", "VK_KHR_display_swapchain", "VK_EXT_debug_marker"});
+ dev.create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
+ ASSERT_NO_FATAL_FAILURE(dev.CheckCreate(phys_dev));
+ DeviceFunctions dev_funcs{env.vulkan_functions, dev};
+
+ PFN_vkCreateSwapchainKHR CreateSwapchainKHR = dev.load("vkCreateSwapchainKHR");
+ PFN_vkCreateSwapchainKHR inst_CreateSwapchainKHR = inst.load("vkCreateSwapchainKHR");
+ PFN_vkGetDeviceGroupSurfacePresentModesKHR GetDeviceGroupSurfacePresentModesKHR =
+ dev.load("vkGetDeviceGroupSurfacePresentModesKHR");
+ PFN_vkCreateSharedSwapchainsKHR CreateSharedSwapchainsKHR = dev.load("vkCreateSharedSwapchainsKHR");
+ ASSERT_TRUE(CreateSwapchainKHR);
+ ASSERT_TRUE(inst_CreateSwapchainKHR);
+ ASSERT_TRUE(GetDeviceGroupSurfacePresentModesKHR);
+ ASSERT_TRUE(CreateSharedSwapchainsKHR);
+
+ VkSwapchainCreateInfoKHR info{};
+ info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+ info.surface = surface;
+
+ VkSwapchainKHR swapchain{};
+ if (CreateSwapchainKHR) CreateSwapchainKHR(dev.dev, &info, nullptr, &swapchain);
+ ASSERT_FALSE(
+ log.find("vkCreateSwapchainKHR: Driver's function pointer was NULL, returning VK_SUCCESS. Was the VK_KHR_swapchain "
+ "extension enabled?"));
+ log.logger.clear();
+ if (dev_funcs.vkDestroySwapchainKHR) dev_funcs.vkDestroySwapchainKHR(dev.dev, swapchain, nullptr);
+ if (inst_CreateSwapchainKHR) inst_CreateSwapchainKHR(dev.dev, &info, nullptr, &swapchain);
+ ASSERT_FALSE(
+ log.find("vkCreateSwapchainKHR: Driver's function pointer was NULL, returning VK_SUCCESS. Was the VK_KHR_swapchain "
+ "extension enabled?"));
+ log.logger.clear();
+ if (dev_funcs.vkDestroySwapchainKHR) dev_funcs.vkDestroySwapchainKHR(dev.dev, swapchain, nullptr);
+
+ VkDeviceGroupPresentModeFlagsKHR modes{};
+ if (GetDeviceGroupSurfacePresentModesKHR) GetDeviceGroupSurfacePresentModesKHR(dev.dev, surface, &modes);
+
+ if (CreateSharedSwapchainsKHR) CreateSharedSwapchainsKHR(dev.dev, 1, &info, nullptr, &swapchain);
+ }
+ env.vulkan_functions.vkDestroySurfaceKHR(inst.inst, surface, nullptr);
+}
diff --git a/tests/loader_wsi_tests.cpp b/tests/loader_wsi_tests.cpp
index a05e7c1ee..095aac958 100644
--- a/tests/loader_wsi_tests.cpp
+++ b/tests/loader_wsi_tests.cpp
@@ -797,12 +797,11 @@ TEST(WsiTests, ForgetEnableSurfaceExtensions) {
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();
+ inst.create_info.add_extension("VK_KHR_surface");
+ ASSERT_NO_FATAL_FAILURE(inst.CheckCreate());
VkSurfaceKHR surface{};
- ASSERT_DEATH(create_surface(inst, surface), "");
+ ASSERT_FALSE(create_surface(inst, surface));
}
TEST(WsiTests, SwapchainFunctional) {
@@ -823,20 +822,12 @@ TEST(WsiTests, SwapchainFunctional) {
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);
- {
+ { // Use GDPA to get functions
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);
+ ASSERT_NO_FATAL_FAILURE(dev.CheckCreate(phys_dev));
VkSwapchainKHR swapchain{};
VkSwapchainCreateInfoKHR swap_create_info{};
@@ -850,12 +841,40 @@ TEST(WsiTests, SwapchainFunctional) {
ASSERT_EQ(VK_SUCCESS, funcs.vkGetSwapchainImagesKHR(dev, swapchain, &count, images.data()));
funcs.vkDestroySwapchainKHR(dev, swapchain, nullptr);
}
+ { // Use GIPA gotten functions
+ DeviceWrapper dev{inst};
+ dev.create_info.add_extension("VK_KHR_swapchain");
+ dev.create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
+
+ ASSERT_NO_FATAL_FAILURE(dev.CheckCreate(phys_dev));
+
+ PFN_vkCreateSwapchainKHR inst_CreateSwapchainKHR = inst.load("vkCreateSwapchainKHR");
+ PFN_vkGetSwapchainImagesKHR inst_GetSwapchainImagesKHR = inst.load("vkGetSwapchainImagesKHR");
+ PFN_vkDestroySwapchainKHR inst_DestroySwapchainKHR = inst.load("vkDestroySwapchainKHR");
+ ASSERT_TRUE(nullptr != inst_CreateSwapchainKHR);
+ ASSERT_TRUE(nullptr != inst_GetSwapchainImagesKHR);
+ ASSERT_TRUE(nullptr != inst_DestroySwapchainKHR);
+
+ VkSwapchainKHR swapchain{};
+ VkSwapchainCreateInfoKHR swap_create_info{};
+ swap_create_info.surface = surface;
+
+ ASSERT_EQ(VK_SUCCESS, inst_CreateSwapchainKHR(dev, &swap_create_info, nullptr, &swapchain));
+ uint32_t count = 0;
+ ASSERT_EQ(VK_SUCCESS, inst_GetSwapchainImagesKHR(dev, swapchain, &count, nullptr));
+ ASSERT_GT(count, 0U);
+ std::array<VkImage, 16> images;
+ ASSERT_EQ(VK_SUCCESS, inst_GetSwapchainImagesKHR(dev, swapchain, &count, images.data()));
+ inst_DestroySwapchainKHR(dev, swapchain, nullptr);
+ }
{ // forget to enable the extension
DeviceWrapper dev{inst};
- dev.CheckCreate(phys_dev);
+ ASSERT_NO_FATAL_FAILURE(dev.CheckCreate(phys_dev));
DeviceFunctions funcs{*inst.functions, dev};
ASSERT_EQ(funcs.vkCreateSwapchainKHR, nullptr);
+ ASSERT_EQ(funcs.vkGetSwapchainImagesKHR, nullptr);
+ ASSERT_EQ(funcs.vkDestroySwapchainKHR, nullptr);
}
{ // forget to set the surface
DeviceWrapper dev{inst};