diff options
-rw-r--r-- | loader/generated/vk_loader_extensions.c | 26 | ||||
-rw-r--r-- | loader/wsi.c | 39 | ||||
-rw-r--r-- | scripts/loader_extension_generator.py | 2 | ||||
-rw-r--r-- | tests/framework/icd/physical_device.h | 4 | ||||
-rw-r--r-- | tests/framework/icd/test_icd.cpp | 101 | ||||
-rw-r--r-- | tests/framework/icd/test_icd.h | 22 | ||||
-rw-r--r-- | tests/framework/test_environment.cpp | 51 | ||||
-rw-r--r-- | tests/framework/test_environment.h | 3 | ||||
-rw-r--r-- | tests/framework/test_util.cpp | 23 | ||||
-rw-r--r-- | tests/framework/test_util.h | 7 | ||||
-rw-r--r-- | tests/live_verification/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tests/live_verification/dynamic_rendering_get_proc_addr.cpp | 6 | ||||
-rw-r--r-- | tests/loader_debug_ext_tests.cpp | 160 | ||||
-rw-r--r-- | tests/loader_get_proc_addr_tests.cpp | 109 | ||||
-rw-r--r-- | tests/loader_wsi_tests.cpp | 49 |
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}; |